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.List;
020    
021    import org.apache.camel.Exchange;
022    import org.apache.camel.Processor;
023    import org.apache.camel.impl.ServiceSupport;
024    import org.apache.camel.util.ServiceHelper;
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    
028    /**
029     * Implements try/catch/finally type processing
030     * 
031     * @version $Revision: $
032     */
033    public class TryProcessor extends ServiceSupport implements Processor {
034        private static final Log LOG = LogFactory.getLog(TryProcessor.class);
035    
036        private final Processor tryProcessor;
037        private final List<CatchProcessor> catchClauses;
038        private final Processor finallyProcessor;
039    
040        public TryProcessor(Processor tryProcessor, List<CatchProcessor> catchClauses, Processor finallyProcessor) {
041            this.tryProcessor = tryProcessor;
042            this.catchClauses = catchClauses;
043            this.finallyProcessor = finallyProcessor;
044        }
045    
046        public String toString() {
047            String finallyText = (finallyProcessor == null) ? "" : " Finally {" + finallyProcessor + "}";
048            return "Try {" + tryProcessor + "} " + catchClauses + finallyText;
049        }
050    
051        public void process(Exchange exchange) throws Exception {
052            boolean doneTry = false;
053            try {
054                tryProcessor.process(exchange);
055                doneTry = true;
056    
057                if (finallyProcessor != null) {
058                    finallyProcessor.process(exchange);
059                }
060            } catch (Exception e) {
061                handleException(exchange, e);
062    
063                if (!doneTry && finallyProcessor != null) {
064                    try {
065                        finallyProcessor.process(exchange);
066                    } catch (Exception e2) {
067                        LOG.warn("Caught exception in finally block while handling other exception: " + e2, e2);
068                    }
069                }
070            }
071        }
072    
073        protected void doStart() throws Exception {
074            ServiceHelper.startServices(tryProcessor, catchClauses, finallyProcessor);
075        }
076    
077        protected void doStop() throws Exception {
078            ServiceHelper.stopServices(tryProcessor, catchClauses, finallyProcessor);
079        }
080    
081        protected void handleException(Exchange exchange, Exception e) throws Exception {
082            for (CatchProcessor catchClause : catchClauses) {
083                if (catchClause.catches(e)) {
084                    // lets attach the exception to the exchange
085                    exchange.setException(e);
086                    try {
087                        catchClause.process(exchange);
088                    } catch (Exception e1) {
089                        LOG.warn("Caught exception inside catch clause: " + e1, e1);
090                        throw e1;
091                    }
092                    return;
093                }
094            }
095    
096            // unhandled exception
097            throw e;
098        }
099    }