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