Author: davsclaus
Date: Wed Nov 11 08:33:02 2009
New Revision: 834801

URL: http://svn.apache.org/viewvc?rev=834801&view=rev
Log:
CAMEL-2158: onException now checks better for exact matched exceptions.

Added:
    
camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionPolicyIssueTest.java
   (with props)
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java?rev=834801&r1=834800&r2=834801&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
 Wed Nov 11 08:33:02 2009
@@ -19,6 +19,7 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.model.OnExceptionDefinition;
@@ -33,7 +34,7 @@
  * <b>Selection strategy:</b>
  * <br/>This strategy applies the following rules:
  * <ul>
- * <li>Will walk the exception hieracy from bottom upwards till the thrown 
exception, meaning that the most outer caused
+ * <li>Will walk the exception hierarchy from bottom upwards till the thrown 
exception, meaning that the most outer caused
  * by is selected first, ending with the thrown exception itself. The method 
{...@link #createExceptionIterator(Throwable)}
  * provides the Iterator used for the walking.</li>
  * <li>The exception type must be configured with an Exception that is an 
instance of the thrown exception, this
@@ -54,25 +55,38 @@
 
     private static final transient Log LOG = 
LogFactory.getLog(DefaultExceptionPolicyStrategy.class);
 
-    public OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicices,
+    public OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
                                                     Exchange exchange, 
Throwable exception) {
 
+        Map<Integer, OnExceptionDefinition> candidates = new TreeMap<Integer, 
OnExceptionDefinition>();
+
         // recursive up the tree using the iterator
+        boolean exactMatch = false;
         Iterator<Throwable> it = createExceptionIterator(exception);
-        while (it.hasNext()) {
-            OnExceptionDefinition type = 
findMatchedExceptionPolicy(exceptionPolicices, exchange, it.next());
-            if (type != null) {
-                return type;
-            }
+        while (!exactMatch && it.hasNext()) {
+            // we should stop looking if we have found an exact match
+            exactMatch = findMatchedExceptionPolicy(exceptionPolicies, 
exchange, it.next(), candidates);
+        }
+
+        // now go through the candidates and find the best
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Found " + candidates.size() + " candidates");
         }
 
-        // no type found
-        return null;
+        if (candidates.isEmpty()) {
+            // no type found
+            return null;
+        } else {
+            // return the first in the map as its sorted and
+            return candidates.values().iterator().next();
+        }
     }
 
 
-    private OnExceptionDefinition 
findMatchedExceptionPolicy(Map<ExceptionPolicyKey, OnExceptionDefinition> 
exceptionPolicices,
-                                                             Exchange 
exchange, Throwable exception) {
+    private boolean findMatchedExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
+                                                             Exchange 
exchange, Throwable exception,
+                                                             Map<Integer, 
OnExceptionDefinition> candidates) {
         if (LOG.isTraceEnabled()) {
             LOG.trace("Finding best suited exception policy for thrown 
exception " + exception.getClass().getName());
         }
@@ -85,7 +99,7 @@
         int candidateDiff = Integer.MAX_VALUE;
 
         // loop through all the entries and find the best candidates to use
-        Set<Map.Entry<ExceptionPolicyKey, OnExceptionDefinition>> entries = 
exceptionPolicices.entrySet();
+        Set<Map.Entry<ExceptionPolicyKey, OnExceptionDefinition>> entries = 
exceptionPolicies.entrySet();
         for (Map.Entry<ExceptionPolicyKey, OnExceptionDefinition> entry : 
entries) {
             Class clazz = entry.getKey().getExceptionClass();
             OnExceptionDefinition type = entry.getValue();
@@ -103,6 +117,7 @@
                 // exact match then break
                 if (clazz.equals(exception.getClass())) {
                     candidate = type;
+                    candidateDiff = 0;
                     break;
                 }
 
@@ -118,15 +133,28 @@
             }
         }
 
-        if (LOG.isTraceEnabled()) {
-            if (candidate != null) {
-                LOG.trace("Using " + candidate + " as the exception policy");
+        if (candidate != null) {
+            if (!candidates.containsKey(candidateDiff)) {
+                // only add as candidate if we do not already have it 
registered with that level
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("Adding " + candidate + " as candidate at level 
" + candidateDiff);
+                }
+                candidates.put(candidateDiff, candidate);
             } else {
-                LOG.trace("No candidate found to be used as exception policy");
+                // we have an existing candidate already which we should 
prefer to use
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("Existing candidate " + 
candidates.get(candidateDiff)
+                        + " takes precedence over " + candidate + " at level " 
+ candidateDiff);
+                }
             }
         }
 
-        return candidate;
+        // if we found a exact match then we should stop continue looking
+        boolean exactMatch = candidateDiff == 0;
+        if (LOG.isTraceEnabled() && exactMatch) {
+            LOG.trace("Exact match found for candidate: " + candidate);
+        }
+        return exactMatch;
     }
 
     /**

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java?rev=834801&r1=834800&r2=834801&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
 Wed Nov 11 08:33:02 2009
@@ -32,12 +32,12 @@
     /**
      * Resolves the {...@link org.apache.camel.model.OnExceptionDefinition} 
that should handle the thrown exception.
      *
-     * @param exceptionPolicices the configured exception policies to resolve 
from
+     * @param exceptionPolicies the configured exception policies to resolve 
from
      * @param exchange           the exchange
      * @param exception          the exception that was thrown
      * @return the resolved exception type to handle this exception, 
<tt>null</tt> if none found.
      */
-    OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicices,
+    OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
                                              Exchange exchange, Throwable 
exception);
 
 }

Added: 
camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionPolicyIssueTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionPolicyIssueTest.java?rev=834801&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionPolicyIssueTest.java
 (added)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionPolicyIssueTest.java
 Wed Nov 11 08:33:02 2009
@@ -0,0 +1,58 @@
+/**
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version $Revision$
+ */
+public class ExceptionPolicyIssueTest extends ContextTestSupport {
+
+    public void testOnExceptionWithGenericException() throws Exception {
+        getMockEndpoint("mock:exception").expectedMessageCount(0);
+        getMockEndpoint("mock:ue").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
onException(MyUnmarshalException.class).handled(true).to("mock:ue");
+                
+                
onException(Exception.class).handled(true).to("mock:exception");
+
+                from("direct:start")
+                    .throwException(new MyUnmarshalException("Could not 
unmarshal", new IllegalArgumentException("Damn")));
+            }
+        };
+    }
+
+    private class MyUnmarshalException extends Exception {
+
+        private MyUnmarshalException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+    }
+}

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

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


Reply via email to