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]