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

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;

import org.apache.commons.configuration.plist.PropertyListConfiguration;
import org.apache.commons.configuration.plist.XMLPropertyListConfiguration;
import org.apache.commons.digester.AbstractObjectCreationFactory;
import org.apache.commons.digester.CallMethodRule;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.ObjectCreationFactory;
import org.apache.commons.digester.Substitutor;
import org.apache.commons.digester.substitution.MultiVariableExpander;
import org.apache.commons.digester.substitution.VariableSubstitutor;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

Factory class to create a CompositeConfiguration from a .xml file using Digester. By default it can handle the Configurations from commons- configuration. If you need to add your own, then you can pass in your own digester rules to use. It is also namespace aware, by providing a digesterRuleNamespaceURI.

Note: Almost all of the features provided by this class and many more are also available for the DefaultConfigurationBuilder class. DefaultConfigurationBuilder also has a more robust merge algorithm for constructing combined configurations. So it is recommended to use this class instead of ConfigurationFactory.

Author:Eric Pugh, Henning P. Schmiedehausen
Version:$Id: ConfigurationFactory.java 1209685 2011-12-02 20:47:44Z oheger $
Deprecated:Use DefaultConfigurationBuilder instead; this class provides the same features as ConfigurationFactory plus some more; it can also process the same configuration definition files.
/** * <p> * Factory class to create a CompositeConfiguration from a .xml file using * Digester. By default it can handle the Configurations from commons- * configuration. If you need to add your own, then you can pass in your own * digester rules to use. It is also namespace aware, by providing a * digesterRuleNamespaceURI. * </p> * <p> * <em>Note:</em> Almost all of the features provided by this class and many * more are also available for the {@link DefaultConfigurationBuilder} * class. {@code DefaultConfigurationBuilder} also has a more robust * merge algorithm for constructing combined configurations. So it is * recommended to use this class instead of {@code ConfigurationFactory}. * </p> * * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a> * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> * @version $Id: ConfigurationFactory.java 1209685 2011-12-02 20:47:44Z oheger $ * @deprecated Use {@link DefaultConfigurationBuilder} instead; this class * provides the same features as ConfigurationFactory plus some more; it can * also process the same configuration definition files. */
@Deprecated public class ConfigurationFactory {
Constant for the root element in the info file.
/** Constant for the root element in the info file.*/
private static final String SEC_ROOT = "configuration/";
Constant for the override section.
/** Constant for the override section.*/
private static final String SEC_OVERRIDE = SEC_ROOT + "override/";
Constant for the additional section.
/** Constant for the additional section.*/
private static final String SEC_ADDITIONAL = SEC_ROOT + "additional/";
Constant for the optional attribute.
/** Constant for the optional attribute.*/
private static final String ATTR_OPTIONAL = "optional";
Constant for the fileName attribute.
/** Constant for the fileName attribute.*/
private static final String ATTR_FILENAME = "fileName";
Constant for the load method.
/** Constant for the load method.*/
private static final String METH_LOAD = "load";
Constant for the default base path (points to actual directory).
/** Constant for the default base path (points to actual directory).*/
private static final String DEF_BASE_PATH = ".";
static logger
/** static logger */
private static Log log = LogFactory.getLog(ConfigurationFactory.class);
The XML file with the details about the configuration to load
/** The XML file with the details about the configuration to load */
private String configurationFileName;
The URL to the XML file with the details about the configuration to load.
/** The URL to the XML file with the details about the configuration to load. */
private URL configurationURL;
The implicit base path for included files. This path is determined by the configuration to load and used unless no other base path was explicitly specified.
/** * The implicit base path for included files. This path is determined by * the configuration to load and used unless no other base path was * explicitly specified. */
private String implicitBasePath;
The basePath to prefix file paths for file based property files.
/** The basePath to prefix file paths for file based property files. */
private String basePath;
URL for xml digester rules file
/** URL for xml digester rules file */
private URL digesterRules;
The digester namespace to parse
/** The digester namespace to parse */
private String digesterRuleNamespaceURI;
Constructor
/** * Constructor */
public ConfigurationFactory() { setBasePath(DEF_BASE_PATH); }
Constructor with ConfigurationFile Name passed
Params:
  • configurationFileName – The path to the configuration file
/** * Constructor with ConfigurationFile Name passed * * @param configurationFileName The path to the configuration file */
public ConfigurationFactory(String configurationFileName) { setConfigurationFileName(configurationFileName); }
Return the configuration provided by this factory. It loads the configuration file which is a XML description of the actual configurations to load. It can contain various different types of configuration, e.g. Properties, XML and JNDI.
Throws:
  • ConfigurationException – A generic exception that we had trouble during the loading of the configuration data.
Returns:A Configuration object
/** * Return the configuration provided by this factory. It loads the * configuration file which is a XML description of the actual * configurations to load. It can contain various different types of * configuration, e.g. Properties, XML and JNDI. * * @return A Configuration object * @throws ConfigurationException A generic exception that we had trouble during the * loading of the configuration data. */
public Configuration getConfiguration() throws ConfigurationException { Digester digester; InputStream input = null; ConfigurationBuilder builder = new ConfigurationBuilder(); URL url = getConfigurationURL(); try { if (url == null) { url = ConfigurationUtils.locate(implicitBasePath, getConfigurationFileName()); } input = url.openStream(); } catch (Exception e) { log.error("Exception caught opening stream to URL", e); throw new ConfigurationException("Exception caught opening stream to URL", e); } if (getDigesterRules() == null) { digester = new Digester(); configureNamespace(digester); initDefaultDigesterRules(digester); } else { digester = DigesterLoader.createDigester(getDigesterRules()); // This might already be too late. As far as I can see, the namespace // awareness must be configured before the digester rules are loaded. configureNamespace(digester); } // Configure digester to always enable the context class loader digester.setUseContextClassLoader(true); // Add a substitutor to resolve system properties enableDigesterSubstitutor(digester); // Put the composite builder object below all of the other objects. digester.push(builder); // Parse the input stream to configure our mappings try { digester.parse(input); input.close(); } catch (SAXException saxe) { log.error("SAX Exception caught", saxe); throw new ConfigurationException("SAX Exception caught", saxe); } catch (IOException ioe) { log.error("IO Exception caught", ioe); throw new ConfigurationException("IO Exception caught", ioe); } return builder.getConfiguration(); }
Returns the configurationFile.
Returns:The name of the configuration file. Can be null.
/** * Returns the configurationFile. * * @return The name of the configuration file. Can be null. */
public String getConfigurationFileName() { return configurationFileName; }
Sets the configurationFile.
Params:
  • configurationFileName – The name of the configurationFile to use.
/** * Sets the configurationFile. * * @param configurationFileName The name of the configurationFile to use. */
public void setConfigurationFileName(String configurationFileName) { File file = new File(configurationFileName).getAbsoluteFile(); this.configurationFileName = file.getName(); implicitBasePath = file.getParent(); }
Returns the URL of the configuration file to be loaded.
Returns:the URL of the configuration to load
/** * Returns the URL of the configuration file to be loaded. * * @return the URL of the configuration to load */
public URL getConfigurationURL() { return configurationURL; }
Sets the URL of the configuration to load. This configuration can be either specified by a file name or by a URL.
Params:
  • url – the URL of the configuration to load
/** * Sets the URL of the configuration to load. This configuration can be * either specified by a file name or by a URL. * * @param url the URL of the configuration to load */
public void setConfigurationURL(URL url) { configurationURL = url; implicitBasePath = url.toString(); }
Returns the digesterRules.
Returns:URL
/** * Returns the digesterRules. * * @return URL */
public URL getDigesterRules() { return digesterRules; }
Sets the digesterRules.
Params:
  • digesterRules – The digesterRules to set
/** * Sets the digesterRules. * * @param digesterRules The digesterRules to set */
public void setDigesterRules(URL digesterRules) { this.digesterRules = digesterRules; }
Adds a substitutor to interpolate system properties
Params:
  • digester – The digester to which we add the substitutor
/** * Adds a substitutor to interpolate system properties * * @param digester The digester to which we add the substitutor */
protected void enableDigesterSubstitutor(Digester digester) { // This is ugly, but it is safe because the Properties object returned // by System.getProperties() (which is actually a Map<Object, Object>) // contains only String keys. @SuppressWarnings("unchecked") Map<String, Object> systemProperties = (Map<String, Object>) (Object) System.getProperties(); MultiVariableExpander expander = new MultiVariableExpander(); expander.addSource("$", systemProperties); // allow expansion in both xml attributes and element text Substitutor substitutor = new VariableSubstitutor(expander); digester.setSubstitutor(substitutor); }
Initializes the parsing rules for the default digester This allows the Configuration Factory to understand the default types: Properties, XML and JNDI. Two special sections are introduced: <override> and <additional>.
Params:
  • digester – The digester to configure
/** * Initializes the parsing rules for the default digester * * This allows the Configuration Factory to understand the default types: * Properties, XML and JNDI. Two special sections are introduced: * <code>&lt;override&gt;</code> and <code>&lt;additional&gt;</code>. * * @param digester The digester to configure */
protected void initDefaultDigesterRules(Digester digester) { initDigesterSectionRules(digester, SEC_ROOT, false); initDigesterSectionRules(digester, SEC_OVERRIDE, false); initDigesterSectionRules(digester, SEC_ADDITIONAL, true); }
Sets up digester rules for a specified section of the configuration info file.
Params:
  • digester – the current digester instance
  • matchString – specifies the section
  • additional – a flag if rules for the additional section are to be added
/** * Sets up digester rules for a specified section of the configuration * info file. * * @param digester the current digester instance * @param matchString specifies the section * @param additional a flag if rules for the additional section are to be * added */
protected void initDigesterSectionRules(Digester digester, String matchString, boolean additional) { setupDigesterInstance( digester, matchString + "properties", new PropertiesConfigurationFactory(), METH_LOAD, additional); setupDigesterInstance( digester, matchString + "plist", new PropertyListConfigurationFactory(), METH_LOAD, additional); setupDigesterInstance( digester, matchString + "xml", new FileConfigurationFactory(XMLConfiguration.class), METH_LOAD, additional); setupDigesterInstance( digester, matchString + "hierarchicalXml", new FileConfigurationFactory(XMLConfiguration.class), METH_LOAD, additional); setupDigesterInstance( digester, matchString + "jndi", new JNDIConfigurationFactory(), null, additional); setupDigesterInstance( digester, matchString + "system", new SystemConfigurationFactory(), null, additional); }
Sets up digester rules for a configuration to be loaded.
Params:
  • digester – the current digester
  • matchString – the pattern to match with this rule
  • factory – an ObjectCreationFactory instance to use for creating new objects
  • method – the name of a method to be called or null for none
  • additional – a flag if rules for the additional section are to be added
/** * Sets up digester rules for a configuration to be loaded. * * @param digester the current digester * @param matchString the pattern to match with this rule * @param factory an ObjectCreationFactory instance to use for creating new * objects * @param method the name of a method to be called or <b>null</b> for none * @param additional a flag if rules for the additional section are to be * added */
protected void setupDigesterInstance( Digester digester, String matchString, ObjectCreationFactory factory, String method, boolean additional) { if (additional) { setupUnionRules(digester, matchString); } digester.addFactoryCreate(matchString, factory); digester.addSetProperties(matchString); if (method != null) { digester.addRule(matchString, new CallOptionalMethodRule(method)); } digester.addSetNext(matchString, "addConfiguration", Configuration.class.getName()); }
Sets up rules for configurations in the additional section.
Params:
  • digester – the current digester
  • matchString – the pattern to match with this rule
/** * Sets up rules for configurations in the additional section. * * @param digester the current digester * @param matchString the pattern to match with this rule */
protected void setupUnionRules(Digester digester, String matchString) { digester.addObjectCreate(matchString, AdditionalConfigurationData.class); digester.addSetProperties(matchString); digester.addSetNext(matchString, "addAdditionalConfig", AdditionalConfigurationData.class.getName()); }
Returns the digesterRuleNamespaceURI.
Returns:A String with the digesterRuleNamespaceURI.
/** * Returns the digesterRuleNamespaceURI. * * @return A String with the digesterRuleNamespaceURI. */
public String getDigesterRuleNamespaceURI() { return digesterRuleNamespaceURI; }
Sets the digesterRuleNamespaceURI.
Params:
  • digesterRuleNamespaceURI – The new digesterRuleNamespaceURI to use
/** * Sets the digesterRuleNamespaceURI. * * @param digesterRuleNamespaceURI The new digesterRuleNamespaceURI to use */
public void setDigesterRuleNamespaceURI(String digesterRuleNamespaceURI) { this.digesterRuleNamespaceURI = digesterRuleNamespaceURI; }
Configure the current digester to be namespace aware and to have a Configuration object to which all of the other configurations should be added
Params:
  • digester – The Digester to configure
/** * Configure the current digester to be namespace aware and to have * a Configuration object to which all of the other configurations * should be added * * @param digester The Digester to configure */
private void configureNamespace(Digester digester) { if (getDigesterRuleNamespaceURI() != null) { digester.setNamespaceAware(true); digester.setRuleNamespaceURI(getDigesterRuleNamespaceURI()); } else { digester.setNamespaceAware(false); } digester.setValidating(false); }
Returns the Base path from which this Configuration Factory operates. This is never null. If you set the BasePath to null, then a base path according to the configuration to load is returned.
Returns:The base Path of this configuration factory.
/** * Returns the Base path from which this Configuration Factory operates. * This is never null. If you set the BasePath to null, then a base path * according to the configuration to load is returned. * * @return The base Path of this configuration factory. */
public String getBasePath() { String path = StringUtils.isEmpty(basePath) || DEF_BASE_PATH.equals(basePath) ? implicitBasePath : basePath; return StringUtils.isEmpty(path) ? DEF_BASE_PATH : path; }
Sets the basePath for all file references from this Configuration Factory. Normally a base path need not to be set because it is determined by the location of the configuration file to load. All relative pathes in this file are resolved relative to this file. Setting a base path makes sense if such relative pathes should be otherwise resolved, e.g. if the configuration file is loaded from the class path and all sub configurations it refers to are stored in a special config directory.
Params:
  • basePath – The new basePath to set.
/** * Sets the basePath for all file references from this Configuration Factory. * Normally a base path need not to be set because it is determined by * the location of the configuration file to load. All relative pathes in * this file are resolved relative to this file. Setting a base path makes * sense if such relative pathes should be otherwise resolved, e.g. if * the configuration file is loaded from the class path and all sub * configurations it refers to are stored in a special config directory. * * @param basePath The new basePath to set. */
public void setBasePath(String basePath) { this.basePath = basePath; }
A base class for digester factory classes. This base class maintains a default class for the objects to be created. There will be sub classes for specific configuration implementations.
/** * A base class for digester factory classes. This base class maintains * a default class for the objects to be created. * There will be sub classes for specific configuration implementations. */
public class DigesterConfigurationFactory extends AbstractObjectCreationFactory {
Actual class to use.
/** Actual class to use. */
private Class<?> clazz;
Creates a new instance of DigesterConfigurationFactory.
Params:
  • clazz – the class which we should instantiate
/** * Creates a new instance of {@code DigesterConfigurationFactory}. * * @param clazz the class which we should instantiate */
public DigesterConfigurationFactory(Class<?> clazz) { this.clazz = clazz; }
Creates an instance of the specified class.
Params:
  • attribs – the attributes (ignored)
Throws:
Returns:the new object
/** * Creates an instance of the specified class. * * @param attribs the attributes (ignored) * @return the new object * @throws Exception if object creation fails */
@Override public Object createObject(Attributes attribs) throws Exception { return clazz.newInstance(); } }
A tiny inner class that allows the Configuration Factory to let the digester construct FileConfiguration objects that already have the correct base Path set.
/** * A tiny inner class that allows the Configuration Factory to * let the digester construct FileConfiguration objects * that already have the correct base Path set. * */
public class FileConfigurationFactory extends DigesterConfigurationFactory {
C'tor
Params:
  • clazz – The class which we should instantiate.
/** * C'tor * * @param clazz The class which we should instantiate. */
public FileConfigurationFactory(Class<?> clazz) { super(clazz); }
Gets called by the digester.
Params:
  • attributes – the actual attributes
Throws:
  • Exception – Couldn't instantiate the requested object.
Returns:the new object
/** * Gets called by the digester. * * @param attributes the actual attributes * @return the new object * @throws Exception Couldn't instantiate the requested object. */
@Override public Object createObject(Attributes attributes) throws Exception { FileConfiguration conf = createConfiguration(attributes); conf.setBasePath(getBasePath()); return conf; }
Creates the object, a FileConfiguration.
Params:
  • attributes – the actual attributes
Throws:
  • Exception – if the object could not be created
Returns:the file configuration
/** * Creates the object, a {@code FileConfiguration}. * * @param attributes the actual attributes * @return the file configuration * @throws Exception if the object could not be created */
protected FileConfiguration createConfiguration(Attributes attributes) throws Exception { return (FileConfiguration) super.createObject(attributes); } }
A factory that returns an XMLPropertiesConfiguration for .xml files and a PropertiesConfiguration for the others.
Since:1.2
/** * A factory that returns an XMLPropertiesConfiguration for .xml files * and a PropertiesConfiguration for the others. * * @since 1.2 */
public class PropertiesConfigurationFactory extends FileConfigurationFactory {
Creates a new instance of PropertiesConfigurationFactory.
/** * Creates a new instance of {@code PropertiesConfigurationFactory}. */
public PropertiesConfigurationFactory() { super(null); }
Creates the new configuration object. Based on the file name provided in the attributes either a PropertiesConfiguration or a XMLPropertiesConfiguration object will be returned.
Params:
  • attributes – the attributes
Throws:
Returns:the new configuration object
/** * Creates the new configuration object. Based on the file name * provided in the attributes either a {@code PropertiesConfiguration} * or a {@code XMLPropertiesConfiguration} object will be * returned. * * @param attributes the attributes * @return the new configuration object * @throws Exception if an error occurs */
@Override protected FileConfiguration createConfiguration(Attributes attributes) throws Exception { String filename = attributes.getValue(ATTR_FILENAME); if (filename != null && filename.toLowerCase().trim().endsWith(".xml")) { return new XMLPropertiesConfiguration(); } else { return new PropertiesConfiguration(); } } }
A factory that returns an XMLPropertyListConfiguration for .xml files and a PropertyListConfiguration for the others.
Since:1.2
/** * A factory that returns an XMLPropertyListConfiguration for .xml files * and a PropertyListConfiguration for the others. * * @since 1.2 */
public class PropertyListConfigurationFactory extends FileConfigurationFactory {
Creates a new instance of PropertyListConfigurationFactory.
/** * Creates a new instance of PropertyListConfigurationFactory</code>. */
public PropertyListConfigurationFactory() { super(null); }
Creates the new configuration object. Based on the file name provided in the attributes either a XMLPropertyListConfiguration or a PropertyListConfiguration object will be returned.
Params:
  • attributes – the attributes
Throws:
Returns:the new configuration object
/** * Creates the new configuration object. Based on the file name * provided in the attributes either a {@code XMLPropertyListConfiguration} * or a {@code PropertyListConfiguration} object will be * returned. * * @param attributes the attributes * @return the new configuration object * @throws Exception if an error occurs */
@Override protected FileConfiguration createConfiguration(Attributes attributes) throws Exception { String filename = attributes.getValue(ATTR_FILENAME); if (filename != null && filename.toLowerCase().trim().endsWith(".xml")) { return new XMLPropertyListConfiguration(); } else { return new PropertyListConfiguration(); } } }
A tiny inner class that allows the Configuration Factory to let the digester construct JNDIConfiguration objects.
/** * A tiny inner class that allows the Configuration Factory to * let the digester construct JNDIConfiguration objects. */
private class JNDIConfigurationFactory extends DigesterConfigurationFactory {
Creates a new instance of JNDIConfigurationFactory.
/** * Creates a new instance of {@code JNDIConfigurationFactory}. */
public JNDIConfigurationFactory() { super(JNDIConfiguration.class); } }
A tiny inner class that allows the Configuration Factory to let the digester construct SystemConfiguration objects.
/** * A tiny inner class that allows the Configuration Factory to * let the digester construct SystemConfiguration objects. */
private class SystemConfigurationFactory extends DigesterConfigurationFactory {
Creates a new instance of SystemConfigurationFactory.
/** * Creates a new instance of {@code SystemConfigurationFactory}. */
public SystemConfigurationFactory() { super(SystemConfiguration.class); } }
A simple data class that holds all information about a configuration from the <additional> section.
/** * A simple data class that holds all information about a configuration * from the <code>&lt;additional&gt;</code> section. */
public static class AdditionalConfigurationData {
Stores the configuration object.
/** Stores the configuration object.*/
private Configuration configuration;
Stores the location of this configuration in the global tree.
/** Stores the location of this configuration in the global tree.*/
private String at;
Returns the value of the at attribute.
Returns:the at attribute
/** * Returns the value of the {@code at} attribute. * * @return the at attribute */
public String getAt() { return at; }
Sets the value of the at attribute.
Params:
  • string – the attribute value
/** * Sets the value of the {@code at} attribute. * * @param string the attribute value */
public void setAt(String string) { at = string; }
Returns the configuration object.
Returns:the configuration
/** * Returns the configuration object. * * @return the configuration */
public Configuration getConfiguration() { return configuration; }
Sets the configuration object. Note: Normally this method should be named setConfiguration(), but the name addConfiguration() is required by some of the digester rules.
Params:
  • config – the configuration to set
/** * Sets the configuration object. Note: Normally this method should be * named {@code setConfiguration()}, but the name * {@code addConfiguration()} is required by some of the digester * rules. * * @param config the configuration to set */
public void addConfiguration(Configuration config) { configuration = config; } }
An internally used helper class for constructing the composite configuration object.
/** * An internally used helper class for constructing the composite * configuration object. */
public static class ConfigurationBuilder {
Stores the composite configuration.
/** Stores the composite configuration.*/
private CompositeConfiguration config;
Stores a collection with the configs from the additional section.
/** Stores a collection with the configs from the additional section.*/
private Collection<AdditionalConfigurationData> additionalConfigs;
Creates a new instance of ConfigurationBuilder.
/** * Creates a new instance of {@code ConfigurationBuilder}. */
public ConfigurationBuilder() { config = new CompositeConfiguration(); additionalConfigs = new LinkedList<AdditionalConfigurationData>(); }
Adds a new configuration to this object. This method is called by Digester.
Params:
  • conf – the configuration to be added
/** * Adds a new configuration to this object. This method is called by * Digester. * * @param conf the configuration to be added */
public void addConfiguration(Configuration conf) { config.addConfiguration(conf); }
Adds information about an additional configuration. This method is called by Digester.
Params:
  • data – the data about the additional configuration
/** * Adds information about an additional configuration. This method is * called by Digester. * * @param data the data about the additional configuration */
public void addAdditionalConfig(AdditionalConfigurationData data) { additionalConfigs.add(data); }
Returns the final composite configuration.
Returns:the final configuration object
/** * Returns the final composite configuration. * * @return the final configuration object */
public CompositeConfiguration getConfiguration() { if (!additionalConfigs.isEmpty()) { Configuration unionConfig = createAdditionalConfiguration(additionalConfigs); if (unionConfig != null) { addConfiguration(unionConfig); } additionalConfigs.clear(); } return config; }
Creates a configuration object with the union of all properties defined in the <additional> section. This implementation returns a HierarchicalConfiguration object.
Params:
  • configs – a collection with AdditionalConfigurationData objects
Returns:the union configuration (can be null)
/** * Creates a configuration object with the union of all properties * defined in the <code>&lt;additional&gt;</code> section. This * implementation returns a {@code HierarchicalConfiguration} * object. * * @param configs a collection with * {@code AdditionalConfigurationData} objects * @return the union configuration (can be <b>null</b>) */
protected Configuration createAdditionalConfiguration(Collection<AdditionalConfigurationData> configs) { HierarchicalConfiguration result = new HierarchicalConfiguration(); for (AdditionalConfigurationData cdata : configs) { result.addNodes(cdata.getAt(), createRootNode(cdata).getChildren()); } return result.isEmpty() ? null : result; }
Creates a configuration root node for the specified configuration.
Params:
  • cdata – the configuration data object
Returns:a root node for this configuration
/** * Creates a configuration root node for the specified configuration. * * @param cdata the configuration data object * @return a root node for this configuration */
private HierarchicalConfiguration.Node createRootNode(AdditionalConfigurationData cdata) { if (cdata.getConfiguration() instanceof HierarchicalConfiguration) { // we can directly use this configuration's root node return ((HierarchicalConfiguration) cdata.getConfiguration()).getRoot(); } else { // transform configuration to a hierarchical root node HierarchicalConfiguration hc = new HierarchicalConfiguration(); ConfigurationUtils.copy(cdata.getConfiguration(), hc); return hc.getRoot(); } } }
A special implementation of Digester's CallMethodRule that is internally used for calling a file configuration's load() method. This class differs from its ancestor that it catches all occurring exceptions when the specified method is called. It then checks whether for the corresponding configuration the optional attribute is set. If this is the case, the exception will simply be ignored.
Since:1.4
/** * A special implementation of Digester's {@code CallMethodRule} that * is internally used for calling a file configuration's {@code load()} * method. This class differs from its ancestor that it catches all occurring * exceptions when the specified method is called. It then checks whether * for the corresponding configuration the optional attribute is set. If * this is the case, the exception will simply be ignored. * * @since 1.4 */
private static class CallOptionalMethodRule extends CallMethodRule {
A flag whether the optional attribute is set for this node.
/** A flag whether the optional attribute is set for this node. */
private boolean optional;
Creates a new instance of CallOptionalMethodRule and sets the name of the method to invoke.
Params:
  • methodName – the name of the method
/** * Creates a new instance of {@code CallOptionalMethodRule} and * sets the name of the method to invoke. * * @param methodName the name of the method */
public CallOptionalMethodRule(String methodName) { super(methodName); }
Checks if the optional attribute is set.
Params:
  • attrs – the attributes
Throws:
/** * Checks if the optional attribute is set. * * @param attrs the attributes * @throws Exception if an error occurs */
@Override public void begin(Attributes attrs) throws Exception { optional = attrs.getValue(ATTR_OPTIONAL) != null && PropertyConverter.toBoolean( attrs.getValue(ATTR_OPTIONAL)).booleanValue(); super.begin(attrs); }
Calls the method. If the optional attribute was set, occurring exceptions will be ignored.
Throws:
  • Exception – if an error occurs
/** * Calls the method. If the optional attribute was set, occurring * exceptions will be ignored. * * @throws Exception if an error occurs */
@Override public void end() throws Exception { try { super.end(); } catch (Exception ex) { if (optional) { log.warn("Could not create optional configuration!", ex); } else { throw ex; } } } } }