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 &quot;flatten&quot;).</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 &quot;flat&quot; 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));


Reply via email to