You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ch...@apache.org on 2007/11/07 17:20:57 UTC

svn commit: r592806 - in /activemq/camel/trunk/camel-core/src: main/java/org/apache/camel/builder/ main/java/org/apache/camel/model/ main/java/org/apache/camel/processor/ test/java/org/apache/camel/builder/

Author: chirino
Date: Wed Nov  7 08:20:56 2007
New Revision: 592806

URL: http://svn.apache.org/viewvc?rev=592806&view=rev
Log:
Applied patch from CAMEL-202

Added:
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FinallyType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptorType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OtherwiseType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RoutesType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/TryType.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/TryProcessor.java

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java Wed Nov  7 08:20:56 2007
@@ -21,6 +21,7 @@
 import org.apache.camel.Predicate;
 import org.apache.camel.Route;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.ChoiceType;
 import org.apache.camel.model.InterceptType;
 import org.apache.camel.model.OtherwiseType;
 import org.apache.camel.model.ProcessorType;
@@ -130,7 +131,7 @@
      * Applies a route for an interceptor if the given predicate is true
      * otherwise the interceptor route is not applied
      */
-    public OtherwiseType intercept(Predicate predicate) {
+    public ChoiceType intercept(Predicate predicate) {
         return routeCollection.intercept(predicate);
     }
 

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java Wed Nov  7 08:20:56 2007
@@ -80,10 +80,10 @@
     }
 
 
