ebourg 2004/12/14 09:03:51
Modified: configuration/src/java/org/apache/commons/configuration
AbstractConfiguration.java
HierarchicalConfiguration.java
MapConfiguration.java PropertyConverter.java
configuration/src/test/org/apache/commons/configuration
TestBaseConfiguration.java
TestBaseNullConfiguration.java
configuration/xdocs changes.xml
Added: configuration/src/test/org/apache/commons/configuration
TestPropertyConverter.java
Removed: configuration/src/test/org/apache/commons/configuration
TestPropertiesTokenizer.java
Log:
Replaced the PropertyTokenizer inner class in AbstractConfiguration with the
split method in PropertyConverter.
Also moved the method building an iterator on the elements of a composite
value in PropertyConverter as toIterator().
Revision Changes Path
1.31 +4 -144
jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractConfiguration.java
Index: AbstractConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractConfiguration.java,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- AbstractConfiguration.java 13 Dec 2004 16:40:14 -0000 1.30
+++ AbstractConfiguration.java 14 Dec 2004 17:03:49 -0000 1.31
@@ -19,18 +19,13 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Properties;
-import java.util.StringTokenizer;
-import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.iterators.FilterIterator;
-import org.apache.commons.collections.iterators.IteratorChain;
-import org.apache.commons.collections.iterators.SingletonIterator;
import org.apache.commons.lang.BooleanUtils;
/**
@@ -55,9 +50,6 @@
/** The property delimiter used while parsing (a comma). */
private static char DELIMITER = ',';
- /** how big the initial arraylist for splitting up name value pairs */
- private static final int INITIAL_LIST_SIZE = 2;
-
/**
* Whether the configuration should throw NoSuchElementExceptions or
simply
* return null when a property does not exist. Defaults to return null.
@@ -108,69 +100,16 @@
/**
* [EMAIL PROTECTED]
*/
- public void addProperty(String key, Object token)
+ public void addProperty(String key, Object value)
{
- for (Iterator it = fetchInsertIterator(token); it.hasNext();)
+ Iterator it = PropertyConverter.toIterator(value, DELIMITER);
+ while (it.hasNext())
{
addPropertyDirect(key, it.next());
}
}
/**
- * Determines all properties to be added to this configuration. This
method
- * is called by <code>addProperty()</code> and <code>setProperty()</code>
- * to obtain all values to be inserted. The passed in token is specially
- * treated depending on its type: <ul><li>Strings are checked for
- * enumeration characters and splitted if necessary.</li><li>For
- * collections the single elements are checked.</li><li>Arrays are
- * treated like collections.</li><li>All other types are directly
- * inserted.</li><li>Recursive combinations are supported, e.g. a
- * collection containing array that contain strings.</li></ul>
- *
- * @param token the token to be checked
- * @return an iterator for the values to be inserted
- */
- protected Iterator fetchInsertIterator(Object token)
- {
- if (token == null)
- {
- return IteratorUtils.emptyIterator();
- }
- if (token instanceof String)
- {
- return split((String) token).iterator();
- }
- else if (token instanceof Collection)
- {
- return fetchInsertIterator(((Collection) token).iterator());
- }
- else if (token.getClass().isArray())
- {
- return fetchInsertIterator(IteratorUtils.arrayIterator(token));
- }
- else
- {
- return new SingletonIterator(token);
- }
- }
-
- /**
- * Recursivle fetches an insert iterator if the token itself is a
composite.
- *
- * @param iterator the iterator to be processed
- * @return a chain iterator for all elements
- */
- private Iterator fetchInsertIterator(Iterator iterator)
- {
- IteratorChain itResult = new IteratorChain();
- while (iterator.hasNext())
- {
- itResult.addIterator(fetchInsertIterator(iterator.next()));
- }
- return itResult;
- }
-
- /**
* Adds a key/value pair to the Configuration. Override this method to
* provide write acces to underlying Configuration store.
*
@@ -283,41 +222,6 @@
}
/**
- * Returns a List of Strings built from the supplied String. Splits up
CSV
- * lists. If no commas are in the String, simply returns a List with the
- * String as its first element.
- *
- * @param token The String to tokenize
- *
- * @return A List of Strings
- */
- protected List split(String token)
- {
- List list = new ArrayList(INITIAL_LIST_SIZE);
-
- if (token.indexOf(DELIMITER) > 0)
- {
- PropertiesTokenizer tokenizer = new PropertiesTokenizer(token);
-
- while (tokenizer.hasMoreTokens())
- {
- list.add(tokenizer.nextToken());
- }
- }
- else
- {
- list.add(token);
- }
-
- //
- // We keep the sequence of the keys here and
- // we also keep it in the List. So the
- // keys are added to the store in the sequence that
- // is given in the properties
- return list;
- }
-
- /**
* [EMAIL PROTECTED]
*/
public Configuration subset(String prefix)
@@ -341,7 +245,7 @@
public void setProperty(String key, Object value)
{
clearProperty(key);
- addProperty(key, value); // QUESTION: or addPropertyDirect?
+ addProperty(key, value);
}
/**
@@ -1002,49 +906,5 @@
}
return value;
}
-
- /**
- * This class divides into tokens a property value. Token separator is
","
- * but commas into the property value are escaped using the backslash in
- * front.
- */
- static class PropertiesTokenizer extends StringTokenizer
- {
- /**
- * Constructor.
- *
- * @param string A String.
- */
- public PropertiesTokenizer(String string)
- {
- super(string, String.valueOf(DELIMITER));
- }
-
- /**
- * Get next token.
- *
- * @return A String.
- */
- public String nextToken()
- {
- StringBuffer buffer = new StringBuffer();
-
- while (hasMoreTokens())
- {
- String token = super.nextToken();
- if (token.endsWith("\\"))
- {
- buffer.append(token.substring(0, token.length() - 1));
- buffer.append(DELIMITER);
- }
- else
- {
- buffer.append(token);
- break;
- }
- }
- return buffer.toString().trim();
- }
- } // class PropertiesTokenizer
}
1.16 +1 -1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
Index: HierarchicalConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- HierarchicalConfiguration.java 13 Dec 2004 16:40:13 -0000 1.15
+++ HierarchicalConfiguration.java 14 Dec 2004 17:03:50 -0000 1.16
@@ -365,7 +365,7 @@
public void setProperty(String key, Object value)
{
Iterator itNodes = fetchNodeList(key).iterator();
- Iterator itValues = fetchInsertIterator(value);
+ Iterator itValues = PropertyConverter.toIterator(value,
getDelimiter());
while (itNodes.hasNext() && itValues.hasNext())
{
((Node) itNodes.next()).setValue(itValues.next());
1.3 +3 -3
jakarta-commons/configuration/src/java/org/apache/commons/configuration/MapConfiguration.java
Index: MapConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/MapConfiguration.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MapConfiguration.java 2 Dec 2004 22:05:52 -0000 1.2
+++ MapConfiguration.java 14 Dec 2004 17:03:50 -0000 1.3
@@ -17,8 +17,8 @@
package org.apache.commons.configuration;
import java.util.Iterator;
-import java.util.Map;
import java.util.List;
+import java.util.Map;
/**
* A Map based Configuration.
@@ -57,7 +57,7 @@
Object value = map.get(key);
if (value instanceof String)
{
- List list = split((String) value);
+ List list = PropertyConverter.split((String) value,
getDelimiter());
return list.size() > 1 ? list : value;
}
else
1.3 +105 -16
jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertyConverter.java
Index: PropertyConverter.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertyConverter.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PropertyConverter.java 18 Oct 2004 10:44:31 -0000 1.2
+++ PropertyConverter.java 14 Dec 2004 17:03:50 -0000 1.3
@@ -25,10 +25,15 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.iterators.IteratorChain;
+import org.apache.commons.collections.iterators.SingletonIterator;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
@@ -384,13 +389,14 @@
}
else if (value instanceof String)
{
- String[] elements = split((String) value, "_");
+ List elements = split((String) value, '_');
+ int size = elements.size();
- if (elements.length >= 1 && (elements[0].length() == 2 ||
elements[0].length() == 0))
+ if (size >= 1 && (((String) elements.get(0)).length() == 2 ||
((String) elements.get(0)).length() == 0))
{
- String language = elements[0];
- String country = elements.length >= 2 ? elements[1] : "";
- String variant = elements.length >= 3 ? elements[2] : "";
+ String language = (String) elements.get(0);
+ String country = (String) ((size >= 2) ? elements.get(1) :
"");
+ String variant = (String) ((size >= 3) ? elements.get(2) :
"");
return new Locale(language, country, variant);
}
@@ -406,34 +412,60 @@
}
/**
- * Split a string on the specified separator. To be removed when
+ * Split a string on the specified delimiter. To be removed when
* commons-lang has a better replacement available (Tokenizer?).
*
* todo: replace with a commons-lang equivalent
*
* @param s the string to split
- * @param separator the separator
+ * @param delimiter the delimiter
*/
- private static String[] split(String s, String separator)
+ static List split(String s, char delimiter)
{
if (s == null)
{
- return new String[0];
+ return new ArrayList();
}
List list = new ArrayList();
+ StringBuffer token = new StringBuffer();
int begin = 0;
- while (begin < s.length())
+ int end = 0;
+ while (begin <= s.length())
{
- int index = s.indexOf(separator, begin);
- int end = index != -1 ? index : s.length();
- list.add(s.substring(begin , end));
+ // find the next delimiter
+ int index = s.indexOf(delimiter, end);
- begin = end + 1;
+ // move the end index at the end of the string if the delimiter
is not found
+ end = (index != -1) ? index : s.length();
+
+ // extract the chunk
+ String chunk = s.substring(begin , end);
+
+ if (chunk.endsWith("\\") && end != s.length())
+ {
+ token.append(chunk.substring(0, chunk.length() - 1));
+ token.append(delimiter);
+ }
+ else
+ {
+ // append the chunk to the token
+ token.append(chunk);
+
+ // add the token to the list
+ list.add(token.toString().trim());
+
+ // reset the token
+ token = new StringBuffer();
+ }
+
+ // move to the next chunk
+ end = end + 1;
+ begin = end;
}
- return (String[]) list.toArray(new String[list.size()]);
+ return list;
}
/**
@@ -562,4 +594,61 @@
throw new ConversionException("The value " + value + " can't be
converted to a Calendar");
}
}
+
+ /**
+ * Return an iterator over the simple values of a composite value. The
value
+ * specified is handled depending on its type:
+ * <ul>
+ * <li>Strings are checked for delimiter characters and splitted if
necessary.</li>
+ * <li>For collections the single elements are checked.</li>
+ * <li>Arrays are treated like collections.</li>
+ * <li>All other types are directly inserted.</li>
+ * <li>Recursive combinations are supported, e.g. a collection
containing array that contain strings.</li>
+ * </ul>
+ *
+ * @param value the value to "split"
+ * @param delimiter the delimiter for String values
+ */
+ public static Iterator toIterator(Object value, char delimiter)
+ {
+ if (value == null)
+ {
+ return IteratorUtils.emptyIterator();
+ }
+ if (value instanceof String)
+ {
+ String s = (String) value;
+ if (s.indexOf(delimiter) > 0)
+ {
+ return split((String) value, delimiter).iterator();
+ }
+ else
+ {
+ return new SingletonIterator(value);
+ }
+ }
+ else if (value instanceof Collection)
+ {
+ return toIterator(((Collection) value).iterator(), delimiter);
+ }
+ else if (value.getClass().isArray())
+ {
+ return toIterator(IteratorUtils.arrayIterator(value), delimiter);
+ }
+ else if (value instanceof Iterator)
+ {
+ Iterator iterator = (Iterator) value;
+ IteratorChain chain = new IteratorChain();
+ while (iterator.hasNext())
+ {
+ chain.addIterator(toIterator(iterator.next(), delimiter));
+ }
+ return chain;
+ }
+ else
+ {
+ return new SingletonIterator(value);
+ }
+ }
+
}
1.19 +1 -15
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestBaseConfiguration.java
Index: TestBaseConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestBaseConfiguration.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- TestBaseConfiguration.java 13 Dec 2004 16:40:14 -0000 1.18
+++ TestBaseConfiguration.java 14 Dec 2004 17:03:51 -0000 1.19
@@ -606,20 +606,6 @@
fail("IllegalStateException should have been thrown for looped
property references");
}
- public void testSplit()
- {
- String s1 = "abc,xyz";
- List tokens = config.split(s1);
- assertEquals("number of tokens in '" + s1 + "'", 2, tokens.size());
- assertEquals("1st token for '" + s1 + "'", "abc", tokens.get(0));
- assertEquals("2nd token for '" + s1 + "'", "xyz", tokens.get(1));
-
- String s2 = "abc\\,xyz";
- tokens = config.split(s2);
- assertEquals("number of tokens in '" + s2 + "'", 1, tokens.size());
- assertEquals("1st token for '" + s2 + "'", "abc,xyz", tokens.get(0));
- }
-
public void testGetHexadecimalValue()
{
config.setProperty("number", "0xFF");
1.3 +14 -29
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestBaseNullConfiguration.java
Index: TestBaseNullConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestBaseNullConfiguration.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestBaseNullConfiguration.java 18 Oct 2004 21:38:45 -0000 1.2
+++ TestBaseNullConfiguration.java 14 Dec 2004 17:03:51 -0000 1.3
@@ -1,5 +1,3 @@
-package org.apache.commons.configuration;
-
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
@@ -16,6 +14,8 @@
* limitations under the License.
*/
+package org.apache.commons.configuration;
+
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Iterator;
@@ -34,22 +34,21 @@
*/
public class TestBaseNullConfiguration extends TestCase
{
- protected BaseConfiguration config = null;
+ protected BaseConfiguration config = null;
protected static Class missingElementException =
NoSuchElementException.class;
protected static Class incompatibleElementException =
ConversionException.class;
- protected void setUp()
- throws Exception
- {
- config = new BaseConfiguration();
- config.setThrowExceptionOnMissing(false);
- }
-
- public void testThrowExceptionOnMissing()
- {
- assertFalse("Throw Exception Property is set!",
config.isThrowExceptionOnMissing());
- }
+ protected void setUp() throws Exception
+ {
+ config = new BaseConfiguration();
+ config.setThrowExceptionOnMissing(false);
+ }
+
+ public void testThrowExceptionOnMissing()
+ {
+ assertFalse("Throw Exception Property is set!",
config.isThrowExceptionOnMissing());
+ }
public void testGetProperty()
{
@@ -495,20 +494,6 @@
fail("IllegalStateException should have been thrown for looped
property references");
}
-
- public void testSplit()
- {
- String s1 = "abc,xyz";
- List tokens = config.split(s1);
- assertEquals("number of tokens in '" + s1 + "'", 2, tokens.size());
- assertEquals("1st token for '" + s1 + "'", "abc", tokens.get(0));
- assertEquals("2nd token for '" + s1 + "'", "xyz", tokens.get(1));
-
- String s2 = "abc\\,xyz";
- tokens = config.split(s2);
- assertEquals("number of tokens in '" + s2 + "'", 1, tokens.size());
- assertEquals("1st token for '" + s2 + "'", "abc,xyz", tokens.get(0));
- }
}
1.1
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestPropertyConverter.java
Index: TestPropertyConverter.java
===================================================================
package org.apache.commons.configuration;
import java.util.List;
import java.util.Iterator;
import junit.framework.TestCase;
/**
* @author Emmanuel Bourg
* @version $Revision: 1.1 $, $Date: 2004/12/14 17:03:51 $
*/
public class TestPropertyConverter extends TestCase
{
public void testSplit()
{
String s = "abc, xyz , 123";
List list = PropertyConverter.split(s, ',');
assertEquals("size", 3, list.size());
assertEquals("1st token for '" + s + "'", "abc", list.get(0));
assertEquals("2nd token for '" + s + "'", "xyz", list.get(1));
assertEquals("3rd token for '" + s + "'", "123", list.get(2));
}
public void testSplitWithEscapedSeparator()
{
String s = "abc\\,xyz, 123";
List list = PropertyConverter.split(s, ',');
assertEquals("size", 2, list.size());
assertEquals("1st token for '" + s + "'", "abc,xyz", list.get(0));
assertEquals("2nd token for '" + s + "'", "123", list.get(1));
}
public void testSplitEmptyValues()
{
String s = ",,";
List list = PropertyConverter.split(s, ',');
assertEquals("size", 3, list.size());
assertEquals("1st token for '" + s + "'", "", list.get(0));
assertEquals("2nd token for '" + s + "'", "", list.get(1));
assertEquals("3rd token for '" + s + "'", "", list.get(2));
}
public void testSplitWithEndingSlash()
{
String s = "abc, xyz\\";
List list = PropertyConverter.split(s, ',');
assertEquals("size", 2, list.size());
assertEquals("1st token for '" + s + "'", "abc", list.get(0));
assertEquals("2nd token for '" + s + "'", "xyz\\", list.get(1));
}
public void testSplitNull()
{
List list = PropertyConverter.split(null, ',');
assertNotNull(list);
assertTrue(list.isEmpty());
}
public void testToIterator()
{
int[] array = new int[]{1, 2, 3};
Iterator it = PropertyConverter.toIterator(array, ',');
assertEquals("1st element", new Integer(1), it.next());
assertEquals("2nd element", new Integer(2), it.next());
assertEquals("3rd element", new Integer(3), it.next());
}
}
1.76 +6 -0 jakarta-commons/configuration/xdocs/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -r1.75 -r1.76
--- changes.xml 4 Dec 2004 15:54:07 -0000 1.75
+++ changes.xml 14 Dec 2004 17:03:51 -0000 1.76
@@ -8,6 +8,12 @@
<body>
<release version="1.1-dev" date="in CVS">
+ <action dev="ebourg" type="update">
+ Replaced the PropertyTokenizer inner class in AbstractConfiguration
+ with the split method in PropertyConverter. Also moved the method
+ building an iterator on the elements of a composite value in
+ PropertyConverter as toIterator().
+ </action>
<action dev="oheger" type="fix" issue="30858">
Some cleanup of the handling of the base path in file based
configurations.
The base path is now always taken into account.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]