You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2008/11/23 12:57:50 UTC

svn commit: r719980 - in /activemq/camel/branches/camel-1.x: ./ camel-core/src/main/java/org/apache/camel/model/ camel-core/src/main/java/org/apache/camel/processor/ camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ camel-core/src/te...

Author: davsclaus
Date: Sun Nov 23 03:57:50 2008
New Revision: 719980

URL: http://svn.apache.org/viewvc?rev=719980&view=rev
Log:
Merged revisions 719978-719979 via svnmerge from 
https://svn.apache.org/repos/asf/activemq/camel/trunk

........
  r719978 | davsclaus | 2008-11-23 12:20:43 +0100 (so, 23 nov 2008) | 1 line
  
  CAMEL-1104: onException now supports an optional when expression to only trigger if the expression evaluates to true
........
  r719979 | davsclaus | 2008-11-23 12:40:03 +0100 (so, 23 nov 2008) | 1 line
  
  CAMEL-1104: onException now supports an optional when expression to only trigger if the expression evaluates to true
........

Added:
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
      - copied unchanged from r719979, activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
    activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyUsingOnlyWhenTest.java
      - copied unchanged from r719979, activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyUsingOnlyWhenTest.java
    activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyUsingWhenTest.java
      - copied unchanged from r719979, activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyUsingWhenTest.java
Modified:
    activemq/camel/branches/camel-1.x/   (props changed)
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ExceptionType.java
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/ErrorHandlerSupport.java
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
    activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
    activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
    activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java

Propchange: activemq/camel/branches/camel-1.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun Nov 23 03:57:50 2008
@@ -1 +1 @@
-/activemq/camel/trunk:709850,711200,711206,711219-711220,711523,711531,711756,711784,711859,711874,711962,711971,712064,712119,712148,712662,712692,712925,713013,713107,713136,713273,713290,713292,713295,713314,713475,713625,713932,713944,714032,717965,717989,718242,718273,718312-718515,719163-719184,719334,719339,719524,719662,719848,719864
+/activemq/camel/trunk:709850,711200,711206,711219-711220,711523,711531,711756,711784,711859,711874,711962,711971,712064,712119,712148,712662,712692,712925,713013,713107,713136,713273,713290,713292,713295,713314,713475,713625,713932,713944,714032,717965,717989,718242,718273,718312-718515,719163-719184,719334,719339,719524,719662,719848,719864,719978-719979

Propchange: activemq/camel/branches/camel-1.x/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ChoiceType.java Sun Nov 23 03:57:50 2008
@@ -88,7 +88,6 @@
         return this;
     }
 
-
     public ExpressionClause<ChoiceType> when() {
         WhenType when = new WhenType();
         getWhenClauses().add(when);
@@ -97,7 +96,6 @@
         return clause;
     }
 
