OptionsContext et
+ * ConfigsContext.
+ *
+ * @author tony
+ */
+ public static class ParserContext extends AbsractDefinitionContextvalid value after check
+ */
+ boolean checkOptionSyntax(String key, String definition) {
+ boolean oldValid = valid;
+ // check definition is not empty
+ if (definition == null || definition.isEmpty() || definition.trim().isEmpty()) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.empty.option.definition", definition));
+ return false;
+ }
+ // check definition contains alias ?
+ if (definition.trim().indexOf('-') != 0) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.unfound.alias.in.option", definition));
+ }
+ // on vérifier que le nom n'est pas dupliqué
+ if (optionKeyUsed.contains(key)) {
+ addError(_("lutinutil.parserdef.duplicated.option.name", key, definition));
+ }
+ // check same number {[< to >]} in definition
+ if (!StringUtil.checkEnclosure(definition, '{', '}')) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.underbrace.option", definition));
+ }
+ if (!StringUtil.checkEnclosure(definition, '<', '>')) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.lesser.option", definition));
+ }
+ if (!StringUtil.checkEnclosure(definition, '[', ']')) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.caret.option", definition));
+ }
+ return !oldValid || valid;
+ }
+
+ boolean checkOption(String[] alias, String definition, int min, int max) {
+ if (alias.length > 4) {
+ addError(_("lutinutil.parserdef.too.much.alias.option", Arrays.toString(alias), definition));
+ }
+ // on vérifier que les alias commencent tous par '-' et ne sont
+ // pas déjà utilisés
+ for (String alia : alias) {
+ if (!alia.startsWith("-")) {
+ addError(_("lutinutil.parserdef.unvalid.syntax.alias.option", alia, definition));
+ }
+ if (aliaKeyUsed.contains(alia)) {
+ addError(_("lutinutil.parserdef.duplicated.option.alias", alia, definition));
+ }
+ }
+ checkCardinalite(min, max, definition);
+ return valid;
+ }
+
+ @Override
+ protected void clear() {
+ super.clear();
+ optionKeyUsed.clear();
+ optionArgumentKeyUsed.clear();
+ aliaKeyUsed.clear();
+ }
+ }
+
+
+ /**
+ * Cette classe contient une option à analyser.
+ *
+ * Elle est de visibilité package, car elle n'a pas à être utilisée ailleurs.
+ *
+ * @author chemit
+ */
+ public static class OptionContext extends AbsractDefinitionContexttrue if tout est ok.
+ */
+ protected boolean checkConfigSyntax(String category, ListoptionName.definition={0,2} --option|-o
+ * [groupArgumentFacultatif]
+ *
+ * @author chemit
+ */
+
+public abstract class DefinitionParser {
+
+ protected static final Log log = LogFactory.getLog(DefinitionParser.class);
+
+ /**
+ * Initialise le parser avec son context remplit avec les données de la source.
+ *
+ * @param source la source de donnée
+ * @return le context de parseur initilisé avec les données de la source
+ * @throws IOException si problème pendant lecture de la source
+ */
+ protected abstract ParserContext init(Object source) throws IOException;
+
+ /**
+ * Effectue la parsing d'un fichier contenant les définitions des options.
+ *
+ * Retourne le parseur utilisé après le parsing.
+ *
+ * A ce stade, aunce definition ou annotation n'as été crée, on connait
+ * uniquement les contexts d'options valides.
+ *
+ *
+ * @param type le type de source à traiter.
+ * @param src la source contenant les définitions des options
+ * @return le parseur après parsing du fichier
+ * @throws IOException if any problem when reading source
+ * @throws IllegalAccessException if pb while init
+ * @throws InstantiationException if pb while init
+ */
+ public static P doParse(Class
type, Object src) throws IOException, IllegalAccessException, InstantiationException {
+ if (type == null) {
+ throw new IllegalArgumentException(_("lutinutil.parserdef.null.sourceType"));
+ }
+ if (src == null) {
+ throw new IllegalArgumentException(_("lutinutil.parserdef.null.source"));
+ }
+
+ // obtain instance of implementation of parser
+ P parser = type.newInstance();
+
+ // init parser parser : reading from source
+ ParserContext context = parser.init(src);
+
+ // parse and build options and configs contexts
+ context.parse();
+
+ // transfert valid option's contexts
+ parser.options = context.getOptions();
+
+ // transfert valid config's contexts
+ parser.configs = context.getConfigs();
+
+ // transfert errors from parser parser
+ parser.errors = context.getErrors().toArray(new DefinitionParserException[context.getNbErrors()]);
+
+ // clean context
+ context.clear();
+
+ return parser;
+ }
+
+ /** safe options contexts available after parsing */
+ protected OptionContext[] options;
+
+ /** safe configs contexts available after parsing */
+ protected ConfigContext[] configs;
+
+ /** errors found while parsing */
+ protected DefinitionParserException[] errors;
+
+ /** @return true if errors were detected while parsing */
+ public boolean hasFailed() {
+ return errors != null && errors.length > 0;
+ }
+
+ /** @return the valid option contexts */
+ public OptionContext[] getOptions() {
+ return options;
+ }
+
+ /** @return the valid config contexts */
+ public ConfigContext[] getConfigs() {
+ return configs;
+ }
+
+ /** @return les erreurs rencontrées pendant le parsing. */
+ public DefinitionParserException[] getErrors() {
+ return errors;
+ }
+
+ /**
+ * Imprime dans un writer les erreurs rencontrées pendant le parsing.
+ *
+ * @param w le writer à utiliser
+ * @throws IOException si problèmes d'écriture dans le writer
+ */
+ public void printErrors(Writer w) throws IOException {
+ if (!hasFailed()) {
+ return;
+ }
+ w.append(_("lutinutil.parserdef.printError.head", errors.length));
+ for (int i = 0, j = errors.length; i < j; i++) {
+ w.append(_("lutinutil.parserdef.printError.error", i + 1, j));
+ w.append(errors[i].toString());
+ }
+ }
+
+}
Index: maven-commandline-plugin/src/java/org/codelutin/option/def/AbsractDefinitionContext.java
diff -u /dev/null maven-commandline-plugin/src/java/org/codelutin/option/def/AbsractDefinitionContext.java:1.1
--- /dev/null Sun Mar 23 00:51:27 2008
+++ maven-commandline-plugin/src/java/org/codelutin/option/def/AbsractDefinitionContext.java Sun Mar 23 00:51:21 2008
@@ -0,0 +1,60 @@
+/**
+ * # #% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * 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.option.def;
+
+import org.codelutin.option.ParserUtil;
+
+/**
+ * Classe abstraite définissant un context de parser de définitions.
+ *
+ * @author tony
+ */
+public abstract class AbsractDefinitionContext
, S extends AbsractDefinitionContext> extends ParserUtil.AbstractParserContext
{ + + protected AbsractDefinitionContext(P parent, boolean withSons) { + super(parent, withSons); + } + + protected DefinitionParserException newError(String content, Exception e) { + DefinitionParserException e1; + if (e == null) { + e1 = new DefinitionParserException(content, this); + } else if (e instanceof DefinitionParserException) { + // propage exception + e1 = (DefinitionParserException) e; + } else { + e1 = new DefinitionParserException(content, e, this); + } + return e1; + } + + protected boolean checkCardinalite(int min, int max, String definition) { + int s = getNbErrors(); + if (min < 0) { + addError(org.codelutin.i18n.I18n._("lutinutil.parserdef.min.can.not.be.negative", min, definition)); + } + if (max == 0) { + addError(org.codelutin.i18n.I18n._("lutinutil.parserdef.max.can.not.be.zero", max, definition)); + } + if (max < -1) { // on vérifie que la cardinalité max >-2 + addError(org.codelutin.i18n.I18n._("lutinutil.parserdef.max.too.low", max, definition)); + } + if (max != -1 && max < min) { // on vérifie que la cardinalité max==-1 || max >= min + addError(org.codelutin.i18n.I18n._("lutinutil.parserdef.max.lowest.than.min", max, min, definition)); + } + return getNbErrors() == s; + } + +} Index: maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserException.java diff -u /dev/null maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserException.java:1.1 --- /dev/null Sun Mar 23 00:51:27 2008 +++ maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserException.java Sun Mar 23 00:51:21 2008 @@ -0,0 +1,66 @@ +/**##% + * 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.option.def; + +import java.util.ArrayList; +import java.util.List; + +/** + * Exception soulevable uniquement par le parser de définition d'option. + *
+ * Cette exception est de type runtime, car une telle exception est toujours + * fatale et le parseur de définition est exécuté indépendemment de toute + * application finale (voir maven-commandline-plugin). + * + * @author chemit + * @see DefinitionParser + */ +public class DefinitionParserException extends RuntimeException { // DefinitionParserException + + final AbsractDefinitionContext context; + private static final long serialVersionUID = 7683172805089232103L; + + public DefinitionParserException(String msg, AbsractDefinitionContext context) { + super(msg); + this.context = context; + } + + public DefinitionParserException(String msg, Throwable eee, AbsractDefinitionContext context) { + super(msg, eee); + this.context = context; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder().append(super.toString()).append("\nfrom contexts :"); + AbsractDefinitionContext cont = context; + List