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.ExceptionType;
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    
031    /**
032     * Support class for {@link ErrorHandler} implementations.
033     *
034     * @version $Revision: 62995 $
035     */
036    public abstract class ErrorHandlerSupport extends ServiceSupport implements ErrorHandler {
037        private Map<ExceptionPolicyKey, ExceptionType> exceptionPolicies = new LinkedHashMap<ExceptionPolicyKey, ExceptionType>();
038        private ExceptionPolicyStrategy exceptionPolicy = createDefaultExceptionPolicyStrategy();
039    
040        public void addExceptionPolicy(ExceptionType exceptionType) {
041            Processor processor = exceptionType.getErrorHandler();
042            addChildService(processor);
043    
044            List<Class> list = exceptionType.getExceptionClasses();
045    
046            for (Class clazz : list) {
047                ExceptionPolicyKey key = new ExceptionPolicyKey(clazz, exceptionType.getOnWhen());
048                exceptionPolicies.put(key, exceptionType);
049            }
050        }
051    
052        /**
053         * Attempts to invoke the handler for this particular exception if one is available
054         */
055        protected boolean customProcessorForException(Exchange exchange, Throwable exception) throws Exception {
056            ExceptionType policy = getExceptionPolicy(exchange, exception);
057            if (policy != null) {
058                Processor processor = policy.getErrorHandler();
059                if (processor != null) {
060                    processor.process(exchange);
061                    return true;
062                }
063            }
064            return false;
065        }
066    
067        /**
068         * Attempts to find the best suited {@link ExceptionType} to be used for handling the given thrown exception.
069         *
070         * @param exchange  the exchange
071         * @param exception the exception that was thrown
072         * @return the best exception type to handle this exception, <tt>null</tt> if none found.
073         */
074        protected ExceptionType getExceptionPolicy(Exchange exchange, Throwable exception) {
075            if (exceptionPolicy == null) {
076                throw new IllegalStateException("The exception policy has not been set");
077            }
078    
079            return exceptionPolicy.getExceptionPolicy(exceptionPolicies, exchange, exception);
080        }
081    
082        /**
083         * Sets the strategy to use for resolving the {@link ExceptionType} to use
084         * for handling thrown exceptions.
085         */
086        public void setExceptionPolicy(ExceptionPolicyStrategy exceptionPolicy) {
087            this.exceptionPolicy = exceptionPolicy;
088        }
089    
090        /**
091         * Creates the default exception policy strategy to use.
092         */
093        public static ExceptionPolicyStrategy createDefaultExceptionPolicyStrategy() {
094            return new DefaultExceptionPolicyStrategy();
095        }
096    
097    }