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.builder;
018
019 import java.util.ArrayList;
020 import java.util.List;
021 import java.util.concurrent.atomic.AtomicBoolean;
022
023 import org.apache.camel.CamelContext;
024 import org.apache.camel.Endpoint;
025 import org.apache.camel.Predicate;
026 import org.apache.camel.Route;
027 import org.apache.camel.Routes;
028 import org.apache.camel.impl.DefaultCamelContext;
029 import org.apache.camel.model.ChoiceType;
030 import org.apache.camel.model.ExceptionType;
031 import org.apache.camel.model.InterceptType;
032 import org.apache.camel.model.ProcessorType;
033 import org.apache.camel.model.RouteType;
034 import org.apache.camel.model.RoutesType;
035 import org.apache.camel.processor.DelegateProcessor;
036 import org.apache.camel.processor.interceptor.StreamCachingInterceptor;
037
038 /**
039 * A <a href="http://activemq.apache.org/camel/dsl.html">Java DSL</a> which is
040 * used to build {@link Route} instances in a {@link CamelContext} for smart routing.
041 *
042 * @version $Revision: 710133 $
043 */
044 public abstract class RouteBuilder extends BuilderSupport implements Routes {
045 private AtomicBoolean initialized = new AtomicBoolean(false);
046 private RoutesType routeCollection = new RoutesType();
047 private List<Route> routes = new ArrayList<Route>();
048
049 public RouteBuilder() {
050 this(null);
051 }
052
053 public RouteBuilder(CamelContext context) {
054 super(context);
055 }
056
057 @Override
058 public String toString() {
059 return routeCollection.toString();
060 }
061
062 /**
063 * Called on initialization to to build the required destinationBuilders
064 */
065 public abstract void configure() throws Exception;
066
067 /**
068 * Creates a new route from the given URI input
069 */
070 public RouteType from(String uri) {
071 RouteType answer = routeCollection.from(uri);
072 configureRoute(answer);
073 return answer;
074 }
075
076 /**
077 * Creates a new route from the given endpoint
078 */
079 public RouteType from(Endpoint endpoint) {
080 RouteType answer = routeCollection.from(endpoint);
081 configureRoute(answer);
082 return answer;
083 }
084
085 /**
086 * Installs the given error handler builder
087 *
088 * @param errorHandlerBuilder the error handler to be used by default for
089 * all child routes
090 * @return the current builder with the error handler configured
091 */
092 public RouteBuilder errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
093 setErrorHandlerBuilder(errorHandlerBuilder);
094 return this;
095 }
096
097 /**
098 * Configures whether or not the error handler is inherited by every
099 * processing node (or just the top most one)
100 *
101 * @param value the flag as to whether error handlers should be inherited or not
102 * @return the current builder
103 */
104 public RouteBuilder inheritErrorHandler(boolean value) {
105 routeCollection.setInheritErrorHandlerFlag(value);
106 return this;
107 }
108
109 /**
110 * Adds the given interceptor to this route
111 */
112 public RouteBuilder intercept(DelegateProcessor interceptor) {
113 routeCollection.intercept(interceptor);
114 return this;
115 }
116
117 /**
118 * Adds a route for an interceptor; use the {@link ProcessorType#proceed()} method
119 * to continue processing the underlying route being intercepted.
120 */
121 public InterceptType intercept() {
122 return routeCollection.intercept();
123 }
124
125 /**
126 * Applies a route for an interceptor if the given predicate is true
127 * otherwise the interceptor route is not applied
128 */
129 public ChoiceType intercept(Predicate predicate) {
130 return routeCollection.intercept(predicate);
131 }
132
133 /**
134 * Adds an exception handler route for the given exception type
135 */
136 public ExceptionType onException(Class exceptionType) {
137 return routeCollection.onException(exceptionType);
138 }
139
140 /**
141 * Adds an exception handler route for the given exception types
142 */
143 public ExceptionType onException(Class... exceptions) {
144 ExceptionType last = null;
145 for (Class ex : exceptions) {
146 last = last == null ? onException(ex) : last.onException(ex);
147 }
148 return last != null ? last : onException(Exception.class);
149 }
150
151 /**
152 * Adds an exception handler route for the given exception type
153 *
154 * @deprecated Please use {@link #onException(Class)} instead. Will be removed in Camel 2.0.
155 */
156 public ExceptionType exception(Class exceptionType) {
157 return onException(exceptionType);
158 }
159
160 // Properties
161 // -----------------------------------------------------------------------
162 public CamelContext getContext() {
163 CamelContext context = super.getContext();
164 if (context == null) {
165 context = createContainer();
166 setContext(context);
167 }
168 return context;
169 }
170
171 /**
172 * Uses {@link org.apache.camel.CamelContext#getRoutes()} to return the routes in the context.
173 */
174 public List<Route> getRouteList() throws Exception {
175 checkInitialized();
176 return routes;
177 }
178
179 @Override
180 public void setInheritErrorHandler(boolean inheritErrorHandler) {
181 super.setInheritErrorHandler(inheritErrorHandler);
182 routeCollection.setInheritErrorHandlerFlag(inheritErrorHandler);
183
184 }
185
186 @Override
187 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
188 super.setErrorHandlerBuilder(errorHandlerBuilder);
189 routeCollection.setErrorHandlerBuilder(getErrorHandlerBuilder());
190 }
191
192 // Implementation methods
193 // -----------------------------------------------------------------------
194 protected void checkInitialized() throws Exception {
195 if (initialized.compareAndSet(false, true)) {
196 // Set the CamelContext ErrorHandler here
197 CamelContext camelContext = getContext();
198 if (camelContext.getErrorHandlerBuilder() != null) {
199 setErrorHandlerBuilder(camelContext.getErrorHandlerBuilder());
200 }
201 configure();
202 populateRoutes(routes);
203 }
204 }
205
206 protected void populateRoutes(List<Route> routes) throws Exception {
207 CamelContext camelContext = getContext();
208 if (camelContext == null) {
209 throw new IllegalArgumentException("No CamelContext has been injected!");
210 }
211 routeCollection.setCamelContext(camelContext);
212 camelContext.addRouteDefinitions(routeCollection.getRoutes());
213 }
214
215 public void setRouteCollection(RoutesType routeCollection) {
216 this.routeCollection = routeCollection;
217 }
218
219 public RoutesType getRouteCollection() {
220 return this.routeCollection;
221 }
222
223 /**
224 * Completely disable stream caching for all routes being defined in the same RouteBuilder after this.
225 */
226 public void noStreamCaching() {
227 StreamCachingInterceptor.noStreamCaching(routeCollection.getInterceptors());
228 }
229
230 /**
231 * Enable stream caching for all routes being defined in the same RouteBuilder after this call.
232 */
233 public void streamCaching() {
234 routeCollection.intercept(new StreamCachingInterceptor());
235 }
236
237 /**
238 * Factory method
239 */
240 protected CamelContext createContainer() {
241 return new DefaultCamelContext();
242 }
243
244 protected void configureRoute(RouteType route) {
245 route.setGroup(getClass().getName());
246 }
247
248 protected void addRoutes(Routes routes) throws Exception {
249 getContext().addRoutes(routes);
250 }
251 }