epugh 2004/04/01 10:43:04 Modified: configuration/src/test/org/apache/commons/configuration TestCompositeConfiguration.java configuration/xdocs changes.xml configuration/src/java/org/apache/commons/configuration SubsetConfiguration.java PropertiesConfiguration.java CompositeConfiguration.java configuration project.xml Added: configuration/src/test/org/apache/commons/configuration TestDOMConfiguration.java TestHierarchicalDOMConfiguration.java configuration/src/java/org/apache/commons/configuration DOMConfiguration.java HierarchicalDOMConfiguration.java Log: Bugzilla Bug 27498 DOM based XMLConfiguration Revision Changes Path 1.7 +16 -1 jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestCompositeConfiguration.java Index: TestCompositeConfiguration.java =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestCompositeConfiguration.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- TestCompositeConfiguration.java 9 Mar 2004 10:31:31 -0000 1.6 +++ TestCompositeConfiguration.java 1 Apr 2004 18:43:03 -0000 1.7 @@ -229,6 +229,21 @@ } /** + * Tests subsets and still can resolve elements + */ + public void testSubsetCanResolve() throws Exception + { + cc = new CompositeConfiguration(); + final BaseConfiguration config = new BaseConfiguration(); + config.addProperty("subset.tempfile", "${java.io.tmpdir}/file.tmp"); + cc.addConfiguration(config); + cc.addConfiguration(ConfigurationConverter.getConfiguration(System.getProperties())); + + Configuration subset = cc.subset("subset"); + assertEquals(System.getProperty("java.io.tmpdir") + "/file.tmp", subset.getString("tempfile")); + } + + /** * Tests <code>List</code> parsing. */ public void testList() throws Exception 1.1 jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestDOMConfiguration.java Index: TestDOMConfiguration.java =================================================================== package org.apache.commons.configuration; /* * Copyright 2001-2004 The Apache Software Foundation. * * 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.File; import junit.framework.TestCase; /** * test for loading and saving xml properties files * * @version $Id: TestDOMConfiguration.java,v 1.1 2004/04/01 18:43:03 epugh Exp $ */ public class TestDOMConfiguration extends TestCase { /** The File that we test with */ private String testProperties = new File("conf/test.xml").getAbsolutePath(); private String testBasePath = new File("conf").getAbsolutePath(); private DOMConfiguration conf; protected void setUp() throws Exception { conf = new DOMConfiguration(new File(testProperties)); } public void testGetProperty() throws Exception { assertEquals("value", conf.getProperty("element")); } public void testGetComplexProperty() throws Exception { assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement")); } public void testSettingFileNames() throws Exception { conf = new DOMConfiguration(); conf.setFileName(testProperties); assertEquals(testProperties.toString(), conf.getFileName()); conf.setBasePath(testBasePath); conf.setFileName("hello.xml"); assertEquals("hello.xml", conf.getFileName()); assertEquals(testBasePath.toString(), conf.getBasePath()); assertEquals(new File(testBasePath, "hello.xml"), conf.getFile()); conf.setBasePath(testBasePath); conf.setFileName("/subdir/hello.xml"); assertEquals("/subdir/hello.xml", conf.getFileName()); assertEquals(testBasePath.toString(), conf.getBasePath()); assertEquals(new File(testBasePath, "/subdir/hello.xml"), conf.getFile()); } public void testLoad() throws Exception { conf = new DOMConfiguration(); conf.setFileName(testProperties); conf.load(); assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement")); } public void testLoadWithBasePath() throws Exception { conf = new DOMConfiguration(); conf.setFileName("test.xml"); conf.setBasePath(testBasePath); conf.load(); assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement")); } } 1.1 jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestHierarchicalDOMConfiguration.java Index: TestHierarchicalDOMConfiguration.java =================================================================== package org.apache.commons.configuration; /* * Copyright 2001-2004 The Apache Software Foundation. * * 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.File; import java.util.Collection; import junit.framework.TestCase; /** * Test class for HierarchicalDOM4JConfiguration, * * @version $Id: TestHierarchicalDOMConfiguration.java,v 1.1 2004/04/01 18:43:03 epugh Exp $ */ public class TestHierarchicalDOMConfiguration extends TestCase { private static final String TEST_DIR = "conf"; private static final String TEST_FILENAME = "testHierarchicalDOM4JConfiguration.xml"; private static final String TEST_FILE = TEST_DIR + File.separator + TEST_FILENAME; private HierarchicalDOMConfiguration config; protected void setUp() throws Exception { config = new HierarchicalDOMConfiguration(); } private void configTest(HierarchicalDOMConfiguration config) { assertEquals(1, config.getMaxIndex("tables.table")); assertEquals("system", config.getProperty("tables.table(0)[EMAIL PROTECTED]")); assertEquals("application", config.getProperty("tables.table(1)[EMAIL PROTECTED]")); assertEquals("users", config.getProperty("tables.table(0).name")); assertEquals("documents", config.getProperty("tables.table(1).name")); Object prop = config.getProperty("tables.table.fields.field.name"); assertTrue(prop instanceof Collection); assertEquals(10, ((Collection) prop).size()); prop = config.getProperty("tables.table(0).fields.field.type"); assertTrue(prop instanceof Collection); assertEquals(5, ((Collection) prop).size()); prop = config.getProperty("tables.table(1).fields.field.type"); assertTrue(prop instanceof Collection); assertEquals(5, ((Collection) prop).size()); } public void testGetProperty() throws Exception { config.setFileName(TEST_FILE); config.load(); configTest(config); } public void testLoadURL() throws Exception { config.load(new File(TEST_FILE).getAbsoluteFile().toURL()); configTest(config); } public void testLoadBasePath1() throws Exception { config.setBasePath(TEST_DIR); config.setFileName(TEST_FILENAME); config.load(); configTest(config); } public void testLoadBasePath2() throws Exception { config.setBasePath(new File(TEST_FILE).getAbsoluteFile().toURL().toString()); config.setFileName(TEST_FILENAME); config.load(); configTest(config); } } 1.18 +3 -0 jakarta-commons/configuration/xdocs/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- changes.xml 1 Apr 2004 18:21:46 -0000 1.17 +++ changes.xml 1 Apr 2004 18:43:04 -0000 1.18 @@ -7,6 +7,9 @@ <body> <release version="1.0-dev-4" date=""> + <action dev="jschaible" type="add"> + Direct support of XML via DOM. New classes DOMConfiguration and HierarchicalDOMConfiguration. + </action> <action dev="jschaible" type="update"> Update build to not include test configuration files in resulting jar. </action> 1.2 +12 -133 jakarta-commons/configuration/src/java/org/apache/commons/configuration/SubsetConfiguration.java Index: SubsetConfiguration.java =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/SubsetConfiguration.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SubsetConfiguration.java 9 Mar 2004 10:31:31 -0000 1.1 +++ SubsetConfiguration.java 1 Apr 2004 18:43:04 -0000 1.2 @@ -16,11 +16,7 @@ package org.apache.commons.configuration; -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.Iterator; -import java.util.List; -import java.util.Properties; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.iterators.TransformIterator; @@ -33,7 +29,7 @@ * @author Emmanuel Bourg * @version $Revision$, $Date$ */ -public class SubsetConfiguration implements Configuration { +public class SubsetConfiguration extends AbstractConfiguration { protected Configuration parent; protected String prefix; @@ -132,7 +128,7 @@ return parent.containsKey(getParentKey(key)); } - public void addProperty(String key, Object value) { + public void addPropertyDirect(String key, Object value) { parent.addProperty(getParentKey(key), value); } @@ -144,7 +140,7 @@ parent.clearProperty(getParentKey(key)); } - public Object getProperty(String key) { + public Object getPropertyDirect(String key) { return parent.getProperty(getParentKey(key)); } @@ -164,130 +160,13 @@ }); } - public Properties getProperties(String key) { - return parent.getProperties(getParentKey(key)); - } - - public boolean getBoolean(String key) { - return parent.getBoolean(getParentKey(key)); - } - - public boolean getBoolean(String key, boolean defaultValue) { - return parent.getBoolean(getParentKey(key), defaultValue); - } - - public Boolean getBoolean(String key, Boolean defaultValue) { - return parent.getBoolean(getParentKey(key), defaultValue); - } - - public byte getByte(String key) { - return parent.getByte(getParentKey(key)); - } - - public byte getByte(String key, byte defaultValue) { - return parent.getByte(getParentKey(key), defaultValue); - } - - public Byte getByte(String key, Byte defaultValue) { - return parent.getByte(getParentKey(key), defaultValue); - } - - public double getDouble(String key) { - return parent.getDouble(getParentKey(key)); - } - - public double getDouble(String key, double defaultValue) { - return parent.getDouble(getParentKey(key), defaultValue); - } - - public Double getDouble(String key, Double defaultValue) { - return parent.getDouble(getParentKey(key), defaultValue); - } - - public float getFloat(String key) { - return parent.getFloat(getParentKey(key)); - } - - public float getFloat(String key, float defaultValue) { - return parent.getFloat(getParentKey(key), defaultValue); - } - - public Float getFloat(String key, Float defaultValue) { - return parent.getFloat(getParentKey(key), defaultValue); - } - - public int getInt(String key) { - return parent.getInt(getParentKey(key)); - } - - public int getInt(String key, int defaultValue) { - return parent.getInt(getParentKey(key), defaultValue); - } - - public Integer getInteger(String key, Integer defaultValue) { - return parent.getInteger(getParentKey(key), defaultValue); - } - - public long getLong(String key) { - return parent.getLong(getParentKey(key)); - } - - public long getLong(String key, long defaultValue) { - return parent.getLong(getParentKey(key), defaultValue); - } - - public Long getLong(String key, Long defaultValue) { - return parent.getLong(getParentKey(key), defaultValue); - } - - public short getShort(String key) { - return parent.getShort(getParentKey(key)); - } - - public short getShort(String key, short defaultValue) { - return parent.getShort(getParentKey(key), defaultValue); - } - - public Short getShort(String key, Short defaultValue) { - return parent.getShort(getParentKey(key), defaultValue); - } - - public BigDecimal getBigDecimal(String key) { - return parent.getBigDecimal(getParentKey(key)); - } - - public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) { - return parent.getBigDecimal(getParentKey(key), defaultValue); - } - - public BigInteger getBigInteger(String key) { - return parent.getBigInteger(getParentKey(key)); - } - - public BigInteger getBigInteger(String key, BigInteger defaultValue) { - return parent.getBigInteger(getParentKey(key), defaultValue); - } - - public String getString(String key) { - return parent.getString(getParentKey(key)); - } - - public String getString(String key, String defaultValue) { - return parent.getString(getParentKey(key), defaultValue); - } - - public String[] getStringArray(String key) { - return parent.getStringArray(getParentKey(key)); - } - - public List getList(String key) { - return parent.getList(getParentKey(key)); - } - - public List getList(String key, List defaultValue) { - return parent.getList(getParentKey(key), defaultValue); + protected String interpolate(String base) + { + if (delimiter == null && "".equals(prefix)) { + return super.interpolate(base); + } else { + SubsetConfiguration config = new SubsetConfiguration(parent, ""); + return config.interpolate(base); + } } - - - } 1.7 +14 -4 jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertiesConfiguration.java Index: PropertiesConfiguration.java =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertiesConfiguration.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- PropertiesConfiguration.java 28 Mar 2004 15:34:23 -0000 1.6 +++ PropertiesConfiguration.java 1 Apr 2004 18:43:04 -0000 1.7 @@ -98,13 +98,23 @@ */ public void load(String fileName) throws ConfigurationException { + InputStream is=null; try { - InputStream is = getPropertyStream(fileName); - load(is); - is.close(); + is = getPropertyStream(fileName); + load(is); } catch (IOException ioe){ throw new ConfigurationException("Could not load from file " + fileName,ioe); + } + finally{ + if(is !=null){ + try{ + is.close(); + } + catch (IOException ioe2){ + ioe2.printStackTrace(); + } + } } } 1.11 +1 -27 jakarta-commons/configuration/src/java/org/apache/commons/configuration/CompositeConfiguration.java Index: CompositeConfiguration.java =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/CompositeConfiguration.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- CompositeConfiguration.java 13 Mar 2004 17:04:04 -0000 1.10 +++ CompositeConfiguration.java 1 Apr 2004 18:43:04 -0000 1.11 @@ -249,32 +249,6 @@ } /** - * Create a CompositeConfiguration object that is a subset - * of this one. Cycles over all the config objects, and calls - * their subset method and then just adds that. - * - * @param prefix - */ - public Configuration subset(String prefix) - { - CompositeConfiguration subsetCompositeConfiguration = - new CompositeConfiguration(); - Configuration subConf = null; - int count = 0; - for (ListIterator i = configList.listIterator(); i.hasNext();) - { - Configuration config = (Configuration) i.next(); - Configuration subset = config.subset(prefix); - if (subset != null && !subset.isEmpty()) - { - subsetCompositeConfiguration.addConfiguration(subset); - subConf = subset; - count++; - } - } - return (count == 1) ? subConf : subsetCompositeConfiguration; - } - /** * Get a List of strings associated with the given configuration key. * * @param key The configuration key. 1.1 jakarta-commons/configuration/src/java/org/apache/commons/configuration/DOMConfiguration.java Index: DOMConfiguration.java =================================================================== package org.apache.commons.configuration; /* * Copyright 2004 The Apache Software Foundation. * * 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.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.NestableRuntimeException; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Reads a XML configuration file. * * To retrieve the value of an attribute of an element, use * <code>[EMAIL PROTECTED]</code>. The '@' symbol was chosen for * consistency with XPath. * * Setting property values will <b>NOT</b> automatically persist * changes to disk, unless <code>autoSave=true</code>. * * @since commons-configuragtion 1.0 */ public class DOMConfiguration extends XMLConfiguration { // For conformance with xpath private static final char ATTRIB_MARKER = '@'; private static final String ATTRIB_START_MARKER = "[" + ATTRIB_MARKER; /** * For consistency with properties files. Access nodes via an * "A.B.C" notation. */ private static final String NODE_DELIMITER = "."; /** * A handle to our data source. */ private String fileName; /** * The XML document from our data source. */ private Document document; /** * If true, modifications are immediately persisted. */ private boolean autoSave = false; /** * Empty construtor. You must provide a file/fileName * and call the load method * */ public DOMConfiguration() { } /** * Attempts to load the XML file as a resource from the * classpath. The XML file must be located somewhere in the * classpath. * * @param resource Name of the resource * @exception ConfigurationException If error reading data source. * @see DOMConfiguration(String) */ public DOMConfiguration(String resource) throws ConfigurationException { setFile(resourceURLToFile(resource)); load(); } /** * Attempts to load the XML file. * * @param file File object representing the XML file. * @exception ConfigurationException If error reading data source. */ public DOMConfiguration(File file) throws ConfigurationException { setFile(file); load(); } public void load() throws ConfigurationException { File file = null; try { file = new File(getBasePath(), getFileName()); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); document = builder.parse(file); } catch (IOException de) { throw new ConfigurationException("Could not load from " + file.getAbsolutePath()); } catch (ParserConfigurationException ex) { throw new ConfigurationException("Could not configure parser"); } catch (FactoryConfigurationError ex) { throw new ConfigurationException("Could not create parser"); } catch (SAXException ex) { throw new ConfigurationException("Error parsing file " + file.getAbsolutePath()); } initProperties(document.getDocumentElement(), new StringBuffer()); } private static File resourceURLToFile(String resource) { URL confURL = DOMConfiguration.class.getClassLoader().getResource(resource); if (confURL == null) { confURL = ClassLoader.getSystemResource(resource); } return new File(confURL.getFile()); } /** * Loads and initializes from the XML file. * * @param element The element to start processing from. Callers * should supply the root element of the document. * @param hierarchy */ private void initProperties(final Element element, final StringBuffer hierarchy) { final StringBuffer buffer = new StringBuffer(); final NodeList list = element.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { final org.w3c.dom.Node w3cNode = list.item(i); if(w3cNode instanceof Element) { final StringBuffer subhierarchy = new StringBuffer(hierarchy.toString()); final Element child = (Element)w3cNode; subhierarchy.append(child.getTagName()); processAttributes(subhierarchy.toString(), child); initProperties(child, new StringBuffer(subhierarchy.toString()).append('.')); } else if(w3cNode instanceof CharacterData) { final CharacterData data = (CharacterData)w3cNode; buffer.append(data.getData()); } } final String text = buffer.toString().trim(); if (text.length() > 0 && hierarchy.length() > 0) { super.addProperty( hierarchy.substring(0, hierarchy.length()-1), text); } } /** * Helper method for constructing properties for the attributes of the * given XML element. * @param hierarchy the actual hierarchy * @param element the actual XML element */ private void processAttributes(String hierarchy, Element element) { // Add attributes as x.y{ATTRIB_START_MARKER}att{ATTRIB_END_MARKER} final NamedNodeMap attributes = element.getAttributes(); for (int i = 0; i < attributes.getLength(); ++i) { final org.w3c.dom.Node w3cNode = attributes.item(i); if (w3cNode instanceof Attr) { Attr attr = (Attr) w3cNode; String attrName = hierarchy + '[' + ATTRIB_MARKER + attr.getName() + ']'; super.addProperty(attrName, attr.getValue()); } } } /** * Calls super method, and also ensures the underlying [EMAIL PROTECTED] * Document} is modified so changes are persisted when saved. * * @param name * @param value */ public void addProperty(String name, Object value) { super.addProperty(name, value); setXmlProperty(name, value); possiblySave(); } /** * Calls super method, and also ensures the underlying [EMAIL PROTECTED] * Document} is modified so changes are persisted when saved. * * @param name * @param value */ public void setProperty(String name, Object value) { super.setProperty(name, value); setXmlProperty(name, value); possiblySave(); } /** * Sets the property value in our document tree, auto-saving if * appropriate. * * @param name The name of the element to set a value for. * @param value The value to set. */ private void setXmlProperty(String name, Object value) { String[] nodes = StringUtils.split(name, NODE_DELIMITER); String attName = null; Element element = document.getDocumentElement(); for (int i = 0; i < nodes.length; i++) { String eName = nodes[i]; int index = eName.indexOf(ATTRIB_START_MARKER); if (index > -1) { attName = eName.substring(index + ATTRIB_START_MARKER.length(), eName.length() - 1); eName = eName.substring(0, index); } Element child = null; final NodeList list = element.getChildNodes(); for (int j = 0; j < list.getLength(); j++) { final org.w3c.dom.Node w3cNode = list.item(j); if (w3cNode instanceof Element) { child = (Element) w3cNode; if (eName.equals(child.getTagName())) { break; } child = null; } } // If we don't find this part of the property in the XML hierarchy // we add it as a new node if (child == null && attName == null) { child = document.createElement(eName); element.appendChild(child); } element = child; } if (attName == null) { final CharacterData data = document.createTextNode((String) value); element.appendChild(data); } else { element.setAttribute(attName, (String) value); } } /** * Calls super method, and also ensures the underlying [EMAIL PROTECTED] * Document} is modified so changes are persisted when saved. * * @param name The name of the property to clear. */ public void clearProperty(String name) { super.clearProperty(name); clearXmlProperty(name); possiblySave(); } private void clearXmlProperty(String name) { String[] nodes = StringUtils.split(name, NODE_DELIMITER); String attName = null; Element element = null; Element child = document.getDocumentElement(); for (int i = 0; i < nodes.length; i++) { element = child; String eName = nodes[i]; int index = eName.indexOf(ATTRIB_START_MARKER); if (index > -1) { attName = eName.substring(index + ATTRIB_START_MARKER.length(), eName.length() - 1); eName = eName.substring(0, index); } final NodeList list = element.getChildNodes(); for (int j = 0; j < list.getLength(); j++) { final org.w3c.dom.Node w3cNode = list.item(j); if (w3cNode instanceof Element) { child = (Element) w3cNode; if (eName.equals(child.getTagName())) { break; } child = null; } } if (child == null) { return; } } if (attName == null) { element.removeChild(child); } else { child.removeAttribute(attName); } } private void possiblySave() { if (autoSave) { try { save(); } catch (ConfigurationException ce) { throw new NestableRuntimeException("Failed to auto-save", ce); } } } /** * If true, changes are automatically persisted. * @param autoSave */ public void setAutoSave(boolean autoSave) { this.autoSave = autoSave; } public synchronized void save() throws ConfigurationException { FileWriter writer = null; try { writer = new FileWriter(getFile()); writer.write(toString()); } catch (IOException ioe){ throw new ConfigurationException("Could not save to " + getFile()); } finally { try { if (writer != null) { writer.close(); } } catch (IOException ioe) { throw new ConfigurationException(ioe); } } } /** * Returns the file. * @return File */ public File getFile() { return ConfigurationUtils.constructFile(getBasePath(), getFileName()); } /** * Sets the file. * @param file The file to set */ public void setFile(File file) { this.fileName = file.getAbsolutePath(); } public void setFileName(String fileName) { this.fileName = fileName; } /** * Returns the fileName. * @return String */ public String getFileName() { return fileName; } public String toString() { StringBuffer buffer = new StringBuffer(); toXML(document, buffer); return buffer.toString(); } private void toXML(final org.w3c.dom.Node element, final StringBuffer buffer) { final NodeList nodeList = element.getChildNodes(); for (int i=0; i<nodeList.getLength(); i++) { final org.w3c.dom.Node node = nodeList.item(i); if (node instanceof Element) { buffer.append("<" + node.getNodeName()); if (node.hasAttributes()) { final NamedNodeMap map = node.getAttributes(); for (int j = 0; j < map.getLength(); j++) { final Attr attr = (Attr) map.item(j); buffer.append(" " + attr.getName()); buffer.append("=\"" + attr.getValue() + "\""); } } buffer.append(">"); toXML(node, buffer); buffer.append("</" + node.getNodeName() + ">"); } else if(node instanceof CharacterData) { final CharacterData data = (CharacterData)node; buffer.append(data.getData()); } } } } 1.1 jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalDOMConfiguration.java Index: HierarchicalDOMConfiguration.java =================================================================== package org.apache.commons.configuration; /* * Copyright 2004 The Apache Software Foundation. * * 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.net.MalformedURLException; import java.net.URL; import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.NodeList; /** * <p>A specialized hierarchical configuration class that is able to parse * XML documents using DOM.</p> * <p>The parsed document will be stored keeping its structure. The * contained properties can be accessed using all methods supported by * the base class <code>HierarchicalConfiguration</code>. * This class is a direct adaption of the * <code>HierarchicalDOM4JConfiguration</code>. * @author Jörg Schaible * @since commons-configuragtion 1.0 */ public class HierarchicalDOMConfiguration extends HierarchicalConfiguration implements BasePathLoader { /** Stores the file name of the document to be parsed.*/ private String file; /** Stores the base path of this configuration.*/ private String basePath; /** * Constructs a HierarchicalDOMConfiguration. */ public HierarchicalDOMConfiguration() { super(); } /** * Returns the name of the file to be parsed by this object. * @return the file to be parsed */ public String getFileName() { return file; } /** * Sets the name of the file to be parsed by this object. * @param file the file to be parsed */ public void setFileName(final String file) { this.file = file; } /** * Returns the base path. * @return the base path */ public String getBasePath() { return basePath; } /** * Allows to set a base path. Relative file names are resolved based on * this path. * @param path the base path; this can be a URL or a file path */ public void setBasePath(final String path) { basePath = path; } /** * Loads and parses an XML document. The file to be loaded must have * been specified before. * @throws ConfigurationException Thrown if an error occurs */ public void load() throws ConfigurationException { try { load(ConfigurationUtils.getURL(getBasePath(), getFileName())); } catch (MalformedURLException mue) { throw new ConfigurationException( "Could not load from " + getBasePath() + ", " + getFileName()); } } /** * Loads and parses the specified XML document. * @param url the URL to the XML document * @throws ConfigurationException Thrown if an error occurs */ public void load(URL url) throws ConfigurationException { try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); initProperties(builder.parse(url.toExternalForm())); } catch (Exception de) { throw new ConfigurationException("Could not load from " + url); } } /** * Initializes this configuration from an XML document. * @param document the document to be parsed */ public void initProperties(final Document document) { constructHierarchy(getRoot(), document.getDocumentElement()); } /** * Helper method for building the internal storage hierarchy. The XML * elements are transformed into node objects. * @param node the actual node * @param element the actual XML element */ private void constructHierarchy(final Node node, final Element element) { final StringBuffer buffer = new StringBuffer(); final NodeList list = element.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { final org.w3c.dom.Node w3cNode = list.item(i); if (w3cNode instanceof Element) { final Element child = (Element) w3cNode; final Node childNode = new Node(child.getTagName()); constructHierarchy(childNode, child); node.addChild(childNode); processAttributes(childNode, child); } else if (w3cNode instanceof CharacterData) { final CharacterData data = (CharacterData) w3cNode; buffer.append(data.getData()); } } final String text = buffer.toString().trim(); if (text.length() > 0) { node.setValue(text); } } /** * Helper method for constructing node objects for the attributes of the * given XML element. * @param node the actual node * @param element the actual XML element */ private void processAttributes(final Node node, final Element element) { final NamedNodeMap attributes = element.getAttributes(); for (int i = 0; i < attributes.getLength(); ++i) { final org.w3c.dom.Node w3cNode = attributes.item(i); if (w3cNode instanceof Attr) { final Attr attr = (Attr) w3cNode; final Node child = new Node( ConfigurationKey.constructAttributeKey(attr.getName())); child.setValue(attr.getValue()); node.addChild(child); } } } } 1.16 +8 -3 jakarta-commons/configuration/project.xml Index: project.xml =================================================================== RCS file: /home/cvs/jakarta-commons/configuration/project.xml,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- project.xml 1 Apr 2004 18:26:15 -0000 1.15 +++ project.xml 1 Apr 2004 18:43:04 -0000 1.16 @@ -1,11 +1,14 @@ <?xml version="1.0"?> - +<!DOCTYPE project [ + <!ENTITY ouml "ö"> +]> <!-- ===================================================================== --> <!-- --> <!-- $Id$ --> <!-- --> <!-- ===================================================================== --> + <project> <pomVersion>3</pomVersion> <name>commons-configuration</name> @@ -119,9 +122,11 @@ <email>[EMAIL PROTECTED]</email> </contributor> <contributor> - <name>Jorg Schaible</name> + <name>Jörg Schaible</name> <id>jschaible</id> <email>[EMAIL PROTECTED]</email> + <organization>Elsag-Solutions AG</organization> + <timezone>+1</timezone> </contributor> <contributor> <name>Konstantin Shaposhnikov</name>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]