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