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.XmlRootElement; 025 import javax.xml.bind.annotation.XmlTransient; 026 027 import org.apache.camel.Processor; 028 import org.apache.camel.processor.CatchProcessor; 029 import org.apache.camel.processor.TryProcessor; 030 import org.apache.camel.spi.RouteContext; 031 032 /** 033 * Represents an XML <try/> element 034 * 035 * @version $Revision: 42401 $ 036 */ 037 @XmlRootElement(name = "try") 038 @XmlAccessorType(XmlAccessType.FIELD) 039 public class TryType extends OutputType<TryType> { 040 @XmlTransient 041 private List<CatchType> catchClauses; 042 @XmlTransient 043 private FinallyType finallyClause; 044 @XmlTransient 045 private boolean initialized; 046 @XmlTransient 047 private List<ProcessorType<?>> outputsWithoutCatches; 048 049 @Override 050 public String toString() { 051 return "Try[ " + getOutputs() + "]"; 052 } 053 054 @Override 055 public Processor createProcessor(RouteContext routeContext) throws Exception { 056 Processor tryProcessor = createOutputsProcessor(routeContext, getOutputsWithoutCatches()); 057 058 Processor finallyProcessor = null; 059 if (finallyClause != null) { 060 finallyProcessor = finallyClause.createProcessor(routeContext); 061 } 062 List<CatchProcessor> catchProcessors = new ArrayList<CatchProcessor>(); 063 if (catchClauses != null) { 064 for (CatchType catchClause : catchClauses) { 065 catchProcessors.add(catchClause.createProcessor(routeContext)); 066 } 067 } 068 return new TryProcessor(tryProcessor, catchProcessors, finallyProcessor); 069 } 070 071 // Fluent API 072 // ------------------------------------------------------------------------- 073 public TryType handle(Class<?> exceptionType) { 074 popBlock(); 075 CatchType answer = new CatchType(exceptionType); 076 addOutput(answer); 077 pushBlock(answer); 078 return this; 079 } 080 081 /** 082 * @deprecated Use {@link #finallyBlock()} instead, as the name 083 * is better. Current name sugests that it handles exception, 084 * while it mimics java finally keyword. Will be removed in Camel 2.0. 085 */ 086 @Deprecated 087 public TryType handleAll() { 088 return finallyBlock(); 089 } 090 091 public TryType finallyBlock() { 092 popBlock(); 093 FinallyType answer = new FinallyType(); 094 addOutput(answer); 095 pushBlock(answer); 096 return this; 097 } 098 099 @Override 100 public ProcessorType<? extends ProcessorType> end() { 101 popBlock(); 102 return super.end(); 103 } 104 105 // Properties 106 // ------------------------------------------------------------------------- 107 108 public List<CatchType> getCatchClauses() { 109 if (catchClauses == null) { 110 checkInitialized(); 111 } 112 return catchClauses; 113 } 114 115 public FinallyType getFinallyClause() { 116 if (finallyClause == null) { 117 checkInitialized(); 118 } 119 return finallyClause; 120 } 121 122 public List<ProcessorType<?>> getOutputsWithoutCatches() { 123 if (outputsWithoutCatches == null) { 124 checkInitialized(); 125 } 126 return outputsWithoutCatches; 127 } 128 129 public void setOutputs(List<ProcessorType<?>> outputs) { 130 initialized = false; 131 super.setOutputs(outputs); 132 } 133 134 @Override 135 public void addOutput(ProcessorType output) { 136 initialized = false; 137 super.addOutput(output); 138 } 139 140 /** 141 * Checks whether or not this object has been initialized 142 */ 143 protected void checkInitialized() { 144 if (!initialized) { 145 initialized = true; 146 outputsWithoutCatches = new ArrayList<ProcessorType<?>>(); 147 catchClauses = new ArrayList<CatchType>(); 148 finallyClause = null; 149 150 for (ProcessorType output : outputs) { 151 if (output instanceof CatchType) { 152 catchClauses.add((CatchType)output); 153 } else if (output instanceof FinallyType) { 154 if (finallyClause != null) { 155 throw new IllegalArgumentException("Multiple finally clauses added: " + finallyClause 156 + " and " + output); 157 } else { 158 finallyClause = (FinallyType)output; 159 } 160 } else { 161 outputsWithoutCatches.add(output); 162 } 163 } 164 } 165 } 166 }