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.ArrayList;
23 import java.util.Properties;
24 import java.util.StringTokenizer;
25
26 import org.apache.commons.cli.CommandLine;
27 import org.apache.commons.cli.GnuParser;
28 import org.apache.commons.cli.Options;
29 import org.apache.commons.cli.Parser;
30 import org.apache.commons.cli.ParseException;
31
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: 1.7 $
47 */
48 public class CommandLineParser {
49
50 protected static CommandLineParser _instance = new CommandLineParser();
51
52 public static CommandLineParser getInstance() {
53 return _instance;
54 }
55
56 /***
57 * Parse out the command line options and configure
58 * the give Jelly instance.
59 *
60 * @param args options from the command line
61 * @exception JellyException
62 * if the command line could not be parsed
63 */
64 public void invokeCommandLineJelly(String[] args) throws JellyException {
65 CommandLine cmdLine = null;
66 try {
67 cmdLine = parseCommandLineOptions(args);
68 } catch (ParseException e) {
69 throw new JellyException(e);
70 }
71
72
73 String scriptFile = null;
74 if (cmdLine.hasOption("script")) {
75 scriptFile = cmdLine.getOptionValue("script");
76 } else {
77 scriptFile = args[0];
78 }
79
80
81
82
83 URL url = ClassLoaderUtils.getClassLoader(getClass()).getResource(scriptFile);
84
85 if (url == null && !(new File(scriptFile)).exists()) {
86 throw new JellyException("Script file " + scriptFile + " not found");
87 }
88
89 try {
90
91 final XMLOutput output = cmdLine.hasOption("o") ?
92 XMLOutput.createXMLOutput(new FileWriter(cmdLine.getOptionValue("o"))) :
93 XMLOutput.createXMLOutput(System.out);
94
95 Jelly jelly = new Jelly();
96 jelly.setScript(scriptFile);
97
98 Script script = jelly.compileScript();
99
100
101 JellyContext context = jelly.getJellyContext();
102 context.setVariable("args", args);
103 context.setVariable("commandLine", cmdLine);
104 script.run(context, output);
105
106
107 Runtime.getRuntime().addShutdownHook(new Thread() {
108 public void run() {
109 try {
110 output.close();
111 }
112 catch (Exception e) {
113
114 }
115 }
116 }
117 );
118
119 } catch (Exception e) {
120 throw new JellyException(e);
121 }
122
123 }
124
125 /***
126 * Parse the command line using CLI. -o and -script are reserved for Jelly.
127 * -Dsysprop=sysval is support on the command line as well.
128 */
129 public CommandLine parseCommandLineOptions(String[] args) throws ParseException {
130
131 Options cmdLineOptions = new Options();
132 cmdLineOptions.addOption("o", true, "Output file");
133 cmdLineOptions.addOption("script", true, "Jelly script to run");
134
135
136 Properties sysProps = System.getProperties();
137
138
139
140 ArrayList filteredArgList = new ArrayList();
141
142 for (int i=0;i<args.length;i++) {
143 String arg = args[i];
144
145
146
147 if (arg.startsWith("-D") && (arg.length() > 2)) {
148 arg = arg.substring(2);
149 StringTokenizer toks = new StringTokenizer(arg, "=");
150
151 if (toks.countTokens() == 2) {
152
153 sysProps.setProperty(toks.nextToken(), toks.nextToken());
154 } else {
155 System.err.println("Invalid system property: " + arg);
156 }
157
158 } else {
159
160 filteredArgList.add(arg);
161
162
163
164 if (arg.startsWith("-") && arg.length() > 1) {
165 if (!(arg.equals("-o") && arg.equals("-script"))) {
166 cmdLineOptions.addOption(arg.substring(1, arg.length()), true, "dynamic option");
167 }
168 }
169 }
170 }
171
172
173 String[] filterArgs = new String[filteredArgList.size()];
174 filteredArgList.toArray(filterArgs);
175
176
177 Parser parser = new GnuParser();
178 return parser.parse(cmdLineOptions, filterArgs);
179 }
180
181 }