-
     public ChoiceType otherwise() {
         OtherwiseType answer = new OtherwiseType();
         setOtherwise(answer);

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ExceptionType.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ExceptionType.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ExceptionType.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/model/ExceptionType.java Sun Nov 23 03:57:50 2008
@@ -33,6 +33,7 @@
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.builder.ErrorHandlerBuilder;
+import org.apache.camel.builder.ExpressionClause;
 import org.apache.camel.language.constant.ConstantLanguage;
 import org.apache.camel.processor.CatchProcessor;
 import org.apache.camel.processor.RedeliveryPolicy;
@@ -52,6 +53,8 @@
 
     @XmlElement(name = "exception")
     private List<String> exceptions = new ArrayList<String>();
+    @XmlElement(name = "onWhen", required = false)
+    private WhenType onWhen;
     @XmlElement(name = "redeliveryPolicy", required = false)
     private RedeliveryPolicyType redeliveryPolicy;
     @XmlElement(name = "handled", required = false)
@@ -79,7 +82,7 @@
 
     @Override
     public String toString() {
-        return "Exception[" + getExceptionClasses() + " -> " + getOutputs() + "]";
+        return "Exception[" + getExceptionClasses() + (onWhen != null ? " " + onWhen : "") + " -> " + getOutputs() + "]";
     }
     
     /**
@@ -142,6 +145,18 @@
         return this;
     }
 
+    public ExceptionType onWhen(Predicate predicate) {
+        setOnWhen(new WhenType(predicate));
+        return this;
+    }
+
+    public ExpressionClause<ExceptionType> onWhen() {
+        onWhen = new WhenType();
+        ExpressionClause<ExceptionType> clause = new ExpressionClause<ExceptionType>(this);
+        onWhen.setExpression(clause);
+        return clause;
+    }
+
     public ExceptionType backOffMultiplier(double backOffMultiplier) {
         getOrCreateRedeliveryPolicy().backOffMultiplier(backOffMultiplier);
         return this;
@@ -255,6 +270,14 @@
         this.handledPolicy = handledPolicy;
     }
 
+    public WhenType getOnWhen() {
+        return onWhen;
+    }
+
+    public void setOnWhen(WhenType onWhen) {
+        this.onWhen = onWhen;
+    }
+
     // Implementation methods
     //-------------------------------------------------------------------------
     protected RedeliveryPolicyType getOrCreateRedeliveryPolicy() {

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java Sun Nov 23 03:57:50 2008
@@ -63,7 +63,6 @@
         // default behavior which can be overloaded on a per exception basis
         RedeliveryPolicy currentRedeliveryPolicy = redeliveryPolicy;
         Processor failureProcessor = deadLetter;
-        
     }
 
     public DeadLetterChannel(Processor output, Processor deadLetter) {

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/ErrorHandlerSupport.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/ErrorHandlerSupport.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/ErrorHandlerSupport.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/ErrorHandlerSupport.java Sun Nov 23 03:57:50 2008
@@ -25,6 +25,7 @@
 import org.apache.camel.impl.ServiceSupport;
 import org.apache.camel.model.ExceptionType;
 import org.apache.camel.processor.exceptionpolicy.DefaultExceptionPolicyStrategy;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyKey;
 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyStrategy;
 
 /**
@@ -33,17 +34,18 @@
  * @version $Revision$
  */
 public abstract class ErrorHandlerSupport extends ServiceSupport implements ErrorHandler {
-    private Map<Class, ExceptionType> exceptionPolicies = new LinkedHashMap<Class, ExceptionType>();
+    private Map<ExceptionPolicyKey, ExceptionType> exceptionPolicies = new LinkedHashMap<ExceptionPolicyKey, ExceptionType>();
     private ExceptionPolicyStrategy exceptionPolicy = createDefaultExceptionPolicyStrategy();
 
-    public void addExceptionPolicy(ExceptionType exception) {
-        Processor processor = exception.getErrorHandler();
+    public void addExceptionPolicy(ExceptionType exceptionType) {
+        Processor processor = exceptionType.getErrorHandler();
         addChildService(processor);
 
-        List<Class> list = exception.getExceptionClasses();
+        List<Class> list = exceptionType.getExceptionClasses();
 
-        for (Class exceptionType : list) {
-            exceptionPolicies.put(exceptionType, exception);
+        for (Class clazz : list) {
+            ExceptionPolicyKey key = new ExceptionPolicyKey(clazz, exceptionType.getOnWhen());
+            exceptionPolicies.put(key, exceptionType);
         }
     }
 

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java Sun Nov 23 03:57:50 2008
@@ -28,19 +28,27 @@
  * The default strategy used in Camel to resolve the {@link org.apache.camel.model.ExceptionType} that should
  * handle the thrown exception.
  * <p/>
- * This strategy applies the following rules:
+ * <b>Selection strategy:</b>
+ * <br/>This strategy applies the following rules:
  * <ul>
- *   <li>The exception type must be configured with an Exception that is an instance of the thrown exception</li>
- *   <li>If the exception type has exactly the thrown exception then its selected</li>
- *   <li>Otherwise the type that has an exception that is super of the thrown exception is selected
- *       (recurring up the exception hierarchy)
- *  </ul>
+ *   <li>The exception type must be configured with an Exception that is an instance of the thrown exception, this
+ *  is tested using the {@link #filter(org.apache.camel.model.ExceptionType, Class, Throwable)} method. </li>
+ *   <li>If the exception type has exactly the thrown exception then its selected as its an exact match</li>
+ *   <li>Otherwise the type that has an exception that is the closests super of the thrown exception is selected
+ *       (recurring up the exception hierarchy)</li>
+ * </ul>
+ * <p/>
+ * <b>Fine grained matching:</b>
+ * <br/> If the {@link ExceptionType} has a when defined with an expression the type is also matches against
+ * the current exchange using the {@link #matchesWhen(org.apache.camel.model.ExceptionType, org.apache.camel.Exchange)}
+ * method. This can be used to for more fine grained matching, so you can e.g. define multiple sets of
+ * exception types with the same exception class(es) but have a predicate attached to select which to select at runtime.
  */
 public class DefaultExceptionPolicyStrategy implements ExceptionPolicyStrategy {
 
     private static final transient Log LOG = LogFactory.getLog(DefaultExceptionPolicyStrategy.class);
 
-    public ExceptionType getExceptionPolicy(Map<Class, ExceptionType> exceptionPolicices, Exchange exchange,
+    public ExceptionType getExceptionPolicy(Map<ExceptionPolicyKey, ExceptionType> exceptionPolicices, Exchange exchange,
                                             Throwable exception) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Finding best suited exception policy for thrown exception " + exception.getClass().getName());
@@ -54,15 +62,22 @@
         int candidateDiff = Integer.MAX_VALUE;
 
         // loop through all the entries and find the best candidates to use
-        Set<Map.Entry<Class, ExceptionType>> entries = exceptionPolicices.entrySet();
-        for (Map.Entry<Class, ExceptionType> entry : entries) {
-            Class clazz = entry.getKey();
+        Set<Map.Entry<ExceptionPolicyKey, ExceptionType>> entries = exceptionPolicices.entrySet();
+        for (Map.Entry<ExceptionPolicyKey, ExceptionType> entry : entries) {
+            Class clazz = entry.getKey().getExceptionClass();
             ExceptionType type = entry.getValue();
 
-            // must be instance of check to ensure that the clazz is one type of the thrown exception
-            if (clazz.isInstance(exception)) {
+            if (filter(type, clazz, exception)) {
+
+                // must match
+                if (!matchesWhen(type, exchange)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("The type did not match when: " + type);
+                    }
+                    continue;
+                }
 
-                // exact match
+                // exact match then break
                 if (clazz.equals(exception.getClass())) {
                     candidate = type;
                     break;
@@ -91,6 +106,40 @@
         return candidate;
     }
 
+    /**
+     * Strategy to filter the given type exception class with the thrown exception
+     *
+     * @param type  the exception type
+     * @param exceptionClass  the current exception class for testing
+     * @param exception  the thrown exception
+     * @return <tt>true</tt> if the to current exception class is a candidate, <tt>false</tt> to skip it. 
+     */
+    protected boolean filter(ExceptionType type, Class exceptionClass, Throwable exception) {
+        // must be instance of check to ensure that the exceptionClass is one type of the thrown exception
+        return exceptionClass.isInstance(exception);
+    }
+
+    /**
+     * Strategy method for matching the exception type with the current exchange.
+     * <p/>
+     * This default implementation will match as:
+     * <ul>
+     *   <li>Always true if no when predicate on the exception type
+     *   <li>Otherwise the when predicate is matches against the current exchange
+     * </ul>
+     *
+     * @param type  the exception type
+     * @param exchange  the current {@link Exchange}
+     * @return <tt>true</tt> if matched, <tt>false</tt> otherwise.
+     */
+    protected boolean matchesWhen(ExceptionType type, Exchange exchange) {
+        if (type.getOnWhen() == null || type.getOnWhen().getExpression() == null) {
+            // if no predicate then it's always a match
+            return true;
+        }
+        return type.getOnWhen().getExpression().matches(exchange);
+    }
+
     private static int getInheritanceLevel(Class clazz) {
         if (clazz == null || "java.lang.Object".equals(clazz.getName())) {
             return 0;

Modified: activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java Sun Nov 23 03:57:50 2008
@@ -37,7 +37,7 @@
      * @param exception          the exception that was thrown
      * @return the resolved exception type to handle this exception, <tt>null</tt> if none found.
      */
-    ExceptionType getExceptionPolicy(Map<Class, ExceptionType> exceptionPolicices, Exchange exchange,
+    ExceptionType getExceptionPolicy(Map<ExceptionPolicyKey, ExceptionType> exceptionPolicices, Exchange exchange,
                                             Throwable exception);
 
 }

Modified: activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java Sun Nov 23 03:57:50 2008
@@ -41,12 +41,12 @@
     // START SNIPPET e2
     public static class MyPolicy implements ExceptionPolicyStrategy {
 
-        public ExceptionType getExceptionPolicy(Map<Class, ExceptionType> exceptionPolicices,
+        public ExceptionType getExceptionPolicy(Map<ExceptionPolicyKey, ExceptionType> exceptionPolicices,
                                                 Exchange exchange,
                                                 Throwable exception) {
             // This is just an example that always forces the exception type configured
             // with MyPolicyException to win.
-            return exceptionPolicices.get(MyPolicyException.class);
+            return exceptionPolicices.get(ExceptionPolicyKey.newInstance(MyPolicyException.class));
         }
     }
     // END SNIPPET e2

Modified: activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java?rev=719980&r1=719979&r2=719980&view=diff
==============================================================================
--- activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java (original)
+++ activemq/camel/branches/camel-1.x/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java Sun Nov 23 03:57:50 2008
@@ -36,30 +36,30 @@
 public class DefaultExceptionPolicyStrategyTest extends TestCase {
 
     private DefaultExceptionPolicyStrategy strategy;
-    private HashMap<Class, ExceptionType> policies;
+    private HashMap<ExceptionPolicyKey, ExceptionType> policies;
     private ExceptionType type1;
     private ExceptionType type2;
     private ExceptionType type3;
 
     private void setupPolicies() {
         strategy = new DefaultExceptionPolicyStrategy();
-        policies = new HashMap<Class, ExceptionType>();
+        policies = new HashMap<ExceptionPolicyKey, ExceptionType>();
         type1 = new ExceptionType(CamelExchangeException.class);
         type2 = new ExceptionType(Exception.class);
         type3 = new ExceptionType(IOException.class);
-        policies.put(CamelExchangeException.class, type1);
-        policies.put(Exception.class, type2);
-        policies.put(IOException.class, type3);
+        policies.put(ExceptionPolicyKey.newInstance(CamelExchangeException.class), type1);
+        policies.put(ExceptionPolicyKey.newInstance(Exception.class), type2);
+        policies.put(ExceptionPolicyKey.newInstance(IOException.class), type3);
     }
 
     private void setupPoliciesNoTopLevelException() {
         // without the top level exception that can be used as fallback
         strategy = new DefaultExceptionPolicyStrategy();
-        policies = new HashMap<Class, ExceptionType>();
+        policies = new HashMap<ExceptionPolicyKey, ExceptionType>();
         type1 = new ExceptionType(CamelExchangeException.class);
         type3 = new ExceptionType(IOException.class);
-        policies.put(CamelExchangeException.class, type1);
-        policies.put(IOException.class, type3);
+        policies.put(ExceptionPolicyKey.newInstance(CamelExchangeException.class), type1);
+        policies.put(ExceptionPolicyKey.newInstance(IOException.class), type3);
     }
 
     public void testDirectMatch1() {