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