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.guice;
018    
019    import java.net.URL;
020    import java.util.LinkedList;
021    import java.util.Map;
022    import java.util.Properties;
023    import java.util.Set;
024    
025    import javax.naming.Context;
026    import javax.naming.InitialContext;
027    import javax.xml.bind.JAXBContext;
028    import javax.xml.bind.JAXBException;
029    
030    import com.google.inject.Binding;
031    import com.google.inject.Injector;
032    import com.google.inject.Key;
033    import com.google.inject.internal.Iterables;
034    import com.google.inject.internal.Maps;
035    
036    import org.apache.camel.CamelContext;
037    import org.apache.camel.ProducerTemplate;
038    import org.apache.camel.impl.MainSupport;
039    import org.apache.camel.util.ObjectHelper;
040    import org.apache.camel.view.ModelFileGenerator;
041    import org.guiceyfruit.Injectors;
042    
043    /**
044     * A command line tool for booting up a CamelContext using a Guice Injector via JNDI
045     * assuming that a valid jndi.properties is on the classpath
046     *
047     * @version $Revision: 18643 $
048     */
049    public class Main extends MainSupport {
050        private static Main instance;
051        private Injector injector;
052        private String jndiProperties;
053     
054        public Main() {
055            addOption(new ParameterOption("j", "jndiProperties",
056                    "Sets the classpath based jndi properties file location", "jndiProperties") {
057                @Override
058                protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
059                    setJndiProperties(parameter);
060                    
061                }
062            });
063        }
064        
065        public void setJndiProperties(String properties) {
066            this.jndiProperties = properties;
067        }
068    
069        public String getJndiProperties() {
070            return this.jndiProperties;
071        }
072    
073        public static void main(String... args) throws Exception {
074            Main main = new Main();
075            instance = main;
076            main.run(args);
077        }
078    
079        /**
080         * Returns the currently executing main
081         *
082         * @return the current running instance
083         */
084        public static Main getInstance() {
085            return instance;
086        }
087    
088        // Properties
089        // -------------------------------------------------------------------------
090        protected void setInjector(Injector injector) {
091            this.injector = injector;        
092        }
093        
094        protected Injector getInjector() {
095            return injector;
096        }
097        
098        // Implementation methods
099        // -------------------------------------------------------------------------
100        protected Injector getInjectorFromContext() throws Exception {
101            Context context = null;
102            URL jndiPropertiesUrl = null;
103            if (ObjectHelper.isNotEmpty(jndiProperties)) {
104                jndiPropertiesUrl = this.getClass().getResource(jndiProperties);
105            }
106            if (jndiPropertiesUrl != null) {
107                Properties properties = new Properties();
108                properties.load(jndiPropertiesUrl.openStream());
109                context = new InitialContext(properties);
110            } else {
111                context = new InitialContext();
112            }
113            return (Injector) context.lookup(Injector.class.getName());
114        }
115        
116        @Override
117        protected void doStart() throws Exception {
118            super.doStart();
119            setInjector(getInjectorFromContext());
120            postProcessContext();
121        }
122    
123        protected void doStop() throws Exception {
124            LOG.info("Apache Camel stopping");
125    
126            if (injector != null) {
127                Injectors.close(injector);
128            }
129        }
130    
131        protected ProducerTemplate findOrCreateCamelTemplate() {
132            if (injector != null) {
133                Set<ProducerTemplate> set = Injectors.getInstancesOf(injector, ProducerTemplate.class);
134                if (!set.isEmpty()) {
135                    // TODO should be Iterables.get(set, 0);
136                    return Iterables.getOnlyElement(set);
137                }
138            }
139            for (CamelContext camelContext : getCamelContexts()) {
140                return camelContext.createProducerTemplate();
141            }
142            throw new IllegalArgumentException("No CamelContexts are available so cannot create a ProducerTemplate!");
143        }
144    
145        protected Map<String, CamelContext> getCamelContextMap() {
146            Map<String, CamelContext> answer = Maps.newHashMap();
147            if (injector != null) {
148                Set<Map.Entry<Key<?>, Binding<?>>> entries = injector.getBindings().entrySet();
149                for (Map.Entry<Key<?>, Binding<?>> entry : entries) {
150                    Key<?> key = entry.getKey();
151                    Class<?> keyType = Injectors.getKeyType(key);
152                    if (keyType != null && CamelContext.class.isAssignableFrom(keyType)) {
153                        Binding<?> binding = entry.getValue();
154                        Object value = binding.getProvider().get();
155                        if (value != null) {
156                            CamelContext castValue = CamelContext.class.cast(value);
157                            answer.put(key.toString(), castValue);
158                        }
159                    }
160                }
161            }
162            return answer;
163        }
164    
165        protected ModelFileGenerator createModelFileGenerator() throws JAXBException {
166            return new ModelFileGenerator(
167                JAXBContext.newInstance("org.apache.camel.model:org.apache.camel.model.config:org.apache.camel.model.dataformat:org.apache.camel.model.language:org.apache.camel.model.loadbalancer"));
168        }
169    }