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.Collection;
021 import java.util.List;
022
023 import javax.xml.bind.annotation.XmlAccessType;
024 import javax.xml.bind.annotation.XmlAccessorType;
025 import javax.xml.bind.annotation.XmlAttribute;
026 import javax.xml.bind.annotation.XmlElementRef;
027 import javax.xml.bind.annotation.XmlRootElement;
028 import javax.xml.bind.annotation.XmlTransient;
029 import javax.xml.bind.annotation.XmlType;
030
031 import org.apache.camel.CamelContext;
032 import org.apache.camel.CamelContextAware;
033 import org.apache.camel.Endpoint;
034 import org.apache.camel.NoSuchEndpointException;
035 import org.apache.camel.Route;
036 import org.apache.camel.builder.ErrorHandlerBuilder;
037 import org.apache.camel.impl.DefaultCamelContext;
038 import org.apache.camel.impl.DefaultRouteContext;
039 import org.apache.camel.processor.interceptor.StreamCachingInterceptor;
040 import org.apache.camel.spi.RouteContext;
041 import org.apache.camel.util.CamelContextHelper;
042 import org.apache.commons.logging.Log;
043 import org.apache.commons.logging.LogFactory;
044
045 /**
046 * Represents an XML <route/> element
047 *
048 * @version $Revision: 674383 $
049 */
050 @XmlRootElement(name = "route")
051 @XmlType(propOrder = {"inputs", "outputs" })
052 @XmlAccessorType(XmlAccessType.PROPERTY)
053 public class RouteType extends ProcessorType<ProcessorType> implements CamelContextAware {
054 private static final transient Log LOG = LogFactory.getLog(RouteType.class);
055 private List<InterceptorType> interceptors = new ArrayList<InterceptorType>();
056 private List<FromType> inputs = new ArrayList<FromType>();
057 private List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>();
058 private String group;
059 private CamelContext camelContext;
060 private Boolean streamCaching;
061
062 public RouteType() {
063 }
064
065 public RouteType(String uri) {
066 from(uri);
067 }
068
069 public RouteType(Endpoint endpoint) {
070 from(endpoint);
071 }
072
073 @Override
074 public String toString() {
075 return "Route[ " + inputs + " -> " + outputs + "]";
076 }
077
078 public void addRoutes(CamelContext context, Collection<Route> routes) throws Exception {
079 setCamelContext(context);
080
081 if (context instanceof DefaultCamelContext) {
082 DefaultCamelContext defaultCamelContext = (DefaultCamelContext) context;
083 ErrorHandlerBuilder handler = defaultCamelContext.getErrorHandlerBuilder();
084 if (handler != null) {
085 setErrorHandlerBuilderIfNull(handler);
086 }
087 }
088
089 for (FromType fromType : inputs) {
090 addRoutes(routes, fromType);
091 }
092 }
093
094
095 public Endpoint resolveEndpoint(String uri) throws NoSuchEndpointException {
096 CamelContext context = getCamelContext();
097 if (context == null) {
098 throw new IllegalArgumentException("No CamelContext has been injected!");
099 }
100 return CamelContextHelper.getMandatoryEndpoint(context, uri);
101 }
102
103 // Fluent API
104 // -----------------------------------------------------------------------
105
106 /**
107 * Creates an input to the route
108 */
109 public RouteType from(String uri) {
110 getInputs().add(new FromType(uri));
111 return this;
112 }
113
114 /**
115 * Creates an input to the route
116 */
117 public RouteType from(Endpoint endpoint) {
118 getInputs().add(new FromType(endpoint));
119 return this;
120 }
121
122 /**
123 * Set the group name for this route
124 */
125 public RouteType group(String name) {
126 setGroup(name);
127 return this;
128 }
129
130 // Properties
131 // -----------------------------------------------------------------------
132
133 public List<InterceptorType> getInterceptors() {
134 return interceptors;
135 }
136
137 @XmlTransient
138 public void setInterceptors(List<InterceptorType> interceptors) {
139 this.interceptors = interceptors;
140 }
141
142 public List<FromType> getInputs() {
143 return inputs;
144 }
145
146 @XmlElementRef
147 public void setInputs(List<FromType> inputs) {
148 this.inputs = inputs;
149 }
150
151 public List<ProcessorType<?>> getOutputs() {
152 return outputs;
153 }
154
155 @XmlElementRef
156 public void setOutputs(List<ProcessorType<?>> outputs) {
157 this.outputs = outputs;
158
159 // TODO I don't think this is called when using JAXB!
160 if (outputs != null) {
161 for (ProcessorType output : outputs) {
162 configureChild(output);
163 }
164 }
165 }
166
167 public CamelContext getCamelContext() {
168 return camelContext;
169 }
170
171 @XmlTransient
172 public void setCamelContext(CamelContext camelContext) {
173 this.camelContext = camelContext;
174 }
175
176 /**
177 * The group that this route belongs to; could be the name of the RouteBuilder class
178 * or be explicitly configured in the XML.
179 *
180 * May be null.
181 */
182 public String getGroup() {
183 return group;
184 }
185
186 @XmlAttribute
187 public void setGroup(String group) {
188 this.group = group;
189 }
190
191 public Boolean getStreamCaching() {
192 return streamCaching;
193 }
194
195 /**
196 * Enable stream caching on this route
197 * @param streamCaching <code>true</code> for enabling stream caching
198 */
199 @XmlAttribute(required = false)
200 public void setStreamCaching(Boolean streamCaching) {
201 this.streamCaching = streamCaching;
202 if (streamCaching != null && streamCaching) {
203 streamCaching();
204 } else {
205 noStreamCaching();
206 }
207 }
208
209
210 // Implementation methods
211 // -------------------------------------------------------------------------
212 protected void addRoutes(Collection<Route> routes, FromType fromType) throws Exception {
213 RouteContext routeContext = new DefaultRouteContext(this, fromType, routes);
214 routeContext.getEndpoint(); // force endpoint resolution
215 if (camelContext != null) {
216 camelContext.getLifecycleStrategy().onRouteContextCreate(routeContext);
217 }
218
219 List<ProcessorType<?>> list = new ArrayList<ProcessorType<?>>(outputs);
220 for (ProcessorType output : list) {
221 output.addRoutes(routeContext, routes);
222 }
223
224 routeContext.commit();
225 }
226
227 @Override
228 protected void configureChild(ProcessorType output) {
229 super.configureChild(output);
230
231 if (isInheritErrorHandler()) {
232 output.setErrorHandlerBuilder(getErrorHandlerBuilder());
233 }
234
235 List<InterceptorType> interceptors = getInterceptors();
236 for (InterceptorType interceptor : interceptors) {
237 output.addInterceptor(interceptor);
238 }
239 /*
240 List<InterceptorType> list = output.getInterceptors();
241 if (list == null) {
242 LOG.warn("No interceptor collection: " + output);
243 } else {
244 list.addAll(getInterceptors());
245 }
246 */
247 }
248
249 /**
250 * Disable stream caching for this Route.
251 */
252 public RouteType noStreamCaching() {
253 StreamCachingInterceptor.noStreamCaching(interceptors);
254 return this;
255 }
256
257 /**
258 * Enable stream caching for this Route.
259 */
260 public RouteType streamCaching() {
261 addInterceptor(new StreamCachingInterceptor());
262 return this;
263 }
264
265 @Override
266 public void addInterceptor(InterceptorType interceptor) {
267 getInterceptors().add(interceptor);
268 }
269 }