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 */
017package org.apache.camel.spring;
018
019import java.util.HashMap;
020import java.util.LinkedList;
021import java.util.Map;
022import java.util.Set;
023import javax.xml.bind.JAXBException;
024
025import org.apache.camel.CamelContext;
026import org.apache.camel.ProducerTemplate;
027import org.apache.camel.impl.MainSupport;
028import org.apache.camel.spring.handler.CamelNamespaceHandler;
029import org.apache.camel.view.ModelFileGenerator;
030import org.springframework.context.ApplicationContext;
031import org.springframework.context.support.AbstractApplicationContext;
032import org.springframework.context.support.ClassPathXmlApplicationContext;
033import 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")
042public 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}