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 }