KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > ui > GroovyMain


1 /*
2  $Id: GroovyMain.java,v 1.12 2005/01/05 09:58:22 jez Exp $
3
4  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5
6  Redistribution and use of this software and associated documentation
7  ("Software"), with or without modification, are permitted provided
8  that the following conditions are met:
9
10  1. Redistributions of source code must retain copyright
11  statements and notices. Redistributions must also contain a
12  copy of this document.
13
14  2. Redistributions in binary form must reproduce the
15  above copyright notice, this list of conditions and the
16  following disclaimer in the documentation and/or other
17  materials provided with the distribution.
18
19  3. The name "groovy" must not be used to endorse or promote
20  products derived from this Software without prior written
21  permission of The Codehaus. For written permission,
22  please contact info@codehaus.org.
23
24  4. Products derived from this Software may not be called "groovy"
25  nor may "groovy" appear in their names without prior written
26  permission of The Codehaus. "groovy" is a registered
27  trademark of The Codehaus.
28
29  5. Due credit should be given to The Codehaus -
30  http://groovy.codehaus.org/
31
32  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
36  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43  OF THE POSSIBILITY OF SUCH DAMAGE.
44
45  */

46 package groovy.ui;
47
48 import groovy.lang.GroovyShell;
49 import groovy.lang.MetaClass;
50 import groovy.lang.Script;
51 import org.apache.commons.cli.*;
52 import org.codehaus.groovy.control.CompilationFailedException;
53 import org.codehaus.groovy.control.CompilerConfiguration;
54 import org.codehaus.groovy.runtime.InvokerHelper;
55
56 import java.io.*;
57 import java.util.Iterator JavaDoc;
58 import java.util.List JavaDoc;
59
60 /**
61  * A Command line to execute groovy.
62  *
63  * @author Jeremy Rayner
64  * @author Yuri Schimke
65  * @version $Revision: 1.12 $
66  */

