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.model;
018    
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.List;
022    
023    import javax.xml.bind.annotation.XmlAccessType;
024    import javax.xml.bind.annotation.XmlAccessorType;
025    import javax.xml.bind.annotation.XmlRootElement;
026    import javax.xml.bind.annotation.XmlTransient;
027    
028    import org.apache.camel.Endpoint;
029    import org.apache.camel.Processor;
030    import org.apache.camel.impl.RouteContext;
031    import org.apache.camel.processor.CatchProcessor;
032    import org.apache.camel.processor.TryProcessor;
033    
034    /**
035     * @version $Revision: 1.1 $
036     */
037    @XmlRootElement(name = "try")
038    @XmlAccessorType(XmlAccessType.FIELD)
039    public class TryType extends OutputType {
040        @XmlTransient
041        private List<CatchType> catchClauses;
042        @XmlTransient
043        private FinallyType finallyClause;
044        @XmlTransient
045        private boolean initialized;
046        @XmlTransient
047        private List<ProcessorType> outputsWithoutCatches;
048    
049        @Override
050        public String toString() {
051            return "Try[ " + getOutputs() + "]";
052        }
053    
054        @Override
055        public Processor createProcessor(RouteContext routeContext) throws Exception {
056            Processor tryProcessor = createOutputsProcessor(routeContext, getOutputsWithoutCatches());
057    
058            Processor finallyProcessor = null;
059            if (finallyClause != null) {
060                finallyProcessor = finallyClause.createProcessor(routeContext);
061            }
062            List<CatchProcessor> catchProcessors = new ArrayList<CatchProcessor>();
063            if (catchClauses != null) {
064                for (CatchType catchClause : catchClauses) {
065                    catchProcessors.add(catchClause.createProcessor(routeContext));
066                }
067            }
068            return new TryProcessor(tryProcessor, catchProcessors, finallyProcessor);
069        }
070    
071        // Fluent API
072        // -------------------------------------------------------------------------
073        public CatchType handle(Class<?> exceptionType) {
074            CatchType answer = new CatchType(exceptionType);
075            addOutput(answer);
076            return answer;
077        }
078    
079        public FinallyType handleAll() {
080            FinallyType answer = new FinallyType();
081            addOutput(answer);
082            return answer;
083        }
084    
085        public TryType process(Processor processor) {
086            super.process(processor);
087            return this;
088        }
089    
090        public TryType to(Endpoint endpoint) {
091            super.to(endpoint);
092            return this;
093        }
094    
095        public TryType to(Collection<Endpoint> endpoints) {
096            super.to(endpoints);
097            return this;
098        }
099    
100        public TryType to(Endpoint... endpoints) {
101            super.to(endpoints);
102            return this;
103        }
104    
105        public TryType to(String uri) {
106            super.to(uri);
107            return this;
108        }
109    
110        public TryType to(String... uris) {
111            super.to(uris);
112            return this;
113        }
114    
115        // Properties
116        // -------------------------------------------------------------------------
117    
118        public List<CatchType> getCatchClauses() {
119            if (catchClauses == null) {
120                checkInitialized();
121            }
122            return catchClauses;
123        }
124    
125        public FinallyType getFinallyClause() {
126            if (finallyClause == null) {
127                checkInitialized();
128            }
129            return finallyClause;
130        }
131    
132        public List<ProcessorType> getOutputsWithoutCatches() {
133            if (outputsWithoutCatches == null) {
134                checkInitialized();
135            }
136            return outputsWithoutCatches;
137        }
138    
139        public void setOutputs(List<ProcessorType> outputs) {
140            initialized = false;
141            super.setOutputs(outputs);
142        }
143    
144        public void addOutput(ProcessorType output) {
145            initialized = false;
146            getOutputs().add(output);
147        }
148    
149        /**
150         * Checks whether or not this object has been initialized
151         */
152        protected void checkInitialized() {
153            if (!initialized) {
154                initialized = true;
155                outputsWithoutCatches = new ArrayList<ProcessorType>();
156                catchClauses = new ArrayList<CatchType>();
157                finallyClause = null;
158    
159                for (ProcessorType output : outputs) {
160                    if (output instanceof CatchType) {
161                        catchClauses.add((CatchType)output);
162                    } else if (output instanceof FinallyType) {
163                        if (finallyClause != null) {
164                            throw new IllegalArgumentException("Multiple finally clauses added: " + finallyClause
165                                                               + " and " + output);
166                        } else {
167                            finallyClause = (FinallyType)output;
168                        }
169                    } else {
170                        outputsWithoutCatches.add(output);
171                    }
172                }
173            }
174        }
175    }