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.ChoiceDefinition; 030 import org.apache.camel.model.InterceptDefinition; 031 import org.apache.camel.model.OnExceptionDefinition; 032 import org.apache.camel.model.RouteDefinition; 033 import org.apache.camel.model.RoutesDefinition; 034 import org.apache.camel.processor.DelegateProcessor; 035 import org.apache.camel.processor.interceptor.StreamCachingInterceptor; 036 037 /** 038 * A <a href="http://camel.apache.org/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: 751655 $ 042 */ 043 public abstract class RouteBuilder extends BuilderSupport implements Routes { 044 private AtomicBoolean initialized = new AtomicBoolean(false); 045 private RoutesDefinition routeCollection = new RoutesDefinition(); 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 * <b>Called on initialization to build the routes using the fluent builder syntax.</b> 063 * <p/> 064 * This is a central method for RouteBuilder implementations to implement 065 * the routes using the Java fluent builder syntax. 066 * 067 * @throws Exception can be thrown during configuration 068 */ 069 public abstract void configure() throws Exception; 070 071 /** 072 * Creates a new route from the given URI input 073 * 074 * @param uri the from uri 075 * @return the builder 076 */ 077 public RouteDefinition from(String uri) { 078 RouteDefinition answer = routeCollection.from(uri); 079 configureRoute(answer); 080 return answer; 081 } 082 083 /** 084 * Creates a new route from the given endpoint 085 * 086 * @param endpoint the from endpoint 087 * @return the builder 088 */ 089 public RouteDefinition from(Endpoint endpoint) { 090 RouteDefinition answer = routeCollection.from(endpoint); 091 configureRoute(answer); 092 return answer; 093 } 094 095 /** 096 * Creates a new route from the given URIs input 097 * 098 * @param uris the from uris 099 * @return the builder 100 */ 101 public RouteDefinition from(String... uris) { 102 RouteDefinition answer = routeCollection.from(uris); 103 configureRoute(answer); 104 return answer; 105 } 106 107 /** 108 * Creates a new route from the given endpoint 109 * 110 * @param endpoints the from endpoints 111 * @return the builder 112 */ 113 public RouteDefinition from(Endpoint... endpoints) { 114 RouteDefinition answer = routeCollection.from(endpoints); 115 configureRoute(answer); 116 return answer; 117 } 118 119 /** 120 * Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder 121 * 122 * @param errorHandlerBuilder the error handler to be used by default for all child routes 123 * @return the current builder with the error handler configured 124 */ 125 public RouteBuilder errorHandler(ErrorHandlerBuilder errorHandlerBuilder) { 126 setErrorHandlerBuilder(errorHandlerBuilder); 127 return this; 128 } 129 130 /** 131 * Configures whether or not the <a href="http://camel.apache.org/error-handler.html">error handler</a> 132 * is inherited by every processing node (or just the top most one) 133 * 134 * @param inherit whether error handlers should be inherited or not 135 * @return the current builder 136 */ 137 public RouteBuilder inheritErrorHandler(boolean inherit) { 138 routeCollection.setInheritErrorHandlerFlag(inherit); 139 return this; 140 } 141 142 /** 143 * Adds the given interceptor to this route 144 * 145 * @param interceptor the interceptor 146 * @return the builder 147 */ 148 public RouteBuilder intercept(DelegateProcessor interceptor) { 149 routeCollection.intercept(interceptor); 150 return this; 151 } 152 153 /** 154 * Adds a route for an interceptor; use the {@link org.apache.camel.model.ProcessorDefinition#proceed()} method 155 * to continue processing the underlying route being intercepted. 156 * @return the builder 157 */ 158 public InterceptDefinition intercept() { 159 return routeCollection.intercept(); 160 } 161 162 /** 163 * Applies a route for an interceptor if the given predicate is true 164 * otherwise the interceptor route is not applied 165 * 166 * @param predicate the predicate 167 * @return the builder 168 */ 169 public ChoiceDefinition intercept(Predicate predicate) { 170 return routeCollection.intercept(predicate); 171 } 172 173 /** 174 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> 175 * for catching certain exceptions and handling them. 176 * 177 * @param exception exception to catch 178 * @return the builder 179 */ 180 public OnExceptionDefinition onException(Class exception) { 181 return routeCollection.onException(exception); 182 } 183 184 /** 185 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> 186 * for catching certain exceptions and handling them. 187 * 188 * @param exceptions list of exceptions to catch 189 * @return the builder 190 */ 191 public OnExceptionDefinition onException(Class... exceptions) { 192 OnExceptionDefinition last = null; 193 for (Class ex : exceptions) { 194 last = last == null ? onException(ex) : last.onException(ex); 195 } 196 return last != null ? last : onException(Exception.class); 197 } 198 199 // Properties 200 // ----------------------------------------------------------------------- 201 public CamelContext getContext() { 202 CamelContext context = super.getContext(); 203 if (context == null) { 204 context = createContainer(); 205 setContext(context); 206 } 207 return context; 208 } 209 210 /** 211 * Uses {@link org.apache.camel.CamelContext#getRoutes()} to return the routes in the context. 212 */ 213 public List<Route> getRouteList() throws Exception { 214 checkInitialized(); 215 return routes; 216 } 217 218 @Override 219 public void setInheritErrorHandler(boolean inheritErrorHandler) { 220 super.setInheritErrorHandler(inheritErrorHandler); 221 routeCollection.setInheritErrorHandlerFlag(inheritErrorHandler); 222 223 } 224 225 @Override 226 public void setErrorHandlerBuilder(ErrorHandlerBuilder errorHandlerBuilder) { 227 super.setErrorHandlerBuilder(errorHandlerBuilder); 228 routeCollection.setErrorHandlerBuilder(getErrorHandlerBuilder()); 229 } 230 231 // Implementation methods 232 // ----------------------------------------------------------------------- 233 protected void checkInitialized() throws Exception { 234 if (initialized.compareAndSet(false, true)) { 235 // Set the CamelContext ErrorHandler here 236 CamelContext camelContext = getContext(); 237 if (camelContext.getErrorHandlerBuilder() != null) { 238 setErrorHandlerBuilder(camelContext.getErrorHandlerBuilder()); 239 } 240 configure(); 241 populateRoutes(routes); 242 } 243 } 244 245 protected void populateRoutes(List<Route> routes) throws Exception { 246 CamelContext camelContext = getContext(); 247 if (camelContext == null) { 248 throw new IllegalArgumentException("CamelContext has not been injected!"); 249 } 250 routeCollection.setCamelContext(camelContext); 251 camelContext.addRouteDefinitions(routeCollection.getRoutes()); 252 } 253 254 public void setRouteCollection(RoutesDefinition routeCollection) { 255 this.routeCollection = routeCollection; 256 } 257 258 public RoutesDefinition getRouteCollection() { 259 return this.routeCollection; 260 } 261 262 /** 263 * Completely disable stream caching for all routes being defined in the same RouteBuilder after this. 264 */ 265 public void noStreamCaching() { 266 StreamCachingInterceptor.noStreamCaching(routeCollection.getInterceptors()); 267 } 268 269 /** 270 * Enable stream caching for all routes being defined in the same RouteBuilder after this call. 271 */ 272 public void streamCaching() { 273 routeCollection.intercept(new StreamCachingInterceptor()); 274 } 275 276 /** 277 * Factory method 278 */ 279 protected CamelContext createContainer() { 280 return new DefaultCamelContext(); 281 } 282 283 protected void configureRoute(RouteDefinition route) { 284 route.setGroup(getClass().getName()); 285 } 286 287 /** 288 * Adds a collection of routes to this context 289 * 290 * @throws Exception if the routes could not be created for whatever reason 291 */ 292 protected void addRoutes(Routes routes) throws Exception { 293 getContext().addRoutes(routes); 294 } 295 }