001    /*
002     $Id: FileSystemCompiler.java 3514 2006-02-07 20:00:41Z dierk $
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.io.File;
049    
050    import org.apache.commons.cli.CommandLine;
051    import org.apache.commons.cli.OptionBuilder;
052    import org.apache.commons.cli.Options;
053    import org.apache.commons.cli.PosixParser;
054    import org.codehaus.groovy.control.CompilationUnit;
055    import org.codehaus.groovy.control.CompilerConfiguration;
056    import org.codehaus.groovy.control.ConfigurationException;
057    
058    public class FileSystemCompiler  
059    {
060        private CompilationUnit unit;
061    
062        
063        public FileSystemCompiler( CompilerConfiguration configuration ) throws ConfigurationException
064        {
065            this.unit = new CompilationUnit( configuration );
066        }
067    
068        
069        public void compile( String[] paths ) throws Exception 
070        {
071            unit.addSources( paths );
072            unit.compile( );
073        }
074    
075        
076        public void compile( File[] files ) throws Exception 
077        {
078            unit.addSources( files );
079            unit.compile( );
080        }
081    
082    
083        public static void displayHelp() // todo: use HelpFormatter to avoid duplication between help and OptionBuilder
084        {
085            System.err.println("Usage: groovyc <options> <source files>");
086            System.err.println("where possible options include: ");
087            System.err.println("  --classpath <path>        Specify where to find user class files");
088            System.err.println("  -d <directory>            Specify where to place generated class files");
089            System.err.println("  --encoding <encoding>     Specify the encoding of the user class files");
090    //        System.err.println("  --strict                  Turn on strict type safety");
091            System.err.println("  --version                 Print the verion");
092            System.err.println("  --help                    Print a synopsis of standard options");
093            System.err.println("  --exception               Print stack trace on error");
094            System.err.println("");
095        }
096    
097        public static void displayVersion() 
098        {
099            System.err.println("groovy compiler version 1.0-rc1");
100            System.err.println("Copyright 2003-2004 The Codehaus. http://groovy.codehaus.org/");
101            System.err.println("");
102        }
103    
104        public static int checkFiles( String[] filenames ) 
105        {
106            int errors = 0;
107    
108            for(int i = 0; i < filenames.length; ++i ) 
109            {
110                File file = new File( filenames[i] );
111    
112                if( !file.exists() ) 
113                {
114                    System.err.println( "error: file not found: " + file );
115                    ++errors;
116                }
117                else if( !file.canRead() ) 
118                {
119                    System.err.println( "error: file not readable: " + file );
120                    ++errors;
121                } else {
122                    String name = file.getName();
123                    int p = name.lastIndexOf(".");
124                    if ( p++ >= 0) {
125                        if (name.substring(p).equals("java")) {
126                            System.err.println( "error: cannot compile file with .java extension: " + file );
127                            ++errors;
128                        }
129                    }
130                }
131            }
132    
133            return errors;
134        }
135    
136        
137        
138       /**
139        *  Primary entry point for compiling from the command line
140        *  (using the groovyc script).
141        */
142        
143        public static void main( String[] args )
144        {
145            boolean displayStackTraceOnError = false;
146            
147            try
148            {
149                //
150                // Parse the command line
151                
152                Options options = new Options();
153        
154                options.addOption(OptionBuilder.withLongOpt("classpath").hasArg().withArgName("classpath").create());
155                options.addOption(OptionBuilder.withLongOpt("sourcepath").hasArg().withArgName("sourcepath").create());
156                options.addOption(OptionBuilder.withLongOpt("encoding").hasArg().withArgName("encoding").create());
157                options.addOption(OptionBuilder.hasArg().create('d'));
158    //            options.addOption(OptionBuilder.withLongOpt("strict").create('s'));
159                options.addOption(OptionBuilder.withLongOpt("help").create('h'));
160                options.addOption(OptionBuilder.withLongOpt("version").create('v'));
161                options.addOption(OptionBuilder.withLongOpt("exception").create('e'));
162        
163                PosixParser cliParser = new PosixParser();
164        
165                CommandLine cli = cliParser.parse(options, args);
166        
167                if( cli.hasOption('h') ) 
168                {
169                    displayHelp();
170                    return;
171                }
172        
173                if( cli.hasOption('v') ) 
174                {
175                    displayVersion();
176                }
177        
178                
179                //
180                // Setup the configuration data
181                
182                CompilerConfiguration configuration = new CompilerConfiguration();
183        
184                if( cli.hasOption("classpath") ) 
185                {
186                    configuration.setClasspath( cli.getOptionValue("classpath") );
187                }
188        
189                if( cli.hasOption('d') ) 
190                {
191                    configuration.setTargetDirectory( cli.getOptionValue('d') );
192                }
193    
194                if (cli.hasOption("encoding")) {
195                    configuration.setSourceEncoding(cli.getOptionValue("encoding"));
196                }
197    
198                displayStackTraceOnError = cli.hasOption('e');
199                
200                
201                //
202                // Load the file name list
203                
204                String[] filenames = cli.getArgs();
205                if( filenames.length == 0 ) 
206                {
207                    displayHelp();
208                    return;
209                }
210        
211                int errors = checkFiles( filenames );
212        
213                
214                //
215                // Create and start the compiler
216                
217                if( errors == 0 ) 
218                {
219                    FileSystemCompiler compiler = new FileSystemCompiler( configuration );
220                    compiler.compile( filenames );
221                }
222            }
223            catch( Throwable e ) 
224            {
225                new ErrorReporter( e, displayStackTraceOnError ).write( System.err );
226            }
227        }
228        
229    }