1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package groovy.ui;
47
48 import groovy.lang.GroovyShell;
49 import groovy.lang.MetaClass;
50 import groovy.lang.Script;
51
52 import java.io.BufferedReader;
53 import java.io.File;
54 import java.io.FileNotFoundException;
55 import java.io.FileReader;
56 import java.io.FileWriter;
57 import java.io.IOException;
58 import java.io.InputStreamReader;
59 import java.io.PrintWriter;
60 import java.util.Iterator;
61 import java.util.List;
62
63 import org.apache.commons.cli.CommandLine;
64 import org.apache.commons.cli.CommandLineParser;
65 import org.apache.commons.cli.HelpFormatter;
66 import org.apache.commons.cli.OptionBuilder;
67 import org.apache.commons.cli.Options;
68 import org.apache.commons.cli.ParseException;
69 import org.apache.commons.cli.PosixParser;
70 import org.codehaus.groovy.control.CompilationFailedException;
71
72 /***
73 * A Command line to execute groovy.
74 *
75 * @author Yuri Schimke
76 * @version $Revision: 1.1 $
77 */
78 public class GroovyMain {
79
80 private List args;
81
82
83 private boolean isScriptFile;
84
85
86 private String script;
87
88
89 private boolean processFiles;
90
91
92 private boolean editFiles;
93
94
95 private boolean autoOutput;
96
97
98 private String backupExtension;
99
100 /***
101 * Main CLI interface.
102 *
103 * @param args
104 * all command line args.
105 */
106 public static void main(String 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 }
118 else {
119 process(cmd);
120 }
121 }
122 catch (ParseException pe) {
123 System.out.println("error: " + pe.getMessage());
124 System.out.println("usage: groovy [-e 'script'] [groovyScript] [arguments]");
125 }
126 }
127
128 /***
129 * Parse the command line.
130 *
131 * @param options
132 * the options parser.
133 * @param args
134 * the command line args.
135 * @return parsed command line.
136 * @throws ParseException
137 * if there was a problem.
138 */
139 private static CommandLine parseCommandLine(Options options, String[] args) throws ParseException {
140 CommandLineParser parser = new PosixParser();
141 CommandLine cmd = parser.parse(options, args);
142 return cmd;
143 }
144
145 /***
146 * Build the options parser.
147 *
148 * @return an options parser.
149 */
150 private static Options buildOptions() {
151 Options options = new Options();
152
153 options.addOption(OptionBuilder.hasArg(false).withDescription("usage information").withLongOpt("help").create('h'));
154
155 options.addOption(OptionBuilder.withArgName("script").hasArg().withDescription("specify a command line script").create('e'));
156
157 options.addOption(OptionBuilder.withArgName("extension").hasOptionalArg().withDescription("modify files in place").create('i'));
158
159 options.addOption(OptionBuilder.hasArg(false).withDescription("process files line by line").create('n'));
160
161 options.addOption(OptionBuilder.hasArg(false).withDescription("process files line by line and print result").create('p'));
162 return options;
163 }
164
165 /***
166 * Process the users request.
167 *
168 * @param line
169 * the parsed command line.
170 * @throws ParseException
171 * if invalid options are chosen
172 */
173 private static void process(CommandLine line) throws ParseException {
174 GroovyMain main = new GroovyMain();
175
176 List args = line.getArgList();
177
178 main.isScriptFile = !line.hasOption('e');
179 main.processFiles = line.hasOption('p') || line.hasOption('n');
180 main.autoOutput = line.hasOption('p');
181 main.editFiles = line.hasOption('i');
182 if (main.editFiles) {
183 main.backupExtension = line.getOptionValue('i');
184 }
185
186 if (main.isScriptFile) {
187 if (args.isEmpty())
188 throw new ParseException("neither -e or filename provided");
189
190 main.script = (String) args.remove(0);
191 if (main.script.endsWith(".java"))
192 throw new ParseException("error: cannot compile file with .java extension: " + main.script);
193 }
194 else {
195 main.script = line.getOptionValue('e');
196 }
197
198 main.args = args;
199
200 main.run();
201 }
202
203 public GroovyMain() {
204 }
205
206 /***
207 * Run the script.
208 */
209 private void run() {
210 try {
211 if (processFiles) {
212 processFiles();
213 }
214 else {
215 processOnce();
216 }
217 }
218 catch (Exception e) {
219 System.out.println("Caught: " + e);
220 e.printStackTrace();
221 }
222 }
223
224 /***
225 * Process the input files.
226 */
227 private void processFiles() throws CompilationFailedException, IOException {
228 GroovyShell groovy = new GroovyShell();
229
230 Script s = null;
231
232 if (isScriptFile)
233 s = groovy.parse(new File(script));
234 else
235 s = groovy.parse(script, "main");
236
237 if (args.isEmpty()) {
238 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
239 PrintWriter writer = new PrintWriter(System.out);
240
241 processReader(s, reader, writer);
242 }
243 else {
244 Iterator i = args.iterator();
245 while (i.hasNext()) {
246 String filename = (String) i.next();
247 File file = new File(filename);
248 processFile(s, file);
249 }
250 }
251 }
252
253 /***
254 * Process a single input file.
255 *
256 * @param s
257 * the script to execute.
258 * @param file
259 * the input file.
260 */
261 private void processFile(Script s, File file) throws IOException {
262 if (!file.exists())
263 throw new FileNotFoundException(file.getName());
264
265 if (!editFiles) {
266 BufferedReader reader = new BufferedReader(new FileReader(file));
267 try {
268 PrintWriter writer = new PrintWriter(System.out);
269 processReader(s, reader, writer);
270 writer.flush();
271 }
272 finally {
273 reader.close();
274 }
275 }
276 else {
277 File backup = null;
278 if (backupExtension == null) {
279 backup = File.createTempFile("groovy_", ".tmp");
280 backup.deleteOnExit();
281 }
282 else {
283 backup = new File(file.getPath() + backupExtension);
284 backup.delete();
285 }
286 if (!file.renameTo(backup))
287 throw new IOException("unable to rename " + file + " to " + backup);
288
289 BufferedReader reader = new BufferedReader(new FileReader(backup));
290 try {
291 PrintWriter writer = new PrintWriter(new FileWriter(file));
292 try {
293 processReader(s, reader, writer);
294 }
295 finally {
296 writer.close();
297 }
298 }
299 finally {
300 reader.close();
301 }
302 }
303 }
304
305 /***
306 * Process a script against a single input file.
307 *
308 * @param s
309 * script to execute.
310 * @param reader
311 * input file.
312 * @param pw
313 * output sink.
314 */
315 private void processReader(Script s, BufferedReader reader, PrintWriter pw) throws IOException {
316 String line = null;
317 s.setProperty("out", pw);
318 while ((line = reader.readLine()) != null) {
319 s.setProperty("line", line);
320 Object o = s.run();
321
322 if (autoOutput) {
323 pw.println(o);
324 }
325 }
326 }
327
328 /***
329 * Process the standard, single script with args.
330 */
331 private void processOnce() throws CompilationFailedException, IOException {
332 GroovyShell groovy = new GroovyShell();
333
334 if (isScriptFile)
335 groovy.run(new File(script), args);
336 else
337 groovy.run(script, "main", args);
338 }
339 }