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