Index: lutincommandline/src/java/org/codelutin/option/ParserFailedException.java diff -u lutincommandline/src/java/org/codelutin/option/ParserFailedException.java:1.1 lutincommandline/src/java/org/codelutin/option/ParserFailedException.java:1.2 --- lutincommandline/src/java/org/codelutin/option/ParserFailedException.java:1.1 Sun Mar 16 11:08:27 2008 +++ lutincommandline/src/java/org/codelutin/option/ParserFailedException.java Sun Mar 16 21:15:58 2008 @@ -8,19 +8,14 @@ import java.io.PrintWriter; import java.io.Writer; import java.util.Arrays; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; /** @author chemit */ public class ParserFailedException extends Exception { private static final long serialVersionUID = 1946217922235980142L; private ParserException[] errors; - private Map unusedArguments; private String[] arguments; - public ParserFailedException(String message) { super(message); } @@ -29,20 +24,16 @@ super(cause); } - public ParserFailedException(String message, ParserException[] errors, String[] arguments, Map unusedArguments) { + public ParserFailedException(String message, ParserException[] errors, String[] arguments) { super(message); this.errors = errors; this.arguments = arguments; - this.unusedArguments = unusedArguments; } public int getNbErrors() { return errors == null ? 0 : errors.length; } - public int getNbUnsued() { - return unusedArguments == null ? 0 : unusedArguments.size(); - } public ParserException[] getErrors() { return errors; @@ -76,7 +67,7 @@ try { w.append(_("lutinutil.parserdef.printError", Arrays.toString(arguments))).append('\n'); - if (!unusedArguments.isEmpty()) { + /*if (!unusedArguments.isEmpty()) { Set unsedPos = unusedArguments.keySet(); w.append(_("lutinutil.parserdef.printError.unused.head", unsedPos.size())); Iterator itr = unsedPos.iterator(); @@ -85,7 +76,7 @@ w.append(_("lutinutil.parserdef.printError.unused", i + 1, j, pos)); w.append(unusedArguments.get(i)); } - } + } */ if (hasFailed) { //w.append(_("lutinutil.parserdef.printError.head", errors.length)); for (int i = 0, j = errors.length; i < j; i++) { Index: lutincommandline/src/java/org/codelutin/option/OptionParserContexts.java diff -u lutincommandline/src/java/org/codelutin/option/OptionParserContexts.java:1.4 lutincommandline/src/java/org/codelutin/option/OptionParserContexts.java:1.5 --- lutincommandline/src/java/org/codelutin/option/OptionParserContexts.java:1.4 Sun Mar 16 11:08:27 2008 +++ lutincommandline/src/java/org/codelutin/option/OptionParserContexts.java Sun Mar 16 21:15:58 2008 @@ -270,6 +270,27 @@ public List getUnusedArguments() { return unusedArguments; } + + public OptionParserResult createResult(String[] args) { + OptionParserResult result = new OptionParserResult(args); + // instanciate real options from safe contexts + for (OptionContext context : getContexts()) { + OptionKey key = context.getKey(); + result.registerOption(key,context.instanciate(key)); + } + + // transfert unused arguments + for (Integer argument : getUnusedArguments()) { + result.registerUnusedArgument(argument); + } + + if (getNbErrors() != 0) { + // attach + result.setError(new ParserFailedException("there argument parsing failed", + getErrors().toArray(new ParserException[getNbErrors()]), args)); + } + return result; + } } /** @author tony */ @@ -383,15 +404,18 @@ lastGroup = context.groupDefinition; } - protected Option instanciate() { + protected OptionKey getKey() { + return parser.getOptionKey(definition.getKey()); + } + + protected Option instanciate(OptionKey key) { // everything is ok, can instance option try { List args = new ArrayList(); for (ArgumentContext argumentContext : contexts) { args.add(argumentContext.instanciate()); } - OptionKey, ? extends OptionAction> key = parser.getOptionKey(definition.getKey()); - return key.addOption(alias, args); + return key.newOption(alias, args); } catch (Exception e) { throw new RuntimeException(e); } @@ -562,11 +586,6 @@ log.info(argument + " : " + result); return result; } - - @Override - public String toString() { - return super.toString() + " argument:" + Arrays.toString(parser.arguments) + ", definition:" + definition + ", commandlinepos:" + commandLinePosition; - } } /** @author tony */ Index: lutincommandline/src/java/org/codelutin/option/AbstractContext.java diff -u lutincommandline/src/java/org/codelutin/option/AbstractContext.java:1.2 lutincommandline/src/java/org/codelutin/option/AbstractContext.java:1.3 --- lutincommandline/src/java/org/codelutin/option/AbstractContext.java:1.2 Sun Mar 16 11:08:27 2008 +++ lutincommandline/src/java/org/codelutin/option/AbstractContext.java Sun Mar 16 21:15:58 2008 @@ -1,7 +1,15 @@ package org.codelutin.option; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * Definition d'un contexte applicatif, encapsulant le parser et les configurations de l'application. @@ -9,51 +17,122 @@ * @author chemit */ public abstract class AbstractContext

{ + + /** logger non statique pour épouser la catégorie de l'implantation */ + protected final Log log = LogFactory.getLog(getClass()); + /** * le parseur utilisé au démarrage pour récupérer les options passées * par l'utilisateur. */ - protected P parser; + protected final P parser; + /** flag pour indiquer si 'lon veut quitter l'appli après les options */ protected boolean quit; + /** flag pour indiquer si l'on affiche ou non l'ui principale */ protected boolean launchUI = true; + /** * flag pour indiquer une première utilisation de l'application (pas de * fichier de configuration) */ protected boolean firstLaunch; - protected AbstractContext(String[] args) throws ParserFailedException, IOException { + /** le fichier source des configs */ + protected File source; + + protected final File home; + + protected AbstractContext(Class

parserClass) throws Exception { + String home = System.getProperty("user.home"); + if (home == null) { + // this is a serious fatal error + throw new RuntimeException("lutinutil.error.user.home"); + } + this.home = new File(home); + + this.parser = parserClass.newInstance(); + + for (ConfigKey configKey : parser.getConfigKeys()) { + configKey.instanciateConfig(); + } + + } + + public void init(String[] args) throws Exception { // parse arguments - getParser().doParse(args); + parser.doParse(args); + + if (parser.getLastResult().getError()!=null) { + throw parser.getLastResult().getError(); + } + // set config file location + initSource(); // init configs - getParser().initConfigs(); + initConfigs(); // init i18n with user locale (or default one if not found) initI18n(); - if (getConfig() != null) { - // mark if first launch - setFirstLaunch(!getConfig().getSource().exists()); - // save config - getConfig().save(); + // save config + save(); + } + + + /** + * Initialize all configs, simply by instanciate them. + * + * @throws Exception if any pb + */ + protected void initConfigs() throws Exception { + + for (ConfigKey configKey : getParser().getConfigKeys()) { + + Config config = getParser().getConfig(configKey); + config.setSource(getSource()); + config.doInit(); } + + // surcharge à partir de l'option config de la ligne de commande + loadFromOptions(); + } + + protected void initSource() throws Exception { + + Config main = getConfig(); + + OptionParserResult result = parser.getLastResult(); + + if (result.isOptionEnabled(main.getConfigFileOptionKey())) { + // override default config file location + result.doActions(this, main.getConfigFileOptionKey()); + + } else { + // default config file location is in your home + setSource(new File(home, main.getFileNameConfigKey().getDefaultValue().getName())); + } + + // mark if first launch + setFirstLaunch(!getSource().exists()); + } /** initialisation i18n après init du parser et des configs. */ public abstract void initI18n(); + /** @return la configuration principale de l'application */ + public abstract Config getConfig(); + /** * @return le parseur utilisé pour parser les options de la ligne de * commande. */ - public abstract P getParser(); - - /** @return la configuration principale de l'application */ - public abstract Config getConfig(); + public P getParser() { + return parser; + } /** * @return true si on doit quitter l'application (uniquement utilisé @@ -91,4 +170,77 @@ public void setFirstLaunch(boolean firstLaunch) { this.firstLaunch = firstLaunch; } + + protected void loadFromOptions() throws Exception { + + if (!getParser().getLastResult().isOptionEnabled(getConfig().getConfigOptionKey())) { + return; + } + + parser.getLastResult().doActions(this, getConfig().getConfigOptionKey()); + } + + /** + * Sauvegarde l'ensemble des configurations, en se basant sur le fichier source + * de la configuration principale. + * + * @throws IOException si probleme lors de la sauvegarde disque + * @throws IllegalStateException si pas de config main, ou pas de fichier ou + * sauvegarder. + */ + public void save() throws IOException, IllegalStateException { + List configs = getParser().getConfigKeys(); + if (configs.isEmpty()) { + // no config + return; + } + Config main = null; + List others = new ArrayList(); + for (ConfigKey configKey : configs) { + Config config = configKey.getConfig(); + if (config.isMain()) { + main = config; + } else { + others.add(config); + } + } + if (main == null || main.getSource() == null) { + // no main config, or source is null + throw new IllegalStateException("could not find main config, nor his source file"); + } + BufferedOutputStream out = null; + try { + out = new BufferedOutputStream(new FileOutputStream(main.getSource())); + main.save(out); + for (Config other : others) { + other.save(out); + } + } finally { + if (out != null) { + out.flush(); + out.close(); + } + } + } + + /** + * Sauvegarder de manière silencieuse l'ensemble des configurations. + * + * @see #save() + */ + public void saveSafely() { + try { + save(); + } catch (Exception e) { + log.warn("lutinutil.error.unsafe.save.config" + e.getMessage(), e); + } + } + + public void setSource(File source) { + this.source = source; + } + + public File getSource() { + return source; + } } \ No newline at end of file Index: lutincommandline/src/java/org/codelutin/option/Config.java diff -u lutincommandline/src/java/org/codelutin/option/Config.java:1.6 lutincommandline/src/java/org/codelutin/option/Config.java:1.7 --- lutincommandline/src/java/org/codelutin/option/Config.java:1.6 Sun Mar 16 11:08:27 2008 +++ lutincommandline/src/java/org/codelutin/option/Config.java Sun Mar 16 21:15:58 2008 @@ -22,18 +22,18 @@ import org.apache.commons.logging.LogFactory; import static org.codelutin.i18n.I18n._; import org.codelutin.util.ReflectUtil; +import org.codelutin.util.SortedProperties; -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.util.ArrayList; import java.util.Collections; +import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -101,7 +101,31 @@ * * @throws Exception if any problem while init */ - protected abstract void init() throws Exception; + protected void init() throws Exception { + log.info("[" + category + "]"); + + // chargement des valeurs par défaut + loadFromDefaultValue(); + + // après le chargement des valeurs par défaut + // la configuration n'est pas modifiée + clearModified(); + + // surcharge à partir du fichier de configuration de l'utilisateur + loadFromSource(); + + // surcharge à partir des propriétés système + loadFromSystem(); + + // surcharge à partir des propriétés de la jvm + loadFromJvm(); + } + + protected abstract OptionKey getConfigOptionKey(); + + protected abstract OptionKey getConfigFileOptionKey(); + + protected abstract ConfigPropertyKey getFileNameConfigKey(); /** la catégorie de la config (clef unique non typée) */ protected final String category; @@ -174,31 +198,6 @@ clearModified(); } - public void save() throws IOException { - if (source == null) { - return; - } - // since config store file can contain more than one Config we must - // obtain first all - Properties props = new Properties(); - - BufferedInputStream in = new BufferedInputStream(new FileInputStream(source)); - props.load(in); - in.close(); - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(source)); - store(out, props, "save configuration [" + category + "] "); - out.close(); - clearModified(); - } - - public void saveSafely() { - try { - save(); - } catch (IOException e) { - log.warn(_("could not save config {0} for reason {1}", getCategory(), e.getMessage()), e); - } - } - protected void doInit() { try { init(); @@ -206,7 +205,7 @@ for (String s : this.toString().split("\n")) { log.debug(s); } - } + } } catch (Exception e) { throw new IllegalStateException(e); } finally { @@ -527,7 +526,7 @@ * @param def the given key to use * @param value the given valuer to set */ - protected void setProperty(ConfigPropertyKey def, Object value) { + public void setProperty(ConfigPropertyKey def, Object value) { checkAuthorizedKey(def); if (initDone && def.isFinal()) { // fatal error , final property @@ -696,11 +695,14 @@ */ protected void updateUniverse() { if (tmp == null || tmp.isEmpty()) { + // nothing to do return; } try { // tmp contains new data to digest - for (Object o : tmp.keySet()) { + Enumeration keys = tmp.keys(); + while (keys.hasMoreElements()) { + Object o = keys.nextElement(); String kStr = o + ""; if (!isMain()) { // la clef est préfixée par la catégorie @@ -751,7 +753,7 @@ /** @return the lazy tmp instance */ protected Properties getTmp() { if (tmp == null) { - tmp = new Properties(); + tmp = new SortedProperties(); } return tmp; } Index: lutincommandline/src/java/org/codelutin/option/OptionParser.java diff -u lutincommandline/src/java/org/codelutin/option/OptionParser.java:1.6 lutincommandline/src/java/org/codelutin/option/OptionParser.java:1.7 --- lutincommandline/src/java/org/codelutin/option/OptionParser.java:1.6 Sun Mar 16 11:08:27 2008 +++ lutincommandline/src/java/org/codelutin/option/OptionParser.java Sun Mar 16 21:15:58 2008 @@ -24,23 +24,16 @@ import org.apache.commons.logging.LogFactory; import org.codelutin.i18n.I18n; import static org.codelutin.i18n.I18n._; -import org.codelutin.option.OptionParserContexts.OptionContext; import org.codelutin.option.OptionParserContexts.ParserContext; import org.codelutin.option.def.OptionDefinition; import org.codelutin.option.def.OptionDefinitionBuilder; -import org.codelutin.util.ArrayUtil; import org.codelutin.util.ReflectUtil; -import java.io.BufferedOutputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.Writer; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * Parser abstrait d'options de la ligne de commande. @@ -66,20 +59,6 @@ */ public abstract class OptionParser { - /** - * la propriéte des classes qui contiennent les inner-classes d'actions - * d'options concretes. - *

- * Le parseur généré contiendra une constante de type tableau de classes. - */ - public static final String ACTION_IMPLEMENTATIONS_PROPERTY = "ACTION_IMPLEMENTATIONS"; - /** - * la propriété des classes concretes de configuration. - *

- * Le parseur contiendra une constantes de type tableau de classes de - * configs. - */ - public static final String CONFIG_IMPLEMENTATIONS_PROPERTY = "CONFIG_IMPLEMENTATIONS"; /** logger non statique pour épouser la catégorie de l'implantation */ protected final Log log = LogFactory.getLog(getClass()); @@ -117,15 +96,14 @@ /** les clefs d'options connues par le parseur */ protected final List configKeys; - /** les arguments non utilisés, indexés par leur position dans du dernier parsing */ - protected Map unusedArguments; - - /** les erreurs rencontrées dans du dernier parsing */ - //protected ParserException[] errors; - - /** les arguments utilisés dans le dernier parsing */ - protected String[] arguments; + /** le dernier result de parsing, ou null si aucun parsing lancé */ + protected OptionParserResult lastResult; + /** + * Init the parser + * + * @throws IllegalArgumentException if any pb while init + */ public OptionParser() throws IllegalArgumentException { // init i18n with default locale @@ -134,56 +112,6 @@ optionKeys = Collections.unmodifiableList(ReflectUtil.getConstants(getClass(), OptionKey.class)); configKeys = Collections.unmodifiableList(ReflectUtil.getConstants(getClass(), ConfigKey.class)); - // enregistrement des actions concretes contenues dans des inner-classes - Class[] actions = ReflectUtil.getConstant(getClass(), ACTION_IMPLEMENTATIONS_PROPERTY); - for (Class action : actions) { - registerActions(action); - } - - // enregistrement des configs concretes - Class[] configs = ReflectUtil.getConstant(getClass(), CONFIG_IMPLEMENTATIONS_PROPERTY); - for (Class config : configs) { - registerConfig(config); - } - } - - /** Initialize all configs, simply by instanciate them. */ - public void initConfigs() { - for (ConfigKey configKey : configKeys) { - configKey.initConfig(this); - configKey.getConfig(); - } - } - - /** - * Enregistre les implantations d'action à partir d'une classe contenant - * des classes imbriquées d'implantation d'OptionAction. - * - * @param clazz la classe contenant des implantations d'OptionAction - */ - public void registerActions(Class clazz) { - // recherche des inner classes - Class[] classes = clazz.getClasses(); - for (Class aClass : classes) { - if (OptionAction.class.isAssignableFrom(aClass)) { - registerAction(aClass); - } - } - } - - /** - * Enregistre une implanation concrete de config. - * - * @param aClass la classe à enregister - */ - @SuppressWarnings({"unchecked"}) - public void registerConfig(Class aClass) { - for (ConfigKey key : configKeys) { - if (key.getAbstractConfigClass().isAssignableFrom(aClass)) { - // found a matching key - ((ConfigKey) key).setConfigClass(aClass); - } - } } public List getConfigKeys() { @@ -198,106 +126,41 @@ * Launch parsing of some arguments. * * @param args arguments to parse - * @throws ParserFailedException if io problems with writers + * @return le result of parsing if succes */ - public void doParse(String... args) throws ParserFailedException { + public OptionParserResult doParse(String... args) { + cleanResult(); - arguments = args; - Map unusedArguments = new HashMap(); + ParserContext context = new ParserContext(this); - if (args.length > 0) { + if (args.length > 0) { // detect options context.detectOptions(args); - - // instanciate real options from safe contexts - for (OptionContext optionContext : context.getContexts()) { - optionContext.instanciate(); - } - - // transfert unused arguments - for (Integer unusedArgument : context.getUnusedArguments()) { - unusedArguments.put(unusedArgument, args[unusedArgument]); - } } + lastResult = context.createResult(args); + // clean parser context.clear(); - if (context.getNbErrors() > 0|| !unusedArguments.isEmpty()) { - - // transfert errors from parser parser - ParserException[] errors = context.getErrors().toArray(new ParserException[context.getNbErrors()]); - throw new ParserFailedException("there argument parsing failed", errors,arguments,unusedArguments); - } - } - - /** - * @param key la clef typée des options à rechercher - * @return true s'il existe des options trouvées lors du dernier - * parsing correspondant à la clef donnée. - */ - public boolean isOptionEnabled(OptionKey key) { - List list = key.getOptions(); - return !list.isEmpty(); - } - - /** @return le nombre d'options valides trouvées lors du dernier parsing */ - public int getNbOptions() { - int result = 0; - for (OptionKey optionKey : optionKeys) { - result += optionKey.getOptions().size(); - } - return result; + return lastResult; } /** - * Pour exécuter les actions de toutes les options trouvées pendant le parsing - * en utilisant l'ordre de définition des options. - * - * @param context used context - * @throws Exception si un problème pendant les actions - */ - public void doAllActions(AbstractContext context) throws Exception { - if (getNbOptions() > 0) { - doActions(context, optionKeys.toArray(new OptionKey[optionKeys.size()])); - } - } - - /** - * Exécute les actions des options dont on donne les clefs. - *

- * L'ordre d'exécution est celui des clefs données. + * Obtient une clef typée d'option à partir de sa clef non typée. * - * @param context used context - * @param keys les clefs des options à utiliser - * @throws Exception si problème dans l'exécution des actions + * @param key la clef non typée + * @return la clef typée ou null si non trouvée. */ @SuppressWarnings({"unchecked"}) - public void doActions(AbstractContext context, OptionKey... keys) throws Exception { - for (OptionKey key : keys) { - key.doAction(context, getOptions(key)); + public OptionKey, ? extends OptionAction> getOptionKey(String key) { + for (OptionKey optionKey : optionKeys) { + if (optionKey.getOptionKey().equals(key)) { + return optionKey; + } } - } - - /** - * Obtenir les options trouvées lors du dernier parsing pour la clef donnée. - * - * @param key la clef typée des options à rechercher - * @return une table des options trouvées ou un tableau vide - */ - public O[] getOptions(OptionKey key) { - return ArrayUtil.toArray(key.getOptions(), key.getOptionClass()); - } - - /** - * Obtenir la première des option de cette clef trouvée lors du dernier parsing - * - * @param key la clef typée de l'option à rechercher - * @return la premier option trouvée ou null - */ - public O getOption(OptionKey key) { - return !isOptionEnabled(key) ? null : getOptions(key)[0]; + return null; } /** @@ -311,81 +174,12 @@ } /** - * Sauvegarde l'ensemble des configurations, en se basant sur le fichier source - * de la configuration principale. - * - * @throws IOException si probleme lors de la sauvegarde disque - * @throws IllegalStateException si pas de config main, ou pas de fichier ou - * sauvegarder. - */ - public void save() throws IOException, IllegalStateException { - List configs = getConfigKeys(); - if (configs.isEmpty()) { - // no config - return; - } - Config main = null; - List others = new ArrayList(); - for (ConfigKey configKey : configs) { - Config config = configKey.getConfig(); - if (config.isMain()) { - main = config; - } else { - others.add(config); - } - } - if (main == null || main.getSource() == null) { - // no main config, or source is null - throw new IllegalStateException("could not find main config, nor his source file"); - } - BufferedOutputStream out = null; - try { - out = new BufferedOutputStream(new FileOutputStream(main.getSource())); - main.save(out); - for (Config other : others) { - other.save(out); - } - } finally { - if (out != null) { - out.flush(); - out.close(); - } - } - } - - /** - * Sauvegarder de manière silencieuse l'ensemble des configurations. + * Print usage of the parser * - * @see #save() + * @param w writer + * @param name title + * @throws IOException if any io pb while writing */ - public void saveSafely() { - try { - save(); - } catch (Exception e) { - log.warn("lutinutil.error.unsafe.save.config" + e.getMessage(), e); - } - } - - /** @return true 0; - //} - - /** @return les erreurs rencontrées lors du dernier parsing */ - //public ParserException[] getErrors() { - // return errors; - //} - - /** @return la liste des arguments non utilisés lors du dernier parsing */ - public String[] getUnusedArguments() { - return unusedArguments.values().toArray(new String[unusedArguments.size()]); - } - - /** @return les arguments en entrée du dernier parsing */ - public String[] getArguments() { - return arguments; - } - public void printUsage(Writer w, String name) throws IOException { String head = _("lutinutil.parserdef.printUsage.head", name); String prefixOption = _("lutinutil.parserdef.printUsage.options.head", name); @@ -394,26 +188,45 @@ ParserUtil.toString(getClass(), w, head, prefix, prefixOption, prefixConfig); } - @Override - protected void finalize() throws Throwable { - super.finalize(); - cleanResult(); + public OptionParserResult getLastResult() { + return lastResult; } /** - * Obtient une clef typée d'option à partir de sa clef non typée. + * Enregistre les implantations d'action à partir d'une classe contenant + * des classes imbriquées d'implantation d'OptionAction. * - * @param key la clef non typée - * @return la clef typée ou null si non trouvée. + * @param clazz la classe contenant des implantations d'OptionAction + */ + public void registerActions(Class clazz) { + // recherche des inner classes + Class[] classes = clazz.getClasses(); + for (Class aClass : classes) { + if (OptionAction.class.isAssignableFrom(aClass)) { + registerAction(aClass); + } + } + } + + /** + * Enregistre une implanation concrete de config. + * + * @param aClass la classe à enregister */ @SuppressWarnings({"unchecked"}) - protected OptionKey, ? extends OptionAction> getOptionKey(String key) { - for (OptionKey optionKey : optionKeys) { - if (optionKey.getOptionKey().equals(key)) { - return optionKey; + public void registerConfig(Class aClass) { + for (ConfigKey key : configKeys) { + if (key.getAbstractConfigClass().isAssignableFrom(aClass)) { + // found a matching key + ((ConfigKey) key).setConfigClass(aClass); } } - return null; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + cleanResult(); } /** @@ -422,7 +235,7 @@ * @param key la clef non typée * @return la clef typée ou null si non trouvée. */ - protected ConfigKey getConfigKey(String key) { + public ConfigKey getConfigKey(String key) { for (ConfigKey optionKey : configKeys) { if (optionKey.getCategory().equals(key)) { return optionKey; @@ -442,14 +255,10 @@ /** nettoye les résultat du parseur (utilisé avant tout parsing) */ protected void cleanResult() { - for (OptionKey optionKey : optionKeys) { - optionKey.resetOptions(); + if (lastResult != null) { + lastResult.clear(); + lastResult = null; } - if (unusedArguments != null) { - unusedArguments.clear(); - unusedArguments = null; - } - arguments = null; } @SuppressWarnings({"unchecked"}) @@ -461,7 +270,6 @@ } } } - } Index: lutincommandline/src/java/org/codelutin/option/ConfigKey.java diff -u lutincommandline/src/java/org/codelutin/option/ConfigKey.java:1.2 lutincommandline/src/java/org/codelutin/option/ConfigKey.java:1.3 --- lutincommandline/src/java/org/codelutin/option/ConfigKey.java:1.2 Sat Mar 15 09:05:17 2008 +++ lutincommandline/src/java/org/codelutin/option/ConfigKey.java Sun Mar 16 21:15:58 2008 @@ -136,16 +136,14 @@ return config; } - public void initConfig(OptionParser optionParser) { + public C instanciateConfig() { if (configClass == null) { throw new IllegalStateException("no concrete config found for " + abstractConfigClass); } try { - //TODO should test if the constructor exists ? - config = configClass.getConstructor(optionParser.getClass()).newInstance(optionParser); + return config = configClass.getConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } - } } \ No newline at end of file Index: lutincommandline/src/java/org/codelutin/option/OptionKey.java diff -u lutincommandline/src/java/org/codelutin/option/OptionKey.java:1.2 lutincommandline/src/java/org/codelutin/option/OptionKey.java:1.3 --- lutincommandline/src/java/org/codelutin/option/OptionKey.java:1.2 Sat Mar 15 09:05:17 2008 +++ lutincommandline/src/java/org/codelutin/option/OptionKey.java Sun Mar 16 21:15:58 2008 @@ -20,11 +20,9 @@ import static org.codelutin.i18n.I18n._; import org.codelutin.option.def.OptionDefinition; -import org.codelutin.util.ArrayUtil; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; -import java.util.ArrayList; import java.util.List; /** @@ -39,8 +37,7 @@ * l'initialisation générique du parseur (utiliser la méthode {@link #setActionClass(Class)} * pour positionner la classe contrête d'OptionAction). *

- * L'action liée est instanciée une seule fois, pour lancer une action utilisez - * la méthode {@link #doAction(AbstractContext , Option[])}. + * L'action liée est instanciée une seule fois. * * @author chemit */ @@ -61,9 +58,6 @@ /** la classe abstraite de l'action de l'option liée */ final protected Class abstractActionClass; - /** la liste des options instanciées lors du dernier parsing */ - final protected List options; - /** le constructeur d'option à utiliser */ protected Constructor optionConstructor; @@ -87,7 +81,6 @@ // we have a concrete action class actionClass = abstractActionClass; } - this.options = new ArrayList(); } public String getOptionKey() { @@ -118,45 +111,6 @@ return definition; } - public List getOptions() { - return options; - } - - /** - * Launch action for the given parser and options - * - * @param context the used context - * @param options the options to fire - * @throws Exception if any problem - */ - public void doAction(C context, O... options) throws Exception { - if (options.length > 0) { - getAction(context.getParser()).doRun(context, options); - } - } - - /** - * Launch action for the given parser - * - * @param context the used context - * @throws Exception if any problem - */ - public void doAction(C context) throws Exception { - if (!options.isEmpty()) { - getAction(context.getParser()).doRun(context, ArrayUtil.toArray(options, optionClass)); - } - } - - protected void resetOptions() { - options.clear(); - } - - protected O addOption(String alias, List args) { - O o = newOption(alias, args); - options.add(o); - return o; - } - /** * Get the shared action linked with this key. * Index: lutincommandline/src/java/org/codelutin/option/OptionParserResult.java diff -u /dev/null lutincommandline/src/java/org/codelutin/option/OptionParserResult.java:1.1 --- /dev/null Sun Mar 16 21:16:04 2008 +++ lutincommandline/src/java/org/codelutin/option/OptionParserResult.java Sun Mar 16 21:15:58 2008 @@ -0,0 +1,188 @@ +package org.codelutin.option; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Classe contenant le resultat d'un parsing d'options réalisé avec succès + * + * @author chemit + */ +public class OptionParserResult { + + protected String[] arguments; + + protected List

+ * L'ordre d'exécution est celui des clefs données. + * + * @param context used context + * @param keys les clefs des options à utiliser + * @throws Exception si problème dans l'exécution des actions + */ + @SuppressWarnings({"unchecked"}) + public void doActions(AbstractContext context, OptionKey... keys) throws Exception { + for (OptionKey key : keys) { + + if (!isOptionEnabled(key)) { + continue; + } + + Option[] options = getOptions(key); + + OptionAction action = key.getAction(context.getParser()); + + action.doRun(context, options); + } + } + + +}