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.Route;
026 import org.apache.camel.RoutesBuilder;
027 import org.apache.camel.impl.DefaultCamelContext;
028 import org.apache.camel.model.InterceptDefinition;
029 import org.apache.camel.model.InterceptFromDefinition;
030 import org.apache.camel.model.InterceptSendToEndpointDefinition;
031 import org.apache.camel.model.OnCompletionDefinition;
032 import org.apache.camel.model.OnExceptionDefinition;
033 import org.apache.camel.model.RouteDefinition;
034 import org.apache.camel.model.RoutesDefinition;
035
036 /**
037 * A <a href="http://camel.apache.org/dsl.html">Java DSL</a> which is
038 * used to build {@link org.apache.camel.impl.DefaultRoute} instances in a {@link CamelContext} for smart routing.
039 *
040 * @version $Revision: 788067 $
041 */
042 public abstract class RouteBuilder extends BuilderSupport implements RoutesBuilder {
043 private AtomicBoolean initialized = new AtomicBoolean(false);
044 private RoutesDefinition routeCollection = new RoutesDefinition();
045 private List<Route> routes = new ArrayList<Route>();
046
047 public RouteBuilder() {
048 this(null);
049 }
050
051 public RouteBuilder(CamelContext context) {
052 super(context);
053 }
054
055 @Override
056 public String toString() {
057 return routeCollection.toString();
058 }
059
060 /**
061 * <b>Called on initialization to build the routes using the fluent builder syntax.</b>
062 * <p/>
063 * This is a central method for RouteBuilder implementations to implement
064 * the routes using the Java fluent builder syntax.
065 *
066 * @throws Exception can be thrown during configuration
067 */
068 public abstract void configure() throws Exception;
069
070 /**
071 * Creates a new route from the given URI input
072 *
073 * @param uri the from uri
074 * @return the builder
075 */
076 public RouteDefinition from(String uri) {
077 routeCollection.setCamelContext(getContext());
078 RouteDefinition answer = routeCollection.from(uri);
079 configureRoute(answer);
080 return answer;
081 }
082
083 /**
084 * Creates a new route from the given URI input
085 *
086 * @param uri the String formatted from uri
087 * @param args arguments for the string formatting of the uri
088 * @return the builder
089 */
090 public RouteDefinition fromF(String uri, Object... args) {
091 routeCollection.setCamelContext(getContext());
092 RouteDefinition answer = routeCollection.from(String.format(uri, args));
093 configureRoute(answer);
094 return answer;
095 }
096
097 /**
098 * Creates a new route from the given endpoint
099 *
100 * @param endpoint the from endpoint
101 * @return the builder
102 */
103 public RouteDefinition from(Endpoint endpoint) {
104 routeCollection.setCamelContext(getContext());
105 RouteDefinition answer = routeCollection.from(endpoint);
106 configureRoute(answer);
107 return answer;
108 }
109
110 /**
111 * Creates a new route from the given URIs input
112 *
113 * @param uris the from uris
114 * @return the builder
115 */
116 public RouteDefinition from(String... uris) {
117 routeCollection.setCamelContext(getContext());
118 RouteDefinition answer = routeCollection.from(uris);
119 configureRoute(answer);
120 return answer;
121 }
122
123 /**
124 * Creates a new route from the given endpoint
125 *
126 * @param endpoints the from endpoints
127 * @return the builder
128 */
129 public RouteDefinition from(Endpoint... endpoints) {
130 routeCollection.setCamelContext(getContext());
131 RouteDefinition answer = routeCollection.from(endpoints);
132 configureRoute(answer);
133 return answer;
134 }
135
136 /**
137 * Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder
138 *
139 * @param errorHandlerBuilder the error handler to be used by default for all child routes
140 * @return the current builder with the error handler configured
141 */
142 public RouteBuilder errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
143 routeCollection.setCamelContext(getContext());
144 setErrorHandlerBuilder(errorHandlerBuilder);
145 return this;
146 }
147
148 /**
149 * Adds a route for an interceptor that intercepts every processing step.
150 *
151 * @return the builder
152 */
153 public InterceptDefinition intercept() {
154 routeCollection.setCamelContext(getContext());
155 return routeCollection.intercept();
156 }
157
158 /**
159 * Adds a route for an interceptor that intercepts incoming messages on any inputs in this route
160 *
161 * @return the builder
162 */
163 public InterceptFromDefinition interceptFrom() {
164 routeCollection.setCamelContext(getContext());
165 return routeCollection.interceptFrom();
166 }
167
168 /**
169 * Adds a route for an interceptor that intercepts incoming messages on the given endpoint.
170 *
171 * @param uri endpoint uri
172 * @return the builder
173 */
174 public InterceptFromDefinition interceptFrom(String uri) {
175 routeCollection.setCamelContext(getContext());
176 return routeCollection.interceptFrom(uri);
177 }
178
179 /**
180 * Applies a route for an interceptor if an exchange is send to the given endpoint
181 *
182 * @param uri endpoint uri
183 * @return the builder
184 */
185 public InterceptSendToEndpointDefinition interceptSendToEndpoint(String uri) {
186 routeCollection.setCamelContext(getContext());
187 return routeCollection.interceptSendToEndpoint(uri);
188 }
189
190 /**
191 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
192 * for catching certain exceptions and handling them.
193 *
194 * @param exception exception to catch
195 * @return the builder
196 */
197 public OnExceptionDefinition onException(Class exception) {
198 routeCollection.setCamelContext(getContext());
199 return routeCollection.onException(exception);
200 }
201
202 /**
203 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a>
204 * for catching certain exceptions and handling them.
205 *
206 * @param exceptions list of exceptions to catch
207 * @return the builder
208 */
209 public OnExceptionDefinition onException(Class... exceptions) {
210 OnExceptionDefinition last = null;
211 for (Class ex : exceptions) {
212 last = last == null ? onException(ex) : last.onException(ex);
213 }
214 return last != null ? last : onException(Exception.class);
215 }
216
217 /**
218 * <a href="http://camel.apache.org/oncompletion.html">On completion</a>
219 * callback for doing custom routing when the {@link org.apache.camel.Exchange} is complete.
220 *
221 * @return the builder
222 */
223 public OnCompletionDefinition onCompletion() {
224 routeCollection.setCamelContext(getContext());
225 return routeCollection.onCompletion();
226 }
227
228 // Properties
229 // -----------------------------------------------------------------------
230 public CamelContext getContext() {
231 CamelContext context = super.getContext();
232 if (context == null) {
233 context = createContainer();
234 setContext(context);
235 }
236 return context;
237 }
238
239 public void addRoutesToCamelContext(CamelContext context) throws Exception {
240 setContext(context);
241 checkInitialized();
242 }
243
244 @Override
245 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) {
246 super.setErrorHandlerBuilder(errorHandlerBuilder);
247 routeCollection.setErrorHandlerBuilder(getErrorHandlerBuilder());
248 }
249
250 // Implementation methods
251 // -----------------------------------------------------------------------
252 protected void checkInitialized() throws Exception {
253 if (initialized.compareAndSet(false, true)) {
254 // Set the CamelContext ErrorHandler here
255 CamelContext camelContext = getContext();
256 if (camelContext.getErrorHandlerBuilder() != null) {
257 setErrorHandlerBuilder(camelContext.getErrorHandlerBuilder());
258 }
259 configure();
260 populateRoutes();
261 }
262 }
263
264 protected void populateRoutes() throws Exception {
265 CamelContext camelContext = getContext();
266 if (camelContext == null) {
267 throw new IllegalArgumentException("CamelContext has not been injected!");
268 }
269 routeCollection.setCamelContext(camelContext);
270 camelContext.addRouteDefinitions(routeCollection.getRoutes());
271 }
272
273 public void setRouteCollection(RoutesDefinition routeCollection) {
274 this.routeCollection = routeCollection;
275 }
276
277 public RoutesDefinition getRouteCollection() {
278 return this.routeCollection;
279 }
280
281 /**
282 * Factory method
283 */
284 protected CamelContext createContainer() {
285 return new DefaultCamelContext();
286 }
287
288 protected void configureRoute(RouteDefinition route) {
289 route.setGroup(getClass().getName());
290 }
291
292 /**
293 * Adds a collection of routes to this context
294 *
295 * @throws Exception if the routes could not be created for whatever reason
296 */
297 protected void addRoutes(RoutesBuilder routes) throws Exception {
298 getContext().addRoutes(routes);
299 }
300 }