commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ohe...@apache.org
Subject svn commit: r202006 - in /jakarta/commons/proper/configuration/trunk: conf/ src/java/org/apache/commons/configuration/ src/test/org/apache/commons/configuration/ xdocs/
Date Mon, 27 Jun 2005 16:30:56 GMT
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: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message