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.util;
018    
019    import java.lang.reflect.InvocationTargetException;
020    import java.lang.reflect.Method;
021    import java.lang.reflect.Modifier;
022    import java.util.Arrays;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    
027    import org.springframework.beans.factory.InitializingBean;
028    
029    import static org.apache.camel.util.ObjectHelper.name;
030    
031    /**
032     * A simple helper bean for running main classes from within the spring.xml
033     * usually asynchronous in a background thread; which is useful for demos such
034     * as running Swing programs in the same JVM.
035     * 
036     * @version $Revision: 747759 $
037     */
038    public class MainRunner implements InitializingBean, Runnable {
039        private static final Log LOG = LogFactory.getLog(MainRunner.class);
040    
041        private Class main;
042        private String[] args = {};
043        private boolean asyncRun = true;
044        private long delay;
045    
046        public String toString() {
047            return "MainRunner(" + name(main) + " " + Arrays.asList(getArgs()) + ")";
048        }
049    
050        public void run() {
051            try {
052                runMethodWithoutCatchingExceptions();
053            } catch (NoSuchMethodException e) {
054                LOG.error("Class: " + name(main) + " does not have a main method: " + e, e);
055            } catch (IllegalAccessException e) {
056                LOG.error("Failed to run: " + this + ". Reason: " + e, e);
057            } catch (InvocationTargetException e) {
058                Throwable throwable = e.getTargetException();
059                LOG.error("Failed to run: " + this + ". Reason: " + throwable, throwable);
060            }
061        }
062    
063        public void runMethodWithoutCatchingExceptions() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
064            if (delay > 0) {
065                try {
066                    Thread.sleep(delay);
067                } catch (InterruptedException e) {
068                    Thread.currentThread().interrupt();
069                }
070            }
071            Method method = main.getMethod("main", String[].class);
072            if (!Modifier.isStatic(method.getModifiers())) {
073                throw new IllegalArgumentException("The main method is not static!: " + method);
074            }
075            Object[] arguments = {getArgs()};
076            method.invoke(null, arguments);
077        }
078    
079        public String[] getArgs() {
080            return args;
081        }
082    
083        public void setArgs(String[] args) {
084            this.args = args;
085        }
086    
087        public boolean isAsyncRun() {
088            return asyncRun;
089        }
090    
091        public void setAsyncRun(boolean asyncRun) {
092            this.asyncRun = asyncRun;
093        }
094    
095        public Class getMain() {
096            return main;
097        }
098    
099        public void setMain(Class main) {
100            this.main = main;
101        }
102    
103        public long getDelay() {
104            return delay;
105        }
106    
107        public void setDelay(long delay) {
108            this.delay = delay;
109        }
110    
111        public void afterPropertiesSet() throws Exception {
112            if (main == null) {
113                throw new IllegalArgumentException("You must specify a main class!");
114            }
115            if (isAsyncRun()) {
116                Thread thread = new Thread(this, "Thread for: " + this);
117                thread.start();
118            } else {
119                runMethodWithoutCatchingExceptions();
120            }
121        }
122    }