📄 rtproperties.java
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2008, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// Runtime properties container// ----------------------------------------------------------------------------// Change History:// 2006/03/26 Martin D. Flynn// -Initial release// 2006/04/02 Martin D. Flynn// -Added ability to separate command-line key/value pairs with a ':'.// 2006/04/23 Martin D. Flynn// -Integrated logging changes made to Print// 2006/06/30 Martin D. Flynn// -Repackaged// 2007/07/27 Martin D. Flynn// -Added support for primitive array types// 2007/08/09 Martin D. Flynn// -Added support for URL and InputStream initializers.// 2007/09/16 Martin D. Flynn// -Added method 'insertKeyValues'// -Added support for key/value replace in config-file value strings// 2008/05/14 Martin D. Flynn// -Added 'setProperties(String props, char propSep)' method.// -Added 'PropertyChangeListener' support// ----------------------------------------------------------------------------package org.opengts.util;import java.io.*;import java.util.*;import java.net.URL;import java.lang.reflect.*;public class RTProperties implements Cloneable{ // ------------------------------------------------------------------------ private static final boolean USE_PROPERTIES_LOADER = true; // ------------------------------------------------------------------------ public static final String KEY_NAME = "$name"; public static final char NameSeparatorChar = ':'; public static final char KeyValSeparatorChar = StringTools.KeyValSeparatorChar; public static final char PropertySeparatorChar = StringTools.PropertySeparatorChar; public static final char ARRAY_DELIM = StringTools.ARRAY_DELIM; // ------------------------------------------------------------------------ public static final String KEY_START_DELIMITER = "${"; public static final String KEY_END_DELIMITER = "}"; public static final int KEY_MAX_RECURSION = 5; public static final int KEY_REPLACEMENT_NONE = 0; public static final int KEY_REPLACEMENT_LOCAL = 1; public static final int KEY_REPLACEMENT_GLOBAL = 2; // ------------------------------------------------------------------------ // This constant controls whether boolean properties with unspecified values // will return true, or false. Example: // "" - getBoolean("bool", dft) returns dft. // "bool=true" - getBoolean("bool", dft) returns 'true'. // "bool=false" - getBoolean("bool", dft) returns 'false'. // "bool=badvalue" - getBoolean("bool", dft) returns dft. // "bool" - getBoolean("bool", dft) returns DEFAULT_TRUE_IF_BOOLEAN_STRING_EMPTY. private static final boolean DEFAULT_TRUE_IF_BOOLEAN_STRING_EMPTY = true; // ------------------------------------------------------------------------ private Map<Object,Object> cfgProperties = null; private boolean ignoreCase = false; private boolean chkEnvProperties = false; private char propertySeparator = PropertySeparatorChar; private int keyReplacementMode = KEY_REPLACEMENT_NONE; // ------------------------------------------------------------------------ /** *** Returns the index of the key/value separator (either '=' or ':'). *** @param kv The String parsed for the key/value separator *** @return The index of the key/value separator **/ private static int _indexOfKeyValSeparator(String kv) { //return kv.indexOf('='); for (int i = 0; i < kv.length(); i++) { char ch = kv.charAt(i); if ((ch == '=') || (ch == ':')) { return i; } } return -1; } // ------------------------------------------------------------------------ /** *** Constructor *** @param map The Object key/value map used to initialize this instance **/ public RTProperties(Map<Object,Object> map) { this.cfgProperties = map; } /** *** Constructor **/ public RTProperties() { this((Map<Object,Object>)null); } /** *** Constructor *** @param props A String containing "key=value key=value ..." specifications used to *** initialize this instance. **/ public RTProperties(String props) { this(); this.setProperties(props, true); } /** *** Constructor *** @param props A String containing "key=value key=value ..." specifications used to *** initialize this instance. *** @param inclName True to parse and set the name of this instance. **/ public RTProperties(String props, boolean inclName) { this(); this.setProperties(props, inclName); } /** *** Constructor *** @param props A String containing "key=value key=value ..." specifications used to *** initialize this instance. *** @param propSep The separator character between one "key=value" pair and the next. *** (ie. in "key=value;key=value", ';' is the property separator) **/ public RTProperties(String props, char propSep) { this(); this.setPropertySeparatorChar(propSep); this.setProperties(props, true); } /** *** Constructor *** @param argv An array of "key=value" specifications. **/ public RTProperties(String argv[]) { this(); if (argv != null) { for (int i = 0; i < argv.length; i++) { int p = _indexOfKeyValSeparator(argv[i]); // argv[i].indexOf("="); String key = (p >= 0)? argv[i].substring(0, p) : argv[i]; String val = (p >= 0)? argv[i].substring(p + 1) : ""; // remove prefixing "-" from key while (key.startsWith("-")) { key = key.substring(1); } // store key/value if (!key.equals("")) { this.setString(key, val); } } } } /** *** Constructor *** @param cfgFile A file specification from which the key=value properties are loaded. **/ public RTProperties(File cfgFile) { this(CreateDefaultMap()); if ((cfgFile == null) || cfgFile.equals("")) { // ignore this case } else if (cfgFile.isFile()) { if (!RTConfig.getBoolean(RTKey.RT_QUIET,true)) { Print.logInfo("Loading config file: " + cfgFile); } try { this.setProperties(cfgFile, true); } catch (IOException ioe) { Print.logError("Unable to load config file: " + cfgFile + " [" + ioe + "]"); } } else { Print.logError("Config file doesn't exist: " + cfgFile); } } /** *** Constructor *** @param cfgURL A URL specification from which the key=value properties are loaded. **/ public RTProperties(URL cfgURL) { this(CreateDefaultMap()); if (cfgURL == null) { // ignore this case } else { if (!RTConfig.getBoolean(RTKey.RT_QUIET,true)) { Print.logInfo("Loading config file: " + cfgURL); } try { this.setProperties(cfgURL, true); } catch (IOException ioe) { Print.logError("Unable to load config file: " + cfgURL + " [" + ioe + "]"); } } } /** *** Copy Constructor *** @param rtp A RTProperties instance from this this instance is initialized **/ public RTProperties(RTProperties rtp) { this(); this.setProperties(rtp, true); } // ------------------------------------------------------------------------ /** *** Returns a clone of this RTProperties instance *** @return A clone of this RTProperties instance **/ public Object clone() { return new RTProperties(this); } // ------------------------------------------------------------------------ /** *** Returns true if the key case on lookups is to be ignored *** @return True if the key case on lookups is to be ignored **/ public boolean getIgnoreKeyCase() { return this.ignoreCase; } /** *** Sets whether key-case is to be ignored on propery lookups. Only valid if the backing Map *** is an <code>OrderedMap</code>. *** @param ignCase True ignore key-case on lookups, false otherwise **/ public void setIgnoreKeyCase(boolean ignCase) { this.ignoreCase = ignCase; Map props = this.getProperties(); if (props instanceof OrderedMap) { ((OrderedMap)props).setIgnoreCase(this.ignoreCase); } else { Print.logWarn("Backing map is not an 'OrderedMap', case insensitive keys not in effect"); } } // ------------------------------------------------------------------------ /** *** Gets the Environment properties check state *** @return True if Environment properties are to be checked when looking up a property. **/ public boolean getCheckEnvProperties() { return this.chkEnvProperties; } /** *** Sets the Environment property check lookup state. *** @param chkEnv True to use the environment variable properties as a backstop when *** obtaining default property values. **/ public void setCheckEnvProperties(boolean chkEnv) { // The purpose of this is to set the environment variable properties as the // backstop when obtaining default property values. Currently this is only // used by RTKey when setting the properties for defaults. In the JDK 1.5 // the System environment is available as a Map, which will make this a bit // easier when this code is eventually converted to JDK 1.5. this.chkEnvProperties = chkEnv; } /** *** Returns true if the specified key exists in the environment properties *** @return True if the specified key exists in the environment properties **/ protected boolean _hasEnvironmentProperty(String key) { try { return this.getCheckEnvProperties() && (key != null) && (System.getenv(key) != null); } catch (Throwable th) { // 'getenv' may not be supported return false; } } /** *** Gets the environment property value for the specified key *** @param key The Environment property key to look up. *** @return The value of the specified environment property key, or null if the key does not exist. **/ protected String _getEnvironmentProperty(String key) { try { return (this.getCheckEnvProperties() && (key != null))? System.getenv(key) : null; } catch (Throwable th) { // 'getenv' may not be supported (ie. not support in 1.4.x) return null; } } // ------------------------------------------------------------------------ /** *** Gets the name of this instance. *** @return The name of this instance **/ public String getName() { return this.getString(KEY_NAME, ""); } /** *** Sets the name of this instance *** @param name The name of this instance to set **/ public void setName(String name) { this.setString(KEY_NAME, name); } // ------------------------------------------------------------------------ /** *** List all defined property keys which do not have a registered default value.<br> *** Used for diagnostice purposes. **/ public void checkDefaults() { // This produces a list of keys in the properties list for which RTKey has not // default value. This is typically for listing unregistered, and possibly // obsolete, properties found in a config file. for (Iterator<?> i = this.keyIterator(); i.hasNext();) { String key = i.next().toString(); if (!RTKey.hasDefault(key)) { Print.logDebug("No default for key: " + key); } } } // ------------------------------------------------------------------------ protected static Class<OrderedMap> DefaultMapClass = OrderedMap.class; /** *** Creates a default Map object container *** @return A default Map object container **/ protected static Map<Object,Object> CreateDefaultMap() { /* try { Map<Object,Object> map = (Map<Object,Object>)DefaultMapClass.newInstance(); // "unchecked cast" return map; } catch (Throwable t) { // (Do not use 'Print' here!!!) System.out.println("[RTProperties] Error instantiating: " + DefaultMapClass); // return new OrderedMap<Object,Object>(); } */ return new OrderedMap<Object,Object>(); } // ------------------------------------------------------------------------ /** *** PropertyChangeListener interface **/ public interface PropertyChangeListener { void propertyChange(RTProperties.PropertyChangeEvent pce); } /** *** PropertyChangeEvent class **/ public class PropertyChangeEvent { private Object keyObj = null; private Object oldVal = null; private Object newVal = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -