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