package net.lshift.spki.convert;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotations to guide the SExp converter.
 */
public class Convert
{
    /**
     * An annotation for annotations - the registry uses this
     * to learn how to interpret an annotation in order to
     * construct a converter for a class
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.ANNOTATION_TYPE,ElementType.TYPE})
    public @interface ConverterFactoryClass {
        Class<? extends ConverterFactory<?>> value();
    }

    /**
     * Each field has a specific position in the sexp
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @ConverterFactoryClass(PositionBeanConverterFactory.class)
    public @interface ByPosition {
        String name();
        String[] fields();
    }

    /**
     * Each field gets a named sub-sexp in the sexp for this object
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @ConverterFactoryClass(NameBeanConverterFactory.class)
    public @interface ByName {
        String value();
    }

    /**
     * There's only one field, which is a list type; write the name first
     * then convert each element of the list one by one
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @ConverterFactoryClass(SequenceConverterFactory.class)
    public @interface SequenceConverted {
        String value();
    }

    /**
     * This is one of several sub-classes, discriminated by the name of the sexp.
     *
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @ConverterFactoryClass(DiscriminatingConverterFactory.class)
    public @interface Discriminated {
       Class<?> [] value();
    }

    /**
     * The converter should be an instance of this class
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @ConverterFactoryClass(ConvertClassFactory.class)
    public @interface ConvertClass {
        // FIXME: why doesn't Class<StepConverter<?,?>> work?
        Class<?> value();
    }

    /**
     * This specifies how to interpret annotations specifying
     * actions that should take place after the converter is registered.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.ANNOTATION_TYPE,ElementType.TYPE})
    public @interface HandlerClass {
        Class<? extends AnnotationHandler<?>> value();
    }

    /**
     * Another converter must be registered for this converter to work
     * - usually a foreign class
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @HandlerClass(RequiresConverterHandler.class)
    public @interface RequiresConverter {
        Class<? extends Converter<?>> value();
    }

    /**
     * This class should be registered after the fact with a
     * DiscriminatingConverter of another class.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    @HandlerClass(InstanceOfHandler.class)
    public @interface InstanceOf {
        Class<?> value();
    }
}

@@ -522,33 +522,16 @@
 ION_TYPE
-,ElementType.TYPE
 %7D)%0A    p
@@ -2437,25 +2437,8 @@
 TYPE
-,ElementType.TYPE
 %7D)%0A 

Remove unnecessary @Target ElementType