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: 660266 $ 042 */ 043 @XmlRootElement(name = "onException") 044 @XmlAccessorType(XmlAccessType.FIELD) 045 public class ExceptionType extends ProcessorType<ProcessorType> { 046 047 /* 048 @XmlElementRef 049 private List<InterceptorType> interceptors = new ArrayList<InterceptorType>(); 050 */ 051 @XmlElement(name = "exception") 052 private List<String> exceptions = new ArrayList<String>(); 053 @XmlElement(name = "redeliveryPolicy", required = false) 054 private RedeliveryPolicyType redeliveryPolicy; 055 @XmlElementRef 056 private List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>(); 057 @XmlTransient 058 private List<Class> exceptionClasses; 059 @XmlTransient 060 private Processor errorHandler; 061 062 public ExceptionType() { 063 } 064 065 public ExceptionType(List<Class> exceptionClasses) { 066 this.exceptionClasses = exceptionClasses; 067 } 068 069 public ExceptionType(Class exceptionType) { 070 exceptionClasses = new ArrayList<Class>(); 071 exceptionClasses.add(exceptionType); 072 } 073 074 @Override 075 public String toString() { 076 return "Exception[ " + getExceptionClasses() + " -> " + getOutputs() + "]"; 077 } 078 079 /** 080 * Allows an exception handler to create a new redelivery policy for this exception type 081 * @param parentPolicy the current redelivery policy 082 * @return a newly created redelivery policy, or return the original policy if no customization is required 083 * for this exception handler. 084 */ 085 public RedeliveryPolicy createRedeliveryPolicy(RedeliveryPolicy parentPolicy) { 086 if (redeliveryPolicy != null) { 087 return redeliveryPolicy.createRedeliveryPolicy(parentPolicy); 088 } else if (errorHandler != null) { 089 // lets create a new error handler that has no retries 090 RedeliveryPolicy answer = parentPolicy.copy(); 091 answer.setMaximumRedeliveries(0); 092 return answer; 093 } 094 return parentPolicy; 095 } 096 097 public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception { 098 // lets attach a processor to an error handler 099 errorHandler = routeContext.createProcessor(this); 100 ErrorHandlerBuilder builder = routeContext.getRoute().getErrorHandlerBuilder(); 101 builder.addErrorHandlers(this); 102 } 103 104 @Override 105 public CatchProcessor createProcessor(RouteContext routeContext) throws Exception { 106 Processor childProcessor = routeContext.createProcessor(this); 107 return new CatchProcessor(getExceptionClasses(), childProcessor); 108 } 109 110 111 // Fluent API 112 //------------------------------------------------------------------------- 113 public ExceptionType backOffMultiplier(double backOffMultiplier) { 114 getOrCreateRedeliveryPolicy().backOffMultiplier(backOffMultiplier); 115 return this; 116 } 117 118 public ExceptionType collisionAvoidanceFactor(double collisionAvoidanceFactor) { 119 getOrCreateRedeliveryPolicy().collisionAvoidanceFactor(collisionAvoidanceFactor); 120 return this; 121 } 122 123 public ExceptionType collisionAvoidancePercent(short collisionAvoidancePercent) { 124 getOrCreateRedeliveryPolicy().collisionAvoidancePercent(collisionAvoidancePercent); 125 return this; 126 } 127 128 public ExceptionType initialRedeliveryDelay(long initialRedeliveryDelay) { 129 getOrCreateRedeliveryPolicy().initialRedeliveryDelay(initialRedeliveryDelay); 130 return this; 131 } 132 133 public ExceptionType maximumRedeliveries(int maximumRedeliveries) { 134 getOrCreateRedeliveryPolicy().maximumRedeliveries(maximumRedeliveries); 135 return this; 136 } 137 138 public ExceptionType useCollisionAvoidance() { 139 getOrCreateRedeliveryPolicy().useCollisionAvoidance(); 140 return this; 141 } 142 143 public ExceptionType useExponentialBackOff() { 144 getOrCreateRedeliveryPolicy().useExponentialBackOff(); 145 return this; 146 } 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 }