Author: oheger
Date: Mon Jun 27 09:30:54 2005
New Revision: 202006
URL: http://svn.apache.org/viewcvs?rev=202006&view=rev
Log:
Fix for issue 35509: Correct handling of tags containing a dot in
XMLConfiguration
Modified:
jakarta/commons/proper/configuration/trunk/conf/test.xml
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/ConfigurationKey.java
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestConfigurationKey.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
jakarta/commons/proper/configuration/trunk/xdocs/howto_xml.xml
Modified: jakarta/commons/proper/configuration/trunk/conf/test.xml
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/conf/test.xml?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/conf/test.xml (original)
+++ jakarta/commons/proper/configuration/trunk/conf/test.xml Mon Jun 27
09:30:54 2005
@@ -58,4 +58,11 @@
<item id="4">four</item>
</list>
</clear>
+
+ <!-- Complex property names -->
+ <complexNames>
+ <my.elem>Name with dot
+ <sub.elem>Another dot</sub.elem>
+ </my.elem>
+ </complexNames>
</testconfig>
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/ConfigurationKey.java
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/ConfigurationKey.java?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/ConfigurationKey.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/ConfigurationKey.java
Mon Jun 27 09:30:54 2005
@@ -1,5 +1,5 @@
/*
- * Copyright 2004 The Apache Software Foundation.
+ * Copyright 2004-2005 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.
@@ -41,6 +41,9 @@
{
/** Constant for a property delimiter.*/
public static final char PROPERTY_DELIMITER = '.';
+
+ /** Constant for an escaped delimiter.*/
+ public static final String ESCAPED_DELIMITER = "..";
/** Constant for an attribute start marker.*/
private static final String ATTRIBUTE_START = "[@";
@@ -195,8 +198,11 @@
*/
private boolean hasDelimiter()
{
- return keyBuffer.length() > 0
- && keyBuffer.charAt(keyBuffer.length() - 1) == PROPERTY_DELIMITER;
+ int count = 0;
+ for (int idx = keyBuffer.length() - 1; idx >= 0
+ && keyBuffer.charAt(idx) == PROPERTY_DELIMITER; idx--, count++)
+ ;
+ return count % 2 == 1;
}
/**
@@ -394,13 +400,15 @@
/**
* Helper method for determining the next indices.
+ *
+ * @return the next key part
*/
- private void findNextIndices()
+ private String findNextIndices()
{
startIndex = endIndex;
// skip empty names
while (startIndex < keyBuffer.length()
- && keyBuffer.charAt(startIndex) == PROPERTY_DELIMITER)
+ && keyBuffer.charAt(startIndex) == PROPERTY_DELIMITER)
{
startIndex++;
}
@@ -410,20 +418,57 @@
{
endIndex = keyBuffer.length();
startIndex = endIndex - 1;
+ return keyBuffer.substring(startIndex, endIndex);
}
else
{
- String s = keyBuffer.toString(); // for compatibility
- endIndex = s.indexOf(PROPERTY_DELIMITER, startIndex);
- if (endIndex < 0)
+ return nextKeyPart();
+ }
+ }
+
+ /**
+ * Helper method for extracting the next key part. Takes escaping of
+ * delimiter characters into account.
+ *
+ * @return the next key part
+ */
+ private String nextKeyPart()
+ {
+ StringBuffer key = new StringBuffer(32);
+ int idx = startIndex;
+ int endIdx = keyBuffer.toString().indexOf(ATTRIBUTE_START,
+ startIndex);
+ if (endIdx < 0 || endIdx == startIndex)
+ {
+ endIdx = keyBuffer.length();
+ }
+ boolean found = false;
+
+ while (!found && idx < endIdx)
+ {
+ char c = keyBuffer.charAt(idx);
+ if (c == PROPERTY_DELIMITER)
{
- endIndex = s.indexOf(ATTRIBUTE_START, startIndex);
- if (endIndex < 0 || endIndex == startIndex)
+ // a duplicated delimiter means escaping
+ if (idx == endIdx - 1
+ || keyBuffer.charAt(idx + 1) != PROPERTY_DELIMITER)
{
- endIndex = keyBuffer.length();
+ found = true;
}
+ else
+ {
+ idx++;
+ }
+ }
+ if (!found)
+ {
+ key.append(c);
+ idx++;
}
}
+
+ endIndex = idx;
+ return key.toString();
}
/**
@@ -456,8 +501,7 @@
hasIndex = false;
indexValue = -1;
- findNextIndices();
- String key = keyBuffer.substring(startIndex, endIndex);
+ String key = findNextIndices();
attribute = checkAttribute(key);
if (!attribute)
@@ -614,7 +658,7 @@
*
* @return a clone of this object
*/
- protected Object clone()
+ public Object clone()
{
try
{
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
Mon Jun 27 09:30:54 2005
@@ -1,5 +1,5 @@
/*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Copyright 2001-2005 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.
@@ -957,7 +957,9 @@
length = key.length();
if (getName() != null)
{
- key.append(getName());
+ key.append(StringUtils.replace(getName(), String
+ .valueOf(ConfigurationKey.PROPERTY_DELIMITER),
+ ConfigurationKey.ESCAPED_DELIMITER));
}
}
Modified:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestConfigurationKey.java
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestConfigurationKey.java?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestConfigurationKey.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestConfigurationKey.java
Mon Jun 27 09:30:54 2005
@@ -1,7 +1,7 @@
package org.apache.commons.configuration;
/*
- * Copyright 2002-2004 The Apache Software Foundation.
+ * Copyright 2002-2005 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.
@@ -151,5 +151,20 @@
k2 = new ConfigurationKey("completely.different.key");
kd = k1.differenceKey(k2);
assertEquals(k2, kd);
+ }
+
+ public void testEscapedDelimiters()
+ {
+ ConfigurationKey k = new ConfigurationKey();
+ k.append("my..elem");
+ k.append("trailing..dot..");
+ k.append("strange");
+ assertEquals("my..elem.trailing..dot...strange", k.toString());
+
+ ConfigurationKey.KeyIterator kit = k.iterator();
+ assertEquals("my.elem", kit.nextKey());
+ assertEquals("trailing.dot.", kit.nextKey());
+ assertEquals("strange", kit.nextKey());
+ assertFalse(kit.hasNext());
}
}
Modified:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
---
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
Mon Jun 27 09:30:54 2005
@@ -477,4 +477,13 @@
}
}
}
+
+ /**
+ * Tests access to tag names with delimiter characters.
+ */
+ public void testComplexNames()
+ {
+ assertEquals("Name with dot", conf.getString("complexNames.my..elem"));
+ assertEquals("Another dot",
conf.getString("complexNames.my..elem.sub..elem"));
+ }
}
Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Mon Jun 27
09:30:54 2005
@@ -23,6 +23,10 @@
<body>
<release version="1.2-dev" date="in SVN">
+ <action dev="oheger" type="update" issue="35509">
+ Updated XMLConfiguration to correctly deal with properties containing
+ dots in their names. Such properties could not be accessed before.
+ </action>
<action dev="oheger" type="update" issue="35119">
PropertiesConfiguration's handling of backslash characters at the end
of line was incorrect when there was an even number of trailing
Modified: jakarta/commons/proper/configuration/trunk/xdocs/howto_xml.xml
URL:
http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/xdocs/howto_xml.xml?rev=202006&r1=202005&r2=202006&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/howto_xml.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/howto_xml.xml Mon Jun 27
09:30:54 2005
@@ -390,6 +390,54 @@
<code>HierarchicalConfiguration</code>.
</p>
</subsection>
+ <subsection name="Escaping dot characters in XML tags">
+ <p>
+ In XML the dot character used as delimiter by most
configuration
+ classes is a legal character that can occur in any tag. So the
+ following XML document is completely valid:
+ </p>
+ <source><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<configuration>
+ <test.value>42</test.value>
+ <test.complex>
+ <test.sub.element>many dots</test.sub.element>
+ </test.complex>
+</configuration>
+]]></source>
+ <p>
+ This XML document can be loaded by
<code>XMLConfiguration</code>
+ without trouble, but when we want to access certain properties
+ we face a problem: The configuration claims that it does not
+ store any values for the properties with the keys
+ <code>test.value</code> or
<code>test.complex.test.sub.element</code>!
+ </p>
+ <p>
+ Of course, it is the dot character contained in the property
+ names, which causes this problem. A dot is always interpreted
+ as a delimiter between elements. So given the property key
+ <code>test.value</code> the configuration would look for an
+ element named <code>test</code> and then for a sub element
+ with the name <code>value</code>. To change this behavior it is
+ possible to escape a dot character, thus telling the
configuration
+ that it is really part of an element name. This is simply done
+ by duplicating the dot. So the following statements will return
+ the desired property values:
+ </p>
+ <source><![CDATA[
+int testVal = config.getInt("test..value");
+String complex = config.getString("test..complex.test..sub..element");
+]]></source>
+ <p>
+ Note the duplicated dots whereever the dot does not act as
+ delimiter. This way it is possible to access properties
containing
+ dots in arbitrary combination. However, as you can see, the
+ escaping can be confusing sometimes. So if you have a choice,
+ you should avoid dots in the tag names of your XML
configuration
+ files.
+ </p>
+ </subsection>
</section>
<section name="Union configuration">
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]