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: 43540 $ 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 String getShortName() { 056 return "try"; 057 } 058 059 @Override 060 public Processor createProcessor(RouteContext routeContext) throws Exception { 061 Processor tryProcessor = createOutputsProcessor(routeContext, getOutputsWithoutCatches()); 062 063 Processor finallyProcessor = null; 064 if (finallyClause != null) { 065 finallyProcessor = finallyClause.createProcessor(routeContext); 066 } 067 List<CatchProcessor> catchProcessors = new ArrayList<CatchProcessor>(); 068 if (catchClauses != null) { 069 for (CatchType catchClause : catchClauses) { 070 catchProcessors.add(catchClause.createProcessor(routeContext)); 071 } 072 } 073 return new TryProcessor(tryProcessor, catchProcessors, finallyProcessor); 074 } 075 076 // Fluent API 077 // ------------------------------------------------------------------------- 078 public TryType handle(Class<?> exceptionType) { 079 popBlock(); 080 CatchType answer = new CatchType(exceptionType); 081 addOutput(answer); 082 pushBlock(answer); 083 return this; 084 } 085 086 /** 087 * @deprecated Use {@link #finallyBlock()} instead, as the name 088 * is better. Current name sugests that it handles exception, 089 * while it mimics java finally keyword. Will be removed in Camel 2.0. 090 */ 091 @Deprecated 092 public TryType handleAll() { 093 return finallyBlock(); 094 } 095 096 public TryType finallyBlock() { 097 popBlock(); 098 FinallyType answer = new FinallyType(); 099 addOutput(answer); 100 pushBlock(answer); 101 return this; 102 } 103 104 @Override 105 public ProcessorType<? extends ProcessorType> end() { 106 popBlock(); 107 return super.end(); 108 } 109 110 // Properties 111 // ------------------------------------------------------------------------- 112 113 public List<CatchType> getCatchClauses() { 114 if (catchClauses == null) { 115 checkInitialized(); 116 } 117 return catchClauses; 118 } 119 120 public FinallyType getFinallyClause() { 121 if (finallyClause == null) { 122 checkInitialized(); 123 } 124 return finallyClause; 125 } 126 127 public List<ProcessorType<?>> getOutputsWithoutCatches() { 128 if (outputsWithoutCatches == null) { 129 checkInitialized(); 130 } 131 return outputsWithoutCatches; 132 } 133 134 public void setOutputs(List<ProcessorType<?>> outputs) { 135 initialized = false; 136 super.setOutputs(outputs); 137 } 138 139 @Override 140 public void addOutput(ProcessorType output) { 141 initialized = false; 142 super.addOutput(output); 143 } 144 145 /** 146 * Checks whether or not this object has been initialized 147 */ 148 protected void checkInitialized() { 149 if (!initialized) { 150 initialized = true; 151 outputsWithoutCatches = new ArrayList<ProcessorType<?>>(); 152 catchClauses = new ArrayList<CatchType>(); 153 finallyClause = null; 154 155 for (ProcessorType output : outputs) { 156 if (output instanceof CatchType) { 157 catchClauses.add((CatchType)output); 158 } else if (output instanceof FinallyType) { 159 if (finallyClause != null) { 160 throw new IllegalArgumentException("Multiple finally clauses added: " + finallyClause 161 + " and " + output); 162 } else { 163 finallyClause = (FinallyType)output; 164 } 165 } else { 166 outputsWithoutCatches.add(output); 167 } 168 } 169 } 170 } 171 }