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.model; 018 019 import java.util.ArrayList; 020 import java.util.Collection; 021 import java.util.List; 022 023 import javax.xml.bind.annotation.XmlAccessType; 024 import javax.xml.bind.annotation.XmlAccessorType; 025 import javax.xml.bind.annotation.XmlAttribute; 026 import javax.xml.bind.annotation.XmlElementRef; 027 import javax.xml.bind.annotation.XmlRootElement; 028 import javax.xml.bind.annotation.XmlTransient; 029 import javax.xml.bind.annotation.XmlType; 030 031 import org.apache.camel.CamelContext; 032 import org.apache.camel.CamelContextAware; 033 import org.apache.camel.Endpoint; 034 import org.apache.camel.NoSuchEndpointException; 035 import org.apache.camel.Route; 036 import org.apache.camel.builder.ErrorHandlerBuilder; 037 import org.apache.camel.impl.DefaultCamelContext; 038 import org.apache.camel.impl.DefaultRouteContext; 039 import org.apache.camel.processor.interceptor.StreamCachingInterceptor; 040 import org.apache.camel.spi.RouteContext; 041 import org.apache.camel.util.CamelContextHelper; 042 import org.apache.commons.logging.Log; 043 import org.apache.commons.logging.LogFactory; 044 045 /** 046 * Represents an XML <route/> element 047 * 048 * @version $Revision: 674383 $ 049 */ 050 @XmlRootElement(name = "route") 051 @XmlType(propOrder = {"inputs", "outputs" }) 052 @XmlAccessorType(XmlAccessType.PROPERTY) 053 public class RouteType extends ProcessorType<ProcessorType> implements CamelContextAware { 054 private static final transient Log LOG = LogFactory.getLog(RouteType.class); 055 private List<InterceptorType> interceptors = new ArrayList<InterceptorType>(); 056 private List<FromType> inputs = new ArrayList<FromType>(); 057 private List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>(); 058 private String group; 059 private CamelContext camelContext; 060 private Boolean streamCaching; 061 062 public RouteType() { 063 } 064 065 public RouteType(String uri) { 066 from(uri); 067 } 068 069 public RouteType(Endpoint endpoint) { 070 from(endpoint); 071 } 072 073 @Override 074 public String toString() { 075 return "Route[ " + inputs + " -> " + outputs + "]"; 076 } 077 078 public void addRoutes(CamelContext context, Collection<Route> routes) throws Exception { 079 setCamelContext(context); 080 081 if (context instanceof DefaultCamelContext) { 082 DefaultCamelContext defaultCamelContext = (DefaultCamelContext) context; 083 ErrorHandlerBuilder handler = defaultCamelContext.getErrorHandlerBuilder(); 084 if (handler != null) { 085 setErrorHandlerBuilderIfNull(handler); 086 } 087 } 088 089 for (FromType fromType : inputs) { 090 addRoutes(routes, fromType); 091 } 092 } 093 094 095 public Endpoint resolveEndpoint(String uri) throws NoSuchEndpointException { 096 CamelContext context = getCamelContext(); 097 if (context == null) { 098 throw new IllegalArgumentException("No CamelContext has been injected!"); 099 } 100 return CamelContextHelper.getMandatoryEndpoint(context, uri); 101 } 102 103 // Fluent API 104 // ----------------------------------------------------------------------- 105 106 /** 107 * Creates an input to the route 108 */ 109 public RouteType from(String uri) { 110 getInputs().add(new FromType(uri)); 111 return this; 112 } 113 114 /** 115 * Creates an input to the route 116 */ 117 public RouteType from(Endpoint endpoint) { 118 getInputs().add(new FromType(endpoint)); 119 return this; 120 } 121 122 /** 123 * Set the group name for this route 124 */ 125 public RouteType group(String name) { 126 setGroup(name); 127 return this; 128 } 129 130 // Properties 131 // ----------------------------------------------------------------------- 132 133 public List<InterceptorType> getInterceptors() { 134 return interceptors; 135 } 136 137 @XmlTransient 138 public void setInterceptors(List<InterceptorType> interceptors) { 139 this.interceptors = interceptors; 140 } 141 142 public List<FromType> getInputs() { 143 return inputs; 144 } 145 146 @XmlElementRef 147 public void setInputs(List<FromType> inputs) { 148 this.inputs = inputs; 149 } 150 151 public List<ProcessorType<?>> getOutputs() { 152 return outputs; 153 } 154 155 @XmlElementRef 156 public void setOutputs(List<ProcessorType<?>> outputs) { 157 this.outputs = outputs; 158 159 // TODO I don't think this is called when using JAXB! 160 if (outputs != null) { 161 for (ProcessorType output : outputs) { 162 configureChild(output); 163 } 164 } 165 } 166 167 public CamelContext getCamelContext() { 168 return camelContext; 169 } 170 171 @XmlTransient 172 public void setCamelContext(CamelContext camelContext) { 173 this.camelContext = camelContext; 174 } 175 176 /** 177 * The group that this route belongs to; could be the name of the RouteBuilder class 178 * or be explicitly configured in the XML. 179 * 180 * May be null. 181 */ 182 public String getGroup() { 183 return group; 184 } 185 186 @XmlAttribute 187 public void setGroup(String group) { 188 this.group = group; 189 } 190 191 public Boolean getStreamCaching() { 192 return streamCaching; 193 } 194 195 /** 196 * Enable stream caching on this route 197 * @param streamCaching <code>true</code> for enabling stream caching 198 */ 199 @XmlAttribute(required = false) 200 public void setStreamCaching(Boolean streamCaching) { 201 this.streamCaching = streamCaching; 202 if (streamCaching != null && streamCaching) { 203 streamCaching(); 204 } else { 205 noStreamCaching(); 206 } 207 } 208 209 210 // Implementation methods 211 // ------------------------------------------------------------------------- 212 protected void addRoutes(Collection<Route> routes, FromType fromType) throws Exception { 213 RouteContext routeContext = new DefaultRouteContext(this, fromType, routes); 214 routeContext.getEndpoint(); // force endpoint resolution 215 if (camelContext != null) { 216 camelContext.getLifecycleStrategy().onRouteContextCreate(routeContext); 217 } 218 219 List<ProcessorType<?>> list = new ArrayList<ProcessorType<?>>(outputs); 220 for (ProcessorType output : list) { 221 output.addRoutes(routeContext, routes); 222 } 223 224 routeContext.commit(); 225 } 226 227 @Override 228 protected void configureChild(ProcessorType output) { 229 super.configureChild(output); 230 231 if (isInheritErrorHandler()) { 232 output.setErrorHandlerBuilder(getErrorHandlerBuilder()); 233 } 234 235 List<InterceptorType> interceptors = getInterceptors(); 236 for (InterceptorType interceptor : interceptors) { 237 output.addInterceptor(interceptor); 238 } 239 /* 240 List<InterceptorType> list = output.getInterceptors(); 241 if (list == null) { 242 LOG.warn("No interceptor collection: " + output); 243 } else { 244 list.addAll(getInterceptors()); 245 } 246 */ 247 } 248 249 /** 250 * Disable stream caching for this Route. 251 */ 252 public RouteType noStreamCaching() { 253 StreamCachingInterceptor.noStreamCaching(interceptors); 254 return this; 255 } 256 257 /** 258 * Enable stream caching for this Route. 259 */ 260 public RouteType streamCaching() { 261 addInterceptor(new StreamCachingInterceptor()); 262 return this; 263 } 264 265 @Override 266 public void addInterceptor(InterceptorType interceptor) { 267 getInterceptors().add(interceptor); 268 } 269 }