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: 45031 $ 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 CamelContext) { 082 ErrorHandlerBuilder handler = context.getErrorHandlerBuilder(); 083 if (handler != null) { 084 setErrorHandlerBuilderIfNull(handler); 085 } 086 } 087 088 for (FromType fromType : inputs) { 089 addRoutes(routes, fromType); 090 } 091 } 092 093 094 public Endpoint resolveEndpoint(String uri) throws NoSuchEndpointException { 095 CamelContext context = getCamelContext(); 096 if (context == null) { 097 throw new IllegalArgumentException("No CamelContext has been injected!"); 098 } 099 return CamelContextHelper.getMandatoryEndpoint(context, uri); 100 } 101 102 // Fluent API 103 // ----------------------------------------------------------------------- 104 105 /** 106 * Creates an input to the route 107 */ 108 public RouteType from(String uri) { 109 getInputs().add(new FromType(uri)); 110 return this; 111 } 112 113 /** 114 * Creates an input to the route 115 */ 116 public RouteType from(Endpoint endpoint) { 117 getInputs().add(new FromType(endpoint)); 118 return this; 119 } 120 121 /** 122 * Set the group name for this route 123 */ 124 public RouteType group(String name) { 125 setGroup(name); 126 return this; 127 } 128 129 // Properties 130 // ----------------------------------------------------------------------- 131 132 public List<InterceptorType> getInterceptors() { 133 return interceptors; 134 } 135 136 @XmlTransient 137 public void setInterceptors(List<InterceptorType> interceptors) { 138 this.interceptors = interceptors; 139 } 140 141 public List<FromType> getInputs() { 142 return inputs; 143 } 144 145 @XmlElementRef 146 public void setInputs(List<FromType> inputs) { 147 this.inputs = inputs; 148 } 149 150 public List<ProcessorType<?>> getOutputs() { 151 return outputs; 152 } 153 154 @XmlElementRef 155 public void setOutputs(List<ProcessorType<?>> outputs) { 156 this.outputs = outputs; 157 158 // TODO I don't think this is called when using JAXB! 159 if (outputs != null) { 160 for (ProcessorType output : outputs) { 161 configureChild(output); 162 } 163 } 164 } 165 166 public CamelContext getCamelContext() { 167 return camelContext; 168 } 169 170 @XmlTransient 171 public void setCamelContext(CamelContext camelContext) { 172 this.camelContext = camelContext; 173 } 174 175 /** 176 * The group that this route belongs to; could be the name of the RouteBuilder class 177 * or be explicitly configured in the XML. 178 * 179 * May be null. 180 */ 181 public String getGroup() { 182 return group; 183 } 184 185 @XmlAttribute 186 public void setGroup(String group) { 187 this.group = group; 188 } 189 190 public Boolean getStreamCaching() { 191 return streamCaching; 192 } 193 194 /** 195 * Enable stream caching on this route 196 * @param streamCaching <code>true</code> for enabling stream caching 197 */ 198 @XmlAttribute(required = false) 199 public void setStreamCaching(Boolean streamCaching) { 200 this.streamCaching = streamCaching; 201 if (streamCaching != null && streamCaching) { 202 streamCaching(); 203 } else { 204 noStreamCaching(); 205 } 206 } 207 208 209 // Implementation methods 210 // ------------------------------------------------------------------------- 211 protected void addRoutes(Collection<Route> routes, FromType fromType) throws Exception { 212 RouteContext routeContext = new DefaultRouteContext(this, fromType, routes); 213 routeContext.getEndpoint(); // force endpoint resolution 214 if (camelContext != null) { 215 camelContext.getLifecycleStrategy().onRouteContextCreate(routeContext); 216 } 217 218 List<ProcessorType<?>> list = new ArrayList<ProcessorType<?>>(outputs); 219 for (ProcessorType output : list) { 220 output.addRoutes(routeContext, routes); 221 } 222 223 routeContext.commit(); 224 } 225 226 @Override 227 protected void configureChild(ProcessorType output) { 228 super.configureChild(output); 229 230 if (isInheritErrorHandler()) { 231 output.setErrorHandlerBuilder(getErrorHandlerBuilder()); 232 } 233 234 List<InterceptorType> interceptors = getInterceptors(); 235 for (InterceptorType interceptor : interceptors) { 236 output.addInterceptor(interceptor); 237 } 238 /* 239 List<InterceptorType> list = output.getInterceptors(); 240 if (list == null) { 241 LOG.warn("No interceptor collection: " + output); 242 } else { 243 list.addAll(getInterceptors()); 244 } 245 */ 246 } 247 248 /** 249 * Disable stream caching for this Route. 250 */ 251 public RouteType noStreamCaching() { 252 StreamCachingInterceptor.noStreamCaching(interceptors); 253 return this; 254 } 255 256 /** 257 * Enable stream caching for this Route. 258 */ 259 public RouteType streamCaching() { 260 addInterceptor(new StreamCachingInterceptor()); 261 return this; 262 } 263 264 @Override 265 public void addInterceptor(InterceptorType interceptor) { 266 getInterceptors().add(interceptor); 267 } 268 }