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