Author: davsclaus
Date: Tue May 31 15:29:20 2011
New Revision: 1129757

URL: http://svn.apache.org/viewvc?rev=1129757&view=rev
Log:
CAMEL-4033: Added copy option to loop EIP.

Added:
    
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopCopyTest.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java
   (contents, props changed)
      - copied, changed from r1129681, 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopTest.java
    
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopCopyTest.scala
      - copied, changed from r1129681, 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopTest.scala
    
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopNoCopyTest.scala
    
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopCopyTest.java
      - copied, changed from r1129681, 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopTest.java
    
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopNoCopyTest.java
    
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopCopyTest.xml
      - copied, changed from r1129681, 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/loop.xml
    
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/model/NodeFactory.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LoopProcessor.java
    
camel/trunk/components/camel-scala/src/main/scala/org/apache/camel/scala/dsl/SLoopDefinition.scala

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java?rev=1129757&r1=1129756&r2=1129757&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java 
(original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java 
Tue May 31 15:29:20 2011
@@ -18,6 +18,7 @@ package org.apache.camel.model;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.camel.Expression;
@@ -35,6 +36,9 @@ import org.apache.camel.spi.RouteContext
 @XmlAccessorType(XmlAccessType.FIELD)
 public class LoopDefinition extends ExpressionNode {
 
+    @XmlAttribute
+    private Boolean copy;
+
     public LoopDefinition() {
     }
 
@@ -46,12 +50,37 @@ public class LoopDefinition extends Expr
         super(expression);
     }
 
+    /**
+     * Enables copy mode so a copy of the input Exchange is used for each 
iteration.
+     * That means each iteration will start from a copy of the same message.
+     * <p/>
+     * By default loop will loop the same exchange all over, so each iteration 
may
+     * have different message content.
+     *
+     * @return the builder
+     */
+    public LoopDefinition copy() {
+        setCopy(true);
+        return this;
+    }
+
     public void setExpression(Expression expr) {
-        if (expr != null) {
-            setExpression(new ExpressionDefinition(expr));
-        }
+        setExpression(new ExpressionDefinition(expr));
     }
-    
+
+    public Boolean getCopy() {
+        return copy;
+    }
+
+    public void setCopy(Boolean copy) {
+        this.copy = copy;
+    }
+
+    public boolean isCopy() {
+        // do not copy by default to be backwards compatible
+        return copy != null ? copy : false;
+    }
+
     @Override
     public String toString() {
         return "Loop[" + getExpression() + " -> " + getOutputs() + "]";
@@ -65,7 +94,7 @@ public class LoopDefinition extends Expr
     @Override
     public Processor createProcessor(RouteContext routeContext) throws 
Exception {
         Processor output = this.createChildProcessor(routeContext, true);
-        return new 
LoopProcessor(getExpression().createExpression(routeContext), output);
+        return new LoopProcessor(output, 
getExpression().createExpression(routeContext), isCopy());
     }
     
 }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/NodeFactory.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/NodeFactory.java?rev=1129757&r1=1129756&r2=1129757&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/NodeFactory.java 
(original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/model/NodeFactory.java 
Tue May 31 15:29:20 2011
@@ -24,6 +24,8 @@ package org.apache.camel.model;
  */
 public class NodeFactory {
 
+    // TODO: Make this as SPI interface and add the other createXXX methods
+
     public FilterDefinition createFilter() {
         return new FilterDefinition();
     }

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LoopProcessor.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LoopProcessor.java?rev=1129757&r1=1129756&r2=1129757&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LoopProcessor.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LoopProcessor.java
 Tue May 31 15:29:20 2011
@@ -29,17 +29,17 @@ import org.slf4j.LoggerFactory;
 
 /**
  * The processor which sends messages in a loop.
- *
- * @version 
  */
 public class LoopProcessor extends DelegateAsyncProcessor implements Traceable 
{
     private static final Logger LOG = 
LoggerFactory.getLogger(LoopProcessor.class);
 
     private final Expression expression;
+    private final boolean copy;
 
-    public LoopProcessor(Expression expression, Processor processor) {
+    public LoopProcessor(Processor processor, Expression expression, boolean 
copy) {
         super(processor);
         this.expression = expression;
+        this.copy = copy;
     }
 
     @Override
@@ -60,6 +60,8 @@ public class LoopProcessor extends Deleg
             return true;
         }
 
+        Exchange target = exchange;
+
         // set the size before we start
         exchange.setProperty(Exchange.LOOP_SIZE, count);
 
@@ -67,24 +69,24 @@ public class LoopProcessor extends Deleg
         while (index.get() < count.get()) {
 
             // and prepare for next iteration
-            ExchangeHelper.prepareOutToIn(exchange);
-            boolean sync = process(exchange, callback, index, count);
+            target = prepareExchange(exchange, index.get());
+            boolean sync = process(target, callback, index, count);
 
             if (!sync) {
-                LOG.trace("Processing exchangeId: {} is continued being 
processed asynchronously", exchange.getExchangeId());
+                LOG.trace("Processing exchangeId: {} is continued being 
processed asynchronously", target.getExchangeId());
                 // the remainder of the routing slip will be completed async
                 // so we break out now, then the callback will be invoked 
which then continue routing from where we left here
                 return false;
             }
 
-            LOG.trace("Processing exchangeId: {} is continued being processed 
synchronously", exchange.getExchangeId());
+            LOG.trace("Processing exchangeId: {} is continued being processed 
synchronously", target.getExchangeId());
 
             // increment counter before next loop
             index.getAndIncrement();
         }
 
         // we are done so prepare the result
-        ExchangeHelper.prepareOutToIn(exchange);
+        ExchangeHelper.copyResults(exchange, target);
         LOG.trace("Processing complete for exchangeId: {} >>> {}", 
exchange.getExchangeId(), exchange);
         callback.done(true);
         return true;
@@ -104,6 +106,8 @@ public class LoopProcessor extends Deleg
                     return;
                 }
 
+                Exchange target = exchange;
+
                 // increment index as we have just processed once
                 index.getAndIncrement();
 
@@ -111,12 +115,12 @@ public class LoopProcessor extends Deleg
                 while (index.get() < count.get()) {
 
                     // and prepare for next iteration
-                    ExchangeHelper.prepareOutToIn(exchange);
+                    target = prepareExchange(exchange, index.get());
 
                     // process again
-                    boolean sync = process(exchange, callback, index, count);
+                    boolean sync = process(target, callback, index, count);
                     if (!sync) {
-                        LOG.trace("Processing exchangeId: {} is continued 
being processed asynchronously", exchange.getExchangeId());
+                        LOG.trace("Processing exchangeId: {} is continued 
being processed asynchronously", target.getExchangeId());
                         // the remainder of the routing slip will be completed 
async
                         // so we break out now, then the callback will be 
invoked which then continue routing from where we left here
                         return;
@@ -127,7 +131,7 @@ public class LoopProcessor extends Deleg
                 }
 
                 // we are done so prepare the result
-                ExchangeHelper.prepareOutToIn(exchange);
+                ExchangeHelper.copyResults(exchange, target);
                 LOG.trace("Processing complete for exchangeId: {} >>> {}", 
exchange.getExchangeId(), exchange);
                 callback.done(false);
             }
@@ -136,16 +140,33 @@ public class LoopProcessor extends Deleg
         return sync;
     }
 
-    @Override
-    public String toString() {
-        return "Loop[for: " + expression + " times do: " + getProcessor() + 
"]";
+    /**
+     * Prepares the exchange for the next iteration
+     *
+     * @param exchange the exchange
+     * @param index the index of the next iteration
+     * @return the exchange to use
+     */
+    protected Exchange prepareExchange(Exchange exchange, int index) {
+        if (copy) {
+            // create a correlated copy, and do not handover completions on 
copies
+            return ExchangeHelper.createCorrelatedCopy(exchange, false);
+        } else {
+            ExchangeHelper.prepareOutToIn(exchange);
+            return exchange;
+        }
+    }
+
+    public Expression getExpression() {
+        return expression;
     }
 
     public String getTraceLabel() {
         return "loop[" + expression + "]";
     }
 
-    public Expression getExpression() {
-        return expression;
+    @Override
+    public String toString() {
+        return "Loop[for: " + expression + " times do: " + getProcessor() + 
"]";
     }
 }

Added: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopCopyTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopCopyTest.java?rev=1129757&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopCopyTest.java
 (added)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopCopyTest.java
 Tue May 31 15:29:20 2011
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class LoopCopyTest extends ContextTestSupport {
+
+    public void testLoopCopy() throws Exception {
+        getMockEndpoint("mock:loop").expectedBodiesReceived("AB", "AB", "AB");
+        getMockEndpoint("mock:result").expectedBodiesReceived("AB");
+
+        template.sendBody("direct:start", "A");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                from("direct:start")
+                    // instruct loop to use copy mode, which mean it will use 
a copy of the input exchange
+                    // for each loop iteration, instead of keep using the same 
exchange all over
+                    .loop(3).copy()
+                        .transform(body().append("B"))
+                        .to("mock:loop")
+                    .end()
+                    .to("mock:result");
+                // END SNIPPET: e1
+            }
+        };
+    }
+}

Copied: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java
 (from r1129681, 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopTest.java)
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopTest.java&r1=1129681&r2=1129757&rev=1129757&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopTest.java 
(original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java
 Tue May 31 15:29:20 2011
@@ -17,87 +17,37 @@
 package org.apache.camel.processor;
 
 import org.apache.camel.ContextTestSupport;
-import org.apache.camel.Processor;
-import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 
 /**
  * @version 
  */
-public class LoopTest extends ContextTestSupport {
-    MockEndpoint resultEndpoint;
+public class LoopNoCopyTest extends ContextTestSupport {
 
-    public void testCounterLoop() throws Exception {
-        performLoopTest("direct:a", 8);
-    }
-
-    public void testExpressionLoop() throws Exception {
-        performLoopTest("direct:b", 6);
-    }
-
-    public void testExpressionClauseLoop() throws Exception {
-        performLoopTest("direct:c", 4);
-    }
-
-    public void testLoopAsBlock() throws Exception {
-        MockEndpoint lastEndpoint = resolveMandatoryEndpoint("mock:last", 
MockEndpoint.class);
-        lastEndpoint.expectedMessageCount(1);
-        performLoopTest("direct:d", 2);
-        lastEndpoint.assertIsSatisfied();
-    }
-
-    public void testLoopWithInvalidExpression() throws Exception {
-        try {
-            performLoopTest("direct:b", 4, "invalid");
-            fail("Exception expected for invalid expression");
-        } catch (RuntimeCamelException e) {
-            // expected
-        }
-    }
-
-    public void testLoopProperties() throws Exception {
-        performLoopTest("direct:e", 10);
-    }
+    public void testLoopNoCopy() throws Exception {
+        getMockEndpoint("mock:loop").expectedBodiesReceived("AB", "ABB", 
"ABBB");
+        getMockEndpoint("mock:result").expectedBodiesReceived("ABBB");
 
-    private void performLoopTest(String endpointUri, int expectedIterations, 
String header) throws InterruptedException {
-        resultEndpoint.expectedMessageCount(expectedIterations);
-        template.sendBodyAndHeader(endpointUri, "<hello 
times='4'>world!</hello>", "loop", header);
-        resultEndpoint.assertIsSatisfied();
-    }
+        template.sendBody("direct:start", "A");
 
-    private void performLoopTest(String endpointUri, int expectedIterations) 
throws InterruptedException {
-        performLoopTest(endpointUri, expectedIterations, "6");
+        assertMockEndpointsSatisfied();
     }
 
     @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        resultEndpoint = resolveMandatoryEndpoint("mock:result", 
MockEndpoint.class);
-        resultEndpoint.reset();
-    }
-
-    protected RouteBuilder createRouteBuilder() {
-        final Processor loopTest = new LoopTestProcessor(10);
-
+    protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
-            public void configure() {
-                // START SNIPPET: ex1
-                from("direct:a").loop(8).to("mock:result");
-                // END SNIPPET: ex1
-                // START SNIPPET: ex2
-                from("direct:b").loop(header("loop")).to("mock:result");
-                // END SNIPPET: ex2
-                // START SNIPPET: ex3
-                
from("direct:c").loop().xpath("/hello/@times").to("mock:result");
-                // END SNIPPET: ex3
-                // START SNIPPET: ex4
-                
from("direct:d").loop(2).to("mock:result").end().to("mock:last");
-                // END SNIPPET: ex4
-                // START SNIPPET: ex5
-                from("direct:e").loop(10).process(loopTest).to("mock:result");
-                // END SNIPPET: ex5
+            @Override
+            public void configure() throws Exception {
+                // START SNIPPET: e1
+                from("direct:start")
+                    // by default loop will keep using the same exchange so on 
the 2nd and 3rd iteration its
+                    // the same exchange that was previous used that are being 
looped all over
+                    .loop(3)
+                        .transform(body().append("B"))
+                        .to("mock:loop")
+                    .end()
+                    .to("mock:result");
+                // END SNIPPET: e1
             }
         };
     }

Propchange: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LoopNoCopyTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
camel/trunk/components/camel-scala/src/main/scala/org/apache/camel/scala/dsl/SLoopDefinition.scala
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-scala/src/main/scala/org/apache/camel/scala/dsl/SLoopDefinition.scala?rev=1129757&r1=1129756&r2=1129757&view=diff
==============================================================================
--- 
camel/trunk/components/camel-scala/src/main/scala/org/apache/camel/scala/dsl/SLoopDefinition.scala
 (original)
+++ 
camel/trunk/components/camel-scala/src/main/scala/org/apache/camel/scala/dsl/SLoopDefinition.scala
 Tue May 31 15:29:20 2011
@@ -23,5 +23,7 @@ import org.apache.camel.scala.dsl.builde
  * Scala enrichment for Camel's LoopDefinition
  */
 case class SLoopDefinition(override val target: LoopDefinition)(implicit val 
builder: RouteBuilder) extends SAbstractDefinition[LoopDefinition] {
- 
+
+    def copy() = wrap(target.copy())
+
 }

Copied: 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopCopyTest.scala
 (from r1129681, 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopTest.scala)
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopCopyTest.scala?p2=camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopCopyTest.scala&p1=camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopTest.scala&r1=1129681&r2=1129757&rev=1129757&view=diff
==============================================================================
--- 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopTest.scala
 (original)
+++ 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopCopyTest.scala
 Tue May 31 15:29:20 2011
@@ -1,3 +1,5 @@
+package org.apache.camel.scala.dsl
+
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -14,54 +16,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.scala.dsl;
- 
 import builder.RouteBuilder
 
 /**
  * Test for looping from the Scala DSL
  */
-class LoopTest extends ScalaTestSupport {
+class LoopCopyTest extends ScalaTestSupport {
 
-  def testSimpleStaticLoop() = doTestLoopStatic("direct:a", "mock:a")
-  def testSimpleDynamicLoop() = doTestLoopDynamic("direct:b", "mock:b")
-  def testBlockStaticLoop() = doTestLoopStatic("direct:c", "mock:c")
-  def testBlockDynamicLoop() = doTestLoopDynamic("direct:d", "mock:d")
-  
-  def doTestLoopStatic(from: String, mock: String) = {
-    mock expect {_.count = 5}
-    test {
-      from ! ("ping")
-    }    
-  }
-  
-  def doTestLoopDynamic(from: String, mock: String) = {
-    mock expect {_.count = 5}
-    test {
-      from ! ("5")
-    }    
+  def testLoopCopy() {
+      getMockEndpoint("mock:loop").expectedBodiesReceived("AB", "AB", "AB")
+      getMockEndpoint("mock:result").expectedBodiesReceived("AB")
+
+      template.sendBody("direct:start", "A")
+
+      assertMockEndpointsSatisfied()
   }
-  
-    
+
   val builder = new RouteBuilder {
-     //START SNIPPET: simple
-     "direct:a" loop(5) to "mock:a"
-     "direct:b" loop(_.in) to "mock:b"
-     //END SNIPPET: simple
-     
-     //START SNIPPET: block
-     "direct:c" ==> {
-       loop(5) {
-         to("mock:c")
-       }
-     }
-     "direct:d" ==> {
-       loop(_.in) {
-         to("mock:d")
+     "direct:start" ==> {
+       loop(3).copy() {
+         transform(simple("${body}B"))
+         to("mock:loop")
        }
+       to("mock:result")
      }
-     //START SNIPPET: block
    }
+
 }
 
 

Added: 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopNoCopyTest.scala
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopNoCopyTest.scala?rev=1129757&view=auto
==============================================================================
--- 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopNoCopyTest.scala
 (added)
+++ 
camel/trunk/components/camel-scala/src/test/scala/org/apache/camel/scala/dsl/LoopNoCopyTest.scala
 Tue May 31 15:29:20 2011
@@ -0,0 +1,47 @@
+package org.apache.camel.scala.dsl
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import builder.RouteBuilder
+
+/**
+ * Test for looping from the Scala DSL
+ */
+class LoopNoCopyTest extends ScalaTestSupport {
+
+  def testLoopNoCopy() {
+      getMockEndpoint("mock:loop").expectedBodiesReceived("AB", "ABB", "ABBB")
+      getMockEndpoint("mock:result").expectedBodiesReceived("ABBB")
+
+      template.sendBody("direct:start", "A")
+
+      assertMockEndpointsSatisfied()
+  }
+
+  val builder = new RouteBuilder {
+     "direct:start" ==> {
+       loop(3) {
+         transform(simple("${body}B"))
+         to("mock:loop")
+       }
+       to("mock:result")
+     }
+   }
+
+}
+
+

Copied: 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopCopyTest.java
 (from r1129681, 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopTest.java)
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopCopyTest.java?p2=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopCopyTest.java&p1=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopTest.java&r1=1129681&r2=1129757&rev=1129757&view=diff
==============================================================================
--- 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopTest.java
 (original)
+++ 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopCopyTest.java
 Tue May 31 15:29:20 2011
@@ -17,16 +17,17 @@
 package org.apache.camel.spring.processor;
 
 import org.apache.camel.CamelContext;
-import org.apache.camel.processor.LoopTest;
+import org.apache.camel.processor.LoopCopyTest;
 
 import static 
org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
 
 /**
  * @version 
  */
-public class SpringLoopTest extends LoopTest {
+public class SpringLoopCopyTest extends LoopCopyTest {
+
     @Override
     protected CamelContext createCamelContext() throws Exception {
-        return createSpringCamelContext(this, 
"org/apache/camel/spring/processor/loop.xml");
+        return createSpringCamelContext(this, 
"org/apache/camel/spring/processor/SpringLoopCopyTest.xml");
     }
 }

Added: 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopNoCopyTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopNoCopyTest.java?rev=1129757&view=auto
==============================================================================
--- 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopNoCopyTest.java
 (added)
+++ 
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLoopNoCopyTest.java
 Tue May 31 15:29:20 2011
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.LoopNoCopyTest;
+
+import static 
org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ * @version 
+ */
+public class SpringLoopNoCopyTest extends LoopNoCopyTest {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        return createSpringCamelContext(this, 
"org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml");
+    }
+}

Copied: 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopCopyTest.xml
 (from r1129681, 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/loop.xml)
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopCopyTest.xml?p2=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopCopyTest.xml&p1=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/loop.xml&r1=1129681&r2=1129757&rev=1129757&view=diff
==============================================================================
--- 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/loop.xml
 (original)
+++ 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopCopyTest.xml
 Tue May 31 15:29:20 2011
@@ -23,62 +23,20 @@
     ">
 
   <camelContext xmlns="http://camel.apache.org/schema/spring";>
-    <!-- START SNIPPET: ex1 -->
+    <!-- START SNIPPET: e1 -->
     <route>
-      <from uri="direct:a"/>
-      <loop>
-        <constant>8</constant>
-        <to uri="mock:result"/>
+      <from uri="direct:start"/>
+      <!-- enable copy mode for loop eip -->
+      <loop copy="true">
+        <constant>3</constant>
+        <transform>
+          <simple>${body}B</simple>
+        </transform>
+        <to uri="mock:loop"/>
       </loop>
+      <to uri="mock:result"/>
     </route>
-    <!-- END SNIPPET: ex1 -->
- 
-    <!-- START SNIPPET: ex2 -->
-    <route>
-      <from uri="direct:b"/>
-      <loop>
-        <header>loop</header>
-        <to uri="mock:result"/>
-      </loop>
-    </route>
-    <!-- END SNIPPET: ex2 -->
- 
-    <!-- START SNIPPET: ex3 -->        
-    <route>
-      <from uri="direct:c"/>
-      <loop>
-        <xpath>/hello/@times</xpath>
-        <to uri="mock:result"/>
-      </loop>
-    </route>
-    <!-- END SNIPPET: ex3 -->
-
-    <!-- START SNIPPET: ex4 -->        
-    <route>
-      <from uri="direct:d"/>
-      <loop>
-        <constant>2</constant>
-        <to uri="mock:result"/>
-      </loop>
-      <to uri="mock:last"/>
-    </route>
-    <!-- END SNIPPET: ex4 -->
-    
-    <!-- START SNIPPET: ex5 -->        
-    <route>
-      <from uri="direct:e"/>
-      <loop>
-        <constant>10</constant>
-        <process ref="myProcessor"/>
-        <to uri="mock:result"/>
-      </loop>
-    </route>
-    <!-- END SNIPPET: ex5 -->
-        
+    <!-- END SNIPPET: e1 -->
   </camelContext>
-  
-  <bean id="myProcessor" class="org.apache.camel.processor.LoopTestProcessor">
-    <constructor-arg index="0" value="10"/>
-  </bean>
-  
+
 </beans>

Added: 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml?rev=1129757&view=auto
==============================================================================
--- 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml
 (added)
+++ 
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/SpringLoopNoCopyTest.xml
 Tue May 31 15:29:20 2011
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+  <camelContext xmlns="http://camel.apache.org/schema/spring";>
+    <!-- START SNIPPET: e1 -->
+    <route>
+      <from uri="direct:start"/>
+      <loop>
+        <constant>3</constant>
+        <transform>
+          <simple>${body}B</simple>
+        </transform>
+        <to uri="mock:loop"/>
+      </loop>
+      <to uri="mock:result"/>
+    </route>
+    <!-- END SNIPPET: e1 -->
+  </camelContext>
+
+</beans>


Reply via email to