001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.processor;
018
019 import java.util.LinkedHashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 import org.apache.camel.Exchange;
024 import org.apache.camel.Processor;
025 import org.apache.camel.impl.ServiceSupport;
026 import org.apache.camel.model.OnExceptionDefinition;
027 import org.apache.camel.processor.exceptionpolicy.DefaultExceptionPolicyStrategy;
028 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyKey;
029 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyStrategy;
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032
033 /**
034 * Support class for {@link ErrorHandler} implementations.
035 *
036 * @version $Revision: 765920 $
037 */
038 public abstract class ErrorHandlerSupport extends ServiceSupport implements ErrorHandler {
039
040 protected final transient Log log = LogFactory.getLog(getClass());
041
042 private final Map<ExceptionPolicyKey, OnExceptionDefinition> exceptionPolicies = new LinkedHashMap<ExceptionPolicyKey, OnExceptionDefinition>();
043 private ExceptionPolicyStrategy exceptionPolicy = createDefaultExceptionPolicyStrategy();
044
045 public void addExceptionPolicy(OnExceptionDefinition exceptionType) {
046 Processor processor = exceptionType.getErrorHandler();
047 addChildService(processor);
048
049 List<Class> list = exceptionType.getExceptionClasses();
050
051 for (Class clazz : list) {
052 ExceptionPolicyKey key = new ExceptionPolicyKey(clazz, exceptionType.getOnWhen());
053 exceptionPolicies.put(key, exceptionType);
054 }
055 }
056
057 /**
058 * Attempts to invoke the handler for this particular exception if one is available
059 */
060 protected boolean customProcessorForException(Exchange exchange, Throwable exception) throws Exception {
061 OnExceptionDefinition policy = getExceptionPolicy(exchange, exception);
062 if (policy != null) {
063 Processor processor = policy.getErrorHandler();
064 if (processor != null) {
065 processor.process(exchange);
066 return true;
067 }
068 }
069 return false;
070 }
071
072 /**
073 * Attempts to find the best suited {@link OnExceptionDefinition} to be used for handling the given thrown exception.
074 *
075 * @param exchange the exchange
076 * @param exception the exception that was thrown
077 * @return the best exception type to handle this exception, <tt>null</tt> if none found.
078 */
079 protected OnExceptionDefinition getExceptionPolicy(Exchange exchange, Throwable exception) {
080 if (exceptionPolicy == null) {
081 throw new IllegalStateException("The exception policy has not been set");
082 }
083
084 return exceptionPolicy.getExceptionPolicy(exceptionPolicies, exchange, exception);
085 }
086
087 /**
088 * Sets the strategy to use for resolving the {@link OnExceptionDefinition} to use
089 * for handling thrown exceptions.
090 */
091 public void setExceptionPolicy(ExceptionPolicyStrategy exceptionPolicy) {
092 this.exceptionPolicy = exceptionPolicy;
093 }
094
095 /**
096 * Creates the default exception policy strategy to use.
097 */
098 public static ExceptionPolicyStrategy createDefaultExceptionPolicyStrategy() {
099 return new DefaultExceptionPolicyStrategy();
100 }
101
102 /**
103 * Whether this error handler supports transacted exchanges or not.
104 */
105 public abstract boolean supportTransacted();
106
107 }