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 import java.util.Collection;
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.Processor;
030 import org.apache.camel.Route;
031 import org.apache.camel.builder.ErrorHandlerBuilder;
032 import org.apache.camel.impl.RouteContext;
033 import org.apache.camel.processor.CatchProcessor;
034 import org.apache.camel.processor.RedeliveryPolicy;
035 import org.apache.camel.util.ObjectHelper;
036
037 /**
038 * @version $Revision: 1.1 $
039 */
040 @XmlRootElement(name = "onException")
041 @XmlAccessorType(XmlAccessType.FIELD)
042 public class ExceptionType extends ProcessorType {
043 @XmlElementRef
044 private List<InterceptorType> interceptors = new ArrayList<InterceptorType>();
045 @XmlElement(name = "exception")
046 private List<String> exceptions = new ArrayList<String>();
047 @XmlElement(name = "redeliveryPolicy", required = false)
048 private RedeliveryPolicyType redeliveryPolicy;
049 @XmlElementRef
050 private List<ProcessorType> outputs = new ArrayList<ProcessorType>();
051 @XmlTransient
052 private List<Class> exceptionClasses;
053 @XmlTransient
054 private Processor errorHandler;
055
056 public ExceptionType() {
057 }
058
059 public ExceptionType(List<Class> exceptionClasses) {
060 this.exceptionClasses = exceptionClasses;
061 }
062
063 public ExceptionType(Class exceptionType) {
064 exceptionClasses = new ArrayList<Class>();
065 exceptionClasses.add(exceptionType);
066 }
067
068 @Override
069 public String toString() {
070 return "Exception[ " + getExceptionClasses() + " -> " + getOutputs() + "]";
071 }
072
073 /**
074 * Allows an exception handler to create a new redelivery policy for this exception type
075 * @param parentPolicy the current redelivery policy
076 * @return a newly created redelivery policy, or return the original policy if no customization is required
077 * for this exception handler.
078 */
079 public RedeliveryPolicy createRedeliveryPolicy(RedeliveryPolicy parentPolicy) {
080 if (redeliveryPolicy != null) {
081 return redeliveryPolicy.createRedeliveryPolicy(parentPolicy);
082 }
083 else if (errorHandler != null) {
084 // lets create a new error handler that has no retries
085 RedeliveryPolicy answer = parentPolicy.copy();
086 answer.setMaximumRedeliveries(0);
087 return answer;
088 }
089 return parentPolicy;
090 }
091
092 public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception {
093 // lets attach a processor to an error handler
094 errorHandler = routeContext.createProcessor(this);
095 ErrorHandlerBuilder builder = routeContext.getRoute().getErrorHandlerBuilder();
096 builder.addErrorHandlers(this);
097 }
098
099 @Override
100 public CatchProcessor createProcessor(RouteContext routeContext) throws Exception {
101 Processor childProcessor = routeContext.createProcessor(this);
102 return new CatchProcessor(getExceptionClasses(), childProcessor);
103 }
104
105
106 // Fluent API
107 //-------------------------------------------------------------------------
108 public ExceptionType backOffMultiplier(double backOffMultiplier) {
109 getOrCreateRedeliveryPolicy().backOffMultiplier(backOffMultiplier);
110 return this;
111 }
112
113 public ExceptionType collisionAvoidanceFactor(double collisionAvoidanceFactor) {
114 getOrCreateRedeliveryPolicy().collisionAvoidanceFactor(collisionAvoidanceFactor);
115 return this;
116 }
117
118 public ExceptionType collisionAvoidancePercent(short collisionAvoidancePercent) {
119 getOrCreateRedeliveryPolicy().collisionAvoidancePercent(collisionAvoidancePercent);
120 return this;
121 }
122
123 public ExceptionType initialRedeliveryDelay(long initialRedeliveryDelay) {
124 getOrCreateRedeliveryPolicy().initialRedeliveryDelay(initialRedeliveryDelay);
125 return this;
126 }
127
128 public ExceptionType maximumRedeliveries(int maximumRedeliveries) {
129 getOrCreateRedeliveryPolicy().maximumRedeliveries(maximumRedeliveries);
130 return this;
131 }
132
133 public ExceptionType useCollisionAvoidance() {
134 getOrCreateRedeliveryPolicy().useCollisionAvoidance();
135 return this;
136 }
137
138 public ExceptionType useExponentialBackOff() {
139 getOrCreateRedeliveryPolicy().useExponentialBackOff();
140 return this;
141 }
142
143
144 // Properties
145 //-------------------------------------------------------------------------
146 public List<InterceptorType> getInterceptors() {
147 return interceptors;
148 }
149
150 public void setInterceptors(List<InterceptorType> interceptors) {
151 this.interceptors = interceptors;
152 }
153
154 public List<ProcessorType> getOutputs() {
155 return outputs;
156 }
157
158 public void setOutputs(List<ProcessorType> outputs) {
159 this.outputs = outputs;
160 }
161
162 public List<Class> getExceptionClasses() {
163 if (exceptionClasses == null) {
164 exceptionClasses = createExceptionClasses();
165 }
166 return exceptionClasses;
167 }
168
169 public void setExceptionClasses(List<Class> exceptionClasses) {
170 this.exceptionClasses = exceptionClasses;
171 }
172
173 public List<String> getExceptions() {
174 return exceptions;
175 }
176
177 public void setExceptions(List<String> exceptions) {
178 this.exceptions = exceptions;
179 }
180
181 public Processor getErrorHandler() {
182 return errorHandler;
183 }
184
185 public RedeliveryPolicyType getRedeliveryPolicy() {
186 return redeliveryPolicy;
187 }
188
189 public void setRedeliveryPolicy(RedeliveryPolicyType redeliveryPolicy) {
190 this.redeliveryPolicy = redeliveryPolicy;
191 }
192
193 // Implementation methods
194 //-------------------------------------------------------------------------
195 protected RedeliveryPolicyType getOrCreateRedeliveryPolicy() {
196 if (redeliveryPolicy == null) {
197 redeliveryPolicy = new RedeliveryPolicyType();
198 }
199 return redeliveryPolicy;
200 }
201
202 protected List<Class> createExceptionClasses() {
203 List<String> list = getExceptions();
204 List<Class> answer = new ArrayList<Class>(list.size());
205 for (String name : list) {
206 Class type = ObjectHelper.loadClass(name, getClass().getClassLoader());
207 answer.add(type);
208 }
209 return answer;
210 }
211 }