You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by rs...@apache.org on 2002/08/04 05:33:31 UTC
cvs commit: xml-axis/java/src/org/apache/axis AxisProperties.java
rsitze 2002/08/03 20:33:31
Modified: java/src/org/apache/axis AxisProperties.java
Log:
Javadoc says it all...
Revision Changes Path
1.3 +185 -13 xml-axis/java/src/org/apache/axis/AxisProperties.java
Index: AxisProperties.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/AxisProperties.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AxisProperties.java 2 Aug 2002 17:27:41 -0000 1.2
+++ AxisProperties.java 4 Aug 2002 03:33:31 -0000 1.3
@@ -55,13 +55,42 @@
package org.apache.axis;
-import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
/**
+ * <p>Configuration properties for AXIS.
+ * </p>
+ *
+ * <p>Manage configuration properties according to a secure
+ * scheme similar to that used by classloaders:
+ * <ul>
+ * <li><code>ClassLoader</code>s are organized in a tree hierarchy.</li>
+ * <li>each <code>ClassLoader</code> has a reference
+ * to a parent <code>ClassLoader</code>.</li>
+ * <li>the root of the tree is the bootstrap <code>ClassLoader</code>er.</li>
+ * <li>the youngest decendent is the thread context class loader.</li>
+ * <li>properties are bound to a <code>ClassLoader</code> instance
+ * <ul>
+ * <li><i>non-default</i> properties bound to a parent <code>ClassLoader</code>
+ * instance take precedence over all properties of the same name bound
+ * to any decendent.
+ * Just to confuse the issue, this is the default case.</li>
+ * <li><i>default</i> properties bound to a parent <code>ClassLoader</code>
+ * instance may be overriden by (default or non-default) properties of
+ * the same name bound to any decendent.
+ * </li>
+ * </ul>
+ * </li>
+ * <li>System properties take precedence over all other properties</li>
+ * </ul>
+ * </p>
+ *
* @author Richard A. Sitze
*/
public class AxisProperties {
+
public static final char NL = '\n';
public static final char CR = '\r';
@@ -70,28 +99,171 @@
*/
public static final String LS = System.getProperty("line.separator",
(new Character(NL)).toString());
+
+ /**
+ * Cache of AXIS Properties, keyed by (thread-context) class loaders.
+ * Use <code>HashMap</code> because it allows 'null' keys, which
+ * allows us to account for the (null) bootstrap classloader.
+ */
+ private static final HashMap axisPropertiesCache = new HashMap();
+
/**
- * Central access point for AXIS to obtain configuration properties.
- * To be extended in the future... or replaced with non-global properties.
+ * Get value for property bound to the current thread context class loader.
+ *
+ * @param property property name.
+ * @return property value if found, otherwise default.
*/
- public static String getProperty(String property) {
- return System.getProperty(property);
+ public static String getProperty(String propertyName) {
+ String value = System.getProperty(propertyName);
+ if (value == null) {
+ Value val = getValueProperty(getThreadContextClassLoader(), propertyName);
+ if (val != null) {
+ value = val.value;
+ }
+ }
+ return value;
}
- public static String getProperty(String property, String dephault) {
- return System.getProperty(property, dephault);
+ /**
+ * Get value for property bound to the current thread context class loader.
+ * If not found, then return default.
+ *
+ * @param property property name.
+ * @param dephault default value.
+ * @return property value if found, otherwise default.
+ */
+ public static String getProperty(String propertyName, String dephault) {
+ String value = getProperty(propertyName);
+ return (value == null) ? dephault : value;
}
/**
- * Central access point for AXIS to set configuration properties.
- * To be extended in the future... or replaced with non-global properties.
+ * Set value for property bound to the current thread context class loader.
+ * @param property property name
+ * @param value property value (non-default) If null, remove the property.
*/
- public static Object setProperty(String property, String value) {
- return System.setProperty(property, value);
+ public static void setProperty(String propertyName, String value) {
+ setProperty(propertyName, value, false);
+ }
+
+ /**
+ * Set value for property bound to the current thread context class loader.
+ * @param property property name
+ * @param value property value. If null, remove the property.
+ * @param isDefault determines if property is default or not.
+ * A non-default property cannot be overriden.
+ * A default property can be overriden by a property
+ * (default or non-default) of the same name bound to
+ * a decendent class loader.
+ */
+ public static void setProperty(String propertyName, String value, boolean isDefault) {
+ if (propertyName != null) {
+ synchronized (axisPropertiesCache) {
+ ClassLoader classLoader = getThreadContextClassLoader();
+ HashMap properties = (HashMap)axisPropertiesCache.get(classLoader);
+
+ if (value == null) {
+ properties.remove(propertyName);
+ } else {
+ if (properties == null) {
+ properties = new HashMap();
+ axisPropertiesCache.put(classLoader, properties);
+ }
+
+ properties.put(propertyName, new Value(value, isDefault));
+ }
+ }
+ }
+ }
+
+ /**
+ * Set property values for <code>Properties</code> bound to the
+ * current thread context class loader.
+ *
+ * @param newProperties name/value pairs to be bound
+ */
+ public static void setProperties(Map newProperties) {
+ setProperties(newProperties, false);
+ }
+
+
+ /**
+ * Set property values for <code>Properties</code> bound to the
+ * current thread context class loader.
+ *
+ * @param newProperties name/value pairs to be bound
+ * @param isDefault determines if properties are default or not.
+ * A non-default property cannot be overriden.
+ * A default property can be overriden by a property
+ * (default or non-default) of the same name bound to
+ * a decendent class loader.
+ */
+ public static void setProperties(Map newProperties, boolean isDefault) {
+ java.util.Iterator it = newProperties.entrySet().iterator();
+
+ /**
+ * Each entry must be mapped to a Property.
+ * 'setProperty' does this for us.
+ */
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry)it.next();
+ setProperty( String.valueOf(entry.getKey()),
+ String.valueOf(entry.getValue()),
+ isDefault);
+ }
+ }
+
+
+ /***************** INTERNAL IMPLEMENTATION *****************/
+
+ private static class Value {
+ final String value;
+ final boolean isDefault;
+
+ Value(String value, boolean isDefault) {
+ this.value = value;
+ this.isDefault = isDefault;
+ }
+ }
+
+ /**
+ * Get value for properties bound to the class loader.
+ * Explore up the tree first, as higher-level class
+ * loaders take precedence over lower-level class loaders.
+ */
+ private static Value getValueProperty(ClassLoader classLoader, String propertyName) {
+ Value value = null;
+
+ if (propertyName != null) {
+ /**
+ * If classLoader isn't bootstrap loader (==null),
+ * then get up-tree value.
+ */
+ if (classLoader != null) {
+ value = getValueProperty(classLoader.getParent(), propertyName);
+ }
+
+ if (value == null || value.isDefault) {
+ synchronized (axisPropertiesCache) {
+ HashMap properties = (HashMap)axisPropertiesCache.get(classLoader);
+
+ if (properties != null) {
+ Value altValue = (Value)properties.get(propertyName);
+
+ // set value only if override exists..
+ // otherwise pass default (or null) on..
+ if (altValue != null)
+ value = altValue;
+ }
+ }
+ }
+ }
+
+ return value;
}
- public static Properties getProperties() {
- return System.getProperties();
+ private static final ClassLoader getThreadContextClassLoader() {
+ return Thread.currentThread().getContextClassLoader();
}
}