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/09 22:35:24 UTC
svn commit: r1101212 - in /commons/proper/configuration/trunk/src:
changes/changes.xml
java/org/apache/commons/configuration/HierarchicalINIConfiguration.java
test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java
Author: oheger
Date: Mon May 9 20:35:24 2011
New Revision: 1101212
URL: http://svn.apache.org/viewvc?rev=1101212&view=rev
Log:
[CONFIGURATION-448] Improved handling of separators in HierarchicalINIConfiguration.
Modified:
commons/proper/configuration/trunk/src/changes/changes.xml
commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalINIConfiguration.java
commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java
Modified: commons/proper/configuration/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/changes/changes.xml?rev=1101212&r1=1101211&r2=1101212&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/changes/changes.xml (original)
+++ commons/proper/configuration/trunk/src/changes/changes.xml Mon May 9 20:35:24 2011
@@ -23,6 +23,10 @@
<body>
<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/trunk/src/java/org/apache/commons/configuration/HierarchicalINIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalINIConfiguration.java?rev=1101212&r1=1101211&r2=1101212&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalINIConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalINIConfiguration.java Mon May 9 20:35:24 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>
@@ -208,6 +221,11 @@ public class HierarchicalINIConfiguratio
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 = "\\";
@@ -347,7 +365,7 @@ public class HierarchicalINIConfiguratio
{
String key = "";
String value = "";
- int index = line.indexOf("=");
+ int index = findSeparator(line);
if (index >= 0)
{
key = line.substring(0, index);
@@ -355,16 +373,7 @@ public class HierarchicalINIConfiguratio
}
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)
@@ -557,6 +566,84 @@ public class HierarchicalINIConfiguratio
}
/**
+ * 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 < 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/trunk/src/test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java?rev=1101212&r1=1101211&r2=1101212&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestHierarchicalINIConfiguration.java Mon May 9 20:35:24 2011
@@ -76,6 +76,16 @@ public class TestHierarchicalINIConfigur
+ " 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;
@@ -704,6 +714,45 @@ public class TestHierarchicalINIConfigur
}
/**
+ * Tests whether the different separators with or without whitespace are
+ * recognized.
+ */
+ public void testSeparators() throws ConfigurationException
+ {
+ HierarchicalINIConfiguration 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
+ {
+ HierarchicalINIConfiguration 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
+ {
+ HierarchicalINIConfiguration 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"));
+ }
+
+ /**
* A thread class for testing concurrent access to the global section.
*/
private static class GlobalSectionTestThread extends Thread