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