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.builder;
018    
019    import org.apache.camel.CamelContext;
020    import org.apache.camel.Endpoint;
021    import org.apache.camel.Predicate;
022    import org.apache.camel.Route;
023    import org.apache.camel.impl.DefaultCamelContext;
024    import org.apache.camel.model.InterceptType;
025    import org.apache.camel.model.OtherwiseType;
026    import org.apache.camel.model.ProcessorType;
027    import org.apache.camel.model.RouteType;
028    import org.apache.camel.model.RoutesType;
029    import org.apache.camel.model.ExceptionType;
030    import org.apache.camel.processor.DelegateProcessor;
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    import java.util.concurrent.atomic.AtomicBoolean;
035    
036    /**
037     * A <a href="http://activemq.apache.org/camel/dsl.html">Java DSL</a> which is
038     * used to build {@link Route} instances in a
039     * 
040     * @{link CamelContext} for smart routing.
041     * 
042     * @version $Revision: 564295 $
043     */
044    public abstract class RouteBuilder extends BuilderSupport {
045        private AtomicBoolean initalized = new AtomicBoolean(false);
046        private RoutesType routeCollection = new RoutesType();
047        private List<Route> routes = new ArrayList<Route>();
048    
049        protected RouteBuilder() {
050            this(null);
051        }
052    
053        protected RouteBuilder(CamelContext context) {
054            super(context);
055        }
056    
057        /**
058         * Called on initialization to to build the required destinationBuilders
059         */
060        public abstract void configure() throws Exception;
061    
062        /**
063         * Creates a new route from the given URI input
064         */
065        public RouteType from(String uri) {
066            return routeCollection.from(uri);
067        }
068    
069        /**
070         * Creates a new route from the given endpoint
071         */
072        public RouteType from(Endpoint endpoint) {
073            return routeCollection.from(endpoint);
074        }
075    
076        /**
077         * Installs the given error handler builder
078         * 
079         * @param errorHandlerBuilder the error handler to be used by default for
080         *                all child routes
081         * @return the current builder with the error handler configured
082         */
083        public RouteBuilder errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
084            setErrorHandlerBuilder(errorHandlerBuilder);
085            return this;
086        }
087    
088        /**
089         * Configures whether or not the error handler is inherited by every
090         * processing node (or just the top most one)
091         * 
092         * @param value the flag as to whether error handlers should be inherited or
093         *                not
094         * @return the current builder
095         */
096        public RouteBuilder inheritErrorHandler(boolean value) {
097            routeCollection.setInheritErrorHandlerFlag(value);
098            return this;
099        }
100    
101        /**
102         * Adds the given interceptor to this route
103         */
104        public RouteBuilder intercept(DelegateProcessor interceptor) {
105            routeCollection.intercept(interceptor);
106            return this;
107        }
108    
109        /**
110         * Adds a route for an interceptor; use the {@link ProcessorType#proceed()} method
111         * to continue processing the underying route being intercepted.
112         *
113         * @return
114         */
115        public InterceptType intercept() {
116            return routeCollection.intercept();
117        }
118    
119        /**
120         * Applies a route for an interceptor if the given predicate is true
121         * otherwise the interceptor route is not applied
122         */
123        public OtherwiseType intercept(Predicate predicate) {
124            return routeCollection.intercept(predicate);
125        }
126    
127        /**
128         * Adds an exception handler route for the given exception type
129         */
130        public ExceptionType exception(Class exceptionType) {
131            return routeCollection.exception(exceptionType);
132        }
133    
134        // Properties
135        // -----------------------------------------------------------------------
136        public CamelContext getContext() {
137            CamelContext context = super.getContext();
138            if (context == null) {
139                context = createContainer();
140                setContext(context);
141            }
142            return context;
143        }
144    
145        /**
146         * Returns the routing map from inbound endpoints to processors
147         */
148        public List<Route> getRouteList() throws Exception {
149            checkInitialized();
150            return routes;
151        }
152    
153        // Implementation methods
154        // -----------------------------------------------------------------------
155        protected void checkInitialized() throws Exception {
156            if (initalized.compareAndSet(false, true)) {
157                configure();
158                populateRoutes(routes);
159            }
160        }
161    
162        protected void populateRoutes(List<Route> routes) throws Exception {
163            CamelContext camelContext = getContext();
164            if (camelContext == null) {
165                throw new IllegalArgumentException("No CamelContext has been injected!");
166            }
167            routeCollection.setCamelContext(camelContext);
168            routeCollection.populateRoutes(routes);
169        }
170    
171        /**
172         * Factory method
173         */
174        protected CamelContext createContainer() {
175            return new DefaultCamelContext();
176        }
177    }