1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jelly.util;
18
19 import java.io.File;
20 import java.io.FileWriter;
21 import java.net.URL;
22 import java.util.Arrays;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Properties;
26
27 import org.apache.commons.cli.CommandLine;
28 import org.apache.commons.cli.Options;
29 import org.apache.commons.cli.ParseException;
30 import org.apache.commons.cli.Parser;
31 import org.apache.commons.cli.HelpFormatter;
32 import org.apache.commons.jelly.Jelly;
33 import org.apache.commons.jelly.JellyContext;
34 import org.apache.commons.jelly.JellyException;
35 import org.apache.commons.jelly.Script;
36 import org.apache.commons.jelly.XMLOutput;
37
38 /***
39 * Utility class to parse command line options using CLI.
40 * Using a separate class allows us to run Jelly without
41 * CLI in the classpath when the command line interface
42 * is not in use.
43 *
44 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
45 * @author Morgan Delagrange
46 * @version $Revision: 155420 $
47 */
48 public class CommandLineParser {
49
50 protected static CommandLineParser _instance = new CommandLineParser();
51
52 private Options cmdLineOptions = null;
53
54 public static CommandLineParser getInstance() {
55 return _instance;
56 }
57
58 /***
59 * Parse out the command line options and configure
60 * the give Jelly instance.
61 *
62 * @param args options from the command line
63 * @exception JellyException
64 * if the command line could not be parsed
65 */
66 public void invokeCommandLineJelly(String[] args) throws JellyException {
67 CommandLine cmdLine = null;
68 try {
69 cmdLine = parseCommandLineOptions(args);
70 } catch (ParseException e) {
71 throw new JellyException(e);
72 }
73
74
75 if (cmdLine.hasOption("h")) {
76 new HelpFormatter().printHelp("jelly [scriptFile] [-script scriptFile] [-o outputFile] [-Dsysprop=syspropval] [-awt]",
77 cmdLineOptions);
78 System.exit(1);
79 }
80 if (cmdLine.hasOption("v")) {
81 System.err.println("Jelly " + Jelly.getJellyVersion());
82 System.err.println(" compiled: " + Jelly.getJellyBuildDate());
83 System.err.println("");
84 System.exit(1);
85 }
86
87
88 String scriptFile = null;
89 if (cmdLine.hasOption("script")) {
90 scriptFile = cmdLine.getOptionValue("script");
91 } else {
92 scriptFile = args[0];
93 }
94
95
96 boolean runInSwingThread = cmdLine.hasOption("awt") || cmdLine.hasOption("swing");
97
98
99
100
101 URL url = ClassLoaderUtils.getClassLoader(getClass()).getResource(scriptFile);
102
103 if (url == null && !(new File(scriptFile)).exists()) {
104 throw new JellyException("Script file " + scriptFile + " not found");
105 }
106
107 try {
108
109 final XMLOutput output = cmdLine.hasOption("o") ?
110 XMLOutput.createXMLOutput(new FileWriter(cmdLine.getOptionValue("o"))) :
111 XMLOutput.createXMLOutput(System.out);
112
113 Jelly jelly = new Jelly();
114 jelly.setScript(scriptFile);
115
116 final Script script = jelly.compileScript();
117
118
119 final JellyContext context = jelly.getJellyContext();
120 context.setVariable("args", args);
121 context.setVariable("commandLine", cmdLine);
122 if (runInSwingThread) {
123 javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() {
124 try {
125 script.run(context, output);
126 } catch (Exception ex) {
127 ex.printStackTrace();
128 }
129 } } ); } else {
130 script.run(context, output);
131 }
132
133
134 Runtime.getRuntime().addShutdownHook(new Thread() {
135 public void run() {
136 try {
137 output.close();
138 }
139 catch (Exception e) {
140
141 }
142 }
143 }
144 );
145
146 } catch (Exception e) {
147 throw new JellyException(e);
148 }
149
150 }
151
152 /***
153 * Parse the command line using CLI. -o and -script are reserved for Jelly.
154 * -Dsysprop=sysval is support on the command line as well.
155 */
156 public CommandLine parseCommandLineOptions(String[] args) throws ParseException {
157
158 cmdLineOptions = new Options();
159 cmdLineOptions.addOption("o", true, "Output file");
160 cmdLineOptions.addOption("script", true, "Jelly script to run");
161 cmdLineOptions.addOption("h","help", false, "Give this help message");
162 cmdLineOptions.addOption("v","version", false, "prints Jelly's version and exits");
163 cmdLineOptions.addOption("script", true, "Jelly script to run");
164 cmdLineOptions.addOption("awt", false, "Wether to run in the AWT thread.");
165 cmdLineOptions.addOption("swing", false, "Synonym of \"-awt\".");
166 List builtinOptionNames = Arrays.asList(new String[]{
167 "-o","-script","-h","--help","-v","--version","-awt","-swing"});
168
169
170 Properties sysProps = System.getProperties();
171
172
173
174 ArrayList filteredArgList = new ArrayList();
175
176 for (int i=0;i<args.length;i++) {
177 String arg = args[i];
178
179
180
181 if (arg.startsWith("-D") && (arg.length() > 2)) {
182 arg = arg.substring(2);
183 int ePos = arg.indexOf("=");
184 if(ePos==-1 || ePos==0 || ePos==arg.length()-1)
185 System.err.println("Invalid system property: \"" + arg + "\".");
186 sysProps.setProperty(arg.substring(0,ePos), arg.substring(ePos+1));
187 } else {
188
189 filteredArgList.add(arg);
190
191
192
193 if (arg.startsWith("-") && arg.length() > 1) {
194 if (!(builtinOptionNames.contains(arg))) {
195 cmdLineOptions.addOption(arg.substring(1, arg.length()), true, "dynamic option");
196 }
197 }
198 }
199 }
200
201
202 String[] filterArgs = new String[filteredArgList.size()];
203 filteredArgList.toArray(filterArgs);
204
205
206 Parser parser = new org.apache.commons.cli.GnuParser();
207 return parser.parse(cmdLineOptions, filterArgs);
208 }
209
210 }