Return-Path: Delivered-To: apmail-camel-commits-archive@www.apache.org Received: (qmail 91877 invoked from network); 11 Nov 2009 08:33:26 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 11 Nov 2009 08:33:26 -0000 Received: (qmail 22306 invoked by uid 500); 11 Nov 2009 08:33:26 -0000 Delivered-To: apmail-camel-commits-archive@camel.apache.org Received: (qmail 22259 invoked by uid 500); 11 Nov 2009 08:33:26 -0000 Mailing-List: contact commits-help@camel.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@camel.apache.org Delivered-To: mailing list commits@camel.apache.org Received: (qmail 22250 invoked by uid 99); 11 Nov 2009 08:33:26 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Nov 2009 08:33:26 +0000 X-ASF-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 11 Nov 2009 08:33:23 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 616662388996; Wed, 11 Nov 2009 08:33:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r834801 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/processor/exceptionpolicy/ test/java/org/apache/camel/issues/ Date: Wed, 11 Nov 2009 08:33:03 -0000 To: commits@camel.apache.org From: davsclaus@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091111083303.616662388996@eris.apache.org> 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 @@ * Selection strategy: *
This strategy applies the following rules: *
    - *
  • Will walk the exception hieracy from bottom upwards till the thrown exception, meaning that the most outer caused + *
  • 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.
  • *
  • 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 exceptionPolicices, + public OnExceptionDefinition getExceptionPolicy(Map exceptionPolicies, Exchange exchange, Throwable exception) { + Map candidates = new TreeMap(); + // recursive up the tree using the iterator + boolean exactMatch = false; Iterator 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 exceptionPolicices, - Exchange exchange, Throwable exception) { + private boolean findMatchedExceptionPolicy(Map exceptionPolicies, + Exchange exchange, Throwable exception, + Map 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> entries = exceptionPolicices.entrySet(); + Set> entries = exceptionPolicies.entrySet(); for (Map.Entry 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, null if none found. */ - OnExceptionDefinition getExceptionPolicy(Map exceptionPolicices, + OnExceptionDefinition getExceptionPolicy(Map 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