You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2007/05/08 22:55:43 UTC
svn commit: r536326 - in /jakarta/commons/proper/configuration/trunk:
conf/test.xml src/java/org/apache/commons/configuration/XMLConfiguration.java
src/test/org/apache/commons/configuration/TestXMLConfiguration.java
xdocs/changes.xml
Author: oheger
Date: Tue May 8 13:55:42 2007
New Revision: 536326
URL: http://svn.apache.org/viewvc?view=rev&rev=536326
Log:
CONFIGURATION-268: Perform correct splitting and escaping when delimiter parsing is disabled for XMLConfiguration
Modified:
jakarta/commons/proper/configuration/trunk/conf/test.xml
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
Modified: jakarta/commons/proper/configuration/trunk/conf/test.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/conf/test.xml?view=diff&rev=536326&r1=536325&r2=536326
==============================================================================
--- jakarta/commons/proper/configuration/trunk/conf/test.xml (original)
+++ jakarta/commons/proper/configuration/trunk/conf/test.xml Tue May 8 13:55:42 2007
@@ -85,4 +85,9 @@
<a name="y">1,2,3</a>
<a name="u,v,w" test="yes">value1,value2</a>
</attrList>
+
+ <!-- An attribute with multiple values and escape characters for testing
+ splitting when delimiter parsing is disabled.
+ -->
+ <expressions value="a \|\| (b && c)|!d"/>
</testconfig>
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java?view=diff&rev=536326&r1=536325&r2=536326
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/XMLConfiguration.java Tue May 8 13:55:42 2007
@@ -40,7 +40,6 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.collections.iterators.SingletonIterator;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.DOMException;
@@ -93,6 +92,35 @@
* <code>cite</code> element the comma is escaped, so that no splitting is
* performed.</p>
*
+ * <p>The configuration API allows setting multiple values for a single attribute,
+ * e.g. something like the following is legal (assuming that the default
+ * expression engine is used):
+ * <pre>
+ * XMLConfiguration config = new XMLConfiguration();
+ * config.addProperty("test.dir[@name]", "C:\\Temp\\");
+ * config.addProperty("test.dir[@name]", "D:\\Data\\");
+ * </pre></p>
+ *
+ * <p>Because in XML such a constellation is not directly supported (an attribute
+ * can appear only once for a single element), the values are concatenated to a
+ * single value. If delimiter parsing is enabled (refer to the
+ * <code>{@link #setDelimiterParsingDisabled(boolean)}</code> method), the
+ * current list delimiter character will be used as separator. Otherwise the
+ * pipe symbol ("|") will be used for this purpose. No matter which character is
+ * used as delimiter, it can always be escaped with a backslash. A backslash
+ * itself can also be escaped with another backslash. Consider the following
+ * example fragment from a configuration file:
+ * <pre>
+ * <directories names="C:\Temp\\|D:\Data\"/>
+ * </pre>
+ * Here the backslash after Temp is escaped. This is necessary because it
+ * would escape the list delimiter (the pipe symbol assuming that list delimiter
+ * parsing is disabled) otherwise. So this attribute would have two values.</p>
+ *
+ * <p>Note: You should ensure that the <em>delimiter parsing disabled</em>
+ * property is always consistent when you load and save a configuration file.
+ * Otherwise the values of properties can become corrupted.</p>
+ *
* <p><code>XMLConfiguration</code> implements the <code>{@link FileConfiguration}</code>
* interface and thus provides full support for loading XML documents from
* different sources like files, URLs, or streams. A full description of these
@@ -102,7 +130,7 @@
* @since commons-configuration 1.0
*
* @author Jörg Schaible
- * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger </a>
+ * @author Oliver Heger
* @version $Revision$, $Date$
*/
public class XMLConfiguration extends AbstractHierarchicalFileConfiguration
@@ -115,6 +143,9 @@
/** Constant for the default root element name. */
private static final String DEFAULT_ROOT_NAME = "configuration";
+ /** Constant for the delimiter for multiple attribute values.*/
+ private static final char ATTR_VALUE_DELIMITER = '|';
+
/** The document from this configuration's data source. */
private Document document;
@@ -432,15 +463,10 @@
if (w3cNode instanceof Attr)
{
Attr attr = (Attr) w3cNode;
- Iterator it;
- if (isDelimiterParsingDisabled())
- {
- it = new SingletonIterator(attr.getValue());
- }
- else
- {
- it = PropertyConverter.split(attr.getValue(), getListDelimiter()).iterator();
- }
+ Iterator it = PropertyConverter.split(
+ attr.getValue(),
+ isDelimiterParsingDisabled() ? ATTR_VALUE_DELIMITER
+ : getListDelimiter()).iterator();
while (it.hasNext())
{
Node child = new XMLNode(attr.getName(),
@@ -570,7 +596,8 @@
document = newDocument;
}
- XMLBuilderVisitor builder = new XMLBuilderVisitor(document, getListDelimiter());
+ XMLBuilderVisitor builder = new XMLBuilderVisitor(document,
+ isDelimiterParsingDisabled() ? (char) 0 : getListDelimiter());
builder.processDocument(getRoot());
return document;
} /* try */
@@ -966,8 +993,12 @@
Element elem = document.createElement(newNode.getName());
if (newNode.getValue() != null)
{
- elem.appendChild(document.createTextNode(
- PropertyConverter.escapeDelimiters(newNode.getValue().toString(), listDelimiter)));
+ String txt = newNode.getValue().toString();
+ if (listDelimiter != 0)
+ {
+ txt = PropertyConverter.escapeDelimiters(txt, listDelimiter);
+ }
+ elem.appendChild(document.createTextNode(txt));
}
if (sibling2 == null)
{
@@ -992,7 +1023,7 @@
* @param node the affected node
* @param elem the element that is associated with this node
* @param name the name of the affected attribute
- * @param listDelimiter the delimiter vor attributes with multiple values
+ * @param listDelimiter the delimiter for attributes with multiple values
*/
private static void updateAttribute(Node node, Element elem, String name, char listDelimiter)
{
@@ -1000,6 +1031,7 @@
{
List attrs = node.getAttributes(name);
StringBuffer buf = new StringBuffer();
+ char delimiter = (listDelimiter != 0) ? listDelimiter : ATTR_VALUE_DELIMITER;
for (Iterator it = attrs.iterator(); it.hasNext();)
{
Node attr = (Node) it.next();
@@ -1007,10 +1039,10 @@
{
if (buf.length() > 0)
{
- buf.append(listDelimiter);
+ buf.append(delimiter);
}
buf.append(PropertyConverter.escapeDelimiters(attr
- .getValue().toString(), getDefaultListDelimiter()));
+ .getValue().toString(), delimiter));
}
attr.setReference(elem);
}
Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?view=diff&rev=536326&r1=536325&r2=536326
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java Tue May 8 13:55:42 2007
@@ -1062,6 +1062,76 @@
}
/**
+ * Tests saving and loading a configuration when delimiter parsing is
+ * disabled.
+ */
+ public void testSaveDelimiterParsingDisabled()
+ throws ConfigurationException
+ {
+ checkSaveDelimiterParsingDisabled("list.delimiter.test");
+ }
+
+ /**
+ * Tests saving and loading a configuration when delimiter parsing is
+ * disabled and attributes are involved.
+ */
+ public void testSaveDelimiterParsingDisabledAttrs()
+ throws ConfigurationException
+ {
+ checkSaveDelimiterParsingDisabled("list.delimiter.test[@attr]");
+ }
+
+ /**
+ * Helper method for testing saving and loading a configuration when
+ * delimiter parsing is disabled.
+ *
+ * @param key the key to be checked
+ * @throws ConfigurationException if an error occurs
+ */
+ private void checkSaveDelimiterParsingDisabled(String key)
+ throws ConfigurationException
+ {
+ conf.clear();
+ conf.setDelimiterParsingDisabled(true);
+ conf.load();
+ conf.setProperty(key, "C:\\Temp\\,C:\\Data\\");
+ conf.addProperty(key, "a,b,c");
+ conf.save(testSaveConf);
+ XMLConfiguration checkConf = new XMLConfiguration();
+ checkConf.setDelimiterParsingDisabled(true);
+ checkConf.setFile(testSaveConf);
+ checkSavedConfig(checkConf);
+ }
+
+ /**
+ * Tests multiple attribute values in delimiter parsing disabled mode.
+ */
+ public void testDelimiterParsingDisabledMultiAttrValues() throws ConfigurationException
+ {
+ conf.clear();
+ conf.setDelimiterParsingDisabled(true);
+ conf.load();
+ List expr = conf.getList("expressions[@value]");
+ assertEquals("Wrong list size", 2, expr.size());
+ assertEquals("Wrong element 1", "a || (b && c)", expr.get(0));
+ assertEquals("Wrong element 2", "!d", expr.get(1));
+ }
+
+ /**
+ * Tests using multiple attribute values, which are partly escaped when
+ * delimiter parsing is not disabled.
+ */
+ public void testMultipleAttrValuesEscaped() throws ConfigurationException
+ {
+ conf.addProperty("test.dir[@name]", "C:\\Temp\\");
+ conf.addProperty("test.dir[@name]", "C:\\Data\\");
+ conf.save(testSaveConf);
+ XMLConfiguration checkConf = new XMLConfiguration();
+ checkConf.setFile(testSaveConf);
+ checkSavedConfig(checkConf);
+ }
+
+ /**
* Prepares a configuration object for testing a reload operation.
*
* @return the initialized configuration
Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?view=diff&rev=536326&r1=536325&r2=536326
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Tue May 8 13:55:42 2007
@@ -23,6 +23,12 @@
<body>
<release version="1.5-SNAPSHOT" date="in SVN" description="">
+ <action dev="oheger" type="update" issue="CONFIGURATION-268">
+ When delimiter parsing was disabled for XMLConfiguration, saving and
+ loading the configuration accidently added escape characters to properties
+ containing the list delimiter character. This has been fixed. It is now
+ also possible to escape the escape character itself.
+ </action>
<action dev="oheger" type="update" issue="CONFIGURATION-253">
The return value of FileConfiguration.getFile() is now always
consistent with the result of getURL().
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org