Author: rgoers Date: Tue May 5 00:43:24 2009 New Revision: 771512 URL: http://svn.apache.org/viewvc?rev=771512&view=rev Log: Pass EntityResolver through MultiFileHierarchicalConfiguration. Allow CatalogResolver to load Catalog even if xml-resolver is in lib/endorsed.
Added: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java (with props) commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml (with props) commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml (with props) Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDefaultConfigurationBuilder.java commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample.xsd Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java Tue May 5 00:43:24 2009 @@ -43,6 +43,7 @@ import org.apache.commons.configuration2.tree.UnionCombiner; import org.apache.commons.configuration2.resolver.CatalogResolver; import org.apache.commons.configuration2.resolver.EntityRegistry; +import org.apache.commons.configuration2.resolver.EntityResolverSupport; import org.apache.commons.lang.text.StrLookup; import org.xml.sax.EntityResolver; @@ -755,7 +756,7 @@ EntityResolver resolver = (EntityResolver) BeanHelper.createBean(decl, CatalogResolver.class); BeanHelper.setProperty(resolver, "fileSystem", getFileSystem()); BeanHelper.setProperty(resolver, "baseDir", getBasePath()); - BeanHelper.setProperty(resolver, "substitutor", getSubstitutor()); + BeanHelper.setProperty(resolver, "substitutor", getSubstitutor()); setEntityResolver(resolver); } } @@ -1390,7 +1391,20 @@ public AbstractConfiguration getEmptyConfiguration( ConfigurationDeclaration decl) throws Exception { - return super.getConfiguration(decl); + AbstractConfiguration config = super.getConfiguration(decl); + + /** + * Some wrapper classes may need to pass the EntityResolver to XMLConfigurations + * they construct buy may not be an XMLConfiguration. + */ + if (config instanceof EntityResolverSupport) + { + DefaultConfigurationBuilder builder = decl.getConfigurationBuilder(); + EntityResolver resolver = builder.getEntityResolver(); + ((EntityResolverSupport) config).setEntityResolver(resolver); + } + + return config; } /** Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java Tue May 5 00:43:24 2009 @@ -38,8 +38,11 @@ import org.apache.commons.configuration2.event.ConfigurationEvent; import org.apache.commons.configuration2.expr.ExpressionEngine; import org.apache.commons.configuration2.tree.ConfigurationNode; +import org.apache.commons.configuration2.tree.TreeUtils; import org.apache.commons.configuration2.reloading.ReloadingStrategy; +import org.apache.commons.configuration2.resolver.EntityResolverSupport; import org.apache.commons.beanutils.BeanUtils; +import org.xml.sax.EntityResolver; /** * This class provides access to multiple configuration files that reside in a location that @@ -54,7 +57,7 @@ * */ public class MultiFileHierarchicalConfiguration extends AbstractHierarchicalFileConfiguration - implements ConfigurationListener, ConfigurationErrorListener + implements ConfigurationListener, ConfigurationErrorListener, EntityResolverSupport { /** * Prevent recursion while resolving unprefixed properties. @@ -92,6 +95,12 @@ /** The Logger name to use */ private String loggerName = ""; + /** The Reloading strategy to use on created configurations */ + private ReloadingStrategy fileStrategy; + + /** The EntityResolver */ + private EntityResolver entityResolver; + /** * Default Constructor */ @@ -156,6 +165,26 @@ this.attributeSplittingDisabled = attributeSplittingDisabled; } + public ReloadingStrategy getReloadingStrategy() + { + return fileStrategy; + } + + public void setReloadingStrategy(ReloadingStrategy strategy) + { + this.fileStrategy = strategy; + } + + public void setEntityResolver(EntityResolver entityResolver) + { + this.entityResolver = entityResolver; + } + + public EntityResolver getEntityResolver() + { + return this.entityResolver; + } + /** * Set to true if an empty Configuration should be returned when loading fails. If * false an exception will be thrown. @@ -687,31 +716,34 @@ } XMLConfiguration configuration = new XMLConfiguration(); - try + if (loggerName != null) { - if (loggerName != null) - { - Logger log = Logger.getLogger(loggerName); - if (log != null) - { - configuration.setLogger(log); - } + Logger log = Logger.getLogger(loggerName); + if (log != null) + { + configuration.setLogger(log); } - configuration.setBasePath(getBasePath()); - configuration.setFileName(path); - configuration.setFileSystem(getFileSystem()); - configuration.setExpressionEngine(getExpressionEngine()); - configuration.setReloadingStrategy(createReloadingStrategy()); - configuration.setDelimiterParsingDisabled(isDelimiterParsingDisabled()); - configuration.setAttributeSplittingDisabled(isAttributeSplittingDisabled()); - configuration.setValidating(validating); - configuration.setSchemaValidation(schemaValidation); - configuration.setListDelimiter(getListDelimiter()); - configuration.addConfigurationListener(this); - configuration.addErrorListener(this); + } + configuration.setBasePath(getBasePath()); + configuration.setFileName(path); + configuration.setFileSystem(getFileSystem()); + configuration.setExpressionEngine(getExpressionEngine()); + ReloadingStrategy strategy = createReloadingStrategy(); + if (strategy != null) + { + configuration.setReloadingStrategy(strategy); + } + configuration.setDelimiterParsingDisabled(isDelimiterParsingDisabled()); + configuration.setAttributeSplittingDisabled(isAttributeSplittingDisabled()); + configuration.setValidating(validating); + configuration.setSchemaValidation(schemaValidation); + configuration.setEntityResolver(entityResolver); + configuration.setListDelimiter(getListDelimiter()); + configuration.addConfigurationListener(this); + configuration.addErrorListener(this); + try + { configuration.load(); - configurationsMap.putIfAbsent(path, configuration); - configuration = configurationsMap.get(path); } catch (ConfigurationException ce) { @@ -720,8 +752,8 @@ throw new ConfigurationRuntimeException(ce); } } - - return configuration; + configurationsMap.putIfAbsent(path, configuration); + return configurationsMap.get(path); } /** Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java Tue May 5 00:43:24 2009 @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Collections; +import java.util.logging.Level; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -948,9 +949,14 @@ initProperties(newDocument, oldDocument == null); document = (oldDocument == null) ? newDocument : oldDocument; } + catch (SAXParseException spe) + { + this.getLogger().log(Level.FINE, "Error parsing " + source.getSystemId(), spe); + throw new ConfigurationException("Error parsing " + source.getSystemId(), spe); + } catch (Exception e) { - throw new ConfigurationException(e.getMessage(), e); + throw new ConfigurationException("Unable to load the configuration", e); } } @@ -971,11 +977,11 @@ } catch (TransformerException e) { - throw new ConfigurationException(e.getMessage(), e); + throw new ConfigurationException("Unable to save the configuration", e); } catch (TransformerFactoryConfigurationError err) { - throw new ConfigurationException(err.getMessage(), err); + throw new ConfigurationException("Unable to save the configuration", err); } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java Tue May 5 00:43:24 2009 @@ -34,6 +34,8 @@ import java.io.InputStream; import java.io.IOException; import java.util.Vector; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Retention; /** * Thin wrapper around xml commons CatalogResolver to allow list of catalogs @@ -88,7 +90,6 @@ { manager.setIgnoreMissingProperties(true); manager.setUseStaticCatalog(false); - manager.setCatalogClassName(Catalog.class.getName()); manager.setFileSystem(fs); setLogger(null); } @@ -246,6 +247,9 @@ */ public static class CatalogManager extends org.apache.xml.resolver.CatalogManager { + /** The static catalog used by this manager. */ + private static org.apache.xml.resolver.Catalog staticCatalog; + /** The FileSystem */ private FileSystem fs; @@ -303,6 +307,54 @@ { return this.substitutor; } + + + /** + * Get a new catalog instance. This method is only overridden because xml-resolver + * might be in a parent ClassLoader and will be incapable of loading our Catalog + * implementation. + * + * This method always returns a new instance of the underlying catalog class. + * @return the Catalog. + */ + public org.apache.xml.resolver.Catalog getPrivateCatalog() + { + org.apache.xml.resolver.Catalog catalog = staticCatalog; + + if (catalog == null || !getUseStaticCatalog()) + { + try + { + catalog = new Catalog(); + catalog.setCatalogManager(this); + catalog.setupReaders(); + catalog.loadSystemCatalogs(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + if (getUseStaticCatalog()) + { + staticCatalog = catalog; + } + } + + return catalog; + } + + /** + * Get a catalog instance. + * + * If this manager uses static catalogs, the same static catalog will + * always be returned. Otherwise a new catalog will be returned. + * @return The Catalog. + */ + public org.apache.xml.resolver.Catalog getCatalog() + { + return getPrivateCatalog(); + } } /** @@ -460,6 +512,6 @@ StrSubstitutor substitutor = ((CatalogManager) catalogManager).getStrSubstitutor(); String resolved = substitutor != null ? substitutor.replace(uriref) : uriref; return super.normalizeURI(resolved); - } + } } } Added: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java?rev=771512&view=auto ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java (added) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java Tue May 5 00:43:24 2009 @@ -0,0 +1,41 @@ +/* + * 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.configuration2.resolver; + +import org.xml.sax.EntityResolver; + +/** + * Interface that identifies the class as using an EntityResolver + * @author <a href="http://commons.apache.org/configuration/team-list.html">Commons + * Configuration team</a> + * @since 1.7 + * @version $Id$ + */ +public interface EntityResolverSupport +{ + /** + * Return the EntityResolver associated with the class. + * @return The EntityResolver. + */ + EntityResolver getEntityResolver(); + + /** + * Set the EntityResolver to assoicate with this class. + * @param resolver The EntityResolver + */ + void setEntityResolver(EntityResolver resolver); +} Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/EntityResolverSupport.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDefaultConfigurationBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDefaultConfigurationBuilder.java?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDefaultConfigurationBuilder.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestDefaultConfigurationBuilder.java Tue May 5 00:43:24 2009 @@ -29,6 +29,7 @@ import java.util.logging.Level; import java.util.logging.StreamHandler; import java.util.logging.SimpleFormatter; +import java.util.logging.ConsoleHandler; import junit.framework.TestCase; @@ -36,6 +37,7 @@ import org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy; import org.apache.commons.configuration2.tree.DefaultConfigurationNode; import org.apache.commons.configuration2.tree.ConfigurationNode; +import org.apache.commons.configuration2.tree.TreeUtils; import org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine; import org.apache.commons.lang.text.StrLookup; @@ -81,6 +83,9 @@ private static final File VALIDATION_FILE = ConfigurationAssert .getTestFile("testValidation.xml"); + private static final File VALIDATION3_FILE = ConfigurationAssert + .getTestFile("testValidation3.xml"); + private static final File MULTI_TENENT_FILE = ConfigurationAssert .getTestFile("testMultiTenentConfigurationBuilder.xml"); @@ -842,6 +847,21 @@ assertEquals("Incorrect value retrieved","value1",value); } + + public void testValidation3() throws Exception + { + System.getProperties().remove("Id"); + factory.setFile(VALIDATION3_FILE); + CombinedConfiguration config = factory.getConfiguration(true); + String value = config.getString("Employee/Name"); + assertNotNull("The test key was not located", value); + assertEquals("Incorrect value retrieved","John Doe",value); + System.setProperty("Id", "1001"); + value = config.getString("Employee/Name"); + assertNotNull("The test key was not located", value); + assertEquals("Incorrect value retrieved","Jane Doe",value); + } + public void testMultiTenentConfiguration() throws Exception { factory.setFile(MULTI_TENENT_FILE); Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample.xsd URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample.xsd?rev=771512&r1=771511&r2=771512&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample.xsd (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample.xsd Tue May 5 00:43:24 2009 @@ -1,18 +1,22 @@ <?xml version="1.0" encoding="UTF-8"?> -<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://commons.apache.org/employee" xmlns:xs="http://www.w3.org/2001/XMLSchema"> - <xs:element name="Employees" type="emp:EmployeesType" xmlns:emp="http://commons.apache.org/employee"/> - <xs:complexType name="EmployeeType"> - <xs:sequence> - <xs:element type="xs:string" name="SSN"/> - <xs:element type="xs:string" name="Name"/> - <xs:element type="xs:string" name="DateOfBirth"/> - <xs:element type="xs:string" name="EmployeeType"/> - <xs:element type="xs:string" name="Salary"/> - </xs:sequence> - </xs:complexType> - <xs:complexType name="EmployeesType"> - <xs:sequence> - <xs:element type="emp:EmployeeType" name="Employee" xmlns:emp="http://commons.apache.org/employee"/> - </xs:sequence> - </xs:complexType> +<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" + targetNamespace="http://commons.apache.org/employee" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="Employees" xmlns="http://commons.apache.org/employee"> + <xs:complexType> + <xs:sequence> + <xs:element name="Employee"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="SSN" minOccurs="0"/> + <xs:element type="xs:string" name="Name" minOccurs="0"/> + <xs:element type="xs:string" name="DateOfBirth" minOccurs="0"/> + <xs:element type="xs:string" name="EmployeeType" minOccurs="0"/> + <xs:element type="xs:string" name="Salary" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> </xs:schema> \ No newline at end of file Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml?rev=771512&view=auto ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml (added) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml Tue May 5 00:43:24 2009 @@ -0,0 +1,8 @@ +<?xml version="1.0" ?> +<Employees xmlns="http://commons.apache.org/employee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://commons.apache.org/employee http://commons.apache.org/sample.xsd"> + <Employee> + <Name>Jane Doe</Name> + </Employee> +</Employees> \ No newline at end of file Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/sample_1001.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml?rev=771512&view=auto ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml (added) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml Tue May 5 00:43:24 2009 @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!-- Test configuration definition file that demonstrates complex initialization --> +<configuration> + <header> + <result delimiterParsingDisabled="true" forceReloadCheck="true" loggerName="TestLogger" + config-class="org.apache.commons.configuration2.DynamicCombinedConfiguration" + keyPattern="$${sys:Id}"> + <nodeCombiner config-class="org.apache.commons.configuration2.tree.MergeCombiner"/> + <expressionEngine config-class="org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine"/> + </result> + <providers> + <provider config-tag="multifile" + config-class="org.apache.commons.configuration2.DefaultConfigurationBuilder$FileConfigurationProvider" + configurationClass="org.apache.commons.configuration2.MultiFileHierarchicalConfiguration"/> + </providers> + <entity-resolver catalogFiles="catalog.xml"/> + </header> + <system/> + <properties fileName="test.properties.xml" throwExceptionOnMissing="true" + config-name="properties"> + </properties> + <multifile filePattern="sample_$$${sys:Id}.xml" + config-name="clientConfig" delimiterParsingDisabled="true" schemaValidation="true"> + </multifile> + <xml fileName="sample.xml" config-name="xml" schemaValidation="true"/> +</configuration> \ No newline at end of file Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testValidation3.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml