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: 705880 $
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 }