Mega Code Archive

 
Categories / Java / Development Class
 

Adds new properties to an existing set of properties

/**  *  Copyright 2007 University Of Southern California  *  *  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.  */ import java.io.IOException; import java.util.Enumeration; import java.util.MissingResourceException; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PropertiesHelper     extends Properties {   /**    * Adds new properties to an existing set of properties while    * substituting variables. This function will allow value    * substitutions based on other property values. Value substitutions    * may not be nested. A value substitution will be ${property.key},    * where the dollar-brace and close-brace are being stripped before    * looking up the value to replace it with. Note that the ${..}    * combination must be escaped from the shell.    *    * @param b is the set of properties to add to existing properties.    * @return the combined set of properties.    */   protected Properties addProperties(Properties b) {     // initial     // Properties result = new Properties(this);     Properties sys = System.getProperties();     Pattern pattern = Pattern.compile("\\$\\{[-a-zA-Z0-9._]+\\}");     for (Enumeration e = b.propertyNames(); e.hasMoreElements(); ) {       String key = (String) e.nextElement();       String value = b.getProperty(key);       // unparse value ${prop.key} inside braces       Matcher matcher = pattern.matcher(value);       StringBuffer sb = new StringBuffer();       while (matcher.find()) {         // extract name of properties from braces         String newKey = value.substring(matcher.start() + 2, matcher.end() - 1);         // try to find a matching value in result properties         String newVal = getProperty(newKey);         // if still not found, try system properties         if (newVal == null) {           newVal = sys.getProperty(newKey);         }         // replace braced string with the actual value or empty string         matcher.appendReplacement(sb, newVal == null ? "" : newVal);       }       matcher.appendTail(sb);       setProperty(key, sb.toString());     }     return this;   }   /**    * Adds new properties to an existing set of properties while    * substituting variables. This function will allow value    * substitutions based on other property values. Value substitutions    * may not be nested. A value substitution will be ${property.key},    * where the dollar-brace and close-brace are being stripped before    * looking up the value to replace it with. Note that the ${..}    * combination must be escaped from the shell.    *    * @param a is the initial set of known properties (besides System ones)    * @param b is the set of properties to add to a    * @return the combined set of properties from a and b.    */   protected static Properties addProperties(Properties a, Properties b) {     // initial     Properties result = new Properties(a);     Properties sys = System.getProperties();     Pattern pattern = Pattern.compile("\\$\\{[-a-zA-Z0-9._]+\\}");     for (Enumeration e = b.propertyNames(); e.hasMoreElements(); ) {       String key = (String) e.nextElement();       String value = b.getProperty(key);       // unparse value ${prop.key} inside braces       Matcher matcher = pattern.matcher(value);       StringBuffer sb = new StringBuffer();       while (matcher.find()) {         // extract name of properties from braces         String newKey = value.substring(matcher.start() + 2, matcher.end() - 1);         // try to find a matching value in result properties         String newVal = result.getProperty(newKey);         // if still not found, try system properties         if (newVal == null) {           newVal = sys.getProperty(newKey);         }         // replace braced string with the actual value or empty string         matcher.appendReplacement(sb, newVal == null ? "" : newVal);       }       matcher.appendTail(sb);       result.setProperty(key, sb.toString());     }     // final     return result;   }   public PropertiesHelper() {     super();   }   public PropertiesHelper(Properties defaults) {     super(defaults);   }   protected PropertiesHelper(String propFilename, Properties defaults) throws       IOException,       MissingResourceException {     // create empty new instance     super(defaults);   }   /**    * Accessor: Overwrite any properties from within the program.    *    * @param key is the key to look up    * @param value is the new property value to place in the system.    * @return the old value, or null if it didn't exist before.    */   /**  public Object setProperty(String key, String value) {       return System.setProperty(key, value);     }    **/   /**    * Accessor: access to the internal properties as read from file.    * An existing system property of the same key will have precedence    * over any project property. This method will remove leading and    * trailing ASCII control characters and whitespaces.    *    * @param key is the key to look up    * @return the value for the key, or null, if not found.    */   /** public String getProperty(String key) {      String result =          System.getProperty(key, this.m_props.getProperty(key));      return (result == null ? result : result.trim());    }    **/   /**    * Accessor: access to the internal properties as read from file    * An existing system property of the same key will have precedence    * over any project property. This method will remove leading and    * trailing ASCII control characters and whitespaces.    *    * @param key is the key to look up    * @param defValue is a default to use, if no value can be found for the key.    * @return the value for the key, or the default value, if not found.    */   /** public String getProperty(String key, String defValue) {      String result =          System.getProperty(key, this.m_props.getProperty(key, defValue));      return (result == null ? result : result.trim());    }    **/   /**    * Extracts a specific property key subset from the known properties.    * The prefix may be removed from the keys in the resulting dictionary,    * or it may be kept. In the latter case, exact matches on the prefix    * will also be copied into the resulting dictionary.    *    * @param prefix is the key prefix to filter the properties by.    * @param keepPrefix if true, the key prefix is kept in the resulting    * dictionary. As side-effect, a key that matches the prefix exactly    * will also be copied. If false, the resulting dictionary's keys are    * shortened by the prefix. An exact prefix match will not be copied,    * as it would result in an empty string key.    * @return a property dictionary matching the filter key. May be    * an empty dictionary, if no prefix matches were found.    *    * @see #getProperty( String ) is used to assemble matches    */   public Properties matchingSubset(String prefix, boolean keepPrefix) {     Properties result = new Properties();     // sanity check     if (prefix == null || prefix.length() == 0) {       return result;     }     String prefixMatch; // match prefix strings with this     String prefixSelf; // match self with this     if (prefix.charAt(prefix.length() - 1) != '.') {       // prefix does not end in a dot       prefixSelf = prefix;       prefixMatch = prefix + '.';     } else {       // prefix does end in one dot, remove for exact matches       prefixSelf = prefix.substring(0, prefix.length() - 1);       prefixMatch = prefix;     }     // POSTCONDITION: prefixMatch and prefixSelf are initialized!     // now add all matches into the resulting properties.     // Remark 1: #propertyNames() will contain the System properties!     // Remark 2: We need to give priority to System properties. This is done     // automatically by calling this class's getProperty method.     String key;     for (Enumeration e = propertyNames(); e.hasMoreElements(); ) {       key = (String) e.nextElement();       if (keepPrefix) {         // keep full prefix in result, also copy direct matches         if (key.startsWith(prefixMatch) || key.equals(prefixSelf)) {           result.setProperty(key,                              getProperty(key));         }       } else {         // remove full prefix in result, dont copy direct matches         if (key.startsWith(prefixMatch)) {           result.setProperty(key.substring(prefixMatch.length()),                              getProperty(key));         }       }     }     // done     return result;   }   /**    * Extracts a specific property key subset from the properties passed.    * The prefix may be removed from the keys in the resulting dictionary,    * or it may be kept. In the latter case, exact matches on the prefix    * will also be copied into the resulting dictionary.    *    *    * @param prefix is the key prefix to filter the properties by.    * @param keepPrefix if true, the key prefix is kept in the resulting    * dictionary. As side-effect, a key that matches the prefix exactly    * will also be copied. If false, the resulting dictionary's keys are    * shortened by the prefix. An exact prefix match will not be copied,    * as it would result in an empty string key.    * @return a property dictionary matching the filter key. May be    * an empty dictionary, if no prefix matches were found.    *    * @see #getProperty( String ) is used to assemble matches    */   public static Properties matchingSubset(Properties properties, String prefix,                                           boolean keepPrefix) {     Properties result = new Properties();     // sanity check     if (prefix == null || prefix.length() == 0) {       return result;     }     String prefixMatch; // match prefix strings with this     String prefixSelf; // match self with this     if (prefix.charAt(prefix.length() - 1) != '.') {       // prefix does not end in a dot       prefixSelf = prefix;       prefixMatch = prefix + '.';     } else {       // prefix does end in one dot, remove for exact matches       prefixSelf = prefix.substring(0, prefix.length() - 1);       prefixMatch = prefix;     }     // POSTCONDITION: prefixMatch and prefixSelf are initialized!     // now add all matches into the resulting properties.     // Remark 1: #propertyNames() will contain the System properties!     // Remark 2: We need to give priority to System properties. This is done     // automatically by calling this class's getProperty method.     String key;     for (Enumeration e = properties.propertyNames(); e.hasMoreElements(); ) {       key = (String) e.nextElement();       if (keepPrefix) {         // keep full prefix in result, also copy direct matches         if (key.startsWith(prefixMatch) || key.equals(prefixSelf)) {           result.setProperty(key,                              properties.getProperty(key));         }       } else {         // remove full prefix in result, dont copy direct matches         if (key.startsWith(prefixMatch)) {           result.setProperty(key.substring(prefixMatch.length()),                              properties.getProperty(key));         }       }     }     // done     return result;   } }