r2584 - in trunk/nuiton-utils: . src/main/java/org/nuiton/util src/test/java/org/nuiton/util src/test/resources src/test/resources/properties
Author: tchemit Date: 2013-07-19 19:37:58 +0200 (Fri, 19 Jul 2013) New Revision: 2584 Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2584 Log: fixes #2778: Remove all deprecated code in the nuiton-utils module Removed: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigHelper.java trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigProvider.java trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java trunk/nuiton-utils/src/main/java/org/nuiton/util/ArgumentsParserException.java trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java trunk/nuiton-utils/src/test/resources/ApplicationUpdater/ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkAuthTest.properties trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties Modified: trunk/nuiton-utils/pom.xml Modified: trunk/nuiton-utils/pom.xml =================================================================== --- trunk/nuiton-utils/pom.xml 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/pom.xml 2013-07-19 17:37:58 UTC (rev 2584) @@ -50,11 +50,6 @@ </dependency> <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-vfs2</artifactId> - </dependency> - - <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </dependency> Deleted: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfig.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,2830 +0,0 @@ -/* - * #%L - * Nuiton Utils - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2010 CodeLutin, Chatellier Eric - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - - -package org.nuiton.util; - -import java.awt.Color; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.Reader; -import java.io.Serializable; -import java.io.Writer; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.URI; -import java.net.URL; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import javax.swing.KeyStroke; -import org.apache.commons.beanutils.ConstructorUtils; -import org.apache.commons.collections.EnumerationUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.util.converter.ConverterUtil; - -import static org.nuiton.i18n.I18n._; - -/** - * Application configuration. - * <p/> - * <h3>A finir...</h3> - * <ul> - * <li>Ajout d'annotations sur les methodes - * pour preciser plus de chose pour les options (pattern, min/max, alias, - * description, ...) - * <li>Trouver un moyen de document les options et actions pour automatiquement - * generer l'aide en ligne. Pour eviter de devoir maintenir une methode - * dans lequel est ecrit l'aide en plus des options. - * <li>Prise en compte du flag {@link #useOnlyAliases} - * <li>Vu qu'en java on ne peut pas pointer une methode mais seulement une classe - * il y a un bout des actions qui sont des chaines (nom de la methode). Il faudrait - * faire un plugin maven qui check que l'action existe bien durant la compilation. - * Il est simple de le faire a l'execution mais c trop tard :( - * <li>Ajouter de la documentation pour {@link #getOptionAsList(String)} - * </ul> - * <p/> - * <h3>Bonnes pratiques</h3> - * <p/> - * Vous devez créer une factory pour créer les instances d'{@link ApplicationConfig} qui contiendra par exemple une méthode : - * <p/> - * <pre> - * - * public static ApplicationConfig getConfig( - * Properties props, String configFilename, String ... args) { - * - * ApplicationConfig conf = new ApplicationConfig( - * MyAppConfigOption.class, MyAppConfigAction.class, - * props, configFilename); - * - * try { - * conf.parse(args); - * } catch (ArgumentsParserException eee) { - * if (log.isErrorEnabled()) { - * log.error("Can't load app configuration", eee); - * } - * } - * return conf; - * } - * - * </pre> - * <p/> - * <ul> - * <li>MyAppConfigOption doit étendre {@link OptionDef} et décrir la configuration de l'application. - * <li>MyAppConfigAction doit étendre {@link ActionDef} et décrir la liste des options - * et de leur alias disponible pour l'application. - * </ul> - * <p/> - * <h3>Lecture des fichiers de configuration</h3> - * <p/> - * La lecture des fichiers de configuration se fait durant l'appel de la methode - * {@link #parse(String...)} en utilisant la valeur de qui doit être définit - * dans les options avec pour clef {@link ApplicationConfig#CONFIG_FILE_NAME} pour - * trouver les fichiers (voir Les options de configuration pour l'ordre de - * chargement des fichiers) - * <p/> - * <h3>La sauvegarde</h3> - * La sauvegarde des options se fait via une des trois methodes disponibles : - * <ul> - * <li> {@link #save(File, boolean, String...)} sauve les données dans le fichier demandé - * <li> {@link #saveForSystem(String...)} sauvegarde les donnees dans /etc - * <li> {@link #saveForUser(String...)} sauvegarde les donnees dans $HOME - * </ul> - * <p/> - * Lors de l'utilisation de la methode {@link #saveForSystem(String...)} ou - * {@link #saveForUser(String...)} seules les options lues dans un fichier ou modifiées par - * programmation ({@link #setOption(String, String)} seront sauvegardées. Par exemple les - * options passees sur la ligne de commande ne seront pas sauvees. - * <p/> - * <h3>Les options de configuration</h3> - * <p/> - * Cette classe permet de lire les fichiers de configuration, utiliser les - * variable d'environnement et de parser la ligne de commande. L'ordre de prise - * en compte des informations trouvées est le suivant (le premier le plus - * important) : - * <ul> - * <li>options ajoutees par programmation: {@link #setOption(String, String)}</li> - * <li>ligne de commande</li> - * <li>variable d'environnement de la JVM: java -Dkey=value</li> - * <li>variable d'environnement; export key=value</li> - * <li>fichier de configuration du repertoire courant: $user.dir/filename</li> - * <li>fichier de configuration du repertoire home de l'utilisateur: $user.home/.filename</li> - * <li>fichier de configuration du repertoire /etc: /etc/filename</li> - * <li>fichier de configuration trouve dans le classpath: $CLASSPATH/filename</li> - * <li>options ajoutees par programmation: {@link #defaults}.put(key, value)</li> - * </ul> - * <p/> - * <p/> - * Les options sur la ligne de commande sont de la forme: - * <pre> - * --option key value - * --monOption key value1 value2 - * </pre> - * <p/> - * <ul> - * <li>--option key value: est la syntaxe par defaut - * <li>--monOption key value1 value2: est la syntaxe si vous avez ajouter une - * methode setMonOption(key, value1, value2) sur votre classe de configuration - * qui herite de {@link ApplicationConfig}. Dans ce cas vous pouvez mettre les - * arguments que vous souhaitez du moment qu'ils soient convertibles de la - * representation String vers le type que vous avez mis. - * </ul> - * <p/> - * <h3>Les actions</h3> - * <p/> - * Les actions ne peuvent etre que sur la ligne de commande. Elles sont de la - * forme: - * <pre> - * --le.package.LaClass#laMethode arg1 arg2 arg3 ... argN - * </pre> - * <p/> - * Une action est donc defini par le chemin complet vers la methode qui traitera - * l'action. Cette methode peut-etre une methode static ou non. Si la methode - * n'est pas static lors de l'instanciation de l'objet on essaie de passer en - * parametre du constructeur la classe de configuration utilisee pour permettre - * a l'action d'avoir a sa disposition les options de configuration. Si aucun - * constructeur avec comme seul parametre une classe heritant de - * {@link ApplicationConfig} n'existe alors le constructeur par defaut est - * utilise (il doit etre accessible). Toutes methodes d'actions faisant - * parties d'un meme objet utiliseront la meme instance de cette objet lors - * de leur execution. - * <p/> - * Si la methode utilise les arguments variants alors tous les arguments - * jusqu'au prochain -- ou la fin de la ligne de commande sont utilises. Sinon - * Le nombre exact d'argument necessaire a la methode sont utilises. - * <p/> - * Les arguments sont automatiquement converti dans le bon type reclame par la - * methode. - * <p/> - * Si l'on veut des arguments optionnels le seul moyen actuellement est - * d'utiliser une methode avec des arguments variants - * <p/> - * Les actions ne sont pas execute mais seulement parsees. Pour les executer - * il faut utiliser la méthode {@link #doAction(int)} qui prend en argument un numero - * de 'step' ou {@link #doAllAction()} qui fait les actions dans l'ordre de leur step. - * Par defaut toutes les actions sont de niveau 0 et sont executee - * dans l'ordre d'apparition sur la ligne de commande. Si l'on souhaite - * distinguer les actions il est possible d'utiliser l'annotation - * {@link ApplicationConfig.Action.Step} sur la methode qui fera l'action en - * precisant une autre valeur que 0. - * <pre> - * doAction(0); - * ... do something ... - * doAction(1); - * </pre> - * dans cette exemple on fait un traitement entre l'execution des actions - * de niveau 0 et les actions de niveau 1. - * <p/> - * <h3>Les arguments non parsées</h3> - * Tout ce qui n'est pas option ou action est considere comme non parse et peut - * etre recupere par la methode {@link #getUnparsed}. Si l'on souhaite forcer - * la fin du parsing de la ligne de commande il est possible de mettre --. - * Par exemple: - * <pre> - * monProg "mon arg" --option k1 v1 -- --option k2 v2 -- autre - * </pre> - * Dans cet exemple seule la premiere option sera considere comme une option. - * On retrouvera dans {@code unparsed}: "mon arg", "--option", "k2", "v2", "--", - * "autre" - * <p/> - * <h3>Les alias</h3> - * On voit qu'aussi bien pour les actions que pour les options, le nom de la - * methode doit etre utilise. Pour eviter ceci il est possible de definir - * des alias ce qui permet de creer des options courtes par exemple. Pour cela, - * on utilise la methode {@link #addAlias(String, String...)}. - * <pre> - * addAlias("-v", "--option", "verbose", "true"); - * addAlias("-o", "--option", "outputfile"); - * addAlias("-i", "--mon.package.MaClass#MaMethode", "import"); - * </pre> - * En faite avant le parsing de la ligne de commande tous les alias trouves sont - * automatiquement remplacer par leur correspondance. Il est donc possible - * d'utiliser ce mecanisme pour autre chose par exemple: - * <pre> - * addAlias("cl", "Code Lutin"); - * addAlias("bp", "Benjamin POUSSIN); - * </pre> - * Dans le premier exemple on simplifie une option de flags l'option -v n'attend - * donc plus d'argument. Dans le second exemple on simplifie une option qui - * attend encore un argment de type File. Enfin dans le troisieme exemple - * on simplifie la syntaxe d'une action et on force le premier argument de - * l'action a etre "import". - * <p/> - * <h3>Conversion de type</h3> - * Pour la conversion de type nous utilisons common-beans. Les types supportes - * sont: - * <ul> - * <li> les primitif (byte, short, int, long, float, double, char, boolean) - * <li> {@link String} - * <li> {@link File} - * <li> {@link URL} - * <li> {@link Class} - * <li> Sql{@link Date} - * <li> Sql{@link Time} - * <li> Sql{@link Timestamp} - * <li> les tableaux d'un type primitif ou {@link String}. Chaque element doit - * etre separe par une virgule. - * </ul> - * <p/> - * Pour suporter d'autre type, il vous suffit d'enregistrer de nouveau - * converter dans commons-beans. - * <p/> - * <h3>Les substitutions de variable</h3> - * {@link ApplicationConfig} supporte les substition de variables de la forme - * <tt>${xxx}</tt> où {@code xxx} est une autre variable de la configuration. - * <p/> - * Exemple (dans un fichier de configuration): - * <pre> - * firstname = John - * lastname = Doe - * fullname = ${firstname} ${lastname} - * </pre> - * <tt>getOption("fullname")</tt> retournera <tt>"John Doe"</tt>. - * - * @author poussin - * @version $Revision$ - * <p/> - * Last update $Date$ by - * @since 0.30 - * @deprecated since 2.6.10 (replaced by org.nuiton.util.config.ApplicationConfig - * in nuiton-config module), will be removed in version 2.7.1. - */ -@Deprecated -public class ApplicationConfig { - - /** Logger. */ - static private Log log = LogFactory.getLog(ApplicationConfig.class); - - /** Used to know what is separator between class and method on command line. */ - private static final String CLASS_METHOD_SEPARATOR = "#"; - - public static final String LIST_SEPARATOR = ","; - - /** Configuration file key option. */ - public static final String CONFIG_FILE_NAME = "config.file"; - - /** Configuration encoding key option. */ - public static final String CONFIG_ENCODING = "config.encoding"; - - /** Permet d'associer un nom de contexte pour prefixer les options {@link #CONFIG_PATH} et {@link #CONFIG_FILE_NAME}. */ - public static final String APP_NAME = "app.name"; - - /** - * Property name of {@link #adjusting} internal state. - * - * @since 1.3 - */ - public static final String ADJUSTING_PROPERTY = "adjusting"; - - /** - * Configuration directory where config path in located. - * <p/> - * Use default system configuration if nothing is defined: - * <ul> - * <li>Linux : /etc/xxx.properties - * <li>Windows : C:\\Windows\\System32\\xxx.properties - * <li>Mac OS : /etc/ - * </ul> - */ - public static final String CONFIG_PATH = "config.path"; - - /** System os name. (windows, linux, max os x) */ - protected String osName; - - /** TODO */ - protected boolean useOnlyAliases; - - /** - * file $user.home/.[filename] - * <p/> - * Not used anymore. Just used for migration issue. - * - * @deprecated since 1.2.1, and can't be removed (for migration purpose) - */ - @Deprecated - protected String userPath = getUserHome() + File.separator + "."; - - /** vrai si on est en train de parser les options de la ligne de commande. */ - protected boolean inParseOptionPhase; - - /** TODO */ - protected Properties defaults = new Properties(); - - /** TODO */ - protected Properties classpath = new Properties(defaults); - - /** TODO */ - protected Properties etcfile = new Properties(classpath); - - /** TODO */ - protected Properties homefile = new Properties(etcfile); - - /** TODO */ - protected Properties curfile = new Properties(homefile); - - /** TODO */ - protected Properties env = new Properties(curfile){ - /** - * Environnement variables can't contains dot (bash, csh, ...). Dots are - * replaced by underscore (_) to find property if property is not find - * with dot - */ - @Override - public synchronized Object get(Object key) { - Object result = super.get(key); - if (result == null && key instanceof String) { - String skey = (String)key; - skey = skey.replace(".", "_"); - result = super.get(skey); - } - return result; - } - /** - * override to use get(key) and not super.get(key) as in initial implementation :( - */ - @Override - public String getProperty(String key) { - Object oval = get(key); - String sval = (oval instanceof String) ? (String)oval : null; - return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval; - - } - - }; - - /** TODO */ - protected Properties jvm = new Properties(env); - - /** TODO */ - protected Properties line = new Properties(jvm); - - /** TODO */ - protected Properties options = new Properties(line); - - /** TODO */ - protected Map<String, CacheItem<?>> cacheOption = new HashMap<String, CacheItem<?>>(); - - /** TODO */ - protected Map<Class<?>, Object> cacheAction = new HashMap<Class<?>, Object>(); - - /** contient apres l'appel de parse, la liste des arguments non utilises */ - protected List<String> unparsed = new ArrayList<String>(); - - /** TODO */ - protected Map<String, List<String>> aliases = new HashMap<String, List<String>>(); - - /** TODO */ - protected Map<Integer, List<Action>> actions = new HashMap<Integer, List<Action>>(); - - /** - * Internal state to manage with masse operations on option and control - * listeners. - * <p/> - * for example, if you want to save options, using javaBeans technology, - * can add a listener to save each time the property is modified. - * <p/> - * Says now you have an algorithm to set new values in configuration using - * setters but you do NOt want to save each time, add in your saving action - * a test to detect if model is adjusting. - * - * @see #saveUserAction - * @since 1.3 - */ - private boolean adjusting; - - /** suport of config modification. */ - protected PropertyChangeSupport pcs = new PropertyChangeSupport(this); - - /** permet de conserver des objets associe avec ce ApplicationConfig */ - transient protected Map<String, Object> context = new HashMap<String, Object>(); - - /** - * Init ApplicationConfig with current simple class name as config file. - * <p/> - * Also init converters. - * - * @see ConverterUtil#initConverters() - */ - public ApplicationConfig() { - - this(null, null); - -// setEncoding("UTF-8"); -// setConfigFileName(getClass().getSimpleName()); -// setEncoding("utf-8"); -// -// // init extra-converters -// ConverterUtil.initConverters(); -// -// // get system os name -// osName = System.getProperty("os.name"); - } - - /** - * Create configuration for a particular configuration filename - * - * @param configFilename name of config to use - */ - public ApplicationConfig(String configFilename) { - this(null, configFilename); - } - - /** - * Init ApplicationConfig with current simple class name as config file - * and use Properties parameter as defaults - * <p/> - * Also init converters. - * - * @param defaults properties - * @see ConverterUtil#initConverters() - */ - public ApplicationConfig(Properties defaults) { - this(defaults, null); - } - - /** - * All in one, this constructor allow to pass all necessary argument to - * initialise ApplicationConfig and parse command line - * - * @param defaults properties that override default value of optionClass, can be null - * @param configFilename override default config filename, can be null - * @since 2.4.8 - */ - public ApplicationConfig(Properties defaults, String configFilename) { - init(defaults, configFilename); - } - - /** - * On separt l'init du corps du constructeur, car les sous classes ne doivent - * pas l'executer. - * - * @param defaults - * @param configFilename - * @since 2.4.9 - */ - protected void init(Properties defaults, String configFilename) { - if (defaults != null) { - // iterate with Properties method and not with Hashtable method to - // prevent missed value with chained Properties object - for (String key : defaults.stringPropertyNames()) { - setDefaultOption(key, defaults.getProperty(key)); - } - } - - setEncoding("UTF-8"); - - if (configFilename == null) { - - setConfigFileName(getClass().getSimpleName()); - } else { - setDefaultOption(CONFIG_FILE_NAME, configFilename); - } - - // init extra-converters - ConverterUtil.initConverters(); - - // get system os name - osName = System.getProperty("os.name"); - - } - - /** - * All in one, this constructor allow to pass all necessary argument to - * initialise ApplicationConfig and parse command line - * - * @param optionClass class that describe option, can be null - * @param actionClass class that describe action, can be null - * @param defaults properties that override default value of optionClass, can be null - * @param configFilename override default config filename, can be null - * @deprecated since 2.4.8, prefer use {@link #ApplicationConfig(Properties, String)} - */ - @Deprecated - public <O extends OptionDef, A extends ActionDef> ApplicationConfig( - Class<O> optionClass, Class<A> actionClass, - Properties defaults, String configFilename) { - this(defaults, configFilename); - if (optionClass != null) { - loadDefaultOptions(optionClass); - } - if (actionClass != null) { - loadActions(actionClass); - } - } - - /** - * Get user home directory (system property {@code user.home}). - * - * @return user home directory - */ - public static String getUserHome() { - String result = System.getProperty("user.home"); - return result; - } - - /** - * Get user name (system property {@code user.name}). - * - * @return user name - */ - public String getUsername() { - String result = getOption("user.name"); - return result; - } - - /** - * Get os name (system property {@code os.name}). - * - * @return os name - * @since 2.6.6 - */ - public String getOsName() { - String result = getOption("os.name"); - return result; - } - - /** - * Get os arch (system property {@code os.arch}). - * - * @return os arch - * @since 2.6.6 - */ - public String getOsArch() { - String result = getOption("os.arch"); - return result; - } - - /** - * Load default options of enum pass in param (enum must extend {@link OptionDef}) - * - * @param optionClass to load - * @param <O> type of enum extend {@link OptionDef} - * @deprecated since 2.4.8, prefer use now {@link #loadDefaultOptions(OptionDef[])} - */ - @Deprecated - public <O extends OptionDef> void loadDefaultOptions(Class<O> optionClass) { - - loadDefaultOptions(optionClass.getEnumConstants()); - } - - /** - * Load default given options. - * - * @param options options to load - * @param <O> type of enum extend {@link OptionDef} - * @since 2.4.8 - */ - public <O extends OptionDef> void loadDefaultOptions(O[] options) { - - // load default option (included configuration file name : important) - for (OptionDef o : options) { - if (o.getDefaultValue() != null) { - setDefaultOption(o.getKey(), o.getDefaultValue()); - } - } - } - - /** - * Load actions of enum pass in param (enum must extend {@link ActionDef}) - * - * @param actionClass to load - * @param <A> type of enum extend {@link ActionDef} - * @deprecated since 2.4.8, prefer use now {@link #loadActions(ActionDef[])} - */ - @Deprecated - public <A extends ActionDef> void loadActions(Class<A> actionClass) { - - loadActions(actionClass.getEnumConstants()); - } - - /** - * Load given actions. - * - * @param actions actions to load - * @param <A> type of enum extend {@link ActionDef} - * @since 2.4.8 - */ - public <A extends ActionDef> void loadActions(A[] actions) { - - // load actions - for (A a : actions) { - for (String alias : a.getAliases()) { - addActionAlias(alias, a.getAction()); - } - } - } - - /** - * Used to put default configuration option in config option. Those options - * are used as fallback value. - * - * @param key default property key - * @param value default property value - */ - public void setDefaultOption(String key, String value) { - defaults.setProperty(key, value); - } - - /** - * Save configuration, in specified file. - * - * @param file file where config will be writen - * @param forceAll if true save all config option - * (with defaults, classpath, env, command line) - * @param excludeKeys optional list of keys to exclude from - * @throws IOException if IO pb - */ - public void save(File file, - boolean forceAll, - String... excludeKeys) throws IOException { - - // store sorted in file - Properties prop = new SortedProperties(); - - if (forceAll) { - prop.putAll(defaults); - prop.putAll(classpath); - } - prop.putAll(etcfile); - prop.putAll(homefile); - prop.putAll(curfile); - if (forceAll) { - prop.putAll(jvm); - prop.putAll(env); - prop.putAll(line); - } - prop.putAll(options); - - for (String excludeKey : excludeKeys) { - prop.remove(excludeKey); - } - - // Ano #687 : create parentFile before using it in FileWriter - boolean dirCreated = - FileUtil.createDirectoryIfNecessary(file.getParentFile()); - if (dirCreated && log.isDebugEnabled()) { - log.debug("Creation of config directory " + file.getParent()); - } - saveResource(file, prop, "Last saved " + new Date()); - } - - /** - * Save configuration, in system directory (/etc/) using the - * {@link #getConfigFileName}. Default, env and commande line note saved. - * - * @param excludeKeys optional list of keys to exclude from - */ - public void saveForSystem(String... excludeKeys) { - File file = getSystemConfigFile(); - if (log.isDebugEnabled()) { - log.debug("will save system configuration in " + file); - } - try { - save(file, false, excludeKeys); - } catch (IOException eee) { - if (log.isWarnEnabled()) { - log.warn(_("nuitonutil.error.applicationconfig.save", file), - eee); - } - } - } - - /** - * Save configuration, in user home directory using the - * {@link #getConfigFileName}. Default, env and commande line note saved - * - * @param excludeKeys optional list of keys to exclude from - */ - public void saveForUser(String... excludeKeys) { - File file = getUserConfigFile(); - if (log.isDebugEnabled()) { - log.debug("will save user configuration in " + file); - } - try { - save(file, false, excludeKeys); - } catch (IOException eee) { - if (log.isWarnEnabled()) { - log.warn(_("nuitonutil.error.applicationconfig.save", file), - eee); - } - } - } - - /** - * Clean the user configuration file (The one in user home) and save it - * in user config file. - * - * All options with an empty value will be removed from this file. - * - * Moreover, like {@link #saveForUser(String...)} the given - * {@code excludeKeys} will never be saved. - * - * This method can be useful when migrating some configuration from a - * version to another one with deprecated options (otherwise they will stay - * for ever in the configuration file with an empty value which is not - * acceptable). - * - * <strong>Important note:</strong> Using this method can have some strange - * side effects, since it could then allow to reuse default configurations - * from other level (default, env, jvm,...). Use with care only! - * - * @param excludeKeys optional list of key to not treat in cleaning process, - * nor save in user user config file. - * @since 2.6.6 - */ - public void cleanUserConfig(String... excludeKeys) { - - Set<String> keys = new HashSet<String>(homefile.stringPropertyNames()); - - List<String> toExclude = Arrays.asList(excludeKeys); - - for (String key : keys) { - if (!toExclude.contains(key)) { - String property = homefile.getProperty(key); - if (StringUtils.isBlank(property)) { - if (log.isInfoEnabled()) { - log.info("Remove blank property: " + key); - } - homefile.remove(key); - } - } - } - - // can now save cleaned user config - saveForUser(excludeKeys); - } - - /** - * Obtain the system config file location. - * - * @return the system config file location - */ - public File getSystemConfigFile() { - File file = new File(getConfigPath(), getConfigFileName()); - return file; - } - - /** - * Obtain the user config file location. - * - * @return the user config file location - */ - public File getUserConfigFile() { - return new File(getUserConfigDirectory(), getConfigFileName()); - } - - /** - * Return list of unparsed command line argument - * - * @return list of unparsed arguments - */ - public List<String> getUnparsed() { - return unparsed; - } - - /** - * Add action to list of action to do. - * - * @param action action to add, can be null. - */ - public void addAction(Action action) { - if (action != null) { - Integer step = action.step; - List<Action> list = actions.get(step); - if (list == null) { - list = new LinkedList<Action>(); - actions.put(step, list); - } - list.add(action); - } - } - - /** - * Return ordered action step number. - * example: 0,1,5,6 - * - * @return ordered action step number - * @since 2.4 - */ - public List<Integer> getActionStep() { - List<Integer> result = new ArrayList<Integer>(actions.keySet()); - Collections.sort(result); - return result; - } - - /** - * Do all action in specified order step (first 0). - * - * @throws IllegalAccessException if action invocation failed - * @throws IllegalArgumentException if action invocation failed - * @throws InvocationTargetException if action invocation failed - * @throws InstantiationException if action invocation failed - * @see Action.Step - * @since 2.4 - */ - public void doAllAction() throws IllegalAccessException, - IllegalArgumentException, - InvocationTargetException, - InstantiationException { - for (int step : getActionStep()) { - doAction(step); - } - } - - /** - * Do action in specified step. - * - * @param step do action only defined in this step - * @throws IllegalAccessException if action invocation failed - * @throws IllegalArgumentException if action invocation failed - * @throws InvocationTargetException if action invocation failed - * @throws InstantiationException if action invocation failed - * @see Action.Step - */ - public void doAction(int step) throws IllegalAccessException, - IllegalArgumentException, - InvocationTargetException, - InstantiationException { - List<Action> list = actions.get(step); - if (list != null) { - for (Action a : list) { - a.doAction(); - } - } - } - - public void setUseOnlyAliases(boolean useOnlyAliases) { - this.useOnlyAliases = useOnlyAliases; - } - - public boolean isUseOnlyAliases() { - return useOnlyAliases; - } - - /** - * Get the encoding used to read/write resources. - * <p/> - * This value is stored as an option using the - * {@link #getEncodingOption()} key. - * - * @return the encoding used to read/write resources. - * @since 2.3 - */ - public String getEncoding() { - return getOption(getEncodingOption()); - } - - /** - * Set the new encoding option. - * - * @param encoding the new value of the option encoding - * @since 2.3 - */ - public void setEncoding(String encoding) { - setDefaultOption(getEncodingOption(), encoding); - } - - /** - * All argument in aliases as key is substitued by target. - * - * @param alias alias string as '-v' - * @param target substitution as '--option verbose true' - */ - public void addAlias(String alias, String... target) { - aliases.put(alias, Arrays.asList(target)); - } - - /** - * Add alias for action. This method put just -- front the actionMethod and - * call {@link #addAlias(String, String...)}. - * - * @param alias the alias to add for the given method action - * @param actionMethod must be fully qualified method path: - * package.Class#method - */ - public void addActionAlias(String alias, String actionMethod) { - addAlias(alias, "--" + actionMethod); - } - - /** - * Set name of file where options are read (in /etc, $HOME, $CURDIR) - * This set used {@link #setDefaultOption(String, String)}. - * - * @param name file name - */ - public void setConfigFileName(String name) { - // put in defaults, this permit user to overwrite it on commande line - setDefaultOption(getConfigFileNameOption(), name); - } - - /** - * Get name of file where options are read (in /etc, $HOME, $CURDIR). - * - * @return name of file - */ - public String getConfigFileName() { - String result = getOption(getConfigFileNameOption()); - return result; - } - - public boolean isAdjusting() { - return adjusting; - } - - public void setAdjusting(boolean adjusting) { - boolean oldvalue = this.adjusting; - this.adjusting = adjusting; - firePropertyChange(ADJUSTING_PROPERTY, oldvalue, adjusting); - } - - protected String getConfigFileNameOption() { - String optionName = CONFIG_FILE_NAME; - if (getOption(APP_NAME) != null) { - optionName = getOption(APP_NAME) + "." + optionName; - } - return optionName; - } - - /** - * Obtains the key used to store the option encoding. - * - * @return the encoding option'key - * @since 2.3 - */ - protected String getEncodingOption() { - String optionName = CONFIG_ENCODING; - if (getOption(APP_NAME) != null) { - optionName = getOption(APP_NAME) + "." + optionName; - } - return optionName; - } - - /** - * Use appName to add a context in config.file and config.path options. - * <p/> - * Ex for an application named 'pollen' : {@code config.file} option becomes - * {@code pollen.config.file} and {@code config.path} becomes - * {@code pollen.config.path} - * - * @param appName to use as application context - * @since 1.2.1 - */ - public void setAppName(String appName) { - setDefaultOption(APP_NAME, appName); - } - - /** - * Get configuration file path to use. - * <p/> - * Use (in order) one of the following definition: - * <ul> - * <li>{@link #CONFIG_PATH} option - * <li>system dependant path - * </ul> - * - * @return path to use with endind {@link File#separator} - * @since 1.2.1 - */ - public String getConfigPath() { - // Concat appName to configPath option to specify context for - // application deployment - String appName = getOption(APP_NAME) != null ? - getOption(APP_NAME) + "." : ""; - - String result = getOption(appName + CONFIG_PATH); - - if (result == null) { - result = getSystemConfigurationPath(); - } - if (log.isDebugEnabled()) { - log.debug("Configuration path used : " + result); - } - return result; - } - - /** - * Get system configuration path. - * <p/> - * Currently supported: - * <ul> - * <li>Windows : C:\Windows\System32 - * <li>Unix : /etc/ - * </ul> - * - * @return the system path - * @since 1.2.1 - */ - protected String getSystemConfigurationPath() { - - String systemPath = null; - - // Windows - if (osName.toLowerCase().contains("windows")) { - - // try 1 : %SystemDirectory% - try { - String systemDirectory = System.getenv("SystemDirectory"); - if (systemDirectory != null && systemDirectory.length() > 0) { - systemPath = systemDirectory; - } - } catch (SecurityException eee) { - if (log.isErrorEnabled()) { - log.error("Can't read env property", eee); - } - } - - // try 2 : %SystemRoot% - if (systemPath != null) { - try { - String systemRoot = System.getenv("SystemRoot"); - if (systemRoot != null && systemRoot.length() > 0) { - systemPath = systemRoot + "\\System32"; - } - } catch (SecurityException eee) { - if (log.isErrorEnabled()) { - log.error("Can't read env property", eee); - } - } - } else { - // default value - systemPath = "C:\\Windows\\System32"; - } - - // %SystemDrive% exists too : C: - } else { - // All others are unix like - // look for in /etc/ - systemPath = File.separator + "etc" + File.separator; - } - if (log.isDebugEnabled()) { - log.debug(systemPath); - } - return systemPath; - } - - /** - * Get user configuration path. - * <p/> - * Currently supported: - * <ul> - * <li>Windows : ${user.home}\\Application Data\\ - * <li>Max os x : ${user.home}/Library/Application Support - * <li>Unix : ${user.home}/.config - * </ul> - * <p/> - * Unix norm is based on freedesktop concept explained here : - * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - * - * @return the user configuration path - * @since 1.2.1 - */ - public String getUserConfigDirectory() { - - String userPath = null; - - String userHome = null; - try { - userHome = getUserHome(); - } catch (SecurityException ignore) { - } - - if (userHome != null) { - // windows - if (osName.toLowerCase().contains("windows")) { - try { - String appDataEV = System.getenv("APPDATA"); - if (appDataEV != null && appDataEV.length() > 0) { - userPath = appDataEV; - } - } catch (SecurityException ignore) { - } - - if (userPath == null || userPath.isEmpty()) { - // ${userHome}\Application Data\ - userPath = userHome + File.separator + "Application Data"; - } - } else if (osName.toLowerCase().contains("mac os x")) { - // ${userHome}/Library/Application Support/${applicationId} - userPath = userHome + File.separator + - "/Library/Application Support"; - } else { - // ${userHome}/.config/ - userPath = userHome + "/.config"; - } - } - - // what if null ? - - return userPath; - } - - /** - * Teste si un option existe ou non. - * - * @param key la clef de l'option à tester - * @return {@code true} si l'option existe, {@code false} sinon. - */ - public boolean hasOption(String key) { - // on est oblige de faire un get, car le containsKey n'est pas recursif - // sur tous les properties - boolean result = options.getProperty(key) != null; - return result; - } - - /** - * Teste si un option existe ou non - * - * @param key la clef de l'option à tester - * @return {@code true} si 'loption existe, {@code false} sinon. - */ - public boolean hasOption(OptionDef key) { - boolean result = hasOption(key.getKey()); - return result; - } - - /** - * ajoute un objet dans le context, la classe de l'objet est utilise comme cle - * - * @since 2.4.2 - */ - public void putObject(Object o) { - putObject(o.getClass().getName(), o); - } - - /** - * ajoute un objet dans le context, 'name' est utilise comme cle - * - * @since 2.4.2 - */ - public void putObject(String name, Object o) { - context.put(name, o); - } - - /** - * recupere un objet de la class<E>, s'il n'existe pas encore, il est cree - * (il faut donc que class<E> soit instanciable - * <p/> - * E peut prendre en argument du contruteur un objet de type ApplicationConfig - * - * @since 2.4.2 - */ - public <E> E getObject(Class<E> clazz) { - E result = getObject(clazz, clazz.getName()); - return result; - } - - /** - * recupere un objet ayant le nom 'name', s'il n'existe pas encore, il est - * cree en utilisant la class<E>, sinon il est simplement caster vers cette - * classe. - * <p/> - * E peut prendre en argument du contruteur un objet de type ApplicationConfig - * - * @since 2.4.2 - */ - public <E> E getObject(Class<E> clazz, String name) { - E result = clazz.cast(context.get(name)); - if (result == null) { - result = ObjectUtil.newInstance( - clazz, Collections.singleton(this), true); - putObject(name, result); - } - return result; - } - - /** - * retourne une nouvelle instance d'un objet dont on recupere la la class - * dans la configuration via la cle 'key'. Retourne null si la cle n'est pas - * retrouve - * - * @since 2.4.2 - */ - public Object getOptionAsObject(String key) { - Object result = null; - if (hasOption(key)) { - Class<?> clazz = getOptionAsClass(key); - result = ObjectUtil.newInstance( - clazz, Collections.singleton(this), true); - } - return result; - } - - /** - * retourne une nouvelle instance d'un objet dont on recupere la la class - * dans la configuration via la cle 'key' et le cast en E. Retourne null - * si la cle n'est pas retrouve - * <p/> - * E peut prendre en argument du contruteur un objet de type ApplicationConfig - * - * @since 2.4.2 - */ - public <E> E getOptionAsObject(Class<E> clazz, String key) { - E result = clazz.cast(getOptionAsObject(key)); - return result; - } - - /** - * retourne l'objet instancier via la classe recupere dans la configuration - * via la cle 'key'. Une fois instancie, le meme objet est toujours retourne. - * On null si key n'est pas retrouve. - * <p/> - * La classe peut avoir un constructeur prenant un ApplicationConfig - * - * @since 2.4.2 - */ - public Object getOptionAsSingleton(String key) { - Object result = context.get(key); - if (result == null) { - result = getOptionAsObject(key); - putObject(key, result); - } - return result; - } - - /** - * retourne l'objet caster en 'E', instancier via la classe recupere dans la - * configuration via la cle 'key'. Une fois instancie, le meme objet est - * toujours retourne. On null si key n'est pas retrouve - * <p/> - * La classe peut avoir un constructeur prenant un ApplicationConfig - * - * @since 2.4.2 - */ - public <E> E getOptionAsSingleton(Class<E> clazz, String key) { - E result = clazz.cast(getOptionAsSingleton(key)); - return result; - } - - /** - * Set option value. - * - * @param key property key - * @param value property value - */ - public void setOption(String key, String value) { - if (inParseOptionPhase) { - line.setProperty(key, value); - } else { - options.setProperty(key, value); - } - } - - /** - * get option value as string. - * <p/> - * Replace inner ${xxx} value. - * - * @param key the option's key - * @return String representation value - */ - public String getOption(String key) { - String value = options.getProperty(key); - // replace ${xxx} - value = replaceRecursiveOptions(value); - return value; - } - - /** - * Replace included ${xxx} suboptions by their values. - * - * @param option option to replace into - * @return replaced option - * @since 1.1.3 - */ - protected String replaceRecursiveOptions(String option) { - - // TODO do a common code with RecursiveProperties code - // TODO but can't overwrite getProperty() method - - String result = option; - - if (result == null) { - return null; - } - - //Ex : result="My name is ${myName}." - int pos = result.indexOf("${", 0); - //Ex : pos=11 - while (pos != -1) { - int posEnd = result.indexOf("}", pos + 1); - //Ex : posEnd=19 - if (posEnd != -1) { - String value = getOption(result.substring(pos + 2, posEnd)); - // Ex : getProperty("myName"); - if (value != null) { - // Ex : value="Thimel" - result = result.substring(0, pos) + value + - result.substring(posEnd + 1); - // Ex : result="My name is " + "Thimel" + "." - pos = result.indexOf("${", pos + value.length()); - // Ex : pos=-1 - } else { - // Ex : value=null - pos = result.indexOf("${", posEnd + 1); - // Ex : pos=-1 - } - // Ex : pos=-1 - } - } - - return result; - } - - /** - * Returns a sub config that encapsulate this ApplicationConfig. - * - * @param prefix prefix to put automaticaly at beginning of all key - * @return sub config that encapsulate this ApplicationConfig - * @since 2.4.9 - */ - public SubApplicationConfig getSubConfig(String prefix) { - SubApplicationConfig result = new SubApplicationConfig(this, prefix); - return result; - } - - /** - * Permet de recuperer l'ensemble des options commencant par une certaine - * chaine. - * - * @param prefix debut de cle a recuperer - * @return la liste des options filtrées - */ - public Properties getOptionStartsWith(String prefix) { - Properties result = new Properties(); - - for (String key : options.stringPropertyNames()) { - if (key.startsWith(prefix)) { - result.setProperty(key, options.getProperty(key)); - } - } - - return result; - } - - /** - * Get option value from a option definition. - * - * @param key the definition of the option - * @return the value for the given option - */ - public Object getOption(OptionDef key) { - Object result = getOption(key.getType(), key.getKey()); - return result; - } - - /** - * Get option value as typed value. - * - * @param <T> type of the object wanted as return type - * @param clazz type of object wanted as return type - * @param key the option's key - * @return typed value - */ - public <T> T getOption(Class<T> clazz, String key) { - String value = getOption(key); - T result = null; - if (value != null) { - result = (T) convertOption(clazz, key, value, false); - } - - return result; - } - - /** - * Convert value in instance of clazz or List if asList is true - * <p/> - * example: - * <li> convertOption(Boolean.class, "toto", "true,true", false) => false - * <li> convertOption(Boolean.class, "toto", null, false) => ? ConverterUtil dependant - * <li> convertOption(Boolean.class, "toto", "true,true", true) => [true, true] - * <li> convertOption(Boolean.class, "toto", null, true) => [] - * - * @param clazz result type expected - * @param key option key - * @param value value to convert - * @param asList value is string that represente a list - * @return the converted option in the required type - */ - protected <T> Object convertOption(Class<T> clazz, - String key, - String value, - boolean asList) { - String cacheKey = key + "-" + asList + "-" + clazz.getName(); - - int hash = 0; - if (value != null) { - hash = value.hashCode(); - } - - CacheItem<?> cacheItem = cacheOption.get(cacheKey); - // compute value if value don't exist in cacheOption or - // if it's modified since last computation - if (cacheItem == null || cacheItem.hash != hash) { - if (asList) { - List<T> list = new ArrayList<T>(); - if (value != null) { - String[] values = StringUtil.split(value, LIST_SEPARATOR); - for (String valueString : values) { - // prefer use our convertert method (auto-register more converters) - T v = ConverterUtil.convert(clazz, valueString); - list.add(v); - } - } - cacheItem = new CacheItem<List<T>>(list, hash); - } else { - // prefer use our converter method (auto-register more converters) - T v = ConverterUtil.convert(clazz, value); - cacheItem = new CacheItem<T>(v, hash); - } - // add new item to the cache - cacheOption.put(cacheKey, cacheItem); - } - - // take result in item - Object result = cacheItem.item; - - return result; - } - - /** - * Help to convert value to list of object. If no option for this key - * empty List is returned finaly - * - * @param key the key of searched option - * @return value of option list - */ - public OptionList getOptionAsList(String key) { - String value = getOption(key); - OptionList result = new OptionList(this, key, value); - return result; - } - - /** - * Get option value as {@link File}. - * - * @param key the option's key - * @return value as file - */ - public File getOptionAsFile(String key) { - File result = getOption(File.class, key); - if (result != null) { - result = result.getAbsoluteFile(); - } - return result; - } - - /** - * Get option value as {@link Color}. - * - * @param key the option's key - * @return value as color - */ - public Color getOptionAsColor(String key) { - Color color = getOption(Color.class, key); - return color; - } - - /** - * Get option value as {@link Properties}, this property must be a filepath - * and file must be a properties. - * <p/> - * Returned Properties is {@link RecursiveProperties}. - * - * @param key the option's key - * @return Properties object loaded with value pointed by file - * @throws IOException if exception occured on read file - */ - public Properties getOptionAsProperties(String key) throws IOException { - File file = getOptionAsFile(key); - Properties prop = new RecursiveProperties(); - FileReader reader = new FileReader(file); - try { - prop.load(reader); - } finally { - reader.close(); - } - return prop; - } - - /** - * Get option value as {@link URL}. - * - * @param key the option's key - * @return value as URL - */ - public URL getOptionAsURL(String key) { - URL result = getOption(URL.class, key); - return result; - } - - /** - * Get option value as {@link Class}. - * - * @param key the option's key - * @return value as Class - */ - public Class<?> getOptionAsClass(String key) { - Class<?> result = getOption(Class.class, key); - return result; - } - - /** - * Get option value as {@link Date}. - * - * @param key the option's key - * @return value as Date - */ - public Date getOptionAsDate(String key) { - Date result = getOption(Date.class, key); - return result; - } - - /** - * Get option value as {@link Time}. - * - * @param key the option's key - * @return value as Time - */ - public Time getOptionAsTime(String key) { - Time result = getOption(Time.class, key); - return result; - } - - /** - * Get option value as {@link Timestamp}. - * - * @param key the option's key - * @return value as Timestamp - */ - public Timestamp getOptionAsTimestamp(String key) { - Timestamp result = getOption(Timestamp.class, key); - return result; - } - - /** - * Get option value as {@code int}. - * - * @param key the option's key - * @return value as {@code int} - */ - public int getOptionAsInt(String key) { - Integer result = getOption(Integer.class, key); - if (result == null) { - // primitive value can not be null - result = 0; - } - return result; - } - - /** - * Get option value as {@code long}. - * - * @param key the option's key - * @return value as {@code long} - */ - public long getOptionAsLong(String key) { - Long result = getOption(Long.class, key); - if (result == null) { - // primitive value can not be null - result = 0L; - } - return result; - } - - /** - * Get option value as {@code float}. - * - * @param key the option's key - * @return value as {@code float} - * @since 2.2 - */ - public float getOptionAsFloat(String key) { - Float result = getOption(Float.class, key); - if (result == null) { - // primitive value can not be null - result = 0f; - } - return result; - } - - /** - * Get option value as {@code double}. - * - * @param key the option's key - * @return value as {@code double} - */ - public double getOptionAsDouble(String key) { - Double result = getOption(Double.class, key); - if (result == null) { - // primitive value can not be null - result = 0d; - } - return result; - } - - /** - * Get option value as {@code boolean}. - * - * @param key the option's key - * @return value as {@code boolean}. - */ - public boolean getOptionAsBoolean(String key) { - Boolean result = getOption(Boolean.class, key); - if (result == null) { - // primitive value can not be null - result = false; - } - return result; - } - - /** - * Get option value as {@link Locale}. - * - * @param key the option's key - * @return value as {@link Locale}. - * @since 2.0 - */ - public Locale getOptionAsLocale(String key) { - Locale result = getOption(Locale.class, key); - return result; - } - - /** - * Get option value as {@link Version}. - * - * @param key the option's key - * @return value as {@link Version}. - * @since 2.0 - */ - public Version getOptionAsVersion(String key) { - Version result = getOption(Version.class, key); - return result; - } - - /** - * Get option value as {@link KeyStroke}. - * - * @param key the option's key - * @return value as {@link KeyStroke}. - * @since 2.5.1 - */ - public KeyStroke getOptionAsKeyStroke(String key) { - KeyStroke result = getOption(KeyStroke.class, key); - return result; - } - - - /** - * Get all options from configuration. - * - * @return Properties which contains all options - */ - public Properties getOptions() { - return options; - } - - /** - * Set manually options when you don't want to use parse method to check - * properties file configured by {@link #setConfigFileName(String)}. - * - * @param options Properties which contains all options to set - */ - public void setOptions(Properties options) { - this.options = options; - } - - /** - * Get all options as flat {@link Properties} object (replace inner options). - * - * @return flat Properties object - * @since 1.2.2 - */ - public Properties getFlatOptions() { - return getFlatOptions(true); - } - - /** - * Get all options as flat {@link Properties} object. - * - * @param replaceInner if {@code true} replace imbricated options by theirs values - * @return flat Properties object - * @since 1.2.2 - */ - public Properties getFlatOptions(boolean replaceInner) { - Properties props = new Properties(); - for (String propertyKey : options.stringPropertyNames()) { - String propertyValue; - if (replaceInner) { - // replace ${xxx} option - propertyValue = getOption(propertyKey); - } else { - // do not replace ${xxx} option - propertyValue = options.getProperty(propertyKey); - } - props.setProperty(propertyKey, propertyValue); - } - return props; - } - - /** - * Install the {@link #saveUserAction} on givne {@code properties}. - * - * @param properties properties on which insalls the saveUserAction - */ - protected void installSaveUserAction(String... properties) { - - // pass in adjusting state - setAdjusting(true); - - try { - // ajout de tous les listeners pour sauver la configuration - // lors de la modification des options de la configuration - for (String propertyKey : properties) { - // add a listener - if (log.isDebugEnabled()) { - log.debug("register saveUserAction on property [" + - propertyKey + ']'); - } - addPropertyChangeListener(propertyKey, saveUserAction); - } - } finally { - - // ok back to normal adjusting state - setAdjusting(false); - } - } - - /** - * Get all set method on this object or super object. - * - * @return map with method name without set and in lower case as key, and - * method as value - */ - protected Map<String, Method> getMethods() { - // looking for all methods set on ApplicationConfig - Method[] allMethods = getClass().getMethods(); - Map<String, Method> methods = new HashMap<String, Method>(); - for (Method m : allMethods) { - String methodName = m.getName(); - if (methodName.startsWith("set")) { - methodName = methodName.substring(3).toLowerCase(); - methods.put(methodName, m); - } - } - return methods; - } - - /** - * Take required argument for method in args. Argument used is removed from - * args. If method has varArgs, we take all argument to next '--' - * - * @param m the method to call - * @param args iterator with many argument (equals or more than necessary - * @return the arguments found for the given method - */ - protected String[] getParams(Method m, ListIterator<String> args) { - List<String> result = new ArrayList<String>(); - if (m.isVarArgs()) { - while (args.hasNext()) { - String p = args.next(); - if (p.startsWith("--")) { - // stop search - args.previous(); - break; - } else { - result.add(p); - args.remove(); - } - } - } else { - int paramLenght = m.getParameterTypes().length; - for (int i = 0; i < paramLenght; i++) { - String p = args.next(); - args.remove(); // remove this arg because is used now - result.add(p); - } - } - return result.toArray(new String[result.size()]); - } - - /** - * Create action from string, string must be [package.][class][#][method] - * if package, class or method missing, default is used - * - * @param name name of the action - * @param args arguments for action invocation - * @return the created action - * @throws ArgumentsParserException if parsing failed - * @throws IllegalAccessException if could not create action - * @throws IllegalArgumentException if could not create action - * @throws InstantiationException if could not create action - * @throws InvocationTargetException if could not create action - */ - protected Action createAction(String name, - ListIterator<String> args) - throws ArgumentsParserException, - InstantiationException, - IllegalAccessException, - IllegalArgumentException, - InvocationTargetException { - Action result = null; - - List<Method> methods = ObjectUtil.getMethod(name, true); - - Class clazz = null; - Method method = null; - if (methods.size() > 0) { - if (methods.size() > 1) { - log.warn(String.format( - "More than one method found, used the first: %s", - methods)); - } - method = methods.get(0); - clazz = method.getDeclaringClass(); - } - - if (method != null) { - // remove option from command line, because is used now - args.remove(); - - // creation de l'object sur lequel on fera l'appel - Object o = cacheAction.get(clazz); - if (o == null && !Modifier.isStatic(method.getModifiers())) { - try { - o = ConstructorUtils.invokeConstructor(clazz, this); - } catch (NoSuchMethodException eee) { - log.debug(String.format( - "Use default constructor, because no constructor" + - " with Config parameter on class %s", - clazz.getName())); - o = clazz.newInstance(); - } - cacheAction.put(clazz, o); - } - - // recherche du step de l'action - int step = 0; - Action.Step annotation = method.getAnnotation(Action.Step.class); - if (annotation != null) { - step = annotation.value(); - } - - String[] params = getParams(method, args); - result = new Action(step, o, method, params); - } - - return result; - } - - /** - * Parse option and call set necessary method, read jvm, env variable, - * Load configuration file and prepare Action. - * - * @param args argument as main(String[] args) - * @return ApplicationConfig instance - * @throws ArgumentsParserException if parsing failed - */ - public ApplicationConfig parse(String... args) throws ArgumentsParserException { - if (args == null) { - args = ArrayUtils.EMPTY_STRING_ARRAY; - } - try { - Map<String, Method> methods = getMethods(); - - List<String> arguments = new ArrayList<String>(args.length); - for (String arg : args) { - if (aliases.containsKey(arg)) { - arguments.addAll(aliases.get(arg)); - } else { - arguments.add(arg); - } - } - - // first parse option - inParseOptionPhase = true; - for (ListIterator<String> i = arguments.listIterator(); - i.hasNext(); ) { - String arg = i.next(); - if (arg.equals("--")) { - // stop parsing - break; - } - if (arg.startsWith("--")) { - String optionName = arg.substring(2); - if (methods.containsKey(optionName)) { - i.remove(); // remove this arg because is used now - Method m = methods.get(optionName); - String[] params = getParams(m, i); - if (log.isDebugEnabled()) { - log.debug(String.format( - "Set option '%s' with method '%s %s'", - optionName, m, Arrays.toString(params))); - } - ObjectUtil.call(this, m, params); - } - } - } - inParseOptionPhase = false; - - // - // second load options from all sources - // - // JVM - jvm.putAll(System.getProperties()); - // ENV - env.putAll(System.getenv()); - - // classpath - String filename = getConfigFileName(); - Enumeration<URL> enumInClasspath = ClassLoader.getSystemClassLoader().getResources(filename); - Set<URL> urlsInClasspath = new HashSet<URL>(EnumerationUtils.toList(enumInClasspath)); - - enumInClasspath = ApplicationConfig.class.getClassLoader().getResources(filename); - urlsInClasspath.addAll(EnumerationUtils.toList(enumInClasspath)); - - if (log.isDebugEnabled() && urlsInClasspath.isEmpty()) { - log.debug("No configuration file found in classpath : /" + filename); - } - - /* TODO EC20100515 not sure if it's usefull :( - if (urlsInClasspath.isEmpty()) { - URL inClasspath = ApplicationConfig.class.getResource("/" + - filename); - if (inClasspath != null) { - urlsInClasspath.add(inClasspath); - } - }*/ - for (URL inClasspath : urlsInClasspath) { - if (log.isInfoEnabled()) { - log.info("Loading configuration file (classpath) : " + - inClasspath); - } - loadResource(inClasspath.toURI(), classpath); - } - - // system directory - File etcConfig = getSystemConfigFile(); -// File etcConfig = new File(getConfigPath(), filename); - if (etcConfig.exists()) { - if (log.isInfoEnabled()) { - log.info("Loading configuration file (etc) : " + etcConfig); - } - loadResource(etcConfig.toURI(), etcfile); - } else { - if (log.isDebugEnabled()) { - log.debug("No configuration file found in system : " + - etcConfig.getAbsolutePath()); - } - } - - // user home directory - File homeConfig = getUserConfigFile(); -// File homeConfig = new File(getUserPath(), filename); - if (log.isDebugEnabled()) { - log.debug("User configuration file : " + homeConfig); - } - // don't use new File(String, String) - File oldHomeConfig = new File(userPath + filename); - - // migration, if homeConfig doesn't exists and oldHomeConfig does - if (!homeConfig.exists() && oldHomeConfig.exists()) { - migrateUserConfigurationFile(oldHomeConfig, homeConfig); - } - // end of migration - - if (homeConfig.exists()) { - if (log.isInfoEnabled()) { - log.info("Loading configuration file (home) : " + - homeConfig); - } - loadResource(homeConfig.toURI(), homefile); - } else { - if (log.isDebugEnabled()) { - log.debug("No configuration file found in user home : " + - homeConfig.getAbsolutePath()); - } - } - - // file $CURDIR/filename - File config = new File(filename); - if (config.exists()) { - if (log.isInfoEnabled()) { - log.info("Loading configuration file (curr) : " + config); - } - loadResource(config.toURI(), curfile); - } else { - if (log.isDebugEnabled()) { - log.debug("No configuration file found in current" + - " directory : " + config.getAbsolutePath()); - } - } - - // - // third parse action and do action - // - for (ListIterator<String> i = arguments.listIterator(); - i.hasNext(); ) { - String arg = i.next(); - if (arg.equals("--")) { - // stop parsing - break; - } - if (arg.startsWith("--")) { - String optionName = arg.substring(2); - Action action = createAction(optionName, i); - addAction(action); - } - } - - // - // not used args added to unparsed - // - arguments.remove("--"); - unparsed.addAll(arguments); - - } catch (Exception eee) { - if (log.isErrorEnabled()) { - log.error(eee); - } - throw new ArgumentsParserException("Can't parse argument", eee); - } - return this; - } - - /** - * Move old user configuration file {@code oldHomeConfig} to {@code - * homeConfig}. - * - * @param oldHomeConfig old configuration file path - * @param homeConfig new configuration file path - * @throws IOException if could not move configuration file - */ - protected void migrateUserConfigurationFile(File oldHomeConfig, - File homeConfig) - throws IOException { - if (log.isInfoEnabled()) { - log.info(_("nuitonutil.config.moving.conf", - oldHomeConfig.getPath(), homeConfig.getPath())); - } - - boolean b = oldHomeConfig.renameTo(homeConfig); - if (!b) { - // could not move... - String message = String.format( - "could not move old configuration file %s to %s", - oldHomeConfig, - homeConfig - ); - throw new IOException(message); - } - } - - /** - * Load a resources given by his {@code uri} to the given - * {@code properties} argument. - * - * @param uri the uri to load - * @param properties the properties file to load - * @throws IOException if something occurs bad while loading resource - * @see Properties#load(Reader) - * @since 2.3 - */ - protected void loadResource(URI uri, Properties properties) throws IOException { - InputStreamReader reader = - new InputStreamReader(uri.toURL().openStream(), getEncoding()); - try { - properties.load(reader); - } finally { - reader.close(); - } - } - - /** - * Save the given {@code properties} into the given {@code file} with - * the given {@code comment}. - * - * @param file the location where to store the properties - * @param properties the properties file to save - * @param comment the comment to add in the saved file - * @throws IOException if something occurs bad while saving resource - * @see Properties#store(Writer, String) - * @since 2.3 - */ - protected void saveResource(File file, - Properties properties, - String comment) throws IOException { - Writer reader = - new OutputStreamWriter(new FileOutputStream(file), getEncoding()); - try { - properties.store(reader, comment); - } finally { - reader.close(); - } - } - - /** For debugging. */ - public void printConfig() { - System.out.println("-------------------Value-------------------------"); - printConfig(System.out); - System.out.println("-------------------------------------------------"); - } - - /** - * Print out current configuration in specified output. - * - * @param output output to write config to - * @since 1.1.4 - */ - public void printConfig(PrintStream output) { - output.println("defaults " + defaults); - output.println("classpath " + classpath); - output.println("etcfile " + etcfile); - output.println("homefile " + homefile); - output.println("curfile " + curfile); - output.println("env " + env); - output.println("jvm " + jvm); - output.println("line " + line); - output.println("options " + options); - } - - /** - * Return all configuration used with value, that respect includePattern - * - * @param includePattern null for all value, or config key pattern (ex: "wikitty.*") - * @param padding for better presentation, you can use padding to align '=' sign - * @return string that represent config - * @since 1.5.2 - */ - public String getPrintableConfig(String includePattern, int padding) { - String msg = "Configuration:\n"; - for (String key : getFlatOptions().stringPropertyNames()) { - if (includePattern == null || "".equals(includePattern) - || key.matches(includePattern)) { - String value = getOption(key); - msg += String.format("\t%" + padding + "s = %s\n", key, value); - } - } - return msg; - } - - protected void firePropertyChange(String propertyName, - Object oldValue, Object newValue) { - pcs.firePropertyChange(propertyName, oldValue, newValue); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - pcs.addPropertyChangeListener(listener); - } - - public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - pcs.addPropertyChangeListener(propertyName, listener); - } - - public void removePropertyChangeListener(PropertyChangeListener listener) { - pcs.removePropertyChangeListener(listener); - } - - public void removePropertyChangeListener(String propertyName, - PropertyChangeListener listener) { - pcs.removePropertyChangeListener(propertyName, listener); - } - - public boolean hasListeners(String propertyName) { - return pcs.hasListeners(propertyName); - } - - public PropertyChangeListener[] getPropertyChangeListeners( - String propertyName) { - return pcs.getPropertyChangeListeners(propertyName); - } - - public PropertyChangeListener[] getPropertyChangeListeners() { - return pcs.getPropertyChangeListeners(); - } - - /////////////////////////////////////////////////////////////////////////// - // - // C L A S S E S D E C L A R A T I O N - // - /////////////////////////////////////////////////////////////////////////// - - - /** - * Action to save user configuration. - * <p/> - * Add it as a listener of the configuration for a given property. - * <p/> - * <b>Note:</b> Will not save if {@link #isAdjusting()} is {@code true}. - * - * @since 1.3 - */ - private final PropertyChangeListener saveUserAction = - new PropertyChangeListener() { - - @Override - public void propertyChange(PropertyChangeEvent evt) { - if (isAdjusting()) { - if (log.isDebugEnabled()) { - log.debug("Skip save while adjusting"); - } - return; - } - if (log.isDebugEnabled()) { - log.debug("Saving configuration fired by property [" + - evt.getPropertyName() + "] at " + - new Date()); - } - saveForUser(); - } - }; - - /** - * Permet de masquer un prefix. Il est possible d'avoir des valeurs par - * defaut. Par exemple: - * <pre> - * monOption=toto - * monPrefix.monOption=titi - * </pre> - * <p/> - * <li>Si on cree le subApp avec le prefix "monPrefix." et qu'on demande la valeur - * de "monOption", la valeur retournee est "titi". - * <li>Si on cree le subApp avec le prefix "monAutrePrefix." et qu'on demande la valeur - * de "monOption", la valeur retournee est "toto" (valeur par defaut de monOption. - * <p/> - * Certaines methodes retournees ne sont pas - * surchargee et ne masque pas le prefix: - * <li>getOptions() - * - * @since 2.4.9 - */ - public static class SubApplicationConfig extends ApplicationConfig { - - protected ApplicationConfig parent; - - protected String prefix; - - public SubApplicationConfig(ApplicationConfig parent, String prefix) { - this.parent = parent; - this.prefix = prefix; - } - - @Override - protected void init(Properties defaults, String configFilename) { - // do nothing - } - - public ApplicationConfig getParent() { - return parent; - } - - public String getPrefix() { - return prefix; - } - - @Override - public Properties getOptions() { - return getParent().getOptions(); - } - - @Override - public void setDefaultOption(String key, String value) { - getParent().setDefaultOption(getPrefix() + key, value); - } - - @Override - public boolean hasOption(String key) { - boolean result = getOption(key) != null; - return result; - } - - @Override - public void setOption(String key, String value) { - getParent().setOption(getPrefix() + key, value); - } - - /** - * Surcharge pour recherche la cle avec le prefix. Si on ne la retrouve - * pas, on recherche sans le prefix pour permettre d'avoir des valeurs - * par defaut. - * - * @param key La cle de l'option - * @return l'option trouvé avec le prefix ou sinon celle sans le prefix - * si pas trouvé. - */ - @Override - public String getOption(String key) { - String result = getParent().getOption(getPrefix() + key); - if (result == null) { - result = getParent().getOption(key); - } - return result; - } - - /** - * Surcharge de la methode pour que les options commencant par le prefix - * soit modifiee pour qu'elle est la meme cle sans le prefix. Le but - * est de garder les autres options et si une option avait le meme nom - * qu'elle soit effacee par celle dont on a supprime le prefix - * - * @param replaceInner le prefix à remplacer - * @return les options commencant par le prefix - * soit modifiee pour qu'elle est la meme cle sans le prefix. Le but - * est de garder les autres options et si une option avait le meme nom - * qu'elle soit effacee par celle dont on a supprime le prefix - */ - @Override - public Properties getFlatOptions(boolean replaceInner) { - Properties result = getParent().getFlatOptions(replaceInner); - Properties tmp = new Properties(); - int lenght = getPrefix().length(); - for (Map.Entry e : result.entrySet()) { - String k = (String) e.getKey(); - if (k.startsWith(getPrefix())) { - k = k.substring(lenght); - String v = (String) e.getValue(); - tmp.setProperty(k, v); - } - } - result.putAll(tmp); - return result; - } - - /** - * Surcharge pour recupere les valeurs commencant par le prefix demande - * en plus du prefix 'sub'. Les options sont ensuite fusionnee pour - * permettre aussi les valeurs par defaut - * - * @param prefix prefix to use - * @return les valeurs commençant par le prefix demandé en plus du - * prefix 'sub'. - */ - @Override - public Properties getOptionStartsWith(String prefix) { - Properties result = getParent().getOptionStartsWith(prefix); - Properties tmp = getParent().getOptionStartsWith(getPrefix() + prefix); - int lenght = getPrefix().length(); - for (Map.Entry e : tmp.entrySet()) { - String k = (String) e.getKey(); - k = k.substring(lenght); - String v = (String) e.getValue(); - // on ajout/ecrase les valeurs de result - result.setProperty(k, v); - } - return result; - } - - @Override - protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { - if (propertyName.startsWith(getPrefix())) { - propertyName = propertyName.substring(getPrefix().length()); - getParent().firePropertyChange(propertyName, oldValue, newValue); - } // else not fire event - } - - @Override - public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { - getParent().addPropertyChangeListener(getPrefix() + propertyName, listener); - } - - @Override - public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { - getParent().removePropertyChangeListener(getPrefix() + propertyName, listener); - } - - @Override - public boolean hasListeners(String propertyName) { - return getParent().hasListeners(getPrefix() + propertyName); - } - - // methode interdite dans le sub - - @Override - public ApplicationConfig parse(String... args) throws ArgumentsParserException { - throw new UnsupportedOperationException("This method is not supported in SubApplicationConfig"); - } - - - } - - /** - * Le contrat de marquage des options, on utilise cette interface pour - * caracteriser une option de configuration. - * <p/> - * <pre> - * public enum MyConfigOption implements OptionDef { - * - * APP_CONFIG_FILE( - * ApplicationConfig.CONFIG_FILE_NAME, - * "Main configuration app file", - * "myApp-config.properties", - * String.class, true, true), - * - * APP_NAME( - * ApplicationConfig.CONFIG_FILE_NAME, - * Application name, - * "MyApp", - * String.class, true, true); - * - * public String key; - * public String description; - * public String defaultValue; - * public Class<?> type; - * public boolean isTransient; - * public boolean isFinal; - * - * private WikittyConfigOption(String key, String description, - * String defaultValue, Class<?> type, boolean isTransient, boolean isFinal) { - * this.key = key; - * this.description = description; - * this.defaultValue = defaultValue; - * this.type = type; - * this.isTransient = isTransient; - * this.isFinal = isFinal; - * } - * - * @Override - * public boolean isFinal() { - * return isFinal; - * } - * - * @Override - * public boolean isTransient() { - * return isTransient; - * } - * - * @Override - * public String getDefaultValue() { - * return defaultValue; - * } - * - * @Override - * public String getDescription() { - * return description; - * } - * - * @Override - * public String getKey() { - * return key; - * } - * - * @Override - * public Class<?> getType() { - * return type; - * } - * - * @Override - * public void setDefaultValue(String defaultValue) { - * this.defaultValue = defaultValue; - * } - * - * @Override - * public void setTransient(boolean isTransient) { - * this.isTransient = isTransient; - * } - * - * @Override - * public void setFinal(boolean isFinal) { - * this.isFinal = isFinal; - * } - * } - * </pre> - * - * @since 1.0.0-rc-9 - */ - public interface OptionDef extends Serializable { - - /** @return la clef identifiant l'option */ - String getKey(); - - /** @return le type de l'option */ - Class<?> getType(); - - /** @return la clef i18n de description de l'option */ - String getDescription(); - - /** - * @return la valeur par defaut de l'option sous forme de chaine de - * caracteres - */ - String getDefaultValue(); - - /** - * @return <code>true</code> si l'option ne peut etre sauvegardee sur - * disque (utile par exemple pour les mots de passe, ...) - */ - boolean isTransient(); - - /** - * @return <code>true</code> si l'option n'est pas modifiable (utilise - * par exemple pour la version de l'application, ...) - */ - boolean isFinal(); - - /** - * Changes the default value of the option. - * - * @param defaultValue the new default value of the option - */ - void setDefaultValue(String defaultValue); - - /** - * Changes the transient state of the option. - * - * @param isTransient the new value of the transient state - */ - void setTransient(boolean isTransient); - - /** - * Changes the final state of the option. - * - * @param isFinal the new transient state value - */ - void setFinal(boolean isFinal); - } - - /** - * Le contrat de marquage des action, on utilise cette interface pour - * caracteriser une action. - * <p/> - * Ex : - * <p/> - * <pre> - * public enum MyAppConfigAction implements ActionDef { - * HELP(MyAppHelpAction.class.getName() + "#show", "-h", "--help"); - * public String action; - * public String[] aliases; - * - * private WikittyConfigAction(String action, String... aliases) { - * this.action = action; - * this.aliases = aliases; - * } - * - * @Override - * public String getAction() { - * return action; - * } - * - * @Override - * public String[] getAliases() { - * return aliases; - * } - * - * } - * </pre> - * - * @author sletellier - * @since 1.5.2 - */ - public interface ActionDef extends Serializable { - - /** - * Must return fully qualified method path : package.Class#method - * - * @return action to run - */ - String getAction(); - - /** - * Return all alias used to execute action. - * - * @return aliases used to execute action - */ - String[] getAliases(); - } - - /** - * Defines a runtime action to be launched via the {@link #doAction()} - * method. - * - * @author poussin - */ - public static class Action { - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface Step { - - int value() default 0; - } - - protected int step; - - protected Object o; - - protected Method m; - - protected String[] params; - - public Action(int step, Object o, Method m, String... params) { - this.step = step; - this.o = o; - this.m = m; - this.params = params; - } - - public void doAction() throws IllegalAccessException, - IllegalArgumentException, - InvocationTargetException, - InstantiationException { - ObjectUtil.call(o, m, params); - } - } - - /** - * Item used for cacheOption - * - * @param <T> - */ - protected static class CacheItem<T> { - - /** typed option value */ - public T item; - - /** hash of string representation */ - public int hash; - - public CacheItem(T item, int hash) { - this.item = item; - this.hash = hash; - } - } - - public static class OptionList { - - protected ApplicationConfig config; - - protected String key; - - protected String value; - - public OptionList(ApplicationConfig config, String key, String value) { - this.config = config; - this.key = key; - this.value = value; - } - - protected <T> List<T> convertListOption(Class<T> type) { - List<T> result = (List<T>) config.convertOption(type, key, - value, - true - ); - return result; - } - - /** - * Get option value as {@link String}. - * - * @return value as String - */ - public List<String> getOption() { - List<String> result = convertListOption(String.class); - return result; - } - - /** - * Get option value as {@link File}. - * - * @return value as file - */ - public List<File> getOptionAsFile() { - List<File> tmp = convertListOption(File.class); - List<File> result = new ArrayList<File>(tmp.size()); - for (File file : tmp) { - result.add(file.getAbsoluteFile()); - } - return result; - } - - /** - * Get option value as {@link URL}. - * - * @return value as URL - */ - public List<URL> getOptionAsURL() { - List<URL> result = convertListOption(URL.class); - return result; - } - - /** - * Get option value as {@link Class}. - * - * @return value as Class - */ - public List<Class> getOptionAsClass() { - List<Class> result = convertListOption(Class.class); - return result; - } - - /** - * Get option value as {@link Date}. - * - * @return value as Date - */ - public List<Date> getOptionAsDate() { - List<Date> result = convertListOption(Date.class); - return result; - } - - /** - * Get option value as {@link Time}. - * - * @return value as Time - */ - public List<Time> getOptionAsTime() { - List<Time> result = convertListOption(Time.class); - return result; - } - - /** - * Get option value as {@link Timestamp}. - * - * @return value as Timestamp - */ - public List<Timestamp> getOptionAsTimestamp() { - List<Timestamp> result = convertListOption(Timestamp.class); - return result; - } - - /** - * Get option value as {@code int}. - * - * @return value as {@code int} - */ - public List<Integer> getOptionAsInt() { - List<Integer> result = convertListOption(Integer.class); - return result; - } - - /** - * Get option value as {@code double}. - * - * @return value as {@code double} - */ - public List<Double> getOptionAsDouble() { - List<Double> result = convertListOption(Double.class); - return result; - } - - /** - * Get option value as {@code boolean}. - * - * @return value as {@code boolean}. - */ - public List<Boolean> getOptionAsBoolean() { - List<Boolean> result = convertListOption(Boolean.class); - return result; - } - } - -} Deleted: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigHelper.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigHelper.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigHelper.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,209 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Utils - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.util; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.HashSet; -import java.util.ServiceLoader; -import java.util.Set; - -/** - * Helper about {@link ApplicationConfig}. - * - * @author tchemit <chemit@codelutin.com> - * @since 2.4.8 - * @deprecated since 2.6.10 (replaced by org.nuiton.util.config.ApplicationConfigConfigHelper - * in nuiton-config module), will be removed in version 2.7.1. - */ -@Deprecated -public class ApplicationConfigHelper { - - /** Logger. */ - private static final Log log = - LogFactory.getLog(ApplicationConfigHelper.class); - - protected ApplicationConfigHelper() { - // helper with no instance - } - - /** - * Obtain all providers on class-path. - * - * @param classLoader optional classLoader used to seek for providers - * @param includes optional includes providers to use (if none then accept all providers) - * @param excludes optional excludes providers (if none the no reject) - * @param verbose verbose flag - * @return sets of providers - */ - public static Set<ApplicationConfigProvider> getProviders(ClassLoader classLoader, - Set<String> includes, - Set<String> excludes, - boolean verbose) { - ServiceLoader<ApplicationConfigProvider> loader; - if (classLoader == null) { - loader = ServiceLoader.load(ApplicationConfigProvider.class); - - } else { - loader = ServiceLoader.load(ApplicationConfigProvider.class, - classLoader); - } - - Set<ApplicationConfigProvider> result = - new HashSet<ApplicationConfigProvider>(); - - for (ApplicationConfigProvider configProvider : loader) { - String name = configProvider.getName(); - if (includes != null && !includes.contains(name)) { - - // reject by include - if (verbose) { - log.info("configuration named '" + name + - "' is rejected by includes."); - } - continue; - } - if (excludes != null && excludes.contains(name)) { - - // reject by exclude - if (verbose) { - log.info("configuration named '" + name + - "' is rejected by excludes."); - } - continue; - } - if (verbose) { - log.info("configuration named '" + name + - "' will be generated."); - } - result.add(configProvider); - } - return result; - } - - public static ApplicationConfigProvider getProvider(ClassLoader classLoader, - String name) { - Set<ApplicationConfigProvider> providers = getProviders( - classLoader, null, null, false); - ApplicationConfigProvider result = null; - for (ApplicationConfigProvider provider : providers) { - if (name.equals(provider.getName())) { - result = provider; - break; - } - } - return result; - } - - /** - * Load default options from all given config providers. - * - * @param config config where to add default options. - * @param providers providers to use - * @since 2.6.7 - */ - public static void loadAllDefaultOption(ApplicationConfig config, - Set<ApplicationConfigProvider> providers) { - - for (ApplicationConfigProvider provider : providers) { - if (log.isInfoEnabled()) { - log.info("Load default options from configuration: " + - provider.getName()); - } - if (log.isInfoEnabled()) { - for (ApplicationConfig.OptionDef optionDef : provider.getOptions()) { - log.info(" " + optionDef.getKey() + - " (" + optionDef.getDefaultValue() + ')'); - } - } - config.loadDefaultOptions(provider.getOptions()); - } - } - - /** - * Gets all transient options from the given providers. - * - * @param providers providers to inspect - * @return the set of all options that are transient - * @see ApplicationConfig.OptionDef#isTransient() - * @since 2.6.7 - */ - public static Set<ApplicationConfig.OptionDef> getTransientOptions(Set<ApplicationConfigProvider> providers) { - Set<ApplicationConfig.OptionDef> result = new HashSet<ApplicationConfig.OptionDef>(); - for (ApplicationConfigProvider provider : providers) { - for (ApplicationConfig.OptionDef def : provider.getOptions()) { - if (def.isTransient()) { - result.add(def); - } - } - } - return result; - } - - - /** - * Gets all final options from the given providers. - * - * @param providers providers to inspect - * @return the set of all options that are final - * @see ApplicationConfig.OptionDef#isFinal() - * @since 2.6.7 - */ - public static Set<ApplicationConfig.OptionDef> getFinalOptions(Set<ApplicationConfigProvider> providers) { - Set<ApplicationConfig.OptionDef> result = new HashSet<ApplicationConfig.OptionDef>(); - for (ApplicationConfigProvider provider : providers) { - for (ApplicationConfig.OptionDef def : provider.getOptions()) { - if (def.isFinal()) { - result.add(def); - } - } - } - return result; - } - - /** - * Get all option keys that should not be saved in the user config file - * from the given options providers. - * <p/> - * Such options are {@code transient} or {@code final}. - * - * @param providers providers to inspect - * @return the set of options key not to store in the config file - * @see ApplicationConfig.OptionDef#isFinal() - * @see ApplicationConfig.OptionDef#isTransient() - * @since 2.6.7 - */ - public static Set<String> getTransientOrFinalOptionKey(Set<ApplicationConfigProvider> providers) { - Set<String> result = new HashSet<String>(); - for (ApplicationConfig.OptionDef def : getTransientOptions(providers)) { - result.add(def.getKey()); - } - for (ApplicationConfig.OptionDef def : getFinalOptions(providers)) { - result.add(def.getKey()); - } - return result; - } -} Deleted: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigProvider.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigProvider.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationConfigProvider.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,82 +0,0 @@ -/* - * #%L - * Nuiton Utils :: Nuiton Utils - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.util; - -import java.util.Locale; -import java.util.ServiceLoader; - -/** - * Provider of a {@link ApplicationConfig}. - * <p/> - * Each library of application which use {@link ApplicationConfig} should - * implements this and add the provider available via the - * {@link ServiceLoader} mecanism. - * <p/> - * Using such provider offers a nice way to find out what options can be loaded - * in a application. It also offers a simply way to generate application - * config report for documentation. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.8 - * @deprecated since 2.6.10 (replaced by org.nuiton.util.config.ApplicationConfigProvider - * in nuiton-config module), will be removed in version 2.7.1. - */ -@Deprecated -public interface ApplicationConfigProvider { - - /** - * Returns the name of the provided application config. - * <p/> - * This should be the name of the library or application which offers - * the configuration. - * - * @return the name of the provided application config - */ - String getName(); - - /** - * Returns the localized description of the configuration. - * - * @param locale locale used to render description - * @return the localized description of the configuration - */ - String getDescription(Locale locale); - - /** - * Returns all options offered by the configuration. - * - * @return all options offered by the configuration - * @see ApplicationConfig.OptionDef - */ - ApplicationConfig.OptionDef[] getOptions(); - - /** - * Returns all actions offered by the configuration. - * - * @return all actions offered by the configuration. - * @see ApplicationConfig.ActionDef - */ - ApplicationConfig.ActionDef[] getActions(); -} Deleted: trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ApplicationUpdater.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,602 +0,0 @@ -package org.nuiton.util; - -/* - * #%L - * Nuiton Utils :: Nuiton Utils - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2013 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.vfs2.AllFileSelector; -import org.apache.commons.vfs2.FileObject; -import org.apache.commons.vfs2.FileSystemException; -import org.apache.commons.vfs2.FileSystemManager; -import org.apache.commons.vfs2.FileSystemOptions; -import org.apache.commons.vfs2.VFS; -import org.apache.commons.vfs2.provider.http.HttpFileSystemConfigBuilder; - -/** - * Permet de telecharger des mises a jour d'application. - * - * Le principe est qu'un fichier properties pointe par une URL indique les - * information necessaire pour la recuperation de l'application. - * - * Si une nouvelle version de l'application existe, elle est alors telechargee - * et decompressee dans un repertoire specifique (elle ne remplace pas l'application - * courante). - * - * Il est alors a la charge d'un script de mettre en place cette nouvelle application - * a la place de l'ancienne. - * - * Il est possible d'interagir avec ApplicationUpdater via l'implantation d'un - * {@link ApplicationUpdaterCallback} passer en parametre de la methode {@link #update} - * - * <h3>Configuration possible</h3> - * Vous pouvez passer un ApplicationConfig dans le constructeur ou utiliser - * la recherche du fichier de configuration par defaut (ApplicationUpdater.properties) - * - * Cette configuration permet de récupérer les informations suivantes: - * <li>http_proxy: le proxy a utiliser pour l'acces au reseau (ex: squid.chezmoi.fr:8080) - * <li>os.name: le nom du systeme d'exploitation sur lequel l'application fonctionne (ex: Linux) - * <li>os.arch: l'architecture du systeme d'exploitation sur lequel l'application fonctionne (ex: amd64) - * - * <h3>format du fichier de properties</h3> - * - * <li>[osName.][osArch.]appName.version=version de l'application</li> - * <li>[osName.][osArch.]appName.auth=true ou false selon que l'acces a l'url - * demande une authentification a fournir par le callback - * (voir {@link ApplicationUpdaterCallback#updateToDo})</li> - * <li>[osName.][osArch.]appName.url=url du fichier compresse de la nouvelle version - * (format <a href="http://commons.apache.org/vfs/filesystems.html">commons-vfs2</a>)</li> - * - * appName est a remplacer par le nom de l'application. Il est possible - * d'avoir plusieurs application dans le meme fichier ou plusieurs version - * en fonction de l'os et de l'architecture. - * - * osName et osArch sont toujours en minuscule - * - * <h3>format des fichiers compresses</h3> - * - * Le fichier compresse doit avoir un repertoire racine qui contient l'ensemble de l'application - * c-a-d que les fichiers ne doivent pas etre directement a la racine lorsqu'on - * decompresse le fichier. - * - * exemple de contenu de fichier compresse convenable - * <pre> - * MonApp-0.3/Readme.txt - * MonApp-0.3/License.txt - * </pre> - * - * Ceci est du au fait qu'on renomme le repertoire racine avec le nom de l'application, - * donc si le repertoire racine n'existe pas ou qu'il y a plusieurs repertoires - * a la racine le resultat de l'operation n'est pas celui souhaite - * - * <h3>os.name and os.arch</h3> - * <table> - * <th><td>os.name</td><td>os.arch</td></th> - * <tr><td>linux</td><td>amd64</td></tr> - * <tr><td>linux</td><td>i386</td></tr> - * <tr><td>mac</td><td>ppc</td></tr> - * <tr><td>windows</td><td>x86</td></tr> - * <tr><td>solaris</td><td>sparc</td></tr> - * </table> - * - * os.name est tronque apres le 1er mot donc "windows 2000" et "windows 2003" - * deviennet tous les deux "windows". Si vous souhaitez gérer plus finement vos - * url de telechargement vous pouvez modifier les donnees via - * {@link ApplicationUpdaterCallback#updateToDo(java.util.Map) } en modifiant - * l'url avant de retourner la map - * - * @author poussin - * @version $Revision$ - * - * Last update: $Date$ - * by : $Author$ - * - * @since 2.6.6 - * @deprecated since 2.6.10 (replaced by org.nuiton.util.updater.ApplicationUpdater - * in nuiton-updater module), will be removed in version 2.7.1. - */ -@Deprecated -public class ApplicationUpdater { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(ApplicationUpdater.class); - - final static private String SEPARATOR_KEY = "."; - - final static public String HTTP_PROXY = "http_proxy"; - - final static public String URL_KEY = "url"; - final static public String AUTHENTICATION_KEY = "auth"; - final static public String VERSION_KEY = "version"; - final static public String VERSION_FILE = "version.appup"; - - protected ApplicationConfig config; - - /** - * Utilise le fichier de configuration par defaut: ApplicationUpdater.properties - */ - public ApplicationUpdater() { - this(null); - } - - /** - * - * @param config La configuration a utiliser pour rechercher le proxy (http_proxy) - * et os.name, os.arch - */ - public ApplicationUpdater(ApplicationConfig config) { - if (config == null) { - try { - config = new ApplicationConfig( - ApplicationUpdater.class.getSimpleName() + ".properties"); - config.parse(); - config = config.getSubConfig( - ApplicationUpdater.class.getSimpleName() + SEPARATOR_KEY); - } catch (ArgumentsParserException eee) { - throw new RuntimeException(eee); - } - } - this.config = config; - } - - - - /** - * - * @param url url where properties file is downloadable. This properties - * must contains information on application release - * @param currentDir directory where application is currently - * @param destDir default directory to put new application version, can be null if you used callback - * @param async if true, check is done in background mode - * @param callback callback used to interact with updater, can be null - */ - public void update(String vfsPropertiesURL, File currentDir, File destDir, boolean async, ApplicationUpdaterCallback callback) { - Updater up = new Updater(config, vfsPropertiesURL, currentDir, destDir, callback); - if (async) { - Thread thread = new Thread(up, ApplicationUpdater.class.getSimpleName()); - thread.start(); - } else { - up.run(); - } - } - - /** - * Permet d'interagir avec ApplicationUpdater - */ - static public interface ApplicationUpdaterCallback { - /** - * Appeler avant la recuperation des nouvelles versions - * - * Permet de modifier le repertoire destination ou l'url du zip de - * l'application pour une application/version - * particuliere ou d'annuler la mise a jour en le supprimant de la map - * qui sera retourne. - * - * Si {@link ApplicationInfo#needAuthentication} est vrai, il faut que - * les valeurs {@link ApplicationInfo#login} et {@link ApplicationInfo#password} - * soient renseignees. Si elle ne le sont pas la recuperation de la - * ressource echouera. Pour des raisons de securite vous pouvez souhaiter - * mettre le mot de passe sous une forme encrypte. Dans ce cas il doit - * etre encadrer par '{' et '}'. Pour encrypter le mot de passe - * vous devez utiliser: - * <pre> - * java -cp commons-vfs-2.0.jar org.apache.commons.vfs2.util.EncryptUtil encrypt mypassword - * </pre> - * @param appToUpdate liste des applications a mettre a jour - * @return null or empty map if we don't want update, otherwize list of - * app to update - * - */ - Map<String, ApplicationInfo> updateToDo(Map<String, ApplicationInfo> appToUpdate); - - /** - * Appeler au démarrage d'une mise à jour. - * - * @param info application à mettre à jour - * @since 2.7 - */ - void startUpdate(ApplicationInfo info); - - /** - * Appeler une fois qu'une mise a jour a parfaitement fonctionne - * - * @param name le nom de l'application - * @param oldVersion l'ancienne version - * @param newVersion la nouvelle version - * @param applicationURL l'url d'ou provient le zip de l'application - * @param dest le repertoire ou se trouve la nouvelle version - */ - void updateDone( - Map<String, ApplicationInfo> appToUpdate, - Map<String, Exception> appUpdateError); - - /** - * Called when exception occur during process initialization - * @param propertiesURL url use to download properties release information - * @param eee exception throw during process - */ - void aborted(String propertiesURL, Exception eee); - } - - static public class ApplicationInfo { - public String name; - public String oldVersion; - public String newVersion; - public String url; - public boolean needAuthentication; - public String login; - public char[] password; - public File destDir; - - public ApplicationInfo(String name, String oldVersion, String newVersion, String url, File destDir, boolean needAuthentication) { - this.name = name; - this.oldVersion = oldVersion; - this.newVersion = newVersion; - this.url = url; - this.needAuthentication = needAuthentication; - this.destDir = destDir; - } - - public void setAuthentication(String login, char[] password) { - this.login = login; - this.password = password; - } - - @Override - public String toString() { - String result = String.format( - "App: %s, oldVersion: %s, newVersion: %s, url: %s, destDir:%s", - name, oldVersion, newVersion, url, destDir); - return result; - } - - } - - /** - * La classe ou le travail est reellement fait, peut-etre appeler dans - * un thread si necessaire - */ - static public class Updater implements Runnable { - - protected ApplicationConfig config; - protected String vfsPropertiesUrl; - protected File currentDir; - protected File destDir; - protected ApplicationUpdaterCallback callback; - - public Updater(ApplicationConfig config, String vfsPropertiesUrl, - File currentDir, File destDir, ApplicationUpdaterCallback callback) { - this.config = config; - this.vfsPropertiesUrl = vfsPropertiesUrl; - this.currentDir = currentDir; - this.destDir = destDir; - this.callback = callback; - } - - /** - * <li>Recupere le fichier properties contenant les informations de mise a jour - * <li>liste les applications et leur version actuelle - * <li>pour chaque application a mettre a jour recupere le zip et le decompresse - * - * Si callback existe envoi les messages necessaire - */ - public void run() { - try { - FileSystemOptions vfsConfig = getVFSConfig(config); - ApplicationConfig releaseConfig = getUpdaterConfig(vfsConfig, vfsPropertiesUrl); - - List<String> appNames = getApplicationName(releaseConfig); - Map<String, String> appVersions = getCurrentVersion(appNames, currentDir); - - log.debug("application current version: " + appVersions); - - // recherche des applications a mettre a jour - Map<String, ApplicationInfo> appToUpdate = new HashMap<String, ApplicationInfo>(); - for (String app : appNames) { - String currentVersion = appVersions.get(app); - String newVersion = releaseConfig.getOption(app + SEPARATOR_KEY + VERSION_KEY); - boolean greater = VersionUtil.greaterThan(newVersion, currentVersion); - log.debug(String.format("for %s Current(%s) < newVersion(%s) ? %s", - app, currentVersion, newVersion, greater)); - if (greater) { - String urlString = releaseConfig.getOption( - app + SEPARATOR_KEY + URL_KEY); - boolean needAuthentication = releaseConfig.getOptionAsBoolean( - app + SEPARATOR_KEY + AUTHENTICATION_KEY); - - appToUpdate.put(app, new ApplicationInfo( - app, currentVersion, newVersion, urlString, destDir, needAuthentication)); - } - } - - // offre la possibilite a l'appelant de modifier les valeurs par defaut - if (callback != null) { - appToUpdate = callback.updateToDo(appToUpdate); - } - - // mise a jour - Map<String, Exception> appUpdateError = new HashMap<String, Exception>(); - for (Map.Entry<String, ApplicationInfo> appInfo : appToUpdate.entrySet()) { - String app = appInfo.getKey(); - ApplicationInfo info = appInfo.getValue(); - try { - doUpdate(vfsConfig, appInfo.getValue()); - } catch (Exception eee) { - appUpdateError.put(app, eee); - try { - // clear data if error occur during uncompress operation - File dest = new File(info.destDir, info.name); - if (dest.exists()) { - log.debug(String.format("Cleaning destination directory due to error '%s'", dest)); - FileUtils.deleteDirectory(dest); - } - } catch(Exception doNothing) { - log.debug("Can't clean directory", doNothing); - } - - - log.warn(String.format( - "Can't update application '%s' with url '%s'", - app, info.url)); - log.debug("Application update aborted because: ", eee); - } - } - - // envoi le resultat a l'appelant s'il le souhaite - if (callback != null) { - callback.updateDone(appToUpdate, appUpdateError); - } - } catch(Exception eee) { - log.warn("Can't update"); - log.info("Application update aborted because: ", eee); - if (callback != null) { - callback.aborted(vfsPropertiesUrl, eee); - } - } - } - - /** - * Decompresse le zip qui est pointer par l'url dans le repertoire - * specifie, et ajoute le fichier contenant la version de l'application. - * Le repertoire root du zip est renomme par le nom de l'application. - * Par exemple si un fichier se nomme "monApp-1.2/Readme.txt" il se - * nommera au final "monApp/Readme.txt" - * - * @param proxy le proxy a utiliser pour la connexion a l'url - * @param info information sur l'application a mettre a jour - * @throws Exception - */ - protected void doUpdate(FileSystemOptions vfsConfig, ApplicationInfo info) throws Exception { - if (info.destDir != null) { - File dest = new File(info.destDir, info.name); - String url = toVfsURL(info.url); - if (info.needAuthentication) { - url = StringUtils.replaceOnce(url, "://", - String.format("://%s:%s@", info.login, new String(info.password))); - } - if (callback!=null) { - callback.startUpdate(info); - } - deepCopy(vfsConfig, url, dest.getAbsolutePath()); - - // ajout du fichier de version - File versionFile = new File(dest, VERSION_FILE); - FileUtils.writeStringToFile(versionFile, info.newVersion); - log.info(String.format( - "Application '%s' is uptodate with version '%s' in '%s'", - info.name, info.newVersion, info.destDir)); - } else { - log.info(String.format("Update for '%s' aborted because destination dir is set to null", info.name)); - } - } - - /** - * Recupere le contenu du repertoire de l'archive pour le mettre dans targetPath - * si targetPath existait deja, il est supprime au prealable. - * - * Si l'archive a plus d'un repertoire root, une exception est levee - * - * @param srcPath source path de la forme vfs2 ex:"zip:http://www.nuiton.org/attachments/download/830/nuiton-utils-2.6.5-deps.zip" - * @param targetPath le path destination - * @throws FileSystemException - */ - protected void deepCopy(FileSystemOptions vfsConfig, - String srcPath, String targetPath) throws FileSystemException { - FileSystemManager fsManager = VFS.getManager(); - FileObject archive = fsManager.resolveFile(srcPath, vfsConfig); - - FileObject[] children = archive.getChildren(); - if (children.length == 1) { - FileObject child = children[0]; - - FileObject target = fsManager.resolveFile(toVfsURL(targetPath), vfsConfig); - target.delete(new AllFileSelector()); - target.copyFrom(child, new AllFileSelector()); - } else { - throw new RuntimeException("must have only one root directory"); - } - } - - /** - * Converti le path en URL vfs2. Path doit etre une URL, mais pour les fichiers - * au lieu d'etre absolue ils peuvent etre relatif, un traitement special - * est donc fait pour ce cas. Cela est necessaire pour facilement faire - * des tests unitaires independant de la machine ou il sont fait - * - * @param path - * @return - */ - protected String toVfsURL(String path) { - String result = path; - Pattern p = Pattern.compile("(.*?file:)([^/][^!]*)(.*)"); - Matcher m = p.matcher(path); - if (m.matches()) { - String filepath = m.group(2); - File f = new File(filepath); - result = path.replaceAll( - "(.*?file:)([^/][^!]*)(.*)", - "$1"+f.getAbsolutePath()+"$3"); - } - return result; - } - - /** - * Return config prepared for os and arch - * - * @return - * @throws Exception - */ - protected ApplicationConfig getUpdaterConfig(FileSystemOptions vfsConfig, String vfsPropertiesUrl) throws Exception { - String osName = StringUtils.lowerCase(config.getOsName()); - String osArch = StringUtils.lowerCase(config.getOsArch()); - // take only first part for osName (windows 2000 or windows 2003 -> windows) - osName = StringUtils.substringBefore(osName, " "); - - if (log.isDebugEnabled()) { - log.debug(String.format("Try to load properties from '%s'", vfsPropertiesUrl)); - } - - Properties prop = new Properties(); - - FileSystemManager fsManager = VFS.getManager(); - FileObject properties = fsManager.resolveFile(toVfsURL(vfsPropertiesUrl), vfsConfig); - try { - InputStream in = new BufferedInputStream(properties.getContent().getInputStream()); - prop.load(in); - } finally { - try { - properties.close(); - } catch (Exception doNothing) { - log.debug("Can't close vfs file", doNothing); - } - } - - if (log.isDebugEnabled()) { - log.debug(String.format( - "Properties loaded from '%s'\n%s", - vfsPropertiesUrl, prop)); - } - - // load config with new properties as default - ApplicationConfig result = new ApplicationConfig(prop); - // don't parse. We want only prop in applicationConfig - result = result.getSubConfig( - ApplicationUpdater.class.getSimpleName() + SEPARATOR_KEY); - - result = result.getSubConfig(osName + SEPARATOR_KEY); - result = result.getSubConfig(osArch + SEPARATOR_KEY); - return result; - } - - /** - * Recupere le proxy http a utiliser pour les connexions reseaux - * - * @param config - * @return - */ - protected FileSystemOptions getVFSConfig(ApplicationConfig config) { - FileSystemOptions result = new FileSystemOptions(); - String proxyHost = config.getOption(HTTP_PROXY); - try { - proxyHost = StringUtils.substringAfter(proxyHost, "://"); - if (StringUtils.isNotBlank(proxyHost)) { - String hostname = StringUtils.substringBefore(proxyHost, ":"); - String port = StringUtils.substringAfter(proxyHost, ":"); - if (StringUtils.isNumeric(port)) { - - int portNumber = Integer.parseInt(port); - - HttpFileSystemConfigBuilder.getInstance().setProxyHost(result, hostname); - HttpFileSystemConfigBuilder.getInstance().setProxyPort(result, portNumber); - } else { - log.warn(String.format("Invalide proxy port number '%s', not used proxy", port)); - } - } - } catch (Exception eee) { - log.warn(String.format("Can't use proxy '%s'", proxyHost), eee); - } - return result; - } - - /** - * Recherche pour chaque application la version courante - * @param apps la liste des applications a rechercher - * @return - */ - protected Map<String, String> getCurrentVersion(List<String> apps, File dir) { - Map<String, String> result = new HashMap<String, String>(); - for (String app : apps) { - File f = new File(dir, app + File.separator + VERSION_FILE); - String version = "0"; - try { - version = FileUtils.readFileToString(f); - } catch (IOException ex) { - log.warn(String.format( - "Can't find file version '%s' for application '%s', this file should be '%s'", - VERSION_FILE, app, f)); - } - version = StringUtils.trim(version); - result.put(app, version); - } - return result; - } - - /** - * Retourne la liste des noms d'application se trouvant dans la - * configuration - * - * @param config - * @return - */ - protected List<String> getApplicationName(ApplicationConfig config) { - Pattern p = Pattern.compile("([^.]+)\\.version"); - List<String> result = new LinkedList<String>(); - for (String v : config.getFlatOptions().stringPropertyNames()) { - Matcher match = p.matcher(v); - if (match.matches()) { - result.add(match.group(1)); - } else if (StringUtils.endsWith(v, ".version")) { - log.debug(String.format("value is not valid application version '%s'",v)); - } - } - return result; - } - - } - -} Deleted: trunk/nuiton-utils/src/main/java/org/nuiton/util/ArgumentsParserException.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/ArgumentsParserException.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/ArgumentsParserException.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,61 +0,0 @@ -/* - * #%L - * Nuiton Utils - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -package org.nuiton.util; - -/** - * Argument parsing exception. - * - * @author Benjamin Poussin <poussin@codelutin.com> - * @deprecated since 2.6.10 (replaced by org.nuiton.util.config.ArgumentsParserException - * in nuiton-config module), will be removed in version 2.7.1. - */ -@Deprecated -public class ArgumentsParserException extends Exception { // ArgumentsParserException - - /** serialVersionUID. */ - private static final long serialVersionUID = 8265924907001359910L; - - /** - * Constructs a new exception with the specified detail message. - * - * @param msg message - */ - public ArgumentsParserException(String msg) { - super(msg); - } - - /** - * Constructs a new exception with the specified detail message and cause. - * - * @param msg message - * @param eee cause - */ - public ArgumentsParserException(String msg, Throwable eee) { - super(msg, eee); - } - -} // ArgumentsParserException - Deleted: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationConfigTest.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,709 +0,0 @@ -/* - * #%L - * Nuiton Utils - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -package org.nuiton.util; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.SystemUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; -import org.nuiton.util.ApplicationConfig.Action; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; - -/** - * @author poussin - * @deprecated since 2.6.10 (replaced by org.nuiton.util.config.ApplicationConfigTest - * in nuiton-config module), will be removed in version 2.7.1. - */ -@Deprecated -public class ApplicationConfigTest { - - private static final Log log = - LogFactory.getLog(ApplicationConfigTest.class); - - /** main folder for tests data * */ - protected static File DIR_TESTS_DATA; - - protected static int DUMMY_ACTION_CALL; - - public static class DummyAction { - @Action.Step(1) - public void dummyAction(String s, int step) { - DUMMY_ACTION_CALL++; - log.info(s + ':' + step); - } - } - - protected static String oldHome; - - @BeforeClass - public static void setUpClass() { - // Initialize test data directory - DIR_TESTS_DATA = FileUtil.getTestSpecificDirectory(ApplicationConfigTest.class, "", "", System.nanoTime()); - - oldHome = SystemUtils.getUserHome().getAbsolutePath(); - } - - protected File testDirectory; - - @Rule - public final TestName testName = new TestName(); - - @Before - public void before() { - testDirectory = new File(DIR_TESTS_DATA, testName.getMethodName()); - } - - @Test - public void testSaveForUser() throws IOException { - - // Initiliaze path and filename - String path = testDirectory.getAbsolutePath(); - - try { - System.setProperty("user.home", path); - - ApplicationConfig config = - new ApplicationConfig(testName.getMethodName()); - - File userFile = config.getUserConfigFile(); - - userFile.delete(); - - config.setOption("key1", "toto"); - config.setOption("key2", "tata"); - config.setOption("key3", "tutu"); - - // Parent directory will be created - config.saveForUser(); - - // I like to test that file.create works :( - Assert.assertTrue(userFile.exists()); - - Properties p = loadPropertyFile(userFile); - - Assert.assertEquals(3, p.size()); - - String property; - - property = p.getProperty("key1"); - Assert.assertEquals("toto", property); - - property = p.getProperty("key2"); - Assert.assertEquals("tata", property); - - property = p.getProperty("key3"); - Assert.assertEquals("tutu", property); - - } finally { - - if (oldHome != null) { - System.setProperty("user.home", oldHome); - } - } - - } - - @Test - public void cleanUserConfig() throws IOException, ArgumentsParserException { - - // Initiliaze path and filename - String path = testDirectory.getAbsolutePath(); - - try { - System.setProperty("user.home", path); - - ApplicationConfig config = - new ApplicationConfig(testName.getMethodName()); - - - config.setOption("key1", "toto"); - config.setOption("key2", ""); - config.setOption("key3", "tutu"); - - File userFile = config.getUserConfigFile(); - - Assert.assertTrue(userFile.getAbsolutePath().startsWith(path)); - - userFile.delete(); - - config.saveForUser(); - - Assert.assertTrue(userFile.exists()); - - Properties p = loadPropertyFile(userFile); - - Assert.assertEquals(3, p.size()); - - String property; - - property = p.getProperty("key1"); - Assert.assertEquals("toto", property); - - property = p.getProperty("key2"); - Assert.assertEquals("", property); - - property = p.getProperty("key3"); - Assert.assertEquals("tutu", property); - - // reload config - config = new ApplicationConfig(testName.getMethodName()); - config.parse(); - - config.cleanUserConfig(); - - Properties p2 = loadPropertyFile(userFile); - - // key2 was removed - Assert.assertEquals(2, p2.size()); - - property = p2.getProperty("key1"); - Assert.assertEquals("toto", property); - - property = p2.getProperty("key2"); - Assert.assertNull(property); - - property = p2.getProperty("key3"); - Assert.assertEquals("tutu", property); - - // now key3 will be removed (even if not blank) - config.cleanUserConfig("key3"); - - // reload config - config = new ApplicationConfig(testName.getMethodName()); - config.parse(); - - Properties p3 = loadPropertyFile(userFile); - - // key3 was removed - Assert.assertEquals(1, p3.size()); - - property = p3.getProperty("key1"); - Assert.assertEquals("toto", property); - - - } finally { - - if (oldHome != null) { - System.setProperty("user.home", oldHome); - } - } - - } - - protected Properties loadPropertyFile(File file) throws IOException { - FileInputStream inStream; - - inStream = FileUtils.openInputStream(file); - try { - Properties p = new Properties(); - p.load(inStream); - inStream.close(); - return p; - } finally { - IOUtils.closeQuietly(inStream); - } - } - - /** - * Test of getUnparsed method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testGetUnparsed() throws Exception { - ApplicationConfig instance = new ApplicationConfig(); - List<String> expResult = new ArrayList<String>(); - List<String> result = instance.getUnparsed(); - Assert.assertEquals(expResult, result); - - expResult.add("toto"); - expResult.add("titi"); - expResult.add("tata"); - - instance.parse("toto", "titi", "tata"); - result = instance.getUnparsed(); - Assert.assertEquals(expResult, result); - } - - /** - * Test of addAction method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testAddAction() throws Exception { - Action action = null; - ApplicationConfig instance = new ApplicationConfig(); - - // test add null Action - instance.addAction(action); - - action = new Action(1, new DummyAction(), DummyAction.class.getMethod("dummyAction", String.class, Integer.TYPE), "coucou", "12"); - instance.addAction(action); - } - - /** - * Test of doAction method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testDoAction() throws Exception { - ApplicationConfig instance = new ApplicationConfig(); - - Action action = new Action(1, new DummyAction(), DummyAction.class.getMethod("dummyAction", String.class, Integer.TYPE), "coucou", "12"); - instance.addAction(action); - - DUMMY_ACTION_CALL = 0; - Assert.assertEquals(0, DUMMY_ACTION_CALL); - instance.doAction(0); - Assert.assertEquals(0, DUMMY_ACTION_CALL); - instance.doAction(1); - Assert.assertEquals(1, DUMMY_ACTION_CALL); - instance.doAction(2); - Assert.assertEquals(1, DUMMY_ACTION_CALL); - } - - /** Test of setUseOnlyAliases method, of class ApplicationConfig. */ - @Test - public void testSetUseOnlyAliases() { - ApplicationConfig instance = new ApplicationConfig(); - Assert.assertEquals(false, instance.isUseOnlyAliases()); - instance.setUseOnlyAliases(false); - Assert.assertEquals(false, instance.isUseOnlyAliases()); - instance.setUseOnlyAliases(true); - Assert.assertEquals(true, instance.isUseOnlyAliases()); - } - - /** - * Test of addAlias method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testAddAlias() throws Exception { - ApplicationConfig instance = new ApplicationConfig(); - instance.addAlias("toto", "totochange"); - instance.addAlias("titi", "titichange"); - - List<String> expResult = new ArrayList<String>(); - List<String> result = instance.getUnparsed(); - Assert.assertEquals(expResult, result); - - expResult.add("totochange"); - expResult.add("titichange"); - expResult.add("tata"); - - instance.parse("toto", "titi", "tata"); - result = instance.getUnparsed(); - Assert.assertEquals(expResult, result); - } - - /** Test of setConfigFileName method, of class ApplicationConfig. */ - @Test - public void testSetConfigFileName() { - ApplicationConfig instance = new ApplicationConfig(); - instance.setConfigFileName("bidulle"); - Assert.assertEquals("bidulle", instance.getConfigFileName()); - } - - /** Test of setOption method, of class ApplicationConfig. */ - @Test - public void testSetOption() { - ApplicationConfig instance = new ApplicationConfig(); - Assert.assertEquals(null, instance.getOption("truc")); - instance.setOption("truc", "bidulle"); - Assert.assertEquals("bidulle", instance.getOption("truc")); - } - - @Test - public void testSubConfig() { - ApplicationConfig instance = new ApplicationConfig(); - Assert.assertEquals(null, instance.getOption("truc")); - instance.setOption("truc", "bidulle"); - instance.setOption("machin", "chouette"); - instance.setOption("toto.truc", "AutreBidulle"); - instance.setOption("toto.specific", "theOne"); - Assert.assertEquals("bidulle", instance.getOption("truc")); - - ApplicationConfig sub = instance.getSubConfig("toto."); - // test la surcharge du default - Assert.assertEquals("AutreBidulle", sub.getOption("truc")); - // test l'utilisation du default - Assert.assertEquals("chouette", sub.getOption("machin")); - // test une valeur specifique au sub - Assert.assertEquals("theOne", sub.getOption("specific")); - - // TODO ajouter d'autres tests, pour les autres methodes surchargee - // TODO ajouter d'autres tests pour des sub-(sub-(sub)) config - } - - /** Test convertion to list */ - @Test - public void testGetAsList() { - List<String> asString = new ArrayList<String>(); - asString.add(ApplicationConfig.class.getName()); - asString.add(ApplicationConfigTest.class.getName()); - - List<Class> asClass = new ArrayList<Class>(); - asClass.add(ApplicationConfig.class); - asClass.add(ApplicationConfigTest.class); - - ApplicationConfig instance = new ApplicationConfig(); - Assert.assertEquals(null, instance.getOption("truc")); - Assert.assertEquals(Collections.EMPTY_LIST, instance.getOptionAsList("truc").getOption()); - - instance.setOption("truc", ApplicationConfig.class.getName() - + "," + ApplicationConfigTest.class.getName()); - - Assert.assertEquals(asString, instance.getOptionAsList("truc").getOption()); - Assert.assertEquals(asClass, instance.getOptionAsList("truc").getOptionAsClass()); - } - - /** Test of getMethods method, of class ApplicationConfig. */ - @Test - public void testGetMethods() { - ApplicationConfig instance = new ApplicationConfig(); - Map<String, Method> result = instance.getMethods(); - Assert.assertTrue(result.containsKey("option")); - } - - /** - * Test of getParams method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testGetParams() throws Exception { - Method m = DummyAction.class.getMethod("dummyAction", String.class, Integer.TYPE); - List<String> list = new ArrayList<String>(Arrays.asList("toto", "10", "/tmp", "9")); - ListIterator<String> args = list.listIterator(); - - ApplicationConfig instance = new ApplicationConfig(); - String[] expResult = new String[]{"toto", "10"}; - String[] result = instance.getParams(m, args); - Assert.assertEquals(Arrays.asList(expResult), Arrays.asList(result)); - Assert.assertEquals(2, list.size()); - } - - /** - * Test of createAction method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testCreateAction() throws Exception { - List<String> list = new ArrayList<String>(Arrays.asList("dummy", "toto", "10", "/tmp", "9")); - ListIterator<String> args = list.listIterator(); - args.next(); - ApplicationConfig instance = new ApplicationConfig(); - - Action result = instance.createAction( - DummyAction.class.getName() + "#dummyAction", args); - Assert.assertEquals(1, result.step); - DUMMY_ACTION_CALL = 0; - result.doAction(); - Assert.assertEquals(1, DUMMY_ACTION_CALL); - } - - /** - * Test of parse method, of class ApplicationConfig. - * - * @throws Exception - */ - @Test - public void testParse() throws Exception { - String[] args = "-f file -v -d -o /tmp/file -m coucou 10 others args".split(" "); - ApplicationConfig instance = new ApplicationConfig(); - instance.addAlias("-f", "--option", "file"); - instance.addAlias("-v", "--option", "verbose", "true"); - instance.addAlias("-d", "--option", "debug", "true"); - instance.addAlias("-o", "--option", "output"); - instance.addAlias("-m", "--" + DummyAction.class.getName() + "#dummyAction"); - instance.parse(args); - - DUMMY_ACTION_CALL = 0; - Assert.assertEquals("file", instance.getOption("file")); - Assert.assertEquals("true", instance.getOption("verbose")); - Assert.assertEquals("true", instance.getOption("debug")); - Assert.assertEquals("/tmp/file", instance.getOption("output")); - Assert.assertEquals(Arrays.asList("others", "args"), instance.getUnparsed()); - - instance.doAction(1); - Assert.assertEquals(1, DUMMY_ACTION_CALL); - } - - /** - * Test that system properties such as ${user.home}, ${user.name} are - * replaced. - * - * @throws ArgumentsParserException - */ - @Test - public void testSystemProperties() throws ArgumentsParserException { - ApplicationConfig instance = new ApplicationConfig(); - instance.parse(); - instance.printConfig(); - - instance.setOption("hellomessage", "Hello ${user.name} !"); - - Assert.assertEquals("Hello " + System.getProperty("user.name") + " !", instance.getOption("hellomessage")); - Assert.assertEquals("Hello ${user.name} !", instance.options.getProperty("hellomessage")); - - instance.setOption("tempdir", "${java.io.tmpdir}" + File.separator + "blah"); - File tempDir = instance.getOptionAsFile("tempdir"); - Assert.assertEquals(new File(System.getProperty("java.io.tmpdir"), "blah").getAbsolutePath(), tempDir.getAbsolutePath()); - - instance.setOption("system", "${os.name}"); - instance.setOption("os", "${system}"); - instance.setOption("sysinfo", "I'm running ${os} :)"); - Assert.assertEquals("I'm running " + System.getProperty("os.name") + " :)", instance.getOption("sysinfo")); - - // test not found properties - instance.setOption("notexists", "Attention ${blah.bloh.bluh} :("); - Assert.assertEquals("Attention ${blah.bloh.bluh} :(", instance.getOption("notexists")); - } - - /** - * test if dot is replaced with _ if properties is not found with dot in env - * - * @throws ArgumentsParserException - */ - @Test - public void testEnvProperties() throws ArgumentsParserException { - ApplicationConfig instance = new ApplicationConfig(); - // simulate env variable with _ to replace dot - instance.env.put("test_env", "value"); - - String value = instance.getOption("test.env"); - Assert.assertEquals("value", value); - } - - /** - * Test unparsed options - * - * @throws Exception - */ - @Test - public void testUnparsed() throws Exception { - - String[] args = "test --du i_am_a_test 2 --option file f1 --option verbose false -- --openui false --m coucou 10 others args".split(" "); - ApplicationConfig instance = new ApplicationConfig(); - instance.addActionAlias("--du", DummyAction.class.getName() + "#" + "dummyAction"); - instance.parse(args); - instance.doAction(1); - - log.info(instance.getUnparsed()); - Assert.assertEquals(8, instance.getUnparsed().size()); - Assert.assertEquals("test", instance.getUnparsed().get(0)); - } - - /** - * Test get flat options method. - * - * @throws Exception - */ - @Test - public void testGetFlatOptions() throws Exception { - - ApplicationConfig instance = new ApplicationConfig(); - instance.parse(); - instance.setDefaultOption("user.firstname", "toto"); - instance.setDefaultOption("user.lastname", "tutu"); - instance.setOption("user.fullname", "${user.lastname} ${user.firstname}"); - - Assert.assertEquals(1, instance.getOptions().size()); - // il y en a plus de 3 car il y a aussi les variables d'environnement - Assert.assertTrue(instance.getFlatOptions().size() > 3); - - // test replacement and non replacement - Assert.assertEquals("tutu toto", - instance.getFlatOptions().getProperty("user.fullname")); - Assert.assertEquals("tutu toto", - instance.getFlatOptions(true).getProperty("user.fullname")); - Assert.assertEquals("${user.lastname} ${user.firstname}", - instance.getFlatOptions(false).getProperty("user.fullname")); - } - - /** - * Test null options. - * <p/> - * TODO EC20100503 this test throw a huge exception - * - * @throws Exception - */ - @Test - public void testGetNullOptions() throws Exception { - ApplicationConfig instance = new ApplicationConfig(); - instance.parse(); - - // primitives can not be null - Assert.assertNotNull(instance.getOptionAsBoolean("dfsdfgqsgqfg")); - Assert.assertNotNull(instance.getOptionAsDouble("dfsdfgqsgqfg")); - Assert.assertNotNull(instance.getOptionAsInt("dfsdfgqsgqfg")); - Assert.assertNotNull(instance.getOptionAsLong("dfsdfgqsgqfg")); - // list option can not be null - Assert.assertNotNull(instance.getOptionAsList("dfsdfgqsgqfg")); - - // all other types can be null - Assert.assertNull(instance.getOptionAsClass("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsDate("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsFile("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsLocale("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsTime("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsTimestamp("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsURL("dfsdfgqsgqfg")); - Assert.assertNull(instance.getOptionAsVersion("dfsdfgqsgqfg")); - } - - /** - * Test on printConfig output. - * - * @throws ArgumentsParserException - * @throws UnsupportedEncodingException - */ - public void testxx() throws ArgumentsParserException, UnsupportedEncodingException { - ApplicationConfig instance = new ApplicationConfig(); - instance.parse(); - instance.setOption("toto", "tata"); - - // get content of printConfig - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - PrintStream ps = new PrintStream(baos); - try { - instance.printConfig(ps); - } finally { - ps.close(); - } - String content = baos.toString("UTF-8"); - - if (log.isDebugEnabled()) { - log.debug("printConfig = " + content); - } - - Assert.assertTrue(content.indexOf("toto=tata") > 0); - } - - @Test - public void testGetOptionAsLocale() { - Locale expected; - Locale actual; - - ApplicationConfig instance = new ApplicationConfig(); - - // test null locale - actual = instance.getOptionAsLocale("toto"); - Assert.assertNull(actual); - - // test not null locale - instance.setOption("toto", "fr"); - - expected = Locale.FRENCH; - actual = instance.getOptionAsLocale("toto"); - Assert.assertNotNull(actual); - Assert.assertEquals(expected, actual); - - } - - @Test - public void testGetOptionAsVersion() { - Version expected; - Version actual; - - ApplicationConfig instance = new ApplicationConfig(); - - // test null version - actual = instance.getOptionAsVersion("toto"); - Assert.assertNull(actual); - - // not null version - instance.setOption("toto", "1.2"); - expected = VersionUtil.valueOf("1.2"); - actual = instance.getOptionAsVersion("toto"); - Assert.assertNotNull(actual); - Assert.assertEquals(expected, actual); - - } - - @Test - public void testGetOptionAsLong() { - ApplicationConfig instance = new ApplicationConfig(); - - // test long is not null - long actual = instance.getOptionAsLong("toto"); - Assert.assertNotNull(actual); - Assert.assertEquals(0l, actual); - - // not null version - long expected = System.currentTimeMillis(); - instance.setOption("toto", "" + expected); - actual = instance.getOptionAsLong("toto"); - Assert.assertEquals(expected, actual); - - } - - @Test - public void testGetOsName() throws Exception { - ApplicationConfig config = new ApplicationConfig(); - config.parse(); - String v = config.getOsName(); - Assert.assertTrue(StringUtils.isNotBlank(v)); - System.out.println("os.name: " + v); - } - - @Test - public void testGetOsArch() throws Exception { - ApplicationConfig config = new ApplicationConfig(); - config.parse(); - String v = config.getOsArch(); - Assert.assertTrue(StringUtils.isNotBlank(v)); - System.out.println("os.arch: " + v); - } - -} Deleted: trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/ApplicationUpdaterTest.java 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,106 +0,0 @@ -package org.nuiton.util; - -/* - * #%L - * Nuiton Utils :: Nuiton Utils - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2013 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - - -import java.io.File; -import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Assert; -import org.junit.Test; -import org.nuiton.util.ApplicationUpdater.ApplicationInfo; - -/** - * - * @author poussin - * @version $Revision$ - * @since 2.6.6 - * - * @deprecated since 2.7 (replaced by org.nuiton.util.updater.ApplicationUpdater - * in nuiton-updater module), will be removed in version 2.7.1. - */ -public class ApplicationUpdaterTest { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(ApplicationUpdaterTest.class); - - static private class Callback implements ApplicationUpdater.ApplicationUpdaterCallback { - - public Map<String, ApplicationInfo> updateToDo(Map<String, ApplicationInfo> appToUpdate) { - log.info("Application to update\n" + appToUpdate); - for (ApplicationInfo info : appToUpdate.values()) { - info.login="ApplicationUpdate"; - info.password=new char[]{'p','a','s','s','w','o','r','d'}; - } - return appToUpdate; - } - - @Override - public void startUpdate(ApplicationInfo info) { - log.info("Start to update: " + info); - } - - public void updateDone(Map<String, ApplicationInfo> appToUpdate, Map<String, Exception> appUpdateError) { - for (Map.Entry<String, Exception> e : appUpdateError.entrySet()) { - log.info(String.format("Error during update for application '%s'", e.getKey()), e.getValue()); - } - Assert.assertTrue("Error: " + appUpdateError, appUpdateError.isEmpty()); - } - - public void aborted(String propertiesURL, Exception eee) { - log.info(String.format("Update aborted for url '%s'", propertiesURL), eee); - Assert.assertTrue(false); - } - - } - - @Test - public void testUpdate() throws Exception { - ApplicationUpdater up = new ApplicationUpdater(); - String url = "file:src/test/resources/properties/ApplicationUpdaterTest.properties"; - File current = new File("src/test/resources/ApplicationUpdater"); - File dest = new File("target/test/ApplicationUpdater/NEW"); - up.update(url, current, dest, false, new Callback()); - } - - @Test - public void testUpdateNetwork() throws Exception { - ApplicationUpdater up = new ApplicationUpdater(); - String url = "http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources..."; - File current = new File("src/test/resources/ApplicationUpdater"); - File dest = new File("target/test/ApplicationUpdater/NEWNETWORK"); - up.update(url, current, dest, false, new Callback()); - } - - @Test - public void testUpdateNetworkAuth() throws Exception { - ApplicationUpdater up = new ApplicationUpdater(); - String url = "http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources..."; - File current = new File("src/test/resources/ApplicationUpdater"); - File dest = new File("target/test/ApplicationUpdater/NEWNETWORKAUTH"); - up.update(url, current, dest, false, new Callback()); - } -} Deleted: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkAuthTest.properties =================================================================== --- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkAuthTest.properties 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkAuthTest.properties 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,32 +0,0 @@ -### -# #%L -# Nuiton Utils :: Nuiton Utils -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2004 - 2013 CodeLutin -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. -# -# You should have received a copy of the GNU General Lesser Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/lgpl-3.0.html>. -# #L% -### -App1.version=0.3 -App1.url=zip:http://test.ApplicationUpdate.nuiton.org/App1-0.3.zip -App1.auth=true -linux.App3.version=8 -linux.App3.url=zip:http://test.ApplicationUpdate.nuiton.org/App3-7.zip -linux.App3.auth=true -linux.amd64.App2.version=7 -linux.amd64.App2.url=zip:http://test.ApplicationUpdate.nuiton.org/App2-7.zip -linux.amd64.App2.auth=true Deleted: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties =================================================================== --- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterNetworkTest.properties 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,29 +0,0 @@ -### -# #%L -# Nuiton Utils :: Nuiton Utils -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2004 - 2013 CodeLutin -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. -# -# You should have received a copy of the GNU General Lesser Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/lgpl-3.0.html>. -# #L% -### -App1.version=0.3 -App1.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources... -linux.App3.version=8 -linux.App3.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources... -linux.amd64.App2.version=7 -linux.amd64.App2.url=zip:http://svn.nuiton.org/svn/nuiton-utils/trunk/nuiton-utils/src/test/resources... Deleted: trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties =================================================================== --- trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-07-19 15:23:57 UTC (rev 2583) +++ trunk/nuiton-utils/src/test/resources/properties/ApplicationUpdaterTest.properties 2013-07-19 17:37:58 UTC (rev 2584) @@ -1,29 +0,0 @@ -### -# #%L -# Nuiton Utils :: Nuiton Utils -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2004 - 2013 CodeLutin -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. -# -# You should have received a copy of the GNU General Lesser Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/lgpl-3.0.html>. -# #L% -### -App1.version=0.3 -App1.url=zip:file:src/test/resources/ApplicationUpdater/zip/App1-0.3.zip -linux.App3.version=8 -linux.App3.url=zip:file:src/test/resources/ApplicationUpdater/zip/App3-7.zip -linux.amd64.App2.version=7 -linux.amd64.App2.url=zip:file:src/test/resources/ApplicationUpdater/zip/App2-7.zip
participants (1)
-
tchemit@users.nuiton.org