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    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlAttribute;
025    import javax.xml.bind.annotation.XmlElementRef;
026    import javax.xml.bind.annotation.XmlRootElement;
027    import javax.xml.bind.annotation.XmlTransient;
028    import javax.xml.bind.annotation.XmlType;
029    
030    import org.apache.camel.CamelContext;
031    import org.apache.camel.CamelContextAware;
032    import org.apache.camel.Endpoint;
033    import org.apache.camel.NoSuchEndpointException;
034    import org.apache.camel.Route;
035    import org.apache.camel.ServiceStatus;
036    import org.apache.camel.builder.ErrorHandlerBuilder;
037    import org.apache.camel.impl.DefaultRouteContext;
038    import org.apache.camel.processor.interceptor.StreamCaching;
039    import org.apache.camel.spi.RouteContext;
040    import org.apache.camel.util.CamelContextHelper;
041    
042    /**
043     * Represents an XML <route/> element
044     *
045     * @version $Revision: 787246 $
046     */
047    @XmlRootElement(name = "route")
048    @XmlType(propOrder = {"inputs", "outputs" })
049    @XmlAccessorType(XmlAccessType.PROPERTY)
050    public class RouteDefinition extends ProcessorDefinition<ProcessorDefinition> implements CamelContextAware {
051        private List<FromDefinition> inputs = new ArrayList<FromDefinition>();
052        private List<ProcessorDefinition> outputs = new ArrayList<ProcessorDefinition>();
053        private CamelContext camelContext;
054        private String group;
055        private Boolean streamCache;
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        /**
198         * Disable stream caching for this Route.
199         */
200        public RouteDefinition noStreamCaching() {
201            setStreamCache(Boolean.FALSE);
202            StreamCaching.noStreamCaching(getInterceptStrategies());
203            return this;
204        }
205    
206        /**
207         * Enable stream caching for this Route.
208         */
209        public RouteDefinition streamCaching() {
210            setStreamCache(Boolean.TRUE);
211            StreamCaching cache = StreamCaching.getStreamCaching(getCamelContext());
212            if (cache == null) {
213                cache = new StreamCaching();
214            }
215    
216            getInterceptStrategies().add(cache);
217            return this;
218        }
219    
220        // Properties
221        // -----------------------------------------------------------------------
222    
223        public List<FromDefinition> getInputs() {
224            return inputs;
225        }
226    
227        @XmlElementRef
228        public void setInputs(List<FromDefinition> inputs) {
229            this.inputs = inputs;
230        }
231    
232        public List<ProcessorDefinition> getOutputs() {
233            return outputs;
234        }
235    
236        @XmlElementRef
237        public void setOutputs(List<ProcessorDefinition> outputs) {
238            this.outputs = outputs;
239    
240            if (outputs != null) {
241                for (ProcessorDefinition output : outputs) {
242                    configureChild(output);
243                }
244            }
245        }
246    
247        public CamelContext getCamelContext() {
248            return camelContext;
249        }
250    
251        @XmlTransient
252        public void setCamelContext(CamelContext camelContext) {
253            this.camelContext = camelContext;
254        }
255    
256        /**
257         * The group that this route belongs to; could be the name of the RouteBuilder class
258         * or be explicitly configured in the XML.
259         *
260         * May be null.
261         */
262        public String getGroup() {
263            return group;
264        }
265    
266        @XmlAttribute
267        public void setGroup(String group) {
268            this.group = group;
269        }
270    
271        public Boolean isStreamCache() {
272            return streamCache;
273        }
274    
275        @XmlAttribute
276        public void setStreamCache(Boolean streamCache) {
277            this.streamCache = streamCache;
278        }
279    
280        // Implementation methods
281        // -------------------------------------------------------------------------
282        protected RouteContext addRoutes(Collection<Route> routes, FromDefinition fromType) throws Exception {
283            RouteContext routeContext = new DefaultRouteContext(this, fromType, routes);
284            // should inherit the intercept strategies we have defined
285            routeContext.setInterceptStrategies(this.getInterceptStrategies());
286            // force endpoint resolution
287            routeContext.getEndpoint();
288            if (camelContext != null) {
289                camelContext.getLifecycleStrategy().onRouteContextCreate(routeContext);
290            }
291    
292            List<ProcessorDefinition> list = new ArrayList<ProcessorDefinition>(outputs);
293            for (ProcessorDefinition output : list) {
294                output.addRoutes(routeContext, routes);
295            }
296    
297            routeContext.commit();
298            return routeContext;
299        }
300    
301    }