All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.configuration.interpol.ConfigurationInterpolator Maven / Gradle / Ivy

Go to download

Tools to assist in the reading of configuration/preferences files in various formats

There is a newer version: 20041012.002804
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.commons.configuration.interpol;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.text.StrLookup;

/**
 * 

* A class that handles interpolation (variable substitution) for configuration * objects. *

*

* Each instance of AbstractConfiguration is associated with an * object of this class. All interpolation tasks are delegated to this object. *

*

* ConfigurationInterpolator works together with the * StrSubstitutor class from Commons Lang. By extending * StrLookup it is able to provide values for variables that * appear in expressions. *

*

* The basic idea of this class is that it can maintain a set of primitive * StrLookup objects, each of which is identified by a special * prefix. The variables to be processed have the form * ${prefix:name}. ConfigurationInterpolator will * extract the prefix and determine, which primitive lookup object is registered * for it. Then the name of the variable is passed to this object to obtain the * actual value. It is also possible to define a default lookup object, which * will be used for variables that do not have a prefix or that cannot be * resolved by their associated lookup object. *

*

* When a new instance of this class is created it is initialized with a default * set of primitive lookup objects. This set can be customized using the static * methods registerGlobalLookup() and * deregisterGlobalLookup(). Per default it contains the * following standard lookup objects: *

*

*

* * * * * * * * * * * * *
PrefixLookup object
sysWith this prefix a lookup object is associated that is able to resolve * system properties.
constThe const prefix indicates that a variable is to be * interpreted as a constant member field of a class (i.e. a field with the * static final modifiers). The name of the variable must be of the form * <full qualified class name>.<field name>, e.g. * org.apache.commons.configuration.interpol.ConfigurationInterpolator.PREFIX_CONSTANTS * .
*

*

* After an instance has been created the current set of lookup objects can be * modified using the registerLookup() and * deregisterLookup() methods. The default lookup object (that is * invoked for variables without a prefix) can be set with the * setDefaultLookup() method. (If a * ConfigurationInterpolator instance is created by a * configuration object, this lookup points to the configuration itself, so that * variables are resolved using the configuration's properties. This ensures * backward compatibility to earlier version of Commons Configuration.) *

*

* Implementation node: Instances of this class are not thread-safe related to * modifications of their current set of registered lookup objects. It is * intended that each instance is associated with a single * Configuration object and used for its interpolation tasks. *

* * @version $Id: ConfigurationInterpolator.java 833923 2009-11-08 20:53:52Z oheger $ * @since 1.4 * @author Commons * Configuration team */ public class ConfigurationInterpolator extends StrLookup { /** * Constant for the prefix of the standard lookup object for resolving * system properties. */ public static final String PREFIX_SYSPROPERTIES = "sys"; /** * Constant for the prefix of the standard lookup object for resolving * constant values. */ public static final String PREFIX_CONSTANTS = "const"; /** * Constant for the prefix of the standard lookup object for resolving * environment properties. * @since 1.7 */ public static final String PREFIX_ENVIRONMENT = "env"; /** Constant for the prefix separator. */ private static final char PREFIX_SEPARATOR = ':'; /** A map with the globally registered lookup objects. */ private static Map globalLookups; /** A map with the locally registered lookup objects. */ private Map localLookups; /** Stores the default lookup object. */ private StrLookup defaultLookup; /** Stores a parent interpolator objects if the interpolator is nested hierarchically. */ private ConfigurationInterpolator parentInterpolator; /** * Creates a new instance of ConfigurationInterpolator. */ public ConfigurationInterpolator() { synchronized (globalLookups) { localLookups = new HashMap(globalLookups); } } /** * Registers the given lookup object for the specified prefix globally. This * means that all instances that are created later will use this lookup * object for this prefix. If for this prefix a lookup object is already * registered, the new lookup object will replace the old one. Note that the * lookup objects registered here will be shared between multiple clients. * So they should be thread-safe. * * @param prefix the variable prefix (must not be null) * @param lookup the lookup object to be used for this prefix (must not be * null) */ public static void registerGlobalLookup(String prefix, StrLookup lookup) { if (prefix == null) { throw new IllegalArgumentException( "Prefix for lookup object must not be null!"); } if (lookup == null) { throw new IllegalArgumentException( "Lookup object must not be null!"); } synchronized (globalLookups) { globalLookups.put(prefix, lookup); } } /** * Deregisters the global lookup object for the specified prefix. This means * that this lookup object won't be available for later created instances * any more. For already existing instances this operation does not have any * impact. * * @param prefix the variable prefix * @return a flag whether for this prefix a lookup object had been * registered */ public static boolean deregisterGlobalLookup(String prefix) { synchronized (globalLookups) { return globalLookups.remove(prefix) != null; } } /** * Registers the given lookup object for the specified prefix at this * instance. From now on this lookup object will be used for variables that * have the specified prefix. * * @param prefix the variable prefix (must not be null) * @param lookup the lookup object to be used for this prefix (must not be * null) */ public void registerLookup(String prefix, StrLookup lookup) { if (prefix == null) { throw new IllegalArgumentException( "Prefix for lookup object must not be null!"); } if (lookup == null) { throw new IllegalArgumentException( "Lookup object must not be null!"); } localLookups.put(prefix, lookup); } /** * Deregisters the lookup object for the specified prefix at this instance. * It will be removed from this instance. * * @param prefix the variable prefix * @return a flag whether for this prefix a lookup object had been * registered */ public boolean deregisterLookup(String prefix) { return localLookups.remove(prefix) != null; } /** * Returns a set with the prefixes, for which lookup objects are registered * at this instance. This means that variables with these prefixes can be * processed. * * @return a set with the registered variable prefixes */ public Set prefixSet() { return localLookups.keySet(); } /** * Returns the default lookup object. * * @return the default lookup object */ public StrLookup getDefaultLookup() { return defaultLookup; } /** * Sets the default lookup object. This lookup object will be used for all * variables without a special prefix. If it is set to null, such * variables won't be processed. * * @param defaultLookup the new default lookup object */ public void setDefaultLookup(StrLookup defaultLookup) { this.defaultLookup = defaultLookup; } /** * Resolves the specified variable. This implementation will try to extract * a variable prefix from the given variable name (the first colon (':') is * used as prefix separator). It then passes the name of the variable with * the prefix stripped to the lookup object registered for this prefix. If * no prefix can be found or if the associated lookup object cannot resolve * this variable, the default lookup object will be used. * * @param var the name of the variable whose value is to be looked up * @return the value of this variable or null if it cannot be * resolved */ public String lookup(String var) { if (var == null) { return null; } int prefixPos = var.indexOf(PREFIX_SEPARATOR); if (prefixPos >= 0) { String prefix = var.substring(0, prefixPos); String name = var.substring(prefixPos + 1); String value = fetchLookupForPrefix(prefix).lookup(name); if (value == null && getParentInterpolator() != null) { value = getParentInterpolator().fetchLookupForPrefix(prefix).lookup(name); } if (value != null) { return value; } } String value = fetchNoPrefixLookup().lookup(var); if (value == null && getParentInterpolator() != null) { value = getParentInterpolator().fetchNoPrefixLookup().lookup(var); } return value; } /** * Returns the lookup object to be used for variables without a prefix. This * implementation will check whether a default lookup object was set. If * this is the case, it will be returned. Otherwise a null lookup * object will be returned (never null). * * @return the lookup object to be used for variables without a prefix */ protected StrLookup fetchNoPrefixLookup() { return (getDefaultLookup() != null) ? getDefaultLookup() : StrLookup.noneLookup(); } /** * Obtains the lookup object for the specified prefix. This method is called * by the lookup() method. This implementation will check * whether a lookup object is registered for the given prefix. If not, a * null lookup object will be returned (never null). * * @param prefix the prefix * @return the lookup object to be used for this prefix */ protected StrLookup fetchLookupForPrefix(String prefix) { StrLookup lookup = (StrLookup) localLookups.get(prefix); if (lookup == null) { lookup = StrLookup.noneLookup(); } return lookup; } /** * Registers the local lookup instances for the given interpolator. * * @param interpolator the instance receiving the local lookups * @since upcoming */ public void registerLocalLookups(ConfigurationInterpolator interpolator) { interpolator.localLookups.putAll(localLookups); } /** * Sets the parent interpolator. This object is used if the interpolation is nested * hierarchically and the current interpolation object cannot resolve a variable. * * @param parentInterpolator the parent interpolator object or null * @since upcoming */ public void setParentInterpolator(ConfigurationInterpolator parentInterpolator) { this.parentInterpolator = parentInterpolator; } /** * Requests the parent interpolator. This object is used if the interpolation is nested * hierarchically and the current interpolation * * @return the parent interpolator or null * @since upcoming */ public ConfigurationInterpolator getParentInterpolator() { return this.parentInterpolator; } // static initializer, sets up the map with the standard lookups static { globalLookups = new HashMap(); globalLookups.put(PREFIX_SYSPROPERTIES, StrLookup.systemPropertiesLookup()); globalLookups.put(PREFIX_CONSTANTS, new ConstantLookup()); globalLookups.put(PREFIX_ENVIRONMENT, new EnvironmentLookup()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy