001    /**
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     * http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.camel.spring;
019    
020    import org.apache.camel.CamelContext;
021    import org.apache.camel.builder.RouteBuilder;
022    import org.springframework.beans.factory.DisposableBean;
023    import org.springframework.beans.factory.FactoryBean;
024    import org.springframework.beans.factory.InitializingBean;
025    import org.springframework.context.ApplicationContext;
026    import org.springframework.context.ApplicationContextAware;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    /**
032     * A Spring {@link FactoryBean} to create and initialize a {@link SpringCamelContext}
033     * and install routes either explicitly configured in Spring XML or found by searching the classpath for Java classes
034     * which extend {@link RouteBuilder} using the nested {@link #setPackages(String[])}.
035     *
036     * @version $Revision: 534941 $
037     */
038    public class CamelContextFactoryBean implements FactoryBean, InitializingBean, DisposableBean, ApplicationContextAware {
039        private CamelContext context;
040        private RouteBuilder routeBuilder;
041        private List<RouteBuilder> additionalBuilders = new ArrayList<RouteBuilder>();
042        private String[] packages = {};
043        private ApplicationContext applicationContext;
044    
045        public Object getObject() throws Exception {
046            return getContext();
047        }
048    
049        public Class getObjectType() {
050            return SpringCamelContext.class;
051        }
052    
053        public boolean isSingleton() {
054            return true;
055        }
056    
057        public void afterPropertiesSet() throws Exception {
058    
059            // lets force any lazy creation
060            getContext();
061    
062            findRouteBuiders();
063            installRoutes();
064    
065            // now lets activate the routes
066            getContext().start();
067        }
068    
069        public void destroy() throws Exception {
070            getContext().stop();
071        }
072    
073        // Properties
074        //-------------------------------------------------------------------------
075        public CamelContext getContext() throws Exception {
076            if (context == null) {
077                context = new SpringCamelContext(getApplicationContext());
078            }
079            return context;
080        }
081    
082        public void setContext(CamelContext context) {
083            this.context = context;
084        }
085    
086        public RouteBuilder getRouteBuilder() {
087            return routeBuilder;
088        }
089    
090        /**
091         * Set a single {@link RouteBuilder} to be used to create the default routes on startup
092         */
093        public void setRouteBuilder(RouteBuilder routeBuilder) {
094            this.routeBuilder = routeBuilder;
095        }
096    
097        /**
098         * Set a collection of {@link RouteBuilder} instances to be used to create the default routes on startup
099         */
100        public void setRouteBuilders(RouteBuilder[] builders) {
101            for (RouteBuilder builder : builders) {
102                additionalBuilders.add(builder);
103            }
104        }
105    
106        public ApplicationContext getApplicationContext() {
107            return applicationContext;
108        }
109    
110        public void setApplicationContext(ApplicationContext applicationContext) {
111            this.applicationContext = applicationContext;
112        }
113    
114        public String[] getPackages() {
115            return packages;
116        }
117    
118        /**
119         * Sets the package names to be recursively searched for Java classes which extend {@link RouteBuilder} to be auto-wired up to the
120         * {@link SpringCamelContext} as a route. Note that classes are excluded if they are specifically configured in the spring.xml
121         *
122         * @param packages the package names which are recursively searched
123         */
124        public void setPackages(String[] packages) {
125            this.packages = packages;
126        }
127    
128        // Implementation methods
129        //-------------------------------------------------------------------------
130    
131        /**
132         * Strategy to install all available routes into the context
133         */
134        protected void installRoutes() throws Exception {
135            for (RouteBuilder routeBuilder : additionalBuilders) {
136                getContext().addRoutes(routeBuilder);
137            }
138            if (routeBuilder != null) {
139                getContext().addRoutes(routeBuilder);
140            }
141        }
142    
143        /**
144         * Strategy method to try find {@link RouteBuilder} instances on the classpath
145         */
146        protected void findRouteBuiders() throws IllegalAccessException, InstantiationException {
147            if (packages != null && packages.length > 0) {
148                RouteBuilderFinder finder = new RouteBuilderFinder(this);
149                finder.appendBuilders(additionalBuilders);
150            }
151        }
152    }