Author: echatellier Date: 2010-03-29 14:59:53 +0200 (Mon, 29 Mar 2010) New Revision: 1807 Log: Fix: #161 (config directory system and user for windows and unix) #415 (permet de specifier le dossier ou chercher la configuration syst?\195?\168me) Modified: trunk/src/main/java/org/nuiton/util/ApplicationConfig.java trunk/src/main/resources/i18n/nuiton-utils-en_GB.properties trunk/src/main/resources/i18n/nuiton-utils-fr_FR.properties Modified: trunk/src/main/java/org/nuiton/util/ApplicationConfig.java =================================================================== --- trunk/src/main/java/org/nuiton/util/ApplicationConfig.java 2010-03-27 20:05:28 UTC (rev 1806) +++ trunk/src/main/java/org/nuiton/util/ApplicationConfig.java 2010-03-29 12:59:53 UTC (rev 1807) @@ -36,6 +36,8 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; @@ -259,22 +261,36 @@ /** Used to know what is separator between class and method on command line. */ static final private String CLASS_METHOD_SEPARATOR = "#"; - + /** Configuration file key option. */ static final public String CONFIG_FILE_NAME = "config.file"; - + + /** + * Configuration directory where config path in located. + * + * 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> + */ + static final public String CONFIG_PATH = "config.path"; + + /** System os name. (windows, linux, max os x) */ + protected String osName; + protected boolean useOnlyAliases = false; - - protected Map<String, List<String>> aliases = new HashMap<String, List<String>>(); - - /** file /etc/[filename] */ - String systemPath = File.separator + "etc" + File.separator; - /** file $user.home/.[filename] */ - //@Deprecated - String userPath = getUserHome() + File.separator + "."; - /** file $user.home/.local/[filename] */ - //String userPath2 = getUserHome() + File.separator + ".config" + File.separator; + /** + * file $user.home/.[filename] + * + * 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 = false; @@ -287,10 +303,14 @@ protected Properties jvm = new Properties(env); protected Properties line = new Properties(jvm); protected Properties options = new Properties(line); + protected Map<String, CacheItem<?>> cacheOption = new HashMap<String, CacheItem<?>>(); 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>(); + + protected Map<String, List<String>> aliases = new HashMap<String, List<String>>(); protected Map<Integer, List<Action>> actions = new HashMap<Integer, List<Action>>(); /** suport of config modification. */ @@ -389,8 +409,17 @@ */ public ApplicationConfig() { setConfigFileName(this.getClass().getSimpleName()); + // init extra-converters ConverterUtil.initConverters(); + + // get system os name + osName = AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override + public String run() { + return System.getProperty("os.name"); + } + }); } /** @@ -473,7 +502,7 @@ * @param excludeKeys optional list of keys to exclude from */ public void saveForSystem(String... excludeKeys) { - File file = new File(systemPath + getConfigFileName()); + File file = new File(getConfigPath() + getConfigFileName()); try { save(file, false, excludeKeys); } catch (IOException eee) { @@ -490,7 +519,7 @@ * @param excludeKeys optional list of keys to exclude from */ public void saveForUser(String... excludeKeys) { - File file = new File(userPath + getConfigFileName()); + File file = new File(getUserPath() + getConfigFileName()); try { save(file, false, excludeKeys); } catch (IOException eee) { @@ -597,6 +626,139 @@ } /** + * Get configuration file path to use. + * + * Use (in order) one of the following definition: + * <ul> + * <li>{@link #CONFIG_PATH} option + * <li>system dependant path + * </ul> + * + * @since 1.2.1 + * @return path to use with endind {@link File#separator} + */ + public String getConfigPath() { + String result = getOption(CONFIG_PATH); + + if (result == null) { + result = getSystemConfigurationPath(); + } + + return result; + } + + /** + * Get system configuration path. + * + * Currently supported: + * <ul> + * <li>Windows : C:\Windows\System32 + * <li>Unix : /etc/ + * </ul> + * + * @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; + } + + return systemPath; + } + + /** + * Get user configuration path. + * + * Currently supported: + * <ul> + * <li>Windows : ${user.home}\\Application Data\\ + * <li>Max os x : ${user.home}/Library/Application Support + * <li>Unix : ${user.home}/.config + * </ul> + * + * Unix norm is based on freedesktop concept explained here : + * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + * + * @since 1.2.1 + */ + protected String getUserPath() { + + String userPath = null; + + String userHome = null; + try { + userHome = System.getProperty("user.home"); + } 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; + } + + /** * Set option value. * * @param key property key @@ -624,7 +786,7 @@ value = replaceRecursiveOptions(value); return value; } - + /** * Replace included ${xxx} suboptions by their values. * @@ -636,9 +798,9 @@ // TODO do a common code with RecursiveProperties code // TODO but can't overwrite getProperty() method - + String result = option; - + if (result == null) { return null; } @@ -1004,8 +1166,8 @@ } } + // first parse option inParseOptionPhase = true; - // first parse option for (ListIterator<String> i = arguments.listIterator(); i.hasNext();) { String arg = i.next(); if (arg.equals("--")) { @@ -1018,7 +1180,9 @@ i.remove(); // remove this arg because is used now Method m = methods.get(optionName); String[] params = getParams(m, i); - log.debug(String.format("Set option '%s' with method '%s %s'", optionName, m, Arrays.toString(params))); + if (log.isDebugEnabled()) { + log.debug(String.format("Set option '%s' with method '%s %s'", optionName, m, Arrays.toString(params))); + } ObjectUtil.call(this, m, params); } } @@ -1051,7 +1215,8 @@ } } - File etcConfig = new File(systemPath + filename); + // system directory + File etcConfig = new File(getConfigPath(), filename); if (etcConfig.exists()) { if (log.isInfoEnabled()) { log.info("Chargement du fichier de config: " + etcConfig); @@ -1064,7 +1229,20 @@ } } - File homeConfig = new File(userPath + filename); + // user home directory + File homeConfig = new File(getUserPath(), filename); + File oldHomeConfig = new File(userPath + filename); // don't use new File(String, String) + + // migration, if homeConfig doesn't exists and oldHomeConfig does + if (!homeConfig.exists() && oldHomeConfig.exists()) { + if (log.isInfoEnabled()) { + log.info(_("Moving old configuration file from %s to %s", oldHomeConfig.getPath(), homeConfig.getPath())); + } + + oldHomeConfig.renameTo(homeConfig); + } + // end of migration + if (homeConfig.exists()) { if (log.isInfoEnabled()) { log.info("Chargement du fichier de config: " + homeConfig); @@ -1076,15 +1254,6 @@ log.debug("No configuration file found in user home : " + homeConfig.getAbsolutePath()); } } -// File homeConfig2 = new File(userPath2 + filename); -// if (!homeConfig2.exists() && homeConfig1.exists()) { -// log.info("Déplacement de l'ancien fichier de config: " + homeConfig1); -// homeConfig1.renameTo(homeConfig2); -// } -// if (homeConfig2.exists()) { -// log.info("Chargement du fichier de config: " + homeConfig2); -// homefile.load(homeConfig2.toURI().toURL().openStream()); -// } // file $CURDIR/filename File config = new File(filename); Modified: trunk/src/main/resources/i18n/nuiton-utils-en_GB.properties =================================================================== --- trunk/src/main/resources/i18n/nuiton-utils-en_GB.properties 2010-03-27 20:05:28 UTC (rev 1806) +++ trunk/src/main/resources/i18n/nuiton-utils-en_GB.properties 2010-03-29 12:59:53 UTC (rev 1807) @@ -1,3 +1,4 @@ +Moving\ old\ configuration\ file\ from\ %s\ to\ %s= hello\ you\ \!=hello you \! nuitonutil.debug.objectutil.create=Try to create %s with %s nuitonutil.debug.objectutil.instantiate=Can't instantiate %s with params %s Modified: trunk/src/main/resources/i18n/nuiton-utils-fr_FR.properties =================================================================== --- trunk/src/main/resources/i18n/nuiton-utils-fr_FR.properties 2010-03-27 20:05:28 UTC (rev 1806) +++ trunk/src/main/resources/i18n/nuiton-utils-fr_FR.properties 2010-03-29 12:59:53 UTC (rev 1807) @@ -1,3 +1,4 @@ +Moving\ old\ configuration\ file\ from\ %s\ to\ %s= hello\ you\ \!=Salut toi\! nuitonutil.debug.objectutil.create=Essaye de cr\u00E9er %s avec %s nuitonutil.debug.objectutil.instantiate=Ne peut pas instancier %s avec les param\u00EAtres %s
participants (1)
-
echatellier@users.nuiton.org