Author: hlship
Date: Mon May 31 17:55:51 2010
New Revision: 949821

URL: http://svn.apache.org/viewvc?rev=949821&view=rev
Log:
Add method mapcat() to the Flow interface

Modified:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/ConcatFlow.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/Flow.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/MappedFlow.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/func/FuncTest.java

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/AbstractFlow.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/AbstractFlow.java
 Mon May 31 17:55:51 2010
@@ -140,6 +140,22 @@ abstract class AbstractFlow<T> implement
         return accumulator;
     }
 
+    public <X> Flow<X> mapcat(Mapper<T, Flow<X>> mapper)
+    {
+        Flow<Flow<X>> flows = map(mapper);
+
+        if (flows.isEmpty())
+            return F.emptyFlow();
+
+        return flows.rest().reduce(new Reducer<Flow<X>, Flow<X>>()
+        {
+            public Flow<X> reduce(Flow<X> accumulator, Flow<X> value)
+            {
+                return accumulator.concat(value);
+            }
+        }, flows.first());
+    }
+
     public Flow<T> remove(Predicate<? super T> predicate)
     {
         Defense.notNull(predicate, "predicate");

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/ConcatFlow.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/ConcatFlow.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/ConcatFlow.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/ConcatFlow.java
 Mon May 31 17:55:51 2010
@@ -22,6 +22,7 @@ package org.apache.tapestry5.func;
  */
 class ConcatFlow<T> extends AbstractFlow<T>
 {
+    // All instance variables are guarded by this
     private Flow<T> firstFlow;
 
     private Flow<T> secondFlow;

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/EmptyFlow.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/EmptyFlow.java
 Mon May 31 17:55:51 2010
@@ -59,10 +59,9 @@ class EmptyFlow<T> extends AbstractFlow<
     }
 
     /** Does nothing; returns this empty list (as a Flow<X>). */
-    @SuppressWarnings("unchecked")
     public <X> Flow<X> map(Mapper<T, X> mapper)
     {
-        return (Flow<X>) this;
+        return F.emptyFlow();
     }
 
     /** Does nothing; returns the initial value. */
@@ -102,4 +101,9 @@ class EmptyFlow<T> extends AbstractFlow<
         return (Flow<T>) other;
     }
 
+    public <X> Flow<X> mapcat(Mapper<T, Flow<X>> mapper)
+    {
+        return F.emptyFlow();
+    }
+
 }

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/Flow.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/Flow.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/Flow.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/Flow.java
 Mon May 31 17:55:51 2010
@@ -36,6 +36,12 @@ public interface Flow<T> extends Iterabl
     <X> Flow<X> map(Mapper<T, X> mapper);
 
     /**
+     * Given a {...@link Mapper} that maps a T to a Flow<X>, this method will 
lazily concatenate
+     * all the output flows into a single Flow<X>.
+     */
+    <X> Flow<X> mapcat(Mapper<T, Flow<X>> mapper);
+
+    /**
      * Filters values, keeping only values where the predicate is true, 
returning a new Flow with just
      * the retained values.
      */

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/MappedFlow.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/MappedFlow.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/MappedFlow.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/func/MappedFlow.java
 Mon May 31 17:55:51 2010
@@ -24,6 +24,7 @@ class MappedFlow<T, X> extends AbstractF
     private final Mapper<T, X> mapper;
 
     // Used to determine first, rest
+    // Guarded by this
     private Flow<T> mappedFlow;
 
     // Guarded by this

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/func/FuncTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/func/FuncTest.java?rev=949821&r1=949820&r2=949821&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/func/FuncTest.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/func/FuncTest.java
 Mon May 31 17:55:51 2010
@@ -588,4 +588,36 @@ public class FuncTest extends TestUtils
             }
         }, initial), initial);
     }
+
+    private Mapper<Integer, Flow<Integer>> sequencer = new Mapper<Integer, 
Flow<Integer>>()
+    {
+
+        public Flow<Integer> map(Integer value)
+        {
+            Flow<Integer> flow = F.flow();
+
+            for (int i = 0; i < value; i++)
+                flow = flow.append(value);
+
+            return flow;
+        }
+    };
+
+    @Test
+    public void mapcat_on_empty_flow_is_empty()
+    {
+        Flow<Integer> flow = F.flow();
+
+        assertSame(flow.mapcat(sequencer), flow);
+
+        assertTrue(filteredEmpty.mapcat(sequencer).isEmpty());
+    }
+
+    @Test
+    public void mapcat()
+    {
+        Flow<Integer> flow = F.flow(3, 1, 2);
+
+        assertListsEquals(flow.mapcat(sequencer).toList(), 3, 3, 3, 1, 2, 2);
+    }
 }


Reply via email to