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.List;
021
022 import javax.xml.bind.annotation.XmlAccessType;
023 import javax.xml.bind.annotation.XmlAccessorType;
024 import javax.xml.bind.annotation.XmlElement;
025 import javax.xml.bind.annotation.XmlElementRef;
026 import javax.xml.bind.annotation.XmlRootElement;
027 import javax.xml.bind.annotation.XmlTransient;
028
029 import org.apache.camel.Expression;
030 import org.apache.camel.Predicate;
031 import org.apache.camel.Processor;
032 import org.apache.camel.builder.ExpressionBuilder;
033 import org.apache.camel.builder.ExpressionClause;
034 import org.apache.camel.processor.CatchProcessor;
035 import org.apache.camel.spi.RouteContext;
036 import org.apache.camel.util.ObjectHelper;
037 import static org.apache.camel.builder.PredicateBuilder.toPredicate;
038
039 /**
040 * Represents an XML <catch/> element
041 *
042 * @version $Revision: 766610 $
043 */
044 @XmlRootElement(name = "doCatch")
045 @XmlAccessorType(XmlAccessType.FIELD)
046 public class CatchDefinition extends ProcessorDefinition<CatchDefinition> {
047 @XmlElement(name = "exception")
048 private List<String> exceptions = new ArrayList<String>();
049 @XmlElement(name = "onWhen", required = false)
050 private WhenDefinition onWhen;
051 @XmlElement(name = "handled", required = false)
052 private ExpressionSubElementDefinition handled;
053 @XmlElementRef
054 private List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>();
055 @XmlTransient
056 private List<Class> exceptionClasses;
057 @XmlTransient
058 private Predicate handledPolicy;
059
060 public CatchDefinition() {
061 }
062
063 public CatchDefinition(List<Class> exceptionClasses) {
064 this.exceptionClasses = exceptionClasses;
065 }
066
067 public CatchDefinition(Class exceptionType) {
068 exceptionClasses = new ArrayList<Class>();
069 exceptionClasses.add(exceptionType);
070 }
071
072 @Override
073 public String toString() {
074 return "DoCatch[ " + getExceptionClasses() + " -> " + getOutputs() + "]";
075 }
076
077 @Override
078 public String getShortName() {
079 return "doCatch";
080 }
081
082 @Override
083 public String getLabel() {
084 return getExceptionClasses().toString();
085 }
086
087 @Override
088 public CatchProcessor createProcessor(RouteContext routeContext) throws Exception {
089 Processor childProcessor = routeContext.createProcessor(this);
090
091 Predicate when = null;
092 if (onWhen != null) {
093 when = onWhen.getExpression().createPredicate(routeContext);
094 }
095
096 Predicate handle = handledPolicy;
097 if (handled != null) {
098 handle = handled.createPredicate(routeContext);
099 }
100
101 return new CatchProcessor(getExceptionClasses(), childProcessor, when, handle);
102 }
103
104 public List<ProcessorDefinition> getOutputs() {
105 return outputs;
106 }
107
108 public void setOutputs(List<ProcessorDefinition> outputs) {
109 this.outputs = outputs;
110 }
111
112 public List<Class> getExceptionClasses() {
113 if (exceptionClasses == null) {
114 exceptionClasses = createExceptionClasses();
115 }
116 return exceptionClasses;
117 }
118
119 public void setExceptionClasses(List<Class> exceptionClasses) {
120 this.exceptionClasses = exceptionClasses;
121 }
122
123 // Fluent API
124 //-------------------------------------------------------------------------
125 /**
126 * Sets the exceptionClasses of the CatchType
127 *
128 * @param exceptionClasses a list of the exception classes
129 * @return the builder
130 */
131 public CatchDefinition exceptionClasses(List<Class> exceptionClasses) {
132 setExceptionClasses(exceptionClasses);
133 return this;
134 }
135
136 /**
137 * Sets an additional predicate that should be true before the onCatch is triggered.
138 * <p/>
139 * To be used for fine grained controlling whether a thrown exception should be intercepted
140 * by this exception type or not.
141 *
142 * @param predicate predicate that determines true or false
143 * @return the builder
144 */
145 public CatchDefinition onWhen(Predicate predicate) {
146 setOnWhen(new WhenDefinition(predicate));
147 return this;
148 }
149
150 /**
151 * Creates an expression to configure an additional predicate that should be true before the
152 * onCatch is triggered.
153 * <p/>
154 * To be used for fine grained controlling whether a thrown exception should be intercepted
155 * by this exception type or not.
156 *
157 * @return the expression clause to configure
158 */
159 public ExpressionClause<CatchDefinition> onWhen() {
160 onWhen = new WhenDefinition();
161 ExpressionClause<CatchDefinition> clause = new ExpressionClause<CatchDefinition>(this);
162 onWhen.setExpression(clause);
163 return clause;
164 }
165
166 /**
167 * Sets whether the exchange should be marked as handled or not.
168 *
169 * @param handled handled or not
170 * @return the builder
171 */
172 public CatchDefinition handled(boolean handled) {
173 Expression expression = ExpressionBuilder.constantExpression(Boolean.toString(handled));
174 return handled(expression);
175 }
176
177 /**
178 * Sets whether the exchange should be marked as handled or not.
179 *
180 * @param handled predicate that determines true or false
181 * @return the builder
182 */
183 public CatchDefinition handled(Predicate handled) {
184 setHandledPolicy(handled);
185 return this;
186 }
187
188 /**
189 * Sets whether the exchange should be marked as handled or not.
190 *
191 * @param handled expression that determines true or false
192 * @return the builder
193 */
194 public CatchDefinition handled(Expression handled) {
195 setHandledPolicy(toPredicate(handled));
196 return this;
197 }
198
199 /**
200 * Sets the exception class that the CatchType want to catch
201 *
202 * @param exception the exception of class
203 * @return the builder
204 */
205 public CatchDefinition exceptionClasses(Class exception) {
206 List<Class> list = getExceptionClasses();
207 list.add(exception);
208 return this;
209 }
210
211 public List<String> getExceptions() {
212 return exceptions;
213 }
214
215 public void setExceptions(List<String> exceptions) {
216 this.exceptions = exceptions;
217 }
218
219 public WhenDefinition getOnWhen() {
220 return onWhen;
221 }
222
223 public void setOnWhen(WhenDefinition onWhen) {
224 this.onWhen = onWhen;
225 }
226
227 public Predicate getHandledPolicy() {
228 return handledPolicy;
229 }
230
231 public void setHandledPolicy(Predicate handledPolicy) {
232 this.handledPolicy = handledPolicy;
233 }
234
235 protected List<Class> createExceptionClasses() {
236 List<String> list = getExceptions();
237 List<Class> answer = new ArrayList<Class>(list.size());
238 for (String name : list) {
239 Class type = ObjectHelper.loadClass(name, getClass().getClassLoader());
240 answer.add(type);
241 }
242 return answer;
243 }
244 }