/**
* 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;
}
}
|