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 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.Expression; 030 import org.apache.camel.Predicate; 031 import org.apache.camel.Processor; 032 import org.apache.camel.builder.ExpressionBuilder; 033 import org.apache.camel.builder.ExpressionClause; 034 import org.apache.camel.processor.CatchProcessor; 035 import org.apache.camel.spi.RouteContext; 036 import org.apache.camel.util.ObjectHelper; 037 import static org.apache.camel.builder.PredicateBuilder.toPredicate; 038 039 /** 040 * Represents an XML <catch/> element 041 * 042 * @version $Revision: 766610 $ 043 */ 044 @XmlRootElement(name = "doCatch") 045 @XmlAccessorType(XmlAccessType.FIELD) 046 public class CatchDefinition extends ProcessorDefinition<CatchDefinition> { 047 @XmlElement(name = "exception") 048 private List<String> exceptions = new ArrayList<String>(); 049 @XmlElement(name = "onWhen", required = false) 050 private WhenDefinition onWhen; 051 @XmlElement(name = "handled", required = false) 052 private ExpressionSubElementDefinition handled; 053 @XmlElementRef 054 private List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>(); 055 @XmlTransient 056 private List<Class> exceptionClasses; 057 @XmlTransient 058 private Predicate handledPolicy; 059 060 public CatchDefinition() { 061 } 062 063 public CatchDefinition(List<Class> exceptionClasses) { 064 this.exceptionClasses = exceptionClasses; 065 } 066 067 public CatchDefinition(Class exceptionType) { 068 exceptionClasses = new ArrayList<Class>(); 069 exceptionClasses.add(exceptionType); 070 } 071 072 @Override 073 public String toString() { 074 return "DoCatch[ " + getExceptionClasses() + " -> " + getOutputs() + "]"; 075 } 076 077 @Override 078 public String getShortName() { 079 return "doCatch"; 080 } 081 082 @Override 083 public String getLabel() { 084 return getExceptionClasses().toString(); 085 } 086 087 @Override 088 public CatchProcessor createProcessor(RouteContext routeContext) throws Exception { 089 Processor childProcessor = routeContext.createProcessor(this); 090 091 Predicate when = null; 092 if (onWhen != null) { 093 when = onWhen.getExpression().createPredicate(routeContext); 094 } 095 096 Predicate handle = handledPolicy; 097 if (handled != null) { 098 handle = handled.createPredicate(routeContext); 099 } 100 101 return new CatchProcessor(getExceptionClasses(), childProcessor, when, handle); 102 } 103 104 public List<ProcessorDefinition> getOutputs() { 105 return outputs; 106 } 107 108 public void setOutputs(List<ProcessorDefinition> outputs) { 109 this.outputs = outputs; 110 } 111 112 public List<Class> getExceptionClasses() { 113 if (exceptionClasses == null) { 114 exceptionClasses = createExceptionClasses(); 115 } 116 return exceptionClasses; 117 } 118 119 public void setExceptionClasses(List<Class> exceptionClasses) { 120 this.exceptionClasses = exceptionClasses; 121 } 122 123 // Fluent API 124 //------------------------------------------------------------------------- 125 /** 126 * Sets the exceptionClasses of the CatchType 127 * 128 * @param exceptionClasses a list of the exception classes 129 * @return the builder 130 */ 131 public CatchDefinition exceptionClasses(List<Class> exceptionClasses) { 132 setExceptionClasses(exceptionClasses); 133 return this; 134 } 135 136 /** 137 * Sets an additional predicate that should be true before the onCatch is triggered. 138 * <p/> 139 * To be used for fine grained controlling whether a thrown exception should be intercepted 140 * by this exception type or not. 141 * 142 * @param predicate predicate that determines true or false 143 * @return the builder 144 */ 145 public CatchDefinition onWhen(Predicate predicate) { 146 setOnWhen(new WhenDefinition(predicate)); 147 return this; 148 } 149 150 /** 151 * Creates an expression to configure an additional predicate that should be true before the 152 * onCatch is triggered. 153 * <p/> 154 * To be used for fine grained controlling whether a thrown exception should be intercepted 155 * by this exception type or not. 156 * 157 * @return the expression clause to configure 158 */ 159 public ExpressionClause<CatchDefinition> onWhen() { 160 onWhen = new WhenDefinition(); 161 ExpressionClause<CatchDefinition> clause = new ExpressionClause<CatchDefinition>(this); 162 onWhen.setExpression(clause); 163 return clause; 164 } 165 166 /** 167 * Sets whether the exchange should be marked as handled or not. 168 * 169 * @param handled handled or not 170 * @return the builder 171 */ 172 public CatchDefinition handled(boolean handled) { 173 Expression expression = ExpressionBuilder.constantExpression(Boolean.toString(handled)); 174 return handled(expression); 175 } 176 177 /** 178 * Sets whether the exchange should be marked as handled or not. 179 * 180 * @param handled predicate that determines true or false 181 * @return the builder 182 */ 183 public CatchDefinition handled(Predicate handled) { 184 setHandledPolicy(handled); 185 return this; 186 } 187 188 /** 189 * Sets whether the exchange should be marked as handled or not. 190 * 191 * @param handled expression that determines true or false 192 * @return the builder 193 */ 194 public CatchDefinition handled(Expression handled) { 195 setHandledPolicy(toPredicate(handled)); 196 return this; 197 } 198 199 /** 200 * Sets the exception class that the CatchType want to catch 201 * 202 * @param exception the exception of class 203 * @return the builder 204 */ 205 public CatchDefinition exceptionClasses(Class exception) { 206 List<Class> list = getExceptionClasses(); 207 list.add(exception); 208 return this; 209 } 210 211 public List<String> getExceptions() { 212 return exceptions; 213 } 214 215 public void setExceptions(List<String> exceptions) { 216 this.exceptions = exceptions; 217 } 218 219 public WhenDefinition getOnWhen() { 220 return onWhen; 221 } 222 223 public void setOnWhen(WhenDefinition onWhen) { 224 this.onWhen = onWhen; 225 } 226 227 public Predicate getHandledPolicy() { 228 return handledPolicy; 229 } 230 231 public void setHandledPolicy(Predicate handledPolicy) { 232 this.handledPolicy = handledPolicy; 233 } 234 235 protected List<Class> createExceptionClasses() { 236 List<String> list = getExceptions(); 237 List<Class> answer = new ArrayList<Class>(list.size()); 238 for (String name : list) { 239 Class type = ObjectHelper.loadClass(name, getClass().getClassLoader()); 240 answer.add(type); 241 } 242 return answer; 243 } 244 }