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.spring;
018    
019    import java.util.HashMap;
020    import java.util.LinkedList;
021    import java.util.Map;
022    import java.util.Set;
023    import javax.xml.bind.JAXBException;
024    
025    import org.apache.camel.CamelContext;
026    import org.apache.camel.ProducerTemplate;
027    import org.apache.camel.impl.MainSupport;
028    import org.apache.camel.spring.handler.CamelNamespaceHandler;
029    import org.apache.camel.util.IOHelper;
030    import org.apache.camel.view.ModelFileGenerator;
031    import org.springframework.context.ApplicationContext;
032    import org.springframework.context.support.AbstractApplicationContext;
033    import org.springframework.context.support.ClassPathXmlApplicationContext;
034    import org.springframework.context.support.FileSystemXmlApplicationContext;
035    
036    /**
037     * A command line tool for booting up a CamelContext using an optional Spring
038     * ApplicationContext
039     *
040     * @version 
041     */
042    @SuppressWarnings("deprecation")
043    public class Main extends MainSupport {
044        protected static Main instance;
045    
046        private String applicationContextUri = "META-INF/spring/*.xml";
047        private String fileApplicationContextUri;
048        private AbstractApplicationContext applicationContext;
049        private AbstractApplicationContext parentApplicationContext;
050        private String parentApplicationContextUri;
051    
052        public Main() {
053    
054            addOption(new ParameterOption("ac", "applicationContext",
055                    "Sets the classpath based spring ApplicationContext", "applicationContext") {
056                protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
057                    setApplicationContextUri(parameter);
058                }
059            });
060    
061            addOption(new ParameterOption("fa", "fileApplicationContext",
062                    "Sets the filesystem based spring ApplicationContext", "fileApplicationContext") {
063                protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
064                    setFileApplicationContextUri(parameter);
065                }
066            });
067    
068        }
069    
070        public static void main(String... args) throws Exception {
071            Main main = new Main();
072            instance = main;
073            main.enableHangupSupport();
074            main.run(args);
075        }
076    
077        /**
078         * Returns the currently executing main
079         *
080         * @return the current running instance
081         */
082        public static Main getInstance() {
083            return instance;
084        }
085        
086        // Properties
087        // -------------------------------------------------------------------------
088        public AbstractApplicationContext getApplicationContext() {
089            return applicationContext;
090        }
091    
092        public void setApplicationContext(AbstractApplicationContext applicationContext) {
093            this.applicationContext = applicationContext;
094        }
095    
096        public String getApplicationContextUri() {
097            return applicationContextUri;
098        }
099    
100        public void setApplicationContextUri(String applicationContextUri) {
101            this.applicationContextUri = applicationContextUri;
102        }
103    
104        public String getFileApplicationContextUri() {
105            return fileApplicationContextUri;
106        }
107    
108        public void setFileApplicationContextUri(String fileApplicationContextUri) {
109            this.fileApplicationContextUri = fileApplicationContextUri;
110        }
111    
112        public AbstractApplicationContext getParentApplicationContext() {
113            if (parentApplicationContext == null) {
114                if (parentApplicationContextUri != null) {
115                    parentApplicationContext = new ClassPathXmlApplicationContext(parentApplicationContextUri);
116                    parentApplicationContext.start();
117                }
118            }
119            return parentApplicationContext;
120        }
121    
122        public void setParentApplicationContext(AbstractApplicationContext parentApplicationContext) {
123            this.parentApplicationContext = parentApplicationContext;
124        }
125    
126        public String getParentApplicationContextUri() {
127            return parentApplicationContextUri;
128        }
129    
130        public void setParentApplicationContextUri(String parentApplicationContextUri) {
131            this.parentApplicationContextUri = parentApplicationContextUri;
132        }
133    
134        // Implementation methods
135        // -------------------------------------------------------------------------
136    
137        @Override
138        protected void doStart() throws Exception {
139            super.doStart();
140            if (applicationContext == null) {
141                applicationContext = createDefaultApplicationContext();
142            }
143            LOG.debug("Starting Spring ApplicationContext: " + applicationContext.getId());
144            applicationContext.start();
145    
146            postProcessContext();
147        }
148    
149        protected void doStop() throws Exception {
150            super.doStop();
151            if (applicationContext != null) {
152                LOG.debug("Stopping Spring ApplicationContext: " + applicationContext.getId());
153                IOHelper.close(applicationContext);
154            }
155        }
156    
157        protected ProducerTemplate findOrCreateCamelTemplate() {
158            String[] names = getApplicationContext().getBeanNamesForType(ProducerTemplate.class);
159            if (names != null && names.length > 0) {
160                return getApplicationContext().getBean(names[0], ProducerTemplate.class);
161            }
162            if (getCamelContexts().isEmpty()) {
163                throw new IllegalArgumentException("No CamelContexts are available so cannot create a ProducerTemplate!");
164            }
165            return getCamelContexts().get(0).createProducerTemplate();
166        }
167    
168        protected AbstractApplicationContext createDefaultApplicationContext() {
169            // file based
170            if (getFileApplicationContextUri() != null) {
171                String[] args = getFileApplicationContextUri().split(";");
172    
173                ApplicationContext parentContext = getParentApplicationContext();
174                if (parentContext != null) {
175                    return new FileSystemXmlApplicationContext(args, parentContext);
176                } else {
177                    return new FileSystemXmlApplicationContext(args);
178                }
179            }
180    
181            // default to classpath based
182            String[] args = getApplicationContextUri().split(";");
183            ApplicationContext parentContext = getParentApplicationContext();
184            if (parentContext != null) {
185                return new ClassPathXmlApplicationContext(args, parentContext);
186            } else {
187                return new ClassPathXmlApplicationContext(args);
188            }
189        }
190        
191        protected Map<String, CamelContext> getCamelContextMap() {
192            Map<String, SpringCamelContext> map = applicationContext.getBeansOfType(SpringCamelContext.class);
193            Set<Map.Entry<String, SpringCamelContext>> entries = map.entrySet();
194            Map<String, CamelContext> answer = new HashMap<String, CamelContext>();
195            for (Map.Entry<String, SpringCamelContext> entry : entries) {
196                String name = entry.getKey();
197                CamelContext camelContext = entry.getValue();
198                answer.put(name, camelContext);
199            }
200            return answer;
201        }
202    
203        protected ModelFileGenerator createModelFileGenerator() throws JAXBException {
204            return new ModelFileGenerator(new CamelNamespaceHandler().getJaxbContext());
205        }
206    }