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: 750806 $ 036 */ 037 @XmlRootElement(name = "try") 038 @XmlAccessorType(XmlAccessType.FIELD) 039 public class TryDefinition extends OutputDefinition<TryDefinition> { 040 @XmlTransient 041 private List<CatchDefinition> catchClauses; 042 @XmlTransient 043 private FinallyDefinition finallyClause; 044 @XmlTransient 045 private boolean initialized; 046 @XmlTransient 047 private List<ProcessorDefinition> 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 (CatchDefinition catchClause : catchClauses) { 070 catchProcessors.add(catchClause.createProcessor(routeContext)); 071 } 072 } 073 return new TryProcessor(tryProcessor, catchProcessors, finallyProcessor); 074 } 075 076 // Fluent API 077 // ------------------------------------------------------------------------- 078 079 /** 080 * Handles the given exception 081 * 082 * @param exceptionType the exception 083 * @return the try builder 084 */ 085 public TryDefinition handle(Class<?> exceptionType) { 086 popBlock(); 087 CatchDefinition answer = new CatchDefinition(exceptionType); 088 addOutput(answer); 089 pushBlock(answer); 090 return this; 091 } 092 093 /** 094 * The finally block for a given handle 095 * 096 * @return the try builder 097 */ 098 public TryDefinition finallyBlock() { 099 popBlock(); 100 FinallyDefinition answer = new FinallyDefinition(); 101 addOutput(answer); 102 pushBlock(answer); 103 return this; 104 } 105 106 @Override 107 public ProcessorDefinition<? extends ProcessorDefinition> end() { 108 popBlock(); 109 return super.end(); 110 } 111 112 // Properties 113 // ------------------------------------------------------------------------- 114 115 public List<CatchDefinition> getCatchClauses() { 116 if (catchClauses == null) { 117 checkInitialized(); 118 } 119 return catchClauses; 120 } 121 122 public FinallyDefinition getFinallyClause() { 123 if (finallyClause == null) { 124 checkInitialized(); 125 } 126 return finallyClause; 127 } 128 129 public List<ProcessorDefinition> getOutputsWithoutCatches() { 130 if (outputsWithoutCatches == null) { 131 checkInitialized(); 132 } 133 return outputsWithoutCatches; 134 } 135 136 public void setOutputs(List<ProcessorDefinition> outputs) { 137 initialized = false; 138 super.setOutputs(outputs); 139 } 140 141 @Override 142 public void addOutput(ProcessorDefinition output) { 143 initialized = false; 144 super.addOutput(output); 145 } 146 147 /** 148 * Checks whether or not this object has been initialized 149 */ 150 protected void checkInitialized() { 151 if (!initialized) { 152 initialized = true; 153 outputsWithoutCatches = new ArrayList<ProcessorDefinition>(); 154 catchClauses = new ArrayList<CatchDefinition>(); 155 finallyClause = null; 156 157 for (ProcessorDefinition output : outputs) { 158 if (output instanceof CatchDefinition) { 159 catchClauses.add((CatchDefinition)output); 160 } else if (output instanceof FinallyDefinition) { 161 if (finallyClause != null) { 162 throw new IllegalArgumentException("Multiple finally clauses added: " + finallyClause 163 + " and " + output); 164 } else { 165 finallyClause = (FinallyDefinition)output; 166 } 167 } else { 168 outputsWithoutCatches.add(output); 169 } 170 } 171 } 172 } 173 }