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