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 }