You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2011/05/10 07:47:54 UTC

svn commit: r1101319 - in /commons/proper/configuration/branches/configuration2_experimental/src: changes/changes.xml main/java/org/apache/commons/configuration2/INIConfiguration.java test/java/org/apache/commons/configuration2/TestINIConfiguration.java

Author: oheger
Date: Tue May 10 05:47:54 2011
New Revision: 1101319

URL: http://svn.apache.org/viewvc?rev=1101319&view=rev
Log:
[CONFIGURATION-448] Improved handling of separators in HierarchicalINIConfiguration. Ported fix to configuration2 branch.

Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/changes/changes.xml
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/INIConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestINIConfiguration.java

Modified: commons/proper/configuration/branches/configuration2_experimental/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/changes/changes.xml?rev=1101319&r1=1101318&r2=1101319&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/changes/changes.xml (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/changes/changes.xml Tue May 10 05:47:54 2011
@@ -79,6 +79,10 @@
     </release>
 
     <release version="1.7" date="in SVN" description="">
+      <action dev="oheger" type="add" issue="CONFIGURATION-448">
+        The parsing of ini files has been improved for property definitions
+        containing multiple separator characters.
+      </action>
       <action dev="oheger" type="add" issue="CONFIGURATION-447">
         DefaultConfigurationBuilder now supports including environment properties
         using the "env" tag.

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/INIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/INIConfiguration.java?rev=1101319&r1=1101318&r2=1101319&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/INIConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/INIConfiguration.java Tue May 10 05:47:54 2011
@@ -133,6 +133,10 @@ import org.apache.commons.lang.StringUti
  *  var3 = foo<br>
  *  var4 = bar<br>
  *  var5 = test2<br>
+ *  <br>
+ *  [sectionSeparators]<br>
+ *  passwd : abc=def<br>
+ *  a:b = "value"
  *  </code>
  * </p>
  * <p>
@@ -150,6 +154,15 @@ import org.apache.commons.lang.StringUti
  * <li>Section three uses both '=' and ':' to separate keys and values.</li>
  * <li>Section 3 has a duplicate key named "var5". The value for this key is
  * [test1, test2], and is represented as a List.</li>
+ * <li>The section called <em>sectionSeparators</em> demonstrates how the
+ * configuration deals with multiple occurrences of separator characters. Per
+ * default the first separator character in a line is detected and used to
+ * split the key from the value. Therefore the first property definition in this
+ * section has the key <code>passwd</code> and the value <code>abc=def</code>.
+ * This default behavior can be changed by using quotes. If there is a separator
+ * character before the first quote character (ignoring whitespace), this
+ * character is used as separator. Thus the second property definition in the
+ * section has the key <code>a:b</code> and the value <code>value</code>.</li>
  * </ul>
  * </p>
  * <p>
@@ -200,6 +213,11 @@ public class INIConfiguration extends Ab
     private static final String LINE_SEPARATOR = System.getProperty("line.separator");
 
     /**
+     * The characters used for quoting values.
+     */
+    private static final String QUOTE_CHARACTERS = "\"'";
+
+    /**
      * The line continuation character.
      */
     private static final String LINE_CONT = "\\";
@@ -333,7 +351,7 @@ public class INIConfiguration extends Ab
                     {
                         String key = "";
                         String value = "";
-                        int index = line.indexOf("=");
+                        int index = findSeparator(line);
                         if (index >= 0)
                         {
                             key = line.substring(0, index);
@@ -341,16 +359,7 @@ public class INIConfiguration extends Ab
                         }
                         else
                         {
-                            index = line.indexOf(":");
-                            if (index >= 0)
-                            {
-                                key = line.substring(0, index);
-                                value = parseValue(line.substring(index + 1), bufferedReader);
-                            }
-                            else
-                            {
-                                key = line;
-                            }
+                            key = line;
                         }
                         key = key.trim();
                         if (key.length() < 1)
@@ -541,6 +550,84 @@ public class INIConfiguration extends Ab
     }
 
     /**
+     * Tries to find the index of the separator character in the given string.
+     * This method checks for the presence of separator characters in the given
+     * string. If multiple characters are found, the first one is assumed to be
+     * the correct separator. If there are quoting characters, they are taken
+     * into account, too.
+     *
+     * @param line the line to be checked
+     * @return the index of the separator character or -1 if none is found
+     */
+    private static int findSeparator(String line)
+    {
+        int index =
+                findSeparatorBeforeQuote(line,
+                        findFirstOccurrence(line, QUOTE_CHARACTERS));
+        if (index < 0)
+        {
+            index = findFirstOccurrence(line, SEPARATOR_CHARS);
+        }
+        return index;
+    }
+
+    /**
+     * Checks for the occurrence of the specified separators in the given line.
+     * The index of the first separator is returned.
+     *
+     * @param line the line to be investigated
+     * @param separators a string with the separator characters to look for
+     * @return the lowest index of a separator character or -1 if no separator
+     *         is found
+     */
+    private static int findFirstOccurrence(String line, String separators)
+    {
+        int index = -1;
+
+        for (int i = 0; i < separators.length(); i++)
+        {
+            char sep = separators.charAt(i);
+            int pos = line.indexOf(sep);
+            if (pos >= 0)
+            {
+                if (index < 0 || pos < index)
+                {
+                    index = pos;
+                }
+            }
+        }
+
+        return index;
+    }
+
+    /**
+     * Searches for a separator character directly before a quoting character.
+     * If the first non-whitespace character before a quote character is a
+     * separator, it is considered the "real" separator in this line - even if
+     * there are other separators before.
+     *
+     * @param line the line to be investigated
+     * @param quoteIndex the index of the quote character
+     * @return the index of the separator before the quote or &lt; 0 if there is
+     *         none
+     */
+    private static int findSeparatorBeforeQuote(String line, int quoteIndex)
+    {
+        int index = quoteIndex - 1;
+        while (index >= 0 && Character.isWhitespace(line.charAt(index)))
+        {
+            index--;
+        }
+
+        if (index >= 0 && SEPARATOR_CHARS.indexOf(line.charAt(index)) < 0)
+        {
+            index = -1;
+        }
+
+        return index;
+    }
+
+    /**
      * Add quotes around the specified value if it contains a comment character.
      */
     private String formatValue(String value)

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestINIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestINIConfiguration.java?rev=1101319&r1=1101318&r2=1101319&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestINIConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestINIConfiguration.java Tue May 10 05:47:54 2011
@@ -80,6 +80,16 @@ public class TestINIConfiguration extend
             + "  line 2" + LINE_SEPARATOR
             + "continueNoLine = one \\" + LINE_SEPARATOR;
 
+    private static final String INI_DATA_SEPARATORS = "[section]"
+            + LINE_SEPARATOR + "var1 = value1" + LINE_SEPARATOR
+            + "var2 : value2" + LINE_SEPARATOR
+            + "var3=value3" + LINE_SEPARATOR
+            + "var4:value4" + LINE_SEPARATOR
+            + "var5 : value=5" + LINE_SEPARATOR
+            + "var:6=value" + LINE_SEPARATOR
+            + "var:7=\"value7\"" + LINE_SEPARATOR
+            + "var:8 =  \"value8\"" + LINE_SEPARATOR;
+
     /** An ini file that contains only a property in the global section. */
     private static final String INI_DATA_GLOBAL_ONLY = "globalVar = testGlobal"
             + LINE_SEPARATOR + LINE_SEPARATOR;
@@ -746,4 +756,43 @@ public class TestINIConfiguration extend
                 config.getString("Environment.Class Path"));
         assertEquals("Wrong path", path, config.getString("Environment.Path"));
     }
+
+    /**
+     * Tests whether the different separators with or without whitespace are
+     * recognized.
+     */
+    public void testSeparators() throws ConfigurationException
+    {
+        INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
+        for (int i = 1; i <= 4; i++)
+        {
+            assertEquals("Wrong value", "value" + i,
+                    config.getString("section.var" + i));
+        }
+    }
+
+    /**
+     * Tests property definitions containing multiple separators.
+     */
+    public void testMultipleSeparators() throws ConfigurationException
+    {
+        INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
+        assertEquals("Wrong value for var5", "value=5",
+                config.getString("section.var5"));
+        assertEquals("Wrong value for var6", "6=value",
+                config.getString("section.var"));
+    }
+
+    /**
+     * Tests property definitions containing multiple separators that are
+     * quoted.
+     */
+    public void testMultipleSeparatorsQuoted() throws ConfigurationException
+    {
+        INIConfiguration config = setUpConfig(INI_DATA_SEPARATORS);
+        assertEquals("Wrong value for var7", "value7",
+                config.getString("section.var:7"));
+        assertEquals("Wrong value for var8", "value8",
+                config.getString("section.var:8"));
+    }
 }