epugh 2004/08/14 04:21:27
Modified: configuration/xdocs changes.xml
configuration/conf test.xml testDigesterConfiguration3.xml
configuration/src/java/org/apache/commons/configuration
XMLConfiguration.java
configuration/src/test/org/apache/commons/configuration
TestXMLConfiguration.java
Log:
30234 clearXmlProperty doesn't remove list properties completely. Extended fix.
Revision Changes Path
1.33 +2 -1 jakarta-commons/configuration/xdocs/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- changes.xml 13 Aug 2004 12:07:41 -0000 1.32
+++ changes.xml 14 Aug 2004 11:21:26 -0000 1.33
@@ -6,7 +6,8 @@
</properties>
<body>
- <release version="1.0rc1" date="2004-06-??">
+ <release version="1.0-rc1" date="2004-06-??">
+ <action dev="epugh" type="add" due-to="Oliver Heger"
issue="30597">HierarchicalConfigurationXMLReader stores comments as text
nodes</action>
<action dev="epugh" type="add" due-to="Ricardo Gladwell"
issue="30648">project.xml contains bad dependencies</action>
<action dev="epugh" type="add" due-to="Brent Worden" issue="30234
">clearXmlProperty doesn't remove list properties completely</action>
<action dev="epugh" type="add" due-to="Ricardo Gladwell" issue="30545">new
ConfigurationDynaBean </action>
1.5 +20 -0 jakarta-commons/configuration/conf/test.xml
Index: test.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/configuration/conf/test.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- test.xml 12 Aug 2004 16:53:52 -0000 1.4
+++ test.xml 14 Aug 2004 11:21:26 -0000 1.5
@@ -33,4 +33,24 @@
<item>six</item>
</sublist>
</list>
+
+ <!-- clear tests -->
+ <clear>
+ <element>value</element>
+ <element2 id="element2">value</element2>
+ <comment><!-- this value is commented --></comment>
+ <cdata><![CDATA[<cdata value>]]></cdata>
+ <list>
+ <item id="1">one</item>
+ <item>two</item>
+ <item id="3">three</item>
+ <item>four</item>
+ </list>
+ <list>
+ <item>one</item>
+ <item id="2">two</item>
+ <item>three</item>
+ <item id="4">four</item>
+ </list>
+ </clear>
</configuration>
1.5 +1 -0
jakarta-commons/configuration/conf/testDigesterConfiguration3.xml
Index: testDigesterConfiguration3.xml
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/conf/testDigesterConfiguration3.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- testDigesterConfiguration3.xml 12 Aug 2004 15:45:22 -0000 1.4
+++ testDigesterConfiguration3.xml 14 Aug 2004 11:21:26 -0000 1.5
@@ -3,6 +3,7 @@
<configuration>
<additional>
+ <!--xml format seems to cause configuration factory to die-->
<!--xml fileName="test.xml"/-->
<hierarchicalXml fileName="testDigesterConfigurationInclude1.xml" at="tables"/>
<properties fileName="testDigesterConfigurationInclude2.properties" at="mail"/>
1.9 +163 -24
jakarta-commons/configuration/src/java/org/apache/commons/configuration/XMLConfiguration.java
Index: XMLConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/XMLConfiguration.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- XMLConfiguration.java 12 Aug 2004 15:45:21 -0000 1.8
+++ XMLConfiguration.java 14 Aug 2004 11:21:26 -0000 1.9
@@ -25,6 +25,9 @@
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
@@ -251,6 +254,120 @@
possiblySave();
}
+ public Object getXmlProperty(String name)
+ {
+ // parse the key
+ String[] nodes = parseElementNames(name);
+ String attName = parseAttributeName(name);
+
+ // get all the matching elements
+ ArrayList children = findElementsForPropertyNodes(nodes);
+
+ ArrayList properties = new ArrayList();
+ if (attName == null)
+ {
+ // return text contents of elements
+ Iterator cIter = children.iterator();
+ while (cIter.hasNext())
+ {
+ Element child = (Element)cIter.next();
+ // add non-empty strings
+ String text = getChildText(child);
+ if (StringUtils.isNotEmpty(text)) {
+ properties.add(text);
+ }
+ }
+ }
+ else
+ {
+ // return text contents of attributes
+ Iterator cIter = children.iterator();
+ while (cIter.hasNext())
+ {
+ Element child = (Element)cIter.next();
+ if (child.hasAttribute(attName)) {
+ properties.add(child.getAttribute(attName));
+ }
+ }
+ }
+
+ switch(properties.size()) {
+ case 0:
+ return null;
+ case 1:
+ return properties.get(0);
+ default:
+ return properties;
+ }
+ }
+
+ /**
+ * TODO Add comment.
+ *
+ * @param nodes
+ * @return
+ */
+ private ArrayList findElementsForPropertyNodes(String[] nodes) {
+ ArrayList children = new ArrayList();
+ ArrayList elements = new ArrayList();
+
+ children.add(document.getDocumentElement());
+ for (int i = 0; i < nodes.length; i++)
+ {
+ elements.clear();
+ elements.addAll(children);
+ children.clear();
+
+ String eName = nodes[i];
+ Iterator eIter = elements.iterator();
+ while(eIter.hasNext())
+ {
+ Element element = (Element)eIter.next();
+ NodeList list = element.getChildNodes();
+ for (int j = 0; j < list.getLength(); j++)
+ {
+ Node node = list.item(j);
+ if (node instanceof Element)
+ {
+ Element child = (Element) node;
+ if (eName.equals(child.getTagName()))
+ {
+ children.add(child);
+ }
+ }
+ }
+ }
+ }
+ return children;
+ }
+
+ private static String getChildText(Node node) {
+
+ // is there anything to do?
+ if (node == null) {
+ return null;
+ }
+
+ // concatenate children text
+ StringBuffer str = new StringBuffer();
+ Node child = node.getFirstChild();
+ while (child != null) {
+ short type = child.getNodeType();
+ if (type == Node.TEXT_NODE) {
+ str.append(child.getNodeValue());
+ }
+ else if (type == Node.CDATA_SECTION_NODE) {
+ str.append(child.getNodeValue());
+ }
+ child = child.getNextSibling();
+ }
+
+ // return text value
+ return StringUtils.trimToNull(str.toString());
+
+ } // getChildText(Node):String
+
+
/**
* Calls super method, and also ensures the underlying [EMAIL PROTECTED]
* Document} is modified so changes are persisted when saved.
@@ -392,39 +509,61 @@
String[] nodes = parseElementNames(name);
String attName = parseAttributeName(name);
- Element element = null;
- Element child = document.getDocumentElement();
- for (int i = 0; i < nodes.length; i++)
- {
- element = child;
- String eName = nodes[i];
+ // get all the matching elements
+ ArrayList children = findElementsForPropertyNodes(nodes);
- NodeList list = element.getChildNodes();
- for (int j = 0; j < list.getLength(); j++) {
- Node node = list.item(j);
- if (node instanceof Element)
+ if (attName == null)
+ {
+ // remove children with no subelements
+ Iterator cIter = children.iterator();
+ while (cIter.hasNext())
+ {
+ Element child = (Element)cIter.next();
+
+ // determine if child has subelments
+ boolean hasSubelements = false;
+ Node subchild = child.getFirstChild();
+ while(subchild != null)
{
- child = (Element) node;
- if (eName.equals(child.getTagName()))
+ if (subchild.getNodeType() == Node.ELEMENT_NODE)
{
+ hasSubelements = true;
break;
}
- child = null;
+ subchild = subchild.getNextSibling();
+ }
+
+ if (!hasSubelements)
+ {
+ // safe to remove
+ if (!child.hasAttributes())
+ {
+ // remove entire node
+ Node parent = child.getParentNode();
+ parent.removeChild(child);
+ }
+ else
+ {
+ // only remove node contents
+ subchild = child.getLastChild();
+ while(subchild != null)
+ {
+ child.removeChild(subchild);
+ subchild = child.getLastChild();
+ }
+ }
}
- }
- if (child == null)
- {
- return;
}
}
-
- if (attName == null)
- {
- element.removeChild(child);
- }
else
{
- child.removeAttribute(attName);
+ // remove attributes from children
+ Iterator cIter = children.iterator();
+ while (cIter.hasNext())
+ {
+ Element child = (Element)cIter.next();
+ child.removeAttribute(attName);
+ }
}
}
1.7 +149 -12
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
Index: TestXMLConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestXMLConfiguration.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestXMLConfiguration.java 12 Aug 2004 16:53:52 -0000 1.6
+++ TestXMLConfiguration.java 14 Aug 2004 11:21:27 -0000 1.7
@@ -17,6 +17,7 @@
package org.apache.commons.configuration;
import java.io.File;
+import java.io.IOException;
import java.util.List;
import java.util.Iterator;
@@ -57,15 +58,128 @@
assertEquals("1<2", conf.getProperty("test.entity"));
}
- public void testClearProperty()
+ public void testClearProperty() throws ConfigurationException, IOException
{
- conf.clearProperty("element");
- assertEquals("element", null, conf.getProperty("element"));
+ // test non-existent element
+ String key = "clearly";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
- conf.clearProperty("list.item");
- assertEquals("list.item", null, conf.getProperty("list.item"));
+ // test single element
+ conf.load();
+ key = "clear.element";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+
+ // test single element with attribute
+ conf.load();
+ key = "clear.element2";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+ key = "[EMAIL PROTECTED]";
+ assertNotNull(key, conf.getProperty(key));
+ assertNotNull(key, conf.getXmlProperty(key));
+
+ // test non-text/cdata element
+ conf.load();
+ key = "clear.comment";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+
+ // test cdata element
+ conf.load();
+ key = "clear.cdata";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+
+ // test multiple sibling elements
+ conf.load();
+ key = "clear.list.item";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+ key = "[EMAIL PROTECTED]";
+ assertNotNull(key, conf.getProperty(key));
+ assertNotNull(key, conf.getXmlProperty(key));
+
+ // test multiple, disjoined elements
+ conf.load();
+ key = "list.item";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
}
+ public void testGetXmlProperty() {
+ // test non-leaf element
+ Object property = conf.getXmlProperty("clear");
+ assertNull(property);
+
+ // test non-existent element
+ property = conf.getXmlProperty("e");
+ assertNull(property);
+
+ // test non-existent element
+ property = conf.getXmlProperty("[EMAIL PROTECTED]");
+ assertNull(property);
+
+ // test single element
+ property = conf.getXmlProperty("element");
+ assertNotNull(property);
+ assertTrue(property instanceof String);
+ assertEquals("value", property);
+
+ // test single attribute
+ property = conf.getXmlProperty("[EMAIL PROTECTED]");
+ assertNotNull(property);
+ assertTrue(property instanceof String);
+ assertEquals("foo", property);
+
+ // test non-text/cdata element
+ property = conf.getXmlProperty("test.comment");
+ assertNull(property);
+
+ // test cdata element
+ property = conf.getXmlProperty("test.cdata");
+ assertNotNull(property);
+ assertTrue(property instanceof String);
+ assertEquals("<cdata value>", property);
+
+ // test multiple sibling elements
+ property = conf.getXmlProperty("list.sublist.item");
+ assertNotNull(property);
+ assertTrue(property instanceof List);
+ List list = (List)property;
+ assertEquals(2, list.size());
+ assertEquals("five", list.get(0));
+ assertEquals("six", list.get(1));
+
+ // test multiple, disjoined elements
+ property = conf.getXmlProperty("list.item");
+ assertNotNull(property);
+ assertTrue(property instanceof List);
+ list = (List)property;
+ assertEquals(4, list.size());
+ assertEquals("one", list.get(0));
+ assertEquals("two", list.get(1));
+ assertEquals("three", list.get(2));
+ assertEquals("four", list.get(3));
+
+ // test multiple, disjoined attributes
+ property = conf.getXmlProperty("[EMAIL PROTECTED]");
+ assertNotNull(property);
+ assertTrue(property instanceof List);
+ list = (List)property;
+ assertEquals(2, list.size());
+ assertEquals("one", list.get(0));
+ assertEquals("three", list.get(1));
+ }
+
public void testGetAttribute() throws Exception
{
assertEquals("[EMAIL PROTECTED]", "foo", conf.getProperty("[EMAIL
PROTECTED]"));
@@ -73,8 +187,33 @@
public void testClearAttribute() throws Exception
{
- conf.clearProperty("[EMAIL PROTECTED]");
- assertEquals("[EMAIL PROTECTED]", null, conf.getProperty("[EMAIL
PROTECTED]"));
+ // test non-existent attribute
+ String key = "[EMAIL PROTECTED]";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+
+ // test single attribute
+ conf.load();
+ key = "[EMAIL PROTECTED]";
+ Object p = conf.getXmlProperty(key);
+ p = conf.getXmlProperty("clear.element2");
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+ key = "clear.element2";
+ assertNotNull(key, conf.getProperty(key));
+ assertNotNull(key, conf.getXmlProperty(key));
+
+ // test multiple, disjoined attributes
+ conf.load();
+ key = "[EMAIL PROTECTED]";
+ conf.clearProperty(key);
+ assertNull(key, conf.getProperty(key));
+ assertNull(key, conf.getXmlProperty(key));
+ key = "clear.list.item";
+ assertNotNull(key, conf.getProperty(key));
+ assertNotNull(key, conf.getXmlProperty(key));
}
public void testSetAttribute() throws Exception
@@ -175,18 +314,17 @@
conf.addProperty("string", "value1");
for (int i = 1; i < 5; i++)
{
- // conf.addProperty("test.array", "value" + i);
+ conf.addProperty("test.array", "value" + i);
}
// add an array of strings in an attribute
for (int i = 1; i < 5; i++)
{
- // conf.addProperty("[EMAIL PROTECTED]", "value" + i);
+ conf.addProperty("[EMAIL PROTECTED]", "value" + i);
}
// save the configuration
conf.save(testSaveConf.getAbsolutePath());
- System.out.println("fulldir: " + testSaveConf.getAbsolutePath());
// read the configuration and compare the properties
XMLConfiguration checkConfig = new XMLConfiguration();
@@ -197,7 +335,6 @@
{
String key = (String) i.next();
assertTrue("The saved configuration doesn't contain the key '" + key +
"'", checkConfig.containsKey(key));
- System.out.println(conf.getProperty(key).getClass().getName() + ":" +
checkConfig.getProperty(key).getClass().getName());
assertEquals("Value of the '" + key + "' property",
conf.getProperty(key), checkConfig.getProperty(key));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]