Index: maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java diff -u /dev/null maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java:1.1 --- /dev/null Sun Mar 23 00:22:41 2008 +++ maven-commandline-plugin/src/java/org/codelutin/option/def/DefinitionParserFromProperties.java Sun Mar 23 00:22:36 2008 @@ -0,0 +1,232 @@ +/* +* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 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 static org.codelutin.i18n.I18n._; +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; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +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; + +/** + * Implantation d'un parseur de définition, ayant pour source un fichier de propriété. + * + * @author tony + */ +public class DefinitionParserFromProperties extends DefinitionParser { + + final static int CDEFINITION_KEY_FACTOR_LENGTH = DefinitionParserUtil.CDEFINITION_KEY_FACTOR.length(); + final static int ODEFINITION_KEY_PREFIX_LENGTH = DefinitionParserUtil.ODEFINITION_KEY_SUFFIX.length(); + + /** + * Initialise un contexte de parseur à partir d'un fichier de propriétés. + * + * @param src la source où lire les définitions (un fichier de propriétés) + * @return un contexte de parseur avec les définitions lues + * @throws java.io.IOException if any problem while reading source + */ + protected ParserContext init(Object src) throws IOException { + File source = (File) src; + if (!source.exists()) { + throw new IllegalArgumentException(_("lutinutil.parserdef.unfound.source", source)); + } + + // load properties file + Properties properties = new Properties(); + InputStream stream = null; + try { + stream = new BufferedInputStream(new FileInputStream(source)); + properties.load(stream); + } finally { + if (stream != null) { + stream.close(); + } + } + + // récupération des clefs d'options + List categories; + Map> cdefinitions; + Map> cmodifiers; + + detectConfigs(properties, + categories = new ArrayList(), + cdefinitions = new HashMap>(), + cmodifiers = new HashMap>() + ); + + List okeys; + List odefinitions; + + detectOptions(properties, categories, + odefinitions = new ArrayList(), + okeys = new ArrayList() + ); + + ParserContext context = createParseContext(categories, cdefinitions, cmodifiers, okeys, odefinitions); + + 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) { + + ParserContext context = new ParserContext(); + + // construction du context de parsing des options + OptionsContext options = new OptionsContext( + context, + okeys.toArray(new String[okeys.size()]), + odefinitions.toArray(new String[okeys.size()]) + ); + + // construction du context de parsing des configs + ConfigsContext configs = new ConfigsContext( + context, + categories.toArray(new String[categories.size()]), + cdefinitions, + cmodifiers); + + context.setOptions(options); + context.setConfigs(configs); + return context; + } + + private void detectOptions(Properties properties, List categories, List odefinitions, List okeys) { + Map optionDefs = new HashMap(); + + String categoriesStr = ""; + if (!categories.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String category : categories) { + sb.append('|').append(category); + } + categoriesStr = sb.substring(1); + + } + List defaultOptions = DefaultOptionAction.getConfigKeys(); + for (Object o : properties.keySet()) { + String fullKey = o.toString(); + if (!fullKey.endsWith(DefinitionParserUtil.ODEFINITION_KEY_SUFFIX)) { + continue; + } + String key = fullKey.substring(0, fullKey.length() - ODEFINITION_KEY_PREFIX_LENGTH); + String realDef = properties.getProperty(fullKey); + if (defaultOptions.contains(fullKey)) { + // do not add this, this is a generated option + log.warn("generic option " + key + " used instead of customize one, you should delete this option from your configuration..."); + // use default definition + realDef = DefaultOptionAction.valueOf(key).def(); + defaultOptions.remove(fullKey); + } + optionDefs.put(fullKey, realDef); + } + + // add default options not already found + for (String optionKey : defaultOptions) { + // get defaultOption + for (DefaultOptionAction option : DefaultOptionAction.values()) { + if (option.configKey().equals(optionKey)) { + optionDefs.put(optionKey, option.def()); + } + } + } + + List keys = new ArrayList(optionDefs.keySet()); + + // on trie les clefs d'options une seule fois + // ensuite on travaille sur cet ordre établi. + Collections.sort(keys); + + // récupérations des définitions d'options + for (String optionKey : keys) { + String realDef = optionDefs.get(optionKey); + realDef = realDef.replace("@categories@", categoriesStr); + String key = optionKey.substring(0, optionKey.length() - ODEFINITION_KEY_PREFIX_LENGTH); + if (log.isDebugEnabled()) { + log.debug("new option " + key + " : " + realDef); + } + okeys.add(key); + odefinitions.add(realDef); + } + } + + protected void detectConfigs(Properties properties, List categories, Map> cdefinitions, Map> cmodifiers) { + + List defaultOptions = MandatoryConfigProperty.getConfigPropertyKeys(); + + for (Object o : properties.keySet()) { + String key = o.toString(); + if (!key.contains(DefinitionParserUtil.CDEFINITION_KEY_FACTOR)) { + continue; + } + + int pos = key.indexOf(DefinitionParserUtil.CDEFINITION_KEY_FACTOR); + String cat = key.substring(0, pos); + String ckey = key.substring(pos + CDEFINITION_KEY_FACTOR_LENGTH); + List defs, mods; + if (!categories.contains(cat)) { + // found a new config category + categories.add(cat); + cdefinitions.put(cat, defs = new ArrayList()); + cmodifiers.put(cat, mods = new ArrayList()); + } else { + defs = cdefinitions.get(cat); + mods = cmodifiers.get(cat); + } + String def = properties.getProperty(key); + ConfigDefEntry cdef = new ConfigDefEntry(ckey, def); + defs.add(cdef); + String mod = properties.getProperty(cat + DefinitionParserUtil.CMODIFIERS_KEY_FACTOR + ckey); + if (mod != null && !"".equals(mod)) { + // only save modifiers if we found one + ConfigDefEntry cmod = new ConfigDefEntry(ckey, mod); + mods.add(cmod); + } + } + + // on trie les catégories une seule fois + // ensuite on travaille sur cet ordre établi. + Collections.sort(categories); + } + + +}