web/play-java-forms/src/main/java/play/data/format/Formatters.java
@SuppressWarnings("unchecked")
  public <A extends Annotation, T> Formatters register(
      final Class<T> clazz, final AnnotationFormatter<A, T> formatter) {
    final Class<? extends Annotation> annotationType =
        (Class<? extends Annotation>)
            GenericTypeResolver.resolveTypeArguments(
                formatter.getClass(), AnnotationFormatter.class)[0];

    conversion.addConverter(
        new ConditionalGenericConverter() {
          public Set<GenericConverter.ConvertiblePair> getConvertibleTypes() {
            Set<GenericConverter.ConvertiblePair> types = new HashSet<>();
            types.add(new GenericConverter.ConvertiblePair(clazz, String.class));
            return types;
          }

          public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
            return (sourceType.getAnnotation(annotationType) != null);
          }

          public Object convert(
              Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
            final A a = (A) sourceType.getAnnotation(annotationType);
            Locale locale = LocaleContextHolder.getLocale();
            try {
              return formatter.print(a, (T) source, locale);
            } catch (Exception ex) {
              throw new ConversionFailedException(sourceType, targetType, source, ex);
            }
          }

          public String toString() {
            return "@"
                + annotationType.getName()
                + " "
                + clazz.getName()
                + " -> "
                + String.class.getName()
                + ": "
                + formatter;
          }
        });

    conversion.addConverter(
        new ConditionalGenericConverter() {
          public Set<GenericConverter.ConvertiblePair> getConvertibleTypes() {
            Set<GenericConverter.ConvertiblePair> types = new HashSet<>();
            types.add(new GenericConverter.ConvertiblePair(String.class, clazz));
            return types;
          }

          public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
            return (targetType.getAnnotation(annotationType) != null);
          }

          public Object convert(
              Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
            final A a = (A) targetType.getAnnotation(annotationType);
            Locale locale = LocaleContextHolder.getLocale();
            try {
              return formatter.parse(a, (String) source, locale);
            } catch (Exception ex) {
              throw new ConversionFailedException(sourceType, targetType, source, ex);
            }
          }

          public String toString() {
            return String.class.getName()
                + " -> @"
                + annotationType.getName()
                + " "
                + clazz.getName()
                + ": "
                + formatter;
          }
        });

    return this;
  }
@SuppressWarnings("unchecked")
  public <A extends Annotation, T> Formatters register(
      final Class<T> clazz, final AnnotationFormatter<A, T> formatter) {
    final Class<? extends Annotation> annotationType =
        (Class<? extends Annotation>)
            GenericTypeResolver.resolveTypeArguments(
                formatter.getClass(), AnnotationFormatter.class)[0];

    conversion.addConverter(
        new ConditionalGenericConverter() {
          public Set<GenericConverter.ConvertiblePair> getConvertibleTypes() {
            Set<GenericConverter.ConvertiblePair> types = new HashSet<>();
            types.add(new GenericConverter.ConvertiblePair(clazz, String.class));
            return types;
          }

          public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
            return (sourceType.getAnnotation(annotationType) != null);
          }

          public Object convert(
              Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
            final A a = (A) sourceType.getAnnotation(annotationType);
            Locale locale = LocaleContextHolder.getLocale();
            try {
              return formatter.print(a, (T) source, locale);
            } catch (Exception ex) {
              throw new ConversionFailedException(sourceType, targetType, source, ex);
            }
          }

          public String toString() {
            return "@"
                + annotationType.getName()
                + " "
                + clazz.getName()
                + " -> "
                + String.class.getName()
                + ": "
                + formatter;
          }
        });

    conversion.addConverter(
        new ConditionalGenericConverter() {
          public Set<GenericConverter.ConvertiblePair> getConvertibleTypes() {
            Set<GenericConverter.ConvertiblePair> types = new HashSet<>();
            types.add(new GenericConverter.ConvertiblePair(String.class, clazz));
            return types;
          }

          public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
            return (targetType.getAnnotation(annotationType) != null);
          }

          public Object convert(
              Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
            final A a = (A) targetType.getAnnotation(annotationType);
            Locale locale = LocaleContextHolder.getLocale();
            try {
              return formatter.parse(a, (String) source, locale);
            } catch (Exception ex) {
              throw new ConversionFailedException(sourceType, targetType, source, ex);
            }
          }

          public String toString() {
            return String.class.getName()
                + " -> @"
                + annotationType.getName()
                + " "
                + clazz.getName()
                + ": "
                + formatter;
          }
        });

    return this;
  }
@ SuppressWarnings ( "unchecked" ) public < A extends Annotation , T > Formatters register ( final Class < T > clazz , final AnnotationFormatter < A , T > formatter ) { final Class < ? extends Annotation > annotationType = ( Class < ? extends Annotation > ) GenericTypeResolver . resolveTypeArguments ( formatter . getClass ( ) , AnnotationFormatter . class ) [ 0 ] ; conversion . addConverter ( new ConditionalGenericConverter ( ) { public Set < GenericConverter . ConvertiblePair > getConvertibleTypes ( ) { Set < GenericConverter . ConvertiblePair > types = new HashSet <> ( ) ; types . add ( new GenericConverter . ConvertiblePair ( clazz , String . class ) ) ; return types ; } public boolean matches ( TypeDescriptor sourceType , TypeDescriptor targetType ) { return ( sourceType . getAnnotation ( annotationType ) != null ) ; } public Object convert ( Object source , TypeDescriptor sourceType , TypeDescriptor targetType ) { final A a = ( A ) sourceType . getAnnotation ( annotationType ) ; Locale locale = LocaleContextHolder . getLocale ( ) ; try { return formatter . print ( a , ( T ) source , locale ) ; } catch ( Exception ex ) { throw new ConversionFailedException ( sourceType , targetType , source , ex ) ; } } public String toString ( ) { return "@" + annotationType . getName ( ) + " " + clazz . getName ( ) + " -> " + String . class . getName ( ) + ": " + formatter ; } } ) ; conversion . addConverter ( new ConditionalGenericConverter ( ) { public Set < GenericConverter . ConvertiblePair > getConvertibleTypes ( ) { Set < GenericConverter . ConvertiblePair > types = new HashSet <> ( ) ; types . add ( new GenericConverter . ConvertiblePair ( String . class , clazz ) ) ; return types ; } public boolean matches ( TypeDescriptor sourceType , TypeDescriptor targetType ) { return ( targetType . getAnnotation ( annotationType ) != null ) ; } public Object convert ( Object source , TypeDescriptor sourceType , TypeDescriptor targetType ) { final A a = ( A ) targetType . getAnnotation ( annotationType ) ; Locale locale = LocaleContextHolder . getLocale ( ) ; try { return formatter . parse ( a , ( String ) source , locale ) ; } catch ( Exception ex ) { throw new ConversionFailedException ( sourceType , targetType , source , ex ) ; } } public String toString ( ) { return String . class . getName ( ) + " -> @" + annotationType . getName ( ) + " " + clazz . getName ( ) + ": " + formatter ; } } ) ; return this ; }
Registers an annotation-based formatter.

@param clazz class handled by this formatter
@param formatter the formatter to register
@param <A> the annotation type
@param <T> the type that will be parsed or printed
@return the modified Formatters object.
Registers an annotation - based formatter .