Index: lutinutil/src/java/org/codelutin/util/OptionParserAnnotationHelper.java diff -u lutinutil/src/java/org/codelutin/util/OptionParserAnnotationHelper.java:1.2 lutinutil/src/java/org/codelutin/util/OptionParserAnnotationHelper.java:1.3 --- lutinutil/src/java/org/codelutin/util/OptionParserAnnotationHelper.java:1.2 Thu Nov 29 22:20:48 2007 +++ lutinutil/src/java/org/codelutin/util/OptionParserAnnotationHelper.java Sun Dec 2 05:13:37 2007 @@ -1,45 +1,70 @@ +/** + * ##% Copyright (C) 2002, 2007 Code Lutin This program is free software; you + * can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. This program is + * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. You + * should have received a copy of the GNU General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place + * - Suite 330, Boston, MA 02111-1307, USA. ##%* + */ + package org.codelutin.util; -import java.lang.annotation.ElementType; +import java.lang.annotation.Annotation; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.LOCAL_VARIABLE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; +import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; /** - * This classe contains all Annotations used in {@link OptionParser} to describe - * parser. + * This class contains all Annotations used in {@link OptionParser} to describe + * option's parser. + *

+ * We have some factories methods to compute hard annotation (usefull for + * code generation : we only instanciate the {@link OptionParserA}, then + * we transform it via javassist to byte-code. * * @author chemit */ - public class OptionParserAnnotationHelper { + //------------------------------------------------------------------------ + // Annotation definitions + //------------------------------------------------------------------------ + /** - * Annotation pour définir le paramétrage d'un parseur d'option + * Annotation pour définir le paramétrage d'un parseur d'options. * * @author chemit */ - @Retention(value = RetentionPolicy.RUNTIME) - - @Target(value = ElementType.TYPE) - + @Retention(value = RUNTIME) + @Target(value = {TYPE, LOCAL_VARIABLE, CONSTRUCTOR, METHOD, FIELD}) public static @interface OptionParserA { - /** @return la liste des clef d'options disponibles */ - public abstract String[] keys(); - + /** @return les options connues du parseur */ + public OptionA[] options() default {}; } /** - * Annotation pour définir le paramétrage d'une définition d'option + * Annotation pour définir le paramétrage de la définition d'une option. + *

+ * Par défault, un groupe d'argument est facultatif, i.e : + * ({@link #min()} =0) + * ({@link #max()} =1) * * @author chemit */ - @Retention(value = RetentionPolicy.RUNTIME) - - @Target(value = ElementType.FIELD) - - public static @interface OptionDefinitionA { + @Retention(value = RUNTIME) + @Target(value = ANNOTATION_TYPE) + public static @interface OptionA { /** @return le nom unique de l'option */ public String key(); @@ -48,58 +73,199 @@ public String[] alias(); /** @return le min */ - public int min(); + public int min() default 0; /** @return le max */ - public int max(); - - /** @return les arguments connus pour cette option */ - public OptionArgumentDefinitionA[] arguments(); - - /** @return la définition originale */ - public String definition(); + public int max() default 1; /** @return la description de la définition */ public String description(); + /** @return les groupes d'arguments connus pour cette option */ + public OptionGroupArgumentA[] groups() default {}; + /** @return la classe d'mplentation de l'option */ public Class impl() default Option.class; } /** - * Annotation pour définir le paramétrage d'une définition d'option + * Annotation pour définir le paramétrage de la définition d'un groupe + * d'arguments d'une option. + *

+ * Par défault, un groupe d'argument est facultatif, i.e : + * ({@link #min()} =0) + * ({@link #max()} =1) + * ({@link #pos()} =-1) * * @author chemit */ - @Retention(value = RetentionPolicy.RUNTIME) + @Retention(value = RUNTIME) + @Target(value = ANNOTATION_TYPE) + public static @interface OptionGroupArgumentA { - @Target(value = ElementType.ANNOTATION_TYPE) + /** @return le min */ + public int min() default 0; - public static @interface OptionArgumentDefinitionA { + /** @return le max */ + public int max() default 1; + + /** @return la position de l'argument (-1 si facultatif) */ + public int pos() default -1; + + /** @return les arguments connus pour ce groupe */ + public OptionArgumentA[] arguments(); + } + + /** + * Annotation pour définir le paramétrage de la définition d'un argument + * d'une option (plus précisement d'un groupe d'arguments d'option). + *

+ * Par défaut, un argument d'option est obligatoire + * ({@link #min()} =1) + * ({@link #max()} =1) + * + * @author chemit + */ + @Retention(value = RUNTIME) + @Target(value = ANNOTATION_TYPE) + public static @interface OptionArgumentA { /** @return la clef de l'argument */ public String key(); - /** - * @return le type de l'argument - * @see OptionArgumentType - */ + /** @return le type de l'argument */ public OptionArgumentType type(); - /** - * @return le type de la valeur de l'argument - * @see OptionArgumentValueType - */ + /** @return le type de la valeur de l'argument */ public OptionArgumentValueType valueType(); /** @return le min */ - public int min(); + public int min() default 1; /** @return le max */ - public int max(); + public int max() default 1; + } - /** @return la position de l'argument (-1 si facultatif) */ - public int pos(); + //------------------------------------------------------------------------ + // Factory methods + //------------------------------------------------------------------------ + + public static OptionParserA newOptionParserA(final OptionA[] optionAs) { + OptionParserA result; + result = new OptionParserA() { + public OptionA[] options() { + return optionAs; + } + + public Class annotationType() { + return OptionParserA.class; + } + }; + return result; + } + + public static OptionA newOptionA(final String key, + final String description, + final int min, final int max, + final String[] alias, + final Class impl, + final OptionGroupArgumentA[] groupAs) { + return new OptionA() { + public String key() { + return key; + } + + public String[] alias() { + return alias; + } + + public int min() { + return min; + } + + public int max() { + return max; + } + + public OptionGroupArgumentA[] groups() { + return groupAs; + } + + public OptionArgumentA[] arguments() { + return new OptionArgumentA[0]; + } + + public String description() { + return description; + } + + public Class impl() { + return impl; + } + + public Class annotationType() { + return OptionA.class; + } + }; + } + + public static OptionGroupArgumentA newOptionGroupArgumentA(final int min, + final int max, + final int pos, + final OptionArgumentA[] argumentAs) { + return new OptionGroupArgumentA() { + public int min() { + return min; + } + + public int max() { + return max; + } + + public int pos() { + return pos; + } + + public OptionArgumentA[] arguments() { + return argumentAs; + } + + public Class annotationType() { + return OptionGroupArgumentA.class; + } + }; + } + public static OptionArgumentA newOptionArgumentA(final OptionArgumentType type, + final OptionArgumentValueType valueType, + final String key, + final int min, + final int max + ) { + return new OptionArgumentA() { + public String key() { + return key; + } + + public OptionArgumentType type() { + return type; + } + + public OptionArgumentValueType valueType() { + return valueType; + } + + public int min() { + return min; + } + + public int max() { + return max; + } + + public Class annotationType() { + return OptionArgumentA.class; + } + }; } }