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 java.util.ArrayList;
020    import java.util.List;
021    import java.util.concurrent.atomic.AtomicBoolean;
022    
023    import org.apache.camel.CamelContext;
024    import org.apache.camel.Endpoint;
025    import org.apache.camel.Exchange;
026    import org.apache.camel.Processor;
027    import org.apache.camel.Route;
028    import org.apache.camel.impl.DefaultCamelContext;
029    
030    /**
031     * A <a href="http://activemq.apache.org/camel/dsl.html">Java DSL</a>
032     * which is used to build {@link Route} instances in a @{link CamelContext} for smart routing.
033     *
034     * @version $Revision: 541693 $
035     */
036    public abstract class RouteBuilder extends BuilderSupport {
037        private List<FromBuilder> fromBuilders = new ArrayList<FromBuilder>();
038        private AtomicBoolean initalized = new AtomicBoolean(false);
039        private List<Route> routes = new ArrayList<Route>();
040    
041        protected RouteBuilder() {
042            this(null);
043        }
044    
045        protected RouteBuilder(CamelContext context) {
046            super(context);
047        }
048    
049        /**
050         * Called on initialization to to build the required destinationBuilders
051         */
052        public abstract void configure() throws Exception;
053    
054        @Fluent
055        public FromBuilder from( @FluentArg("uri") String uri) {
056            if( uri == null ) {
057                    throw new IllegalArgumentException("uri parameter cannot be null");
058            }
059            Endpoint endpoint = endpoint(uri);
060            if( endpoint == null ) {
061                    throw new IllegalArgumentException("uri '"+uri+"' could not be resolved.");
062            }
063            return from(endpoint);
064        }
065    
066        @Fluent
067        public FromBuilder from( @FluentArg("ref") Endpoint endpoint) {
068            FromBuilder answer = new FromBuilder(this, endpoint);
069            addFromBuilder(answer);
070            return answer;
071        }
072    
073        /**
074         * Installs the given error handler builder
075         *
076         * @param errorHandlerBuilder the error handler to be used by default for all child routes
077         * @return the current builder with the error handler configured
078         */
079        public RouteBuilder errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
080            setErrorHandlerBuilder(errorHandlerBuilder);
081            return this;
082        }
083    
084        /**
085         * Configures whether or not the error handler is inherited by every processing node (or just the top most one)
086         *
087         * @param value the flag as to whether error handlers should be inherited or not
088         * @return the current builder
089         */
090        public RouteBuilder inheritErrorHandler(boolean value) {
091            setInheritErrorHandler(value);
092            return this;
093        }
094    
095        // Properties
096        //-----------------------------------------------------------------------
097        public CamelContext getContext() {
098            CamelContext context = super.getContext();
099            if (context == null) {
100                context = createContainer();
101                setContext(context);
102            }
103            return context;
104        }
105    
106        /**
107         * Returns the routing map from inbound endpoints to processors
108         */
109        public List<Route> getRouteList() throws Exception {
110            checkInitialized();
111            return routes;
112        }
113    
114        /**
115         * Returns the builders which have been created
116         */
117        public List<FromBuilder> getFromBuilders() throws Exception {
118            checkInitialized();
119            return fromBuilders;
120        }
121    
122        // Implementation methods
123        //-----------------------------------------------------------------------
124        public void addFromBuilder(FromBuilder answer) {
125            fromBuilders.add(answer);
126        }
127    
128        protected void checkInitialized() throws Exception {
129            if (initalized.compareAndSet(false, true)) {
130                configure();
131                populateRoutes(routes);
132            }
133        }
134    
135        protected void populateRoutes(List<Route> routes) throws Exception {
136            for (FromBuilder builder : fromBuilders) {
137                Route route = builder.createRoute();
138                routes.add(route);
139            }
140        }
141    
142        /**
143         * Factory method
144         */
145        protected CamelContext createContainer() {
146            return new DefaultCamelContext();
147        }
148    }