001    /*
002     $Id: GroovyStarter.java 4098 2006-10-10 16:09:48Z blackdrag $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    package org.codehaus.groovy.tools;
047    
048    import java.lang.reflect .*;
049    import java.io.FileInputStream;
050    
051    
052    
053    /**
054     * Helper class to help classworlds to load classes. 
055     */
056    public class GroovyStarter {
057    
058        static void printUsage() {
059            System.out.println("possible programs are 'groovyc','groovy','console','grok' and 'groovysh'");
060            System.exit(1);
061        }
062        
063        
064        public static void rootLoader(String args[]) {
065            String conf = System.getProperty("groovy.starter.conf",null);
066            LoaderConfiguration lc = new LoaderConfiguration();
067            
068            // evaluate parameters
069            boolean hadMain=false, hadConf=false, hadCP=false;
070            int argsOffset = 0;
071            while (args.length-argsOffset>0 && !(hadMain && hadConf && hadCP)) {
072                if (args[argsOffset].equals("--classpath")) {
073                    if (hadCP) break;
074                    if (args.length==argsOffset+1) {
075                        exit("classpath parameter needs argument");
076                    }
077                    lc.addClassPath(args[argsOffset+1]);
078                    argsOffset+=2;
079                } else if (args[argsOffset].equals("--main")) {
080                    if (hadMain) break;
081                    if (args.length==argsOffset+1) {
082                        exit("main parameter needs argument");
083                    }
084                    lc.setMainClass(args[argsOffset+1]);
085                    argsOffset+=2;
086                } else if (args[argsOffset].equals("--conf")) {
087                    if (hadConf) break;
088                    if (args.length==argsOffset+1) {
089                        exit("conf parameter needs argument");
090                    }
091                    conf=args[argsOffset+1];
092                    argsOffset+=2;
093                } else {
094                    break;
095                }            
096            }
097            
098            // we need to know the class we want to start
099            if (lc.getMainClass()==null && conf==null) {
100                exit("no configuration file or main class specified");
101            }
102            
103            // copy arguments for main class 
104            String[] newArgs = new String[args.length-argsOffset];
105            for (int i=0; i<newArgs.length; i++) {
106                newArgs[i] = args[i+argsOffset];
107            }        
108            // load configuration file
109            if (conf!=null) {
110                try {
111                    lc.configure(new FileInputStream(conf));
112                } catch (Exception e) {
113                    System.err.println("exception while configuring main class loader:");
114                    exit(e);
115                }
116            }
117            // create loader and execute main class
118            ClassLoader loader = new RootLoader(lc);
119            Method m=null;
120            try {
121                Class c = loader.loadClass(lc.getMainClass());
122                m = c.getMethod("main", new Class[]{String[].class});
123            } catch (ClassNotFoundException e1) {
124                exit(e1);
125            } catch (SecurityException e2) {
126                exit(e2);
127            } catch (NoSuchMethodException e2) {
128                exit(e2);
129            }
130            try {
131                m.invoke(null, new Object[]{newArgs});
132            } catch (IllegalArgumentException e3) {
133                exit(e3);
134            } catch (IllegalAccessException e3) {
135                exit(e3);
136            } catch (InvocationTargetException e3) {
137                exit(e3);
138            } 
139        }
140        
141        private static void exit(Exception e) {
142            e.printStackTrace();
143            System.exit(1);
144        }
145        
146        private static void exit(String msg) {
147            System.err.println(msg);
148            System.exit(1);
149        }
150     
151        // after migration from classworlds to the rootloader rename
152        // the rootLoader method to main and remove this method as 
153        // well as the classworlds method
154       /* public static void main(String args[],ClassWorld classWorld ) {
155            classworlds(args,classWorld);
156        }*/
157        
158        public static void main(String args[]) {
159            try {
160                rootLoader(args);
161            } catch (Throwable t) {
162                t.printStackTrace();
163            }
164        }
165    
166        /*public static void classworlds(String oldArgs[],ClassWorld classWorld ) {
167            try {
168                // Creates a realm with *just* the system classloader
169                ClassRealm system = classWorld.newRealm("system");
170         
171                // Get the groovy realm
172                ClassRealm groovy = classWorld.getRealm("groovy");
173               
174                // import everything from the system realm, because imports
175                // are searched *first* in Classworlds
176                groovy.importFrom("system", "");
177                
178                //add tools.jar to classpath
179                String tools = System.getProperty("tools.jar");
180                if (tools!=null) {
181                    URL ref = (new File(tools)).toURI().toURL();
182                    groovy.addConstituent(ref);
183                }
184            
185                if (oldArgs.length==0) {
186                    printUsage();
187                    System.exit(1);
188                }
189                
190                String program = oldArgs[0].toLowerCase();
191                String[] args = new String[oldArgs.length-1];
192                for (int i=0; i<args.length; i++) {
193                    args[i] = oldArgs[i+1];
194                }
195                
196                if (program.equals("groovyc")) {
197                    org.codehaus.groovy.tools.FileSystemCompiler.main(args);
198                } else if (program.equals("groovy")) {
199                    GroovyMain.main(args);
200                } else if (program.equals("console")) {
201                    // work around needed, because the console is compiled after this files
202                    Class c = Class.forName("groovy.ui.Console");
203                    Method m= c.getMethod("main", new Class[]{String[].class});
204                    m.invoke(null, new Object[]{args});
205                } else if (program.equals("groovysh")) {
206                    InteractiveShell.main(args);
207                 } else if (program.equals("grok")) {
208                    org.codehaus.groovy.tools.Grok.main(args);
209                } else {
210                    System.out.println("unknown program "+program);
211                    printUsage();
212                    System.exit(1);
213                }
214            
215            } catch (Exception e) {
216                e.printStackTrace();
217                System.exit(1);
218            }
219            
220        }*/
221        
222    }