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