-    public OtherwiseType otherwise() {
+    public ChoiceType otherwise() {
         OtherwiseType answer = new OtherwiseType();
         setOtherwise(answer);
-        return answer;
+        return this;
     }
 
     // Properties

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FilterType.java Wed Nov  7 08:20:56 2007
@@ -30,7 +30,7 @@
  */
 @XmlRootElement(name = "filter")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class FilterType extends ExpressionNode {
+public class FilterType extends ExpressionNode implements Block {
     public FilterType() {
     }
 

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FinallyType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FinallyType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FinallyType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/FinallyType.java Wed Nov  7 08:20:56 2007
@@ -28,7 +28,7 @@
  */
 @XmlRootElement(name = "finally")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class FinallyType extends OutputType<ProcessorType> {
+public class FinallyType extends OutputType<ProcessorType> implements Block {
     @Override
     public String toString() {
         return "Finally[" + getOutputs() + "]";

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptType.java Wed Nov  7 08:20:56 2007
@@ -64,7 +64,7 @@
     /**
      * Applies this interceptor only if the given predicate is true
      */
-    public OtherwiseType when(Predicate predicate) {
+    public ChoiceType when(Predicate predicate) {
         return choice().when(PredicateBuilder.not(predicate)).proceed().otherwise();
 
     }

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptorType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptorType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptorType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/InterceptorType.java Wed Nov  7 08:20:56 2007
@@ -26,6 +26,6 @@
  * @version $Revision: 1.1 $
  */
 @XmlType(name = "interceptorType")
-public abstract class InterceptorType extends OutputType implements Block{
+public abstract class InterceptorType extends OutputType implements Block {
     public abstract DelegateProcessor createInterceptor(RouteContext routeContext) throws Exception;
 }

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OtherwiseType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OtherwiseType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OtherwiseType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/OtherwiseType.java Wed Nov  7 08:20:56 2007
@@ -28,7 +28,7 @@
  */
 @XmlRootElement(name = "otherwise")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class OtherwiseType extends OutputType<ProcessorType> {
+public class OtherwiseType extends OutputType<ProcessorType> implements Block {
 
     @Override
     public String toString() {

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorType.java Wed Nov  7 08:20:56 2007
@@ -68,6 +68,7 @@
     private DelegateProcessor lastInterceptor;
     private NodeFactory nodeFactory;
     private LinkedList<Block> blocks = new LinkedList<Block>();
+    private ProcessorType<? extends ProcessorType> parent = null;
 
     // else to use an
     // optional
@@ -196,12 +197,15 @@
     /**
      * Ends the current block
      */
-    public Type end() {
+    public ProcessorType<? extends ProcessorType> end() {
         if (blocks.isEmpty()) {
-            throw new IllegalArgumentException("No block active!");
+        	if (parent == null) {
+                throw new IllegalArgumentException("Root node with no active block");
+        	}
+        	return parent;
         }
-        blocks.removeLast();
-        return (Type) this;
+        popBlock();
+        return this;
     }
 
     /**
@@ -274,6 +278,7 @@
      */
     public FilterType filter(Predicate predicate) {
         FilterType filter = new FilterType(predicate);
+        filter.setParent(this);
         addOutput(filter);
         return filter;
     }
@@ -281,6 +286,7 @@
     public FilterType filter(ExpressionType expression) {
         FilterType filter = getNodeFactory().createFilter();
         filter.setExpression(expression);
+        filter.setParent(this);
         addOutput(filter);
         return filter;
     }
@@ -297,6 +303,7 @@
      */
     public ChoiceType choice() {
         ChoiceType answer = new ChoiceType();
+        answer.setParent(this);
         addOutput(answer);
         return answer;
     }
@@ -308,6 +315,7 @@
      */
     public TryType tryBlock() {
         TryType answer = new TryType();
+        answer.setParent(this);
         addOutput(answer);
         return answer;
     }
@@ -631,13 +639,17 @@
 
     public void addInterceptor(InterceptorType interceptor) {
         addOutput(interceptor);
-        addBlock(interceptor);
+        pushBlock(interceptor);
     }
 
-    protected void addBlock(Block block) {
+    protected void pushBlock(Block block) {
         blocks.add(block);
     }
 
+    protected Block popBlock() {
+    	return blocks.isEmpty() ? null : blocks.removeLast();
+    }
+
     public Type proceed() {
         addOutput(new ProceedType());
         return (Type) this;
@@ -652,7 +664,7 @@
     /**
      * Apply an interceptor route if the predicate is true
      */
-    public OtherwiseType intercept(Predicate predicate) {
+    public ChoiceType intercept(Predicate predicate) {
         InterceptType answer = new InterceptType();
         addOutput(answer);
         return answer.when(predicate);
@@ -1017,7 +1029,15 @@
 
     // Properties
     // -------------------------------------------------------------------------
-
+    @XmlTransient
+    ProcessorType<? extends ProcessorType> getParent() {
+    	return parent;
+    }
+    
+    void setParent(ProcessorType<? extends ProcessorType> parent) {
+    	this.parent = parent;
+    }
+    
     @XmlTransient
     public ErrorHandlerBuilder getErrorHandlerBuilder() {
         if (errorHandlerBuilder == null) {

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RoutesType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RoutesType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RoutesType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/RoutesType.java Wed Nov  7 08:20:56 2007
@@ -172,7 +172,7 @@
         return answer;
     }
 
-    public OtherwiseType intercept(Predicate predicate) {
+    public ChoiceType intercept(Predicate predicate) {
         InterceptType answer = new InterceptType();
         getIntercepts().add(answer);
         return answer.when(predicate);

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/TryType.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/TryType.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/TryType.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/model/TryType.java Wed Nov  7 08:20:56 2007
@@ -68,18 +68,28 @@
 
     // Fluent API
     // -------------------------------------------------------------------------
-    public CatchType handle(Class<?> exceptionType) {
+    public TryType handle(Class<?> exceptionType) {
+        popBlock();
         CatchType answer = new CatchType(exceptionType);
         addOutput(answer);
-        return answer;
+        pushBlock(answer);
+        return this;
     }
 
-    public FinallyType handleAll() {
+    public TryType handleAll() {
+        popBlock();
         FinallyType answer = new FinallyType();
         addOutput(answer);
-        return answer;
+        pushBlock(answer);
+        return this;
     }
 
+    @Override
+    public ProcessorType<? extends ProcessorType> end() {
+    	popBlock();
+    	return super.end();
+    }
+    
     // Properties
     // -------------------------------------------------------------------------
 
@@ -109,9 +119,10 @@
         super.setOutputs(outputs);
     }
 
+    @Override
     public void addOutput(ProcessorType output) {
         initialized = false;
-        getOutputs().add(output);
+        super.addOutput(output);
     }
 
     /**

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/TryProcessor.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/TryProcessor.java?rev=592806&r1=592805&r2=592806&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/TryProcessor.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/TryProcessor.java Wed Nov  7 08:20:56 2007
@@ -70,6 +70,7 @@
             try {
                 DeadLetterChannel.setFailureHandled(exchange, true);
                 handleException(exchange, e);
+                exchange.setException(null);
             } catch (Exception ex) {
                 throw ex;
             } catch (Throwable ex) {

Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java?rev=592806&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java Wed Nov  7 08:20:56 2007
@@ -0,0 +1,395 @@
+/**
+ * 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.builder;
+
+import java.util.ArrayList;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.TestSupport;
+import org.apache.camel.ValidationException;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.processor.DelegateProcessor;
+
+/**
+ * @version $Revision$
+ */
+public class BuilderWithScopesTest extends TestSupport {
+	
+    final ArrayList<String> order = new ArrayList<String>();
+    final DelegateProcessor interceptor1 = new DelegateProcessor() {
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            order.add("START:1");
+            super.process(exchange);
+            order.add("END:1");
+        }
+    };
+    final DelegateProcessor interceptor2 = new DelegateProcessor() {
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            order.add("START:2");
+            super.process(exchange);
+            order.add("END:2");
+        }
+    };
+    final Processor orderProcessor = new Processor() {
+        public void process(Exchange exchange) {
+            order.add("INVOKED");
+        }
+    };
+    final Processor orderProcessor2 = new Processor() {
+        public void process(Exchange exchange) {
+            order.add("INVOKED2");
+        }
+    };
+    final Processor orderProcessor3 = new Processor() {
+        public void process(Exchange exchange) {
+            order.add("INVOKED3");
+        }
+    };
+    final Processor toProcessor = new Processor() {
+        public void process(Exchange exchange) {
+            order.add("TO");
+        }
+    };
+    final Processor validator = new Processor() {
+        public void process(Exchange exchange) throws Exception {
+            order.add("VALIDATE");
+            Object value = exchange.getIn().getHeader("foo");
+            if (value == null) {
+            	throw new IllegalArgumentException("The foo header is not present.");
+            } else if (!value.equals("bar")) {
+                throw new ValidationException(exchange, "The foo header does not equal bar! Was: " + value);
+            }
+        }
+    };
+
+    
+    protected void runTest(RouteBuilder builder, 
+    		ArrayList<String> expected) throws Exception {
+        runTest(builder, expected, null);
+    }
+
+    protected void runTest(RouteBuilder builder, 
+    		ArrayList<String> expected, String header) throws Exception {
+    	
+        order.clear();
+        CamelContext container = new DefaultCamelContext();
+
+        container.addRoutes(builder);
+        container.start();
+
+        Endpoint endpoint = container.getEndpoint("direct:a");
+        Exchange exchange = endpoint.createExchange();
+        if (header != null) {
+            exchange.getIn().setHeader("foo", header);
+        }
+        Producer producer = endpoint.createProducer();
+        producer.process(exchange);
+        
+        log.debug("Interceptor invocation order:" + order);
+        assertEquals(expected, order);
+    }
+    
+    public void testRouteWithFilterEnd() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("TO");
+        
+        runTest(new RouteBuilder() {
+	            public void configure() {
+	                from("direct:a")
+	                    .filter(header("foo").isEqualTo("bar")).process(orderProcessor).end()
+	                    .process(toProcessor);
+	            }
+	        }, expected, "banana");
+    }
+
+    public void testRouteWithFilterNoEnd() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        
+        runTest(new RouteBuilder() {
+	            public void configure() {
+	                from("direct:a")
+	                    .filter(header("foo").isEqualTo("bar")).process(orderProcessor)
+	                    .process(toProcessor);
+	            }
+	        }, expected, "banana");
+    }
+
+    protected RouteBuilder createChoiceBuilder() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+                    .choice()
+                        .when(header("foo").isEqualTo("bar")).process(orderProcessor)
+                        .when(header("foo").isEqualTo("cheese")).process(orderProcessor2)
+                        .end()
+                    .process(toProcessor);
+            }
+        };
+    };
+
+    public void testRouteWithChoice1() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED");
+        expected.add("TO");
+        
+        runTest(createChoiceBuilder(), expected, "bar");
+    }    
+
+    public void testRouteWithChoice2() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED2");
+        expected.add("TO");
+        
+        runTest(createChoiceBuilder(), expected, "cheese");
+    }    
+
+    public void testRouteWithChoice3() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("TO");
+        
+        runTest(createChoiceBuilder(), expected, "banana");
+    }    
+
+    public void testRouteWithChoiceNoEnd() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED");
+        
+        runTest(new RouteBuilder() {
+	            public void configure() {
+	                from("direct:a")
+	                    .choice()
+	                        .when(header("foo").isEqualTo("bar")).process(orderProcessor)
+	                        .when(header("foo").isEqualTo("cheese")).process(orderProcessor2)
+	                    .process(toProcessor);	// continuation of the second when clause
+	            }
+	        }, expected, "bar");
+    }    
+
+    protected RouteBuilder createChoiceWithOtherwiseBuilder() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+                    .choice()
+                        .when(header("foo").isEqualTo("bar")).process(orderProcessor)
+                        .when(header("foo").isEqualTo("cheese")).process(orderProcessor2)
+                        .otherwise().process(orderProcessor3)
+                        .end()
+                    .process(toProcessor);
+            }
+        };
+    };
+
+    public void testRouteWithChoiceOtherwise1() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED");
+        expected.add("TO");
+        
+        runTest(createChoiceWithOtherwiseBuilder(), expected, "bar");
+    }    
+
+    public void testRouteWithChoiceOtherwise2() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED2");
+        expected.add("TO");
+        
+        runTest(createChoiceWithOtherwiseBuilder(), expected, "cheese");
+    }    
+
+    public void testRouteWithChoiceOtherwise3() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED3");
+        expected.add("TO");
+        runTest(createChoiceWithOtherwiseBuilder(), expected, "banana");
+    }    
+
+    public void testRouteWithChoiceOtherwiseNoEnd() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("INVOKED");
+        
+        runTest(new RouteBuilder() {
+	            public void configure() {
+	                from("direct:a")
+	                    .choice()
+	                        .when(header("foo").isEqualTo("bar")).process(orderProcessor)
+	                        .when(header("foo").isEqualTo("cheese")).process(orderProcessor2)
+	                        .otherwise().process(orderProcessor3)
+	                    .process(toProcessor);	// continuation of the otherwise clause
+	            }
+	        }, expected, "bar");
+    }
+    
+    protected RouteBuilder createTryCatchNoEnd() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+	                .tryBlock().process(validator).process(toProcessor)
+	                .handle(ValidationException.class).process(orderProcessor)
+	                .process(orderProcessor3);	// continuation of the handle clause
+            }
+        };
+    };
+    
+    public void testRouteWithTryCatchNoEndNoException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("TO");
+        
+        runTest(createTryCatchNoEnd(), expected, "bar");
+    }
+    
+    public void testRouteWithTryCatchNoEndWithCaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchNoEnd(), expected, "banana");
+    }
+
+    public void testRouteWithTryCatchNoEndWithUncaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        
+        runTest(createTryCatchNoEnd(), expected);
+    }
+
+    protected RouteBuilder createTryCatchEnd() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+	                .tryBlock().process(validator).process(toProcessor)
+	                .handle(ValidationException.class).process(orderProcessor)
+	                .end()
+	                .process(orderProcessor3);
+            }
+        };
+    };
+
+    public void testRouteWithTryCatchEndNoException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("TO");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchEnd(), expected, "bar");
+    }
+    
+    public void testRouteWithTryCatchEndWithCaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchEnd(), expected, "banana");
+    }
+
+    public void testRouteWithTryCatchEndWithUncaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        
+        runTest(createTryCatchEnd(), expected);
+    }
+    
+    protected RouteBuilder createTryCatchFinallyNoEnd() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+	                .tryBlock().process(validator).process(toProcessor)
+	                .handle(ValidationException.class).process(orderProcessor)
+                    .handleAll().process(orderProcessor2)
+	                .process(orderProcessor3);	// continuation of the handleAll clause
+            }
+        };
+    };
+    
+    public void testRouteWithTryCatchFinallyNoEndNoException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("TO");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyNoEnd(), expected, "bar");
+    }
+    
+    public void testRouteWithTryCatchFinallyNoEndWithCaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyNoEnd(), expected, "banana");
+    }
+
+    public void testRouteWithTryCatchFinallyNoEndWithUncaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyNoEnd(), expected);
+    }
+    
+    protected RouteBuilder createTryCatchFinallyEnd() { 	
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:a")
+	                .tryBlock().process(validator).process(toProcessor)
+	                .handle(ValidationException.class).process(orderProcessor)
+                    .handleAll().process(orderProcessor2)
+                    .end()
+	                .process(orderProcessor3);
+            }
+        };
+    };
+    
+    public void testRouteWithTryCatchFinallyEndNoException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("TO");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyEnd(), expected, "bar");
+    }
+    
+    public void testRouteWithTryCatchFinallyEndWithCaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyEnd(), expected, "banana");
+    }
+
+    public void testRouteWithTryCatchFinallyEndWithUncaughtException() throws Exception {
+        ArrayList<String> expected = new ArrayList<String>();
+        expected.add("VALIDATE");
+        expected.add("INVOKED2");
+        expected.add("INVOKED3");
+        
+        runTest(createTryCatchFinallyEnd(), expected);
+    }
+}