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