Index: maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java diff -u maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java:1.2 maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java:1.3 --- maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java:1.2 Sun Mar 23 23:48:46 2008 +++ maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java Mon Mar 24 01:34:00 2008 @@ -22,7 +22,6 @@ import static org.codelutin.option.def.DefinitionParserContexts.ConfigsContext; import static org.codelutin.option.def.DefinitionParserContexts.OptionsContext; import static org.codelutin.option.def.DefinitionParserContexts.ParserContext; -import org.codelutin.option.def.DefinitionParserUtil.ConfigDefEntry; import org.codelutin.option.def.loader.ConfigLoader; import org.codelutin.option.def.loader.OptionLoader; @@ -30,10 +29,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Properties; @@ -61,7 +56,6 @@ throw new IllegalArgumentException(_("lutinutil.parserdef.unfound.source", source)); } - // load properties file Properties properties = new Properties(); InputStream stream = null; @@ -74,12 +68,8 @@ } } - ConfigLoader configLoader = new ConfigLoader(injects); - OptionLoader optionLoader = new OptionLoader(); - load(properties, configLoader, optionLoader); - // récupération des clefs d'options - List categories; + /*List categories; Map> cdefinitions; Map> cmodifiers; @@ -95,24 +85,32 @@ detectOptions(properties, categories, odefinitions = new ArrayList(), okeys = new ArrayList() - ); + );*/ + + //ParserContext context = createParseContext(categories, cdefinitions, cmodifiers, okeys, odefinitions); - ParserContext context = createParseContext(categories, cdefinitions, cmodifiers, okeys, odefinitions); + ConfigLoader configLoader = new ConfigLoader(injects); + configLoader.doLoad(properties); + + OptionLoader optionLoader = new OptionLoader(configLoader.getCategoriesStr()); + optionLoader.doLoad(properties); + + ParserContext context = new ParserContext(); + + // construction du context de parsing des options + OptionsContext options = new OptionsContext(context, optionLoader.getOptions()); + + // construction du context de parsing des configs + ConfigsContext configs = new ConfigsContext(context, configLoader.getConfigs()); + + context.setOptions(options); + context.setConfigs(configs); - okeys.clear(); - categories.clear(); - odefinitions.clear(); properties.clear(); return context; } - public void load(Properties p, ConfigLoader configLoader, OptionLoader optionLoader) throws Exception { - configLoader.doLoad(p); - optionLoader.setCategoriesStr(configLoader.getCategoriesStr()); - optionLoader.doLoad(p); - } - - public ParserContext createParseContext(List categories, Map> cdefinitions, Map> cmodifiers, List okeys, List odefinitions) { + /*public ParserContext createParseContext(List categories, Map> cdefinitions, Map> cmodifiers, List okeys, List odefinitions) { ParserContext context = new ParserContext(); @@ -133,9 +131,9 @@ context.setOptions(options); context.setConfigs(configs); return context; - } + }*/ - private void detectOptions(Properties properties, List categories, List odefinitions, List okeys) { + /*private void detectOptions(Properties properties, List categories, List odefinitions, List okeys) { Map optionDefs = new HashMap(); String categoriesStr = ""; @@ -229,7 +227,7 @@ // on trie les catégories une seule fois // ensuite on travaille sur cet ordre établi. Collections.sort(categories); - } + } */ } Index: maven-commandline-plugin/src/java/org/codelutin/option/def/MandatoryConfigProperty.java diff -u maven-commandline-plugin/src/java/org/codelutin/option/def/MandatoryConfigProperty.java:1.2 maven-commandline-plugin/src/java/org/codelutin/option/def/MandatoryConfigProperty.java:1.3 --- maven-commandline-plugin/src/java/org/codelutin/option/def/MandatoryConfigProperty.java:1.2 Sun Mar 23 23:48:46 2008 +++ maven-commandline-plugin/src/java/org/codelutin/option/def/MandatoryConfigProperty.java Mon Mar 24 01:34:00 2008 @@ -26,24 +26,27 @@ public enum MandatoryConfigProperty { /** le nom du fichier de configuration de l'application */ - configFileName("java.io.File"), + configFileName("java.io.File", "mandatory,static,final"), /** l'encoding a utiliser sur le systeme */ - encoding("java.lang.String"), + encoding("java.lang.String", "mandatory,static,final"), /** la locale par default à utiliser */ - locale("java.util.Locale"), + locale("java.util.Locale", "mandatory,static"), /** le nom du projet */ - projectName("java.lang.String"), + projectName("java.lang.String", "mandatory,static,final"), /** la version du projet */ - version("org.codelutin.util.VersionNumber"); + version("org.codelutin.util.VersionNumber", "mandatory,static,final"); private final String type; + private final String modifiers; - private MandatoryConfigProperty(String type) { + + MandatoryConfigProperty(String type, String modifiers) { this.type = type; + this.modifiers = modifiers; } public String category() { @@ -54,6 +57,10 @@ return type; } + public String getModifiers() { + return modifiers; + } + public String getEntryKey() { return category() + DefinitionParserUtil.CDEFINITION_KEY_FACTOR + name(); } Index: maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserContexts.java diff -u maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserContexts.java:1.1 maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserContexts.java:1.2 --- maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserContexts.java:1.1 Sun Mar 23 00:51:21 2008 +++ maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserContexts.java Mon Mar 24 01:34:00 2008 @@ -26,6 +26,9 @@ import org.codelutin.option.def.DefinitionParserUtil.ConfigDefEntry; import static org.codelutin.option.def.DefinitionParserUtil.IDENTIFIER_PATTERN; import static org.codelutin.option.def.DefinitionParserUtil.OPENING_CHARS; +import org.codelutin.option.def.loader.ConfigLoaderEntry; +import org.codelutin.option.def.loader.ConfigPropertyLoaderEntry; +import org.codelutin.option.def.loader.OptionLoaderEntry; import org.codelutin.util.CardinalityHelper; import org.codelutin.util.ConverterUtil; import org.codelutin.util.StringUtil; @@ -99,8 +102,10 @@ /** @author tony */ public static class OptionsContext extends AbsractDefinitionContext { - protected final String[] okeys; - protected final String[] odefinitions; + //protected final String[] okeys; + //protected final String[] odefinitions; + + protected final List source; /** la liste des alias d'option déjà rencontrées pendant le parsing */ protected final List aliaKeyUsed; @@ -113,23 +118,40 @@ OptionsContext(ParserContext context, String[] keys, String[] definitions) { super(context, true); - this.okeys = keys; - this.odefinitions = definitions; + //this.okeys = keys; + //this.odefinitions = definitions; + this.optionArgumentKeyUsed = new ArrayList(); + this.optionKeyUsed = new ArrayList(); + this.aliaKeyUsed = new ArrayList(); + source = null; + } + + public OptionsContext(ParserContext context, List options) { + super(context, true); this.optionArgumentKeyUsed = new ArrayList(); this.optionKeyUsed = new ArrayList(); this.aliaKeyUsed = new ArrayList(); + this.source = options; } protected void parseOptions() { // parse options - for (int i = 0, j = okeys.length; i < j; i++) { + for (OptionLoaderEntry entry : source) { + String key = entry.getName(); + String definition = entry.getDefinition(); + if (checkOptionSyntax(key, definition)) { + OptionContext optionContext = parseOption(key, definition); + addSon(optionContext); + } + } + /*for (int i = 0, j = okeys.length; i < j; i++) { String key = okeys[i]; String definition = odefinitions[i]; if (checkOptionSyntax(key, definition)) { OptionContext optionContext = parseOption(key, definition); addSon(optionContext); } - } + }*/ } OptionContext parseOption(String key, String definition) { @@ -575,33 +597,41 @@ */ public static class ConfigsContext extends AbsractDefinitionContext { - - protected final String[] categories; - protected final Map> definitions; - protected final Map> modifiers; + //protected final String[] categories; + //protected final Map> definitions; + //protected final Map> modifiers; protected List safeCategories; + protected final List source; + protected ConfigsContext(ParserContext parent, String[] categories, Map> definitions, Map> modifiers) { super(parent, true); - this.categories = categories; - this.definitions = definitions; - this.modifiers = modifiers; + //this.categories = categories; + //this.definitions = definitions; + //this.modifiers = modifiers; + this.source = null; + } + + public ConfigsContext(ParserContext parent, List configs) { + super(parent, true); + this.source = configs; + //this.categories = null; + //this.definitions = null; + //this.modifiers = null; } protected void parseConfigs() { this.safeCategories = new ArrayList(); Map _defs = new HashMap(); HashMap _mods = new HashMap(); - for (String category : categories) { - List configDefs = definitions.get(category); - List configMods = modifiers.get(category); + for (ConfigLoaderEntry entry : source) { _defs.clear(); _mods.clear(); - if (checkConfigSyntax(category, configDefs, configMods, _defs, _mods)) { - ConfigContext context = new ConfigContext(this, category, _defs, _mods); + if (checkConfigSyntax(entry, _defs, _mods)) { + ConfigContext context = new ConfigContext(this, entry.getName(), _defs, _mods); log.debug(context); addSon(context); } @@ -617,6 +647,100 @@ } /** + * @param source la source a analyser + * @param _defs le dictionnaire de definition a construire + * @param _mods le dictionnaire de modifiers a construire + * @return true if tout est ok. + */ + protected boolean checkConfigSyntax(ConfigLoaderEntry source, Map _defs, Map _mods) { + + String category = source.getName(); + if (safeCategories.contains(category)) { + // fatal error + addError(_("lutinutil.error.parserdef.config.duplicated.category", category, safeCategories)); + return false; + } + // check valid syntax of the category + if (!IDENTIFIER_PATTERN.matcher(category).matches()) { + addError(_("lutinutil.error.parserdef.config.unvalid.syntax.category", category)); + return false; + } + + List keyUsed = new ArrayList(); + for (ConfigPropertyLoaderEntry sourceP : source.getProperties()) { + String key = sourceP.getName(); + // check if key is syntax valid + if (!IDENTIFIER_PATTERN.matcher(key).matches()) { + addError(_("lutinutil.error.parserdef.config.unvalid.syntax.property.key", key)); + return false; + } + // check if not already registred key + if (keyUsed.contains(key)) { + addError(_("lutinutil.error.parserdef.config.duplicated.property.key", key, category, keyUsed)); + return false; + } + String value = sourceP.getDefinition(); + // check syntax of definition type:defaultValue + Matcher matcher = CONFIG_PROPERTY_DEFINITION_PATTERN.matcher(value); + if (matcher.matches()) { + String type = matcher.group(0); + keyUsed.add(key); + _defs.put(key, new String[]{type}); + } else { + matcher = CONFIG_PROPERTY_DEFINITION_WITH_DEFAULT_PATTERN.matcher(value); + if (matcher.matches()) { + String type = matcher.group(1); + String defaultValue = matcher.group(matcher.groupCount()); + keyUsed.add(key); + _defs.put(key, new String[]{type, defaultValue}); + } else { + addError(_("lutinutil.error.parserdef.config.unvalid.syntax.property.definition", value, key, category)); + return false; + } + } + } + // check if there is no mods without a def + for (ConfigPropertyLoaderEntry sourceP : source.getProperties()) { + String key = sourceP.getName(); + if (!keyUsed.contains(key)) { + // found a mod with no def + addError(_("lutinutil.error.parserdef.config.orphan.modifier", key, category, keyUsed)); + return false; + } + // check syntax of modifiers, [XXX,]*[XXX] + + String value = sourceP.getModifiers().trim(); + String[] mods = value.split(","); + if (value.length()==0 || mods.length == 0) { + _mods.put(key, 0); + mods =new String[0]; + } + List modifiers = new ArrayList(); + for (String mod : mods) { + ConfigPropertyModifier val; + try { + val = ConfigPropertyModifier.valueOf(mod.toUpperCase()); + } catch (IllegalArgumentException e) { + addError(_("lutinutil.parserdef.unvalid.syntax.unknown.modifier", mod)); + return false; + } + if (modifiers.contains(val.getIntValue())) { + // duplicated modifier + addError(_("lutinutil.error.parserdef.config.duplicated.property.modifier", mod, key, category, Arrays.toString(mods))); + return false; + } + modifiers.add(val.getIntValue()); + } + int _mod = 0; + for (Integer modifier : modifiers) { + _mod |= modifier; + } + _mods.put(key, _mod); + } + return true; + } + + /** * @param category la catégorie de la config * @param configDefs les entrées de définitions de propriétés de la config * @param configMods les entrées de modifiers de propriétés de la config @@ -690,7 +814,7 @@ try { val = ConfigPropertyModifier.valueOf(mod.toUpperCase()); } catch (IllegalArgumentException e) { - addError(_("lutinutil.parserdef.unvalid.syntax.unknown.modifier",mod)); + addError(_("lutinutil.parserdef.unvalid.syntax.unknown.modifier", mod)); return false; } if (modifiers.contains(val.getIntValue())) { @@ -712,8 +836,9 @@ @Override protected void clear() { super.clear(); - definitions.clear(); - modifiers.clear(); + source.clear(); + //definitions.clear(); + //modifiers.clear(); safeCategories.clear(); safeCategories = null; }