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    
024    import javax.xml.bind.JAXBException;
025    
026    import org.apache.camel.CamelContext;
027    import org.apache.camel.ProducerTemplate;
028    import org.apache.camel.spring.handler.CamelNamespaceHandler;
029    import org.apache.camel.util.MainSupport;
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 $Revision: 706831 $
041     */
042    public class Main extends MainSupport {
043        private 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) {
070            Main main = new Main();
071            instance = main;
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        @Override
085        public void enableDebug() {
086            super.enableDebug();
087            setParentApplicationContextUri("/META-INF/services/org/apache/camel/spring/debug.xml");
088        }
089    
090        @Override
091        public void enableTrace() {
092            // TODO
093            super.enableTrace();
094            setParentApplicationContextUri("/META-INF/services/org/apache/camel/spring/trace.xml");
095        }
096    
097        // Properties
098        // -------------------------------------------------------------------------
099        public AbstractApplicationContext getApplicationContext() {
100            return applicationContext;
101        }
102    
103        public void setApplicationContext(AbstractApplicationContext applicationContext) {
104            this.applicationContext = applicationContext;
105        }
106    
107        public String getApplicationContextUri() {
108            return applicationContextUri;
109        }
110    
111        public void setApplicationContextUri(String applicationContextUri) {
112            this.applicationContextUri = applicationContextUri;
113        }
114    
115        public String getFileApplicationContextUri() {
116            return fileApplicationContextUri;
117        }
118    
119        public void setFileApplicationContextUri(String fileApplicationContextUri) {
120            this.fileApplicationContextUri = fileApplicationContextUri;
121        }
122    
123        public AbstractApplicationContext getParentApplicationContext() {
124            if (parentApplicationContext == null) {
125                if (parentApplicationContextUri != null) {
126                    parentApplicationContext = new ClassPathXmlApplicationContext(parentApplicationContextUri);
127                    parentApplicationContext.start();
128                }
129            }
130            return parentApplicationContext;
131        }
132    
133        public void setParentApplicationContext(AbstractApplicationContext parentApplicationContext) {
134            this.parentApplicationContext = parentApplicationContext;
135        }
136    
137        public String getParentApplicationContextUri() {
138            return parentApplicationContextUri;
139        }
140    
141        public void setParentApplicationContextUri(String parentApplicationContextUri) {
142            this.parentApplicationContextUri = parentApplicationContextUri;
143        }
144    
145        // Implementation methods
146        // -------------------------------------------------------------------------
147    
148        @Override
149        protected void doStart() throws Exception {
150            super.doStart();
151            if (applicationContext == null) {
152                applicationContext = createDefaultApplicationContext();
153            }
154            applicationContext.start();
155    
156            postProcessContext();
157        }
158    
159        protected ProducerTemplate findOrCreateCamelTemplate() {
160            String[] names = getApplicationContext().getBeanNamesForType(ProducerTemplate.class);
161            if (names != null && names.length > 0) {
162                return (ProducerTemplate) getApplicationContext().getBean(names[0], ProducerTemplate.class);
163            }
164            for (CamelContext camelContext : getCamelContexts()) {
165                return camelContext.createProducerTemplate();
166            }
167            throw new IllegalArgumentException("No CamelContexts are available so cannot create a ProducerTemplate!");
168        }
169    
170        protected AbstractApplicationContext createDefaultApplicationContext() {
171            // file based
172            if (getFileApplicationContextUri() != null) {
173                String[] args = getFileApplicationContextUri().split(";");
174    
175                ApplicationContext parentContext = getParentApplicationContext();
176                if (parentContext != null) {
177                    return new FileSystemXmlApplicationContext(args, parentContext);
178                } else {
179                    return new FileSystemXmlApplicationContext(args);
180                }
181            }
182            
183            // default to classpath based
184            String[] args = getApplicationContextUri().split(";");
185            ApplicationContext parentContext = getParentApplicationContext();
186            if (parentContext != null) {
187                return new ClassPathXmlApplicationContext(args, parentContext);
188            } else {
189                return new ClassPathXmlApplicationContext(args);
190            }
191        }
192    
193        protected void doStop() throws Exception {
194            LOG.info("Apache Camel terminating");
195    
196            if (applicationContext != null) {
197                applicationContext.close();
198            }
199        }
200    
201        protected Map<String, CamelContext> getCamelContextMap() {
202            Map<String, SpringCamelContext> map = applicationContext.getBeansOfType(SpringCamelContext.class);
203            Set<Map.Entry<String, SpringCamelContext>> entries = map.entrySet();
204            Map<String, CamelContext> answer = new HashMap<String, CamelContext>();
205            for (Map.Entry<String, SpringCamelContext> entry : entries) {
206                String name = entry.getKey();
207                CamelContext camelContext = entry.getValue();
208                answer.put(name, camelContext);
209            }
210            return answer;
211        }
212    
213        protected ModelFileGenerator createModelFileGenerator() throws JAXBException {
214            return new ModelFileGenerator(new CamelNamespaceHandler().getJaxbContext());
215        }
216    }