1 package net.sf.tomp.xtcl;
2
3 import org.apache.commons.cli.CommandLine;
4 import org.apache.commons.cli.HelpFormatter;
5 import org.apache.commons.cli.Option;
6 import org.apache.commons.cli.OptionBuilder;
7 import org.apache.commons.cli.Options;
8 import org.apache.commons.cli.PosixParser;
9
10 import java.io.File;
11 import java.io.PrintWriter;
12
13 /***
14 * Main XTCL entry point, allows execution of XTCL script from files or
15 * interactively command-by-command from comman line. <br/>
16 *
17 * Usage examples: <br/>
18 *
19 * Execution of the script file specified by option <tt>-f</tt> filename <br/>
20 *
21 * <pre>java net.sf.tomp.xtcl.Main -q -f demo\echo.xcf</pre>
22 *
23 * gives just <br/>
24 *
25 * <pre>Echo!</pre>
26 *
27 * The same in default verbose (non-quiet) mode: <br/>
28 *
29 * <pre>java net.sf.tomp.xtcl.Main -f demo\echo.xcf</pre>
30 *
31 * gives <br/>
32 *
33 * <pre>XTCL - program from file 'demo\echo.xcf'
34 0.0: Echo!
35 OK ECHO Echo! (0 ms)
36 Execution time: 0 ms.</pre>
37 *
38 * Execution of command specified directly on command line <br/>
39 *
40 * <pre>java net.sf.tomp.xtcl.Main -q ECHO Hello!</pre>
41 *
42 * gives <br/>
43 *
44 * <pre>Hello!</pre>
45 *
46 * The same in default verbose (non-quiet) mode: <br/>
47 *
48 * <pre>java net.sf.tomp.xtcl.Main ECHO Hello!</pre>
49 *
50 * gives <br/>
51 *
52 * <pre>XTCL - command read from command line:
53 Hello!
54 OK ECHO Hello!Execution time: 0 ms.</pre>
55 *
56 * Options -f and commands directly on command line may be combined. Example:
57 * <br/>First, execute the script <tt>demo\echo.xcf</tt> then the command
58 * <tt>ECHO Hello!</tt>.<br/>
59 * If <tt>-F</tt> is specified, the script
60 * file is executed after the command on the command line. <br/>
61 *
62 * <pre>java net.sf.tomp.xtcl.Main -q -f demo\echo.xcf ECHO Hello!</pre>
63 *
64 * gives <br/>
65 *
66 * <pre>Echo!
67 Hello!</pre>
68 *
69 * while <br/>
70 *
71 * <pre>java net.sf.tomp.xtcl.Main -q -F demo\echo.xcf ECHO Hello!</pre>
72 *
73 * gives <br/>
74 *
75 * <pre>Hello!
76 Echo!</pre>
77 *
78 * The two parameters -f and -F can even be combined:<br/>
79 *
80 * <pre>java net.sf.tomp.xtcl.Main -q -f demo\echo.xcf -F demo\echo.xcf ECHO Hello!</pre>
81 *
82 * gives <br/>
83 *
84 * <pre>Echo!
85 Hello!
86 Echo!</pre>
87 *
88 * Interactive mode: commands are entered to System.in and immediatelly executed
89 * until END is entered. <br/>
90 *
91 * <pre>java net.sf.tomp.xtcl.Main -i -q</pre>
92 *
93 * Interactive work may look like: <br/>
94 *
95 * <pre>
96 XTCL 0>echo gujh
97 gujh
98
99 XTCL 1>end</pre>
100 *
101 * @author tomp
102 * @version 2004-07-29
103 */
104 public class Main {
105 /***
106 * Main XTCL entry point, allows execution of XTCL script from files or
107 * interactively command-by-command from command line.
108 *
109 * @param args
110 * the command line arguments
111 * @throws Exception
112 * if execution fails
113 */
114 public static void main(String[] args) throws Exception {
115
116 Context context = new Context();
117
118 context.setOut(System.err);
119
120
121 Compiler comp = context.getCompiler();
122
123 Command cs = null;
124
125
126 context.put("$out", System.out);
127
128 int returnCode = 0;
129
130 OptionBuilder.hasArgs(1);
131 OptionBuilder.withLongOpt("script");
132 OptionBuilder.withDescription("run the specified script");
133 OptionBuilder.withArgName("scripttext");
134
135 Option oScript = OptionBuilder.create('s');
136
137 OptionBuilder.hasArgs(1);
138 OptionBuilder.withLongOpt("script-after");
139 OptionBuilder.withDescription("run the specified script after the command on command line");
140 OptionBuilder.withArgName("scripttext");
141
142 Option oAfterScript = OptionBuilder.create('S');
143
144 OptionBuilder.hasArgs(1);
145 OptionBuilder.withLongOpt("script-file");
146 OptionBuilder.withDescription("run the specified script file");
147 OptionBuilder.withArgName("scriptfile");
148
149 Option oFile = OptionBuilder.create('f');
150
151 OptionBuilder.hasArgs(1);
152 OptionBuilder.withLongOpt("script-file-after");
153 OptionBuilder
154 .withDescription("run the specified script file after the command on command line");
155 OptionBuilder.withArgName("scriptfile");
156
157 Option oAfterFile = OptionBuilder.create('F');
158
159 OptionBuilder.hasArgs(1);
160 OptionBuilder.withLongOpt("uri-resolver");
161 OptionBuilder.withDescription("use the specified URIResolver");
162 OptionBuilder.withArgName("URIResolver_classname");
163
164 Option oUR = OptionBuilder.create('u');
165
166 OptionBuilder.hasArgs(1);
167 OptionBuilder.withLongOpt("resolving-reader");
168 OptionBuilder.withDescription("use the specified resolving XMLReader");
169 OptionBuilder.withArgName("ResolvingXMLReader_classname");
170
171 Option oRR = OptionBuilder.create('r');
172
173 OptionBuilder.withLongOpt("ignore-errors");
174 OptionBuilder.withDescription("ignore errors and continue processing");
175
176 Option oIgnore = OptionBuilder.create('g');
177
178 OptionBuilder.withLongOpt("quiet");
179 OptionBuilder.withDescription("provide no info on processing");
180
181 Option oVerb = OptionBuilder.create('q');
182
183 OptionBuilder.withLongOpt("verbose");
184 OptionBuilder.withDescription("provide extra rich info on processing");
185
186 Option oExtraVerb = OptionBuilder.create('v');
187
188 OptionBuilder.withLongOpt("interactive");
189 OptionBuilder
190 .withDescription("enter interactive mode, 'END' finishes execution");
191
192 Option oInt = OptionBuilder.create('i');
193
194 OptionBuilder.withLongOpt("usage");
195 OptionBuilder.withDescription("print just usage (not whole help)");
196
197 Option oHelp = OptionBuilder.create('h');
198
199 Options opts = new Options();
200
201 opts.addOption(oScript);
202 opts.addOption(oAfterScript);
203 opts.addOption(oFile);
204 opts.addOption(oAfterFile);
205 opts.addOption(oUR);
206 opts.addOption(oRR);
207 opts.addOption(oIgnore);
208 opts.addOption(oVerb);
209 opts.addOption(oExtraVerb);
210 opts.addOption(oInt);
211 opts.addOption(oHelp);
212
213 CommandLine cl = new PosixParser().parse(opts, args);
214
215 context.setVerbose(!cl.hasOption('q'));
216
217 boolean breakOnError = true;
218
219
220 if (args.length == 0) {
221
222 PrintWriter pw = new PrintWriter(System.out);
223
224
225 new HelpFormatter()
226 .printHelp(
227 pw,
228 80,
229 "java net.sf.tomp.xtcl.Main",
230 "\nXTCL - simple XML Transformations Shell, http://tomp.sf.net",
231 opts, 10, 25,
232 "Copyright (c) 2003-2004 Tomas Pitner", true);
233 pw.flush();
234
235 } else {
236
237 if (cl.hasOption('h')) {
238 PrintWriter pw = new PrintWriter(System.out);
239
240
241 new HelpFormatter().printUsage(pw, 80,
242 "java net.sf.tomp.xtcl.Main", opts);
243 pw.flush();
244 }
245 if (cl.hasOption('u')) {
246 Context.setUriResolverClass(Class.forName(cl
247 .getOptionValue('u')));
248 if (comp.getContext().isVerbose()) {
249 System.out.println("Use UriResolverClass="
250 + cl.getOptionValue('u'));
251 }
252 }
253 if (cl.hasOption('r')) {
254 Context.setResolvingXMLReaderClass(Class.forName(cl
255 .getOptionValue('r')));
256 if (context.isVerbose()) {
257 System.out.println("Use ResolvingXMLReaderClass="
258 + cl.getOptionValue('r'));
259 }
260 }
261 if (cl.hasOption('g')) {
262 breakOnError = false;
263 if (comp.getContext().isVerbose()) {
264 System.out.println("Ignore errors");
265 }
266 }
267
268
269 if (cl.hasOption('s')) {
270 String s = cl.getOptionValue('s');
271
272 if (context.isExtraVerbose()) {
273 System.out.println("XTCL - program '" + s + "'");
274 } else if (context.isVerbose()) {
275 System.out.println("XTCL - program from script on command line");
276 }
277
278 returnCode = execute(context, comp
279 .compile(s));
280 }
281
282 if (cl.hasOption('f')) {
283 File f = new File(cl.getOptionValue('f'));
284
285 if (context.isVerbose()) {
286 System.out.println("XTCL - program from file '" + f + "'");
287 }
288
289 returnCode = execute(context, comp
290 .compile(new CommandLineReader(f)));
291 }
292
293 if (cl.getArgs().length > 0) {
294 if (context.isVerbose()) {
295 System.out
296 .println("XTCL - command read from command line:");
297 }
298
299 cs = comp.compile(cl.getArgs(), new CommandLineReader());
300 returnCode = execute(context, cs);
301
302 }
303
304 if (cl.hasOption('F')) {
305 File f = new File(cl.getOptionValue('F'));
306
307 if (context.isVerbose()) {
308 System.out.println("XTCL - program from file '" + f + "'");
309 }
310
311 returnCode = execute(context, comp
312 .compile(new CommandLineReader(f)));
313 }
314
315 if (cl.hasOption('S')) {
316 String s = cl.getOptionValue('S');
317
318 if (context.isExtraVerbose()) {
319 System.out.println("XTCL - program '" + s + "'");
320 } else if (context.isVerbose()) {
321 System.out.println("XTCL - program from script on command line");
322 }
323
324 returnCode = execute(context, comp
325 .compile(s));
326 }
327 if (cl.hasOption('i')) {
328 if (context.isVerbose()) {
329 System.out
330 .println("XTCL - interactive mode. Enter the commands (END for quit):");
331 }
332
333 new InteractiveExecutor(context).interactive();
334 }
335 }
336
337 System.exit(returnCode);
338 }
339
340 /***
341 * Utility method. It executes a Command in a Context and returns
342 * the result. Also, it measures the execution time.
343 *
344 * @param context
345 * @param cs
346 * @return return code (0 == OK, otherwise error)
347 * @throws Exception
348 */
349 private static int execute(Context context, Command cs) throws Exception {
350 if (cs == null)
351 return 0;
352 long start = System.currentTimeMillis();
353
354 int returnCode = context.execute(cs);
355
356 long end = System.currentTimeMillis();
357
358 if (context.isVerbose()) {
359 System.out.println("Execution time: " + (end - start) + " ms.");
360 }
361 if (returnCode != 0)
362 System.exit(returnCode);
363 return returnCode;
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376