67 public class GroovyMain {
68     // arguments to the script
69
private List JavaDoc args;
70
71     // is this a file on disk
72
private boolean isScriptFile;
73
74     // filename or content of script
75
private String JavaDoc script;
76
77     // process args as input files
78
private boolean processFiles;
79
80     // edit input files in place
81
private boolean editFiles;
82
83     // automatically output the result of each script
84
private boolean autoOutput;
85
86     // process sockets
87
private boolean processSockets;
88
89     // port to listen on when processing sockets
90
private int port;
91
92     // backup input files with extension
93
private String JavaDoc backupExtension;
94
95     // do you want full stack traces in script exceptions?
96
private boolean debug = false;
97
98     // Compiler configuration, used to set the encodings of the scripts/classes
99
private CompilerConfiguration conf = new CompilerConfiguration();
100
101     /**
102      * Main CLI interface.
103      *
104      * @param args all command line args.
105      */

106     public static void main(String JavaDoc args[]) {
107         MetaClass.setUseReflection(true);
108
109         Options options = buildOptions();
110
111         try {
112             CommandLine cmd = parseCommandLine(options, args);
113
114             if (cmd.hasOption('h')) {
115                 HelpFormatter formatter = new HelpFormatter();
116                 formatter.printHelp("groovy", options);
117             } else if (cmd.hasOption('v')) {
118                 String JavaDoc version = InvokerHelper.getVersion();
119                 System.out.println("Groovy Version: " + version + " JVM: " + System.getProperty("java.vm.version"));
120             } else {
121                 // If we fail, then exit with an error so scripting frameworks can catch it
122
if (!process(cmd)) {
123                     System.exit(1);
124                 }
125             }
126         } catch (ParseException pe) {
127             System.out.println("error: " + pe.getMessage());
128             HelpFormatter formatter = new HelpFormatter();
129             formatter.printHelp("groovy", options);
130         }
131     }
132
133     /**
134      * Parse the command line.
135      *
136      * @param options the options parser.
137      * @param args the command line args.
138      * @return parsed command line.
139      * @throws ParseException if there was a problem.
140      */

141     private static CommandLine parseCommandLine(Options options, String JavaDoc[] args) throws ParseException {
142         CommandLineParser parser = new PosixParser();
143         CommandLine cmd = parser.parse(options, args, true);
144         return cmd;
145     }
146
147     /**
148      * Build the options parser. Has to be synchronized because of the way Options are constructed.
149      *
150      * @return an options parser.
151      */

152     private static synchronized Options buildOptions() {
153         Options options = new Options();
154
155         options.addOption(OptionBuilder.hasArg(false).withDescription("usage information").withLongOpt("help").create('h'));
156
157         options.addOption(OptionBuilder.hasArg(false).withDescription("debug mode will print out full stack traces").withLongOpt("debug").create('d'));
158
159         options.addOption(OptionBuilder.hasArg(false).withDescription("display the Groovy and JVM versions").withLongOpt("version").create('v'));
160
161         options.addOption(OptionBuilder.withArgName("charset").hasArg().withDescription("specify the encoding of the files").withLongOpt("encoding").create('c'));
162
163         options.addOption(OptionBuilder.withArgName("script").hasArg().withDescription("specify a command line script").create('e'));
164
165         options.addOption(OptionBuilder.withArgName("extension").hasOptionalArg().withDescription("modify files in place").create('i'));
166
167         options.addOption(OptionBuilder.hasArg(false).withDescription("process files line by line").create('n'));
168
169         options.addOption(OptionBuilder.hasArg(false).withDescription("process files line by line and print result").create('p'));
170
171         options.addOption(OptionBuilder.withArgName("port").hasOptionalArg().withDescription("listen on a port and process inbound lines").create('l'));
172         return options;
173     }
174
175     /**
176      * Process the users request.
177      *
178      * @param line the parsed command line.
179      * @throws ParseException if invalid options are chosen
180      */

181     private static boolean process(CommandLine line) throws ParseException {
182         GroovyMain main = new GroovyMain();
183
184         List JavaDoc args = line.getArgList();
185
186         // add the ability to parse scripts with a specified encoding
187
if (line.hasOption('c')) {
188             main.conf.setSourceEncoding(line.getOptionValue("encoding"));
189         }
190
191         main.isScriptFile = !line.hasOption('e');
192         main.debug = line.hasOption('d');
193         main.processFiles = line.hasOption('p') || line.hasOption('n');
194         main.autoOutput = line.hasOption('p');
195         main.editFiles = line.hasOption('i');
196         if (main.editFiles) {
197             main.backupExtension = line.getOptionValue('i');
198         }
199
200         if (main.isScriptFile) {
201             if (args.isEmpty())
202                 throw new ParseException("neither -e or filename provided");
203
204             main.script = (String JavaDoc) args.remove(0);
205             if (main.script.endsWith(".java"))
206                 throw new ParseException("error: cannot compile file with .java extension: " + main.script);
207         } else {
208             main.script = line.getOptionValue('e');
209         }
210
211         main.processSockets = line.hasOption('l');
212         if (main.processSockets) {
213             String JavaDoc p = line.getOptionValue('l', "1960"); // default port to listen to
214
main.port = new Integer JavaDoc(p).intValue();
215         }
216         main.args = args;
217
218         return main.run();
219     }
220
221
222     /**
223      * Run the script.
224      */

225     private boolean run() {
226         try {
227             if (processSockets) {
228                 processSockets();
229             } else if (processFiles) {
230                 processFiles();
231             } else {
232                 processOnce();
233             }
234             return true;
235         } catch (Exception JavaDoc e) {
236             System.err.println("Caught: " + e);
237             if (debug) {
238                 e.printStackTrace();
239             } else {
240                 StackTraceElement JavaDoc[] stackTrace = e.getStackTrace();
241                 for (int i = 0; i < stackTrace.length; i++) {
242                     StackTraceElement JavaDoc element = stackTrace[i];
243                     if (!element.getFileName().endsWith(".java")) {
244                         System.err.println("\tat " + element);
245                     }
246                 }
247             }
248             return false;
249         }
250     }
251
252     /**
253      * Process Sockets.
254      */

255     private void processSockets() throws CompilationFailedException, IOException {
256         GroovyShell groovy = new GroovyShell(conf);
257         //check the script is currently valid before starting a server against the script
258
if (isScriptFile) {
259             groovy.parse(new FileInputStream(script));
260         } else {
261             groovy.parse(script);
262         }
263         new GroovySocketServer(groovy, isScriptFile, script, autoOutput, port);
264     }
265
266     /**
267      * Process the input files.
268      */

269     private void processFiles() throws CompilationFailedException, IOException {
270         GroovyShell groovy = new GroovyShell(conf);
271
272         Script s = null;
273
274         if (isScriptFile)
275             s = groovy.parse(new File(script));
276         else
277             s = groovy.parse(script, "main");
278
279         if (args.isEmpty()) {
280             BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
281             PrintWriter writer = new PrintWriter(System.out);
282
283             processReader(s, reader, writer);
284         } else {
285             Iterator JavaDoc i = args.iterator();
286             while (i.hasNext()) {
287                 String JavaDoc filename = (String JavaDoc) i.next();
288                 File file = new File(filename);
289                 processFile(s, file);
290             }
291         }
292     }
293
294     /**
295      * Process a single input file.
296      *
297      * @param s the script to execute.
298      * @param file the input file.
299      */

300     private void processFile(Script s, File file) throws IOException {
301         if (!file.exists())
302             throw new FileNotFoundException(file.getName());
303
304         if (!editFiles) {
305             BufferedReader reader = new BufferedReader(new FileReader(file));
306             try {
307                 PrintWriter writer = new PrintWriter(System.out);
308                 processReader(s, reader, writer);
309                 writer.flush();
310             } finally {
311                 reader.close();
312             }
313         } else {
314             File backup = null;
315             if (backupExtension == null) {
316                 backup = File.createTempFile("groovy_", ".tmp");
317                 backup.deleteOnExit();
318             } else {
319                 backup = new File(file.getPath() + backupExtension);
320                 backup.delete();
321             }
322             if (!file.renameTo(backup))
323                 throw new IOException("unable to rename " + file + " to " + backup);
324
325             BufferedReader reader = new BufferedReader(new FileReader(backup));
326             try {
327                 PrintWriter writer = new PrintWriter(new FileWriter(file));
328                 try {
329                     processReader(s, reader, writer);
330                 } finally {
331                     writer.close();
332                 }
333             } finally {
334                 reader.close();
335             }
336         }
337     }
338
339     /**
340      * Process a script against a single input file.
341      *
342      * @param s script to execute.
343      * @param reader input file.
344      * @param pw output sink.
345      */

346     private void processReader(Script s, BufferedReader reader, PrintWriter pw) throws IOException {
347         String JavaDoc line = null;
348         s.setProperty("out", pw);
349         while ((line = reader.readLine()) != null) {
350             s.setProperty("line", line);
351             Object JavaDoc o = s.run();
352
353             if (autoOutput) {
354                 pw.println(o);
355             }
356         }
357     }
358
359     /**
360      * Process the standard, single script with args.
361      */

362     private void processOnce() throws CompilationFailedException, IOException {
363         GroovyShell groovy = new GroovyShell(conf);
364
365         if (isScriptFile)
366             groovy.run(new File(script), args);
367         else
368             groovy.run(script, "main", args);
369     }
370 }
Popular Tags