Author: oheger
Date: Mon Jan 21 13:44:38 2008
New Revision: 614023
URL: http://svn.apache.org/viewvc?rev=614023&view=rev
Log:
Provided a new implementation of PropertyConverter.toIterator() that does not
depend on commons-collections
Modified:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/PropertyConverter.java
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestPropertyConverter.java
Modified:
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/PropertyConverter.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/PropertyConverter.java?rev=614023&r1=614022&r2=614023&view=diff
==============================================================================
---
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/PropertyConverter.java
(original)
+++
commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/PropertyConverter.java
Mon Jan 21 13:44:38 2008
@@ -35,12 +35,10 @@
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
+import java.util.LinkedList;
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;
import org.apache.commons.lang.SystemUtils;
@@ -80,7 +78,7 @@
*/
private PropertyConverter()
{
- // to prevent instanciation...
+ // to prevent instantiation...
}
/**
@@ -861,66 +859,101 @@
}
/**
- * Return an iterator over the simple values of a composite value. The
value
- * specified is handled depending on its type:
+ * Returns an iterator over the simple values of a composite value. This
+ * implementation calls <code>[EMAIL PROTECTED] #flatten(Object,
char)}</code> and
+ * returns an iterator over the returned collection.
+ *
+ * @param value the value to "split"
+ * @param delimiter the delimiter for String values
+ * @return an iterator for accessing the single values
+ */
+ public static Iterator<Object> toIterator(Object value, char delimiter)
+ {
+ return flatten(value, delimiter).iterator();
+ }
+
+ /**
+ * Returns a collection with all values contained in the specified object.
+ * This method is used for instance by the <code>addProperty()</code>
+ * implementation of the default configurations to gather all values of the
+ * property to add. Depending on the type of the passed in object the
+ * following things happen:
* <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>
+ * <li>Strings are checked for delimiter characters and split if
necessary.</li>
+ * <li>For objects implementing the <code>Iterable</code> interface, the
+ * corresponding <code>Iterator</code> is obtained, and contained elements
+ * are added to the resulting collection.</li>
+ * <li>Arrays are treated as <code>Iterable</code> objects.</li>
+ * <li>All other types are directly inserted.</li>
+ * <li>Recursive combinations are supported, e.g. a collection containing
+ * an array that contains strings: The resulting collection will only
+ * contain primitive objects (hence the name "flatten").</li>
* </ul>
*
- * @param value the value to "split"
+ * @param value the value to be processed
* @param delimiter the delimiter for String values
- * @return an iterator for accessing the single values
+ * @return a "flat" collection containing all primitive values of
+ * the passed in object
*/
- public static Iterator toIterator(Object value, char delimiter)
+ public static Collection<Object> flatten(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);
+ return split((String) s, delimiter);
}
}
- else if (value instanceof Collection)
+
+ Collection<Object> result = new LinkedList<Object>();
+ if (value instanceof Iterable)
{
- return toIterator(((Collection) value).iterator(), delimiter);
+ flattenIterator(result, ((Iterable<?>) value).iterator(),
delimiter);
}
- else if (value.getClass().isArray())
+ else if (value instanceof Iterator)
{
- return toIterator(IteratorUtils.arrayIterator(value), delimiter);
+ flattenIterator(result, (Iterator<?>) value, delimiter);
}
- else if (value instanceof Iterator)
+ else if (value != null)
{
- Iterator iterator = (Iterator) value;
- IteratorChain chain = new IteratorChain();
- while (iterator.hasNext())
+ if (value.getClass().isArray())
+ {
+ for (int len = Array.getLength(value), idx = 0; idx < len;
idx++)
+ {
+ result.addAll(flatten(Array.get(value, idx), delimiter));
+ }
+ }
+ else
{
- chain.addIterator(toIterator(iterator.next(), delimiter));
+ result.add(value);
}
- return chain;
}
- else
+
+ return result;
+ }
+
+ /**
+ * Flattens the given iterator. For each element in the iteration
+ * <code>flatten()</code> will be called recursively.
+ *
+ * @param target the target collection
+ * @param it the iterator to process
+ * @param delimiter the delimiter for String values
+ */
+ private static void flattenIterator(Collection<Object> target,
+ Iterator<?> it, char delimiter)
+ {
+ while (it.hasNext())
{
- return new SingletonIterator(value);
+ target.addAll(flatten(it.next(), delimiter));
}
}
/**
* Performs interpolation of the specified value. This method checks if the
* given value contains variables of the form <code>${...}</code>. If
- * this is the case, all occurrances will be substituted by their current
+ * this is the case, all occurrences will be substituted by their current
* values.
*
* @param value the value to be interpolated
Modified:
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestPropertyConverter.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestPropertyConverter.java?rev=614023&r1=614022&r2=614023&view=diff
==============================================================================
---
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestPropertyConverter.java
(original)
+++
commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestPropertyConverter.java
Mon Jan 21 13:44:38 2008
@@ -19,6 +19,9 @@
import java.lang.reflect.Method;
import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -37,6 +40,9 @@
*/
public class TestPropertyConverter extends TestCase
{
+ /** An array with test values for the flatten test.*/
+ private static final Integer[] FLATTEN_VALUES = { 1, 2, 3, 4, 5, 6, 28 };
+
public void testSplit()
{
String s = "abc, xyz , 123";
@@ -119,6 +125,95 @@
}
/**
+ * Tests flattening an array of values.
+ */
+ public void testFlattenArray()
+ {
+ checkFlattenResult(PropertyConverter.flatten(FLATTEN_VALUES, ','));
+ }
+
+ /**
+ * Tests flattening a collection.
+ */
+ public void testFlattenCollection()
+ {
+ checkFlattenResult(PropertyConverter.flatten(Arrays
+ .asList(FLATTEN_VALUES), ','));
+ }
+
+ /**
+ * Tests flattening an iterator.
+ */
+ public void testFlattenIterator()
+ {
+ checkFlattenResult(PropertyConverter.flatten(Arrays.asList(
+ FLATTEN_VALUES).iterator(), ','));
+ }
+
+ /**
+ * Tests flattening a comma delimited string.
+ */
+ public void testFlattenString()
+ {
+ StringBuilder buf = new StringBuilder();
+ for (Integer val : FLATTEN_VALUES)
+ {
+ if (buf.length() > 0)
+ {
+ buf.append(',');
+ }
+ buf.append(val);
+ }
+ checkFlattenResult(PropertyConverter.flatten(buf.toString(), ','));
+ }
+
+ /**
+ * Tests flattening a null value.
+ */
+ public void testFlattenNull()
+ {
+ assertTrue("Result collection not empty", PropertyConverter.flatten(
+ null, ',').isEmpty());
+ }
+
+ /**
+ * Tests the flatten() method with a complex mixed input.
+ */
+ public void testFlattenMixed()
+ {
+ Collection<Object> data = new ArrayList<Object>();
+ data.add(1);
+ data.add("2,3");
+ Object[] ar = new Object[2];
+ ar[0] = 4;
+ Collection<Object> data2 = new ArrayList<Object>();
+ data2.add("5");
+ data2.add(new Object[] {
+ 6, "28"
+ });
+ ar[1] = data2;
+ data.add(ar);
+ checkFlattenResult(PropertyConverter.flatten(data, ','));
+ }
+
+ /**
+ * Tests the result of a flatten operation.
+ *
+ * @param col the resulting collection
+ */
+ private void checkFlattenResult(Collection<Object> col)
+ {
+ assertEquals("Wrong number of elements", FLATTEN_VALUES.length, col
+ .size());
+ Iterator<Object> it = col.iterator();
+ for (Integer val : FLATTEN_VALUES)
+ {
+ assertEquals("Wrong value in result", val.toString(), String
+ .valueOf(it.next()));
+ }
+ }
+
+ /**
* Tests the interpolation features.
*/
public void testInterpolateString()
@@ -346,7 +441,7 @@
{
return;
}
-
+
try
{
assertEquals(enumObject, PropertyConverter.toEnum(new Integer(-1),
enumClass));