%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.jelly.Jelly |
|
|
1 | /* |
|
2 | * Copyright 2002,2004 The Apache Software Foundation. |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | ||
17 | package org.apache.commons.jelly; |
|
18 | ||
19 | import java.io.File; |
|
20 | import java.io.InputStream; |
|
21 | import java.io.FileInputStream; |
|
22 | import java.io.IOException; |
|
23 | import java.net.MalformedURLException; |
|
24 | import java.net.URL; |
|
25 | import java.util.Enumeration; |
|
26 | import java.util.Properties; |
|
27 | ||
28 | import org.apache.commons.jelly.parser.XMLParser; |
|
29 | import org.apache.commons.jelly.util.ClassLoaderUtils; |
|
30 | import org.apache.commons.jelly.util.CommandLineParser; |
|
31 | import org.apache.commons.logging.Log; |
|
32 | import org.apache.commons.logging.LogFactory; |
|
33 | ||
34 | import org.xml.sax.SAXException; |
|
35 | ||
36 | /** |
|
37 | * <p><code>Jelly</code> is a helper class which is capable of |
|
38 | * running a Jelly script. This class can be used from the command line |
|
39 | * or can be used as the basis of an Ant task.</p> Command line usage is as follows: |
|
40 | * |
|
41 | * <pre> |
|
42 | * jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval] |
|
43 | * </pre> |
|
44 | * |
|
45 | * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> |
|
46 | * @version $Revision: 1.34 $ |
|
47 | */ |
|
48 | 36 | public class Jelly { |
49 | ||
50 | /** The Log to which logging calls will be made. */ |
|
51 | 36 | private static final Log log = LogFactory.getLog(Jelly.class); |
52 | ||
53 | /** The JellyContext to use */ |
|
54 | private JellyContext context; |
|
55 | ||
56 | /** The URL of the script to execute */ |
|
57 | private URL url; |
|
58 | ||
59 | /** The URL of the root context for other scripts */ |
|
60 | private URL rootContext; |
|
61 | ||
62 | /** Whether we have loaded the properties yet */ |
|
63 | 150 | private boolean loadedProperties = false; |
64 | ||
65 | /** |
|
66 | * whether to override the default namespace |
|
67 | */ |
|
68 | 150 | private String defaultNamespaceURI = null; |
69 | ||
70 | /** |
|
71 | * whether or not to validate the Jelly script |
|
72 | */ |
|
73 | 150 | private boolean validateXML = false; |
74 | ||
75 | 150 | public Jelly() { |
76 | 150 | } |
77 | ||
78 | /** |
|
79 | * Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval] |
|
80 | */ |
|
81 | public static void main(String[] args) throws Exception { |
|
82 | ||
83 | try { |
|
84 | 0 | if (args.length <= 0) { |
85 | 0 | System.out.println("Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]"); |
86 | 0 | return; |
87 | } |
|
88 | ||
89 | // parse the command line options using CLI |
|
90 | // using a separate class to avoid unnecessary |
|
91 | // dependencies |
|
92 | 0 | CommandLineParser.getInstance().invokeCommandLineJelly(args); |
93 | 0 | } |
94 | catch (JellyException e) { |
|
95 | 0 | Throwable cause = e.getCause(); |
96 | ||
97 | 0 | if (cause == null) { |
98 | 0 | e.printStackTrace(); |
99 | } else { |
|
100 | 0 | cause.printStackTrace(); |
101 | } |
|
102 | } |
|
103 | 0 | } |
104 | ||
105 | /** |
|
106 | * Compiles the script |
|
107 | */ |
|
108 | public Script compileScript() throws JellyException { |
|
109 | 116 | if (! loadedProperties) { |
110 | 112 | loadedProperties = true; |
111 | 112 | loadJellyProperties(); |
112 | } |
|
113 | ||
114 | 116 | XMLParser parser = new XMLParser(); |
115 | try { |
|
116 | 116 | parser.setContext(getJellyContext()); |
117 | 116 | } catch (MalformedURLException e) { |
118 | 0 | throw new JellyException(e.toString()); |
119 | } |
|
120 | ||
121 | 116 | Script script = null; |
122 | try { |
|
123 | 116 | parser.setDefaultNamespaceURI(this.defaultNamespaceURI); |
124 | 116 | parser.setValidating(this.validateXML); |
125 | 116 | script = parser.parse(getUrl()); |
126 | 110 | script = script.compile(); |
127 | 110 | if (log.isDebugEnabled()) { |
128 | 0 | log.debug("Compiled script: " + getUrl()); |
129 | } |
|
130 | 110 | } catch (IOException e) { |
131 | 0 | throw new JellyException("could not parse Jelly script",e); |
132 | } catch (SAXException e) { |
|
133 | 6 | throw new JellyException("could not parse Jelly script",e); |
134 | } |
|
135 | ||
136 | 110 | return script; |
137 | } |
|
138 | ||
139 | ||
140 | // Properties |
|
141 | //------------------------------------------------------------------------- |
|
142 | ||
143 | /** |
|
144 | * Sets the script URL to use as an absolute URL or a relative filename |
|
145 | */ |
|
146 | public void setScript(String script) throws MalformedURLException { |
|
147 | 2 | setUrl(resolveURL(script)); |
148 | 2 | } |
149 | ||
150 | public URL getUrl() { |
|
151 | 228 | return url; |
152 | } |
|
153 | ||
154 | /** |
|
155 | * Sets the script URL to use |
|
156 | */ |
|
157 | public void setUrl(URL url) { |
|
158 | 112 | this.url = url; |
159 | 112 | } |
160 | ||
161 | /** |
|
162 | * Gets the root context |
|
163 | */ |
|
164 | public URL getRootContext() throws MalformedURLException { |
|
165 | 112 | if (rootContext == null) { |
166 | 112 | rootContext = new File(System.getProperty("user.dir")).toURL(); |
167 | } |
|
168 | 112 | return rootContext; |
169 | } |
|
170 | ||
171 | /** |
|
172 | * Sets the root context |
|
173 | */ |
|
174 | public void setRootContext(URL rootContext) { |
|
175 | 0 | this.rootContext = rootContext; |
176 | 0 | } |
177 | ||
178 | /** |
|
179 | * The context to use |
|
180 | */ |
|
181 | public JellyContext getJellyContext() throws MalformedURLException { |
|
182 | 116 | if (context == null) { |
183 | // take off the name off the URL |
|
184 | 112 | String text = getUrl().toString(); |
185 | 112 | int idx = text.lastIndexOf('/'); |
186 | 112 | text = text.substring(0, idx + 1); |
187 | 112 | context = new JellyContext(getRootContext(), class="keyword">new URL(text)); |
188 | } |
|
189 | 116 | return context; |
190 | } |
|
191 | ||
192 | ||
193 | /** |
|
194 | * Set the jelly namespace to use for unprefixed elements. |
|
195 | * Will be overridden by an explicit namespace in the |
|
196 | * XML document. |
|
197 | * |
|
198 | * @param namespace jelly namespace to use (e.g. 'jelly:core') |
|
199 | */ |
|
200 | public void setDefaultNamespaceURI(String namespace) { |
|
201 | 4 | this.defaultNamespaceURI = namespace; |
202 | 4 | } |
203 | ||
204 | /** |
|
205 | * When set to true, the XML parser will attempt to validate |
|
206 | * the Jelly XML before converting it into a Script. |
|
207 | * |
|
208 | * @param validate whether or not to validate |
|
209 | */ |
|
210 | public void setValidateXML(boolean validate) { |
|
211 | 10 | this.validateXML = validate; |
212 | 10 | } |
213 | ||
214 | // Implementation methods |
|
215 | //------------------------------------------------------------------------- |
|
216 | /** |
|
217 | * @return the URL for the relative file name or absolute URL |
|
218 | */ |
|
219 | protected URL resolveURL(String name) throws MalformedURLException { |
|
220 | ||
221 | 2 | URL resourceUrl = ClassLoaderUtils.getClassLoader(getClass()).getResource(name); |
222 | 2 | if (resourceUrl == null) |
223 | { |
|
224 | 2 | File file = new File(name); |
225 | 2 | if (file.exists()) { |
226 | 0 | return file.toURL(); |
227 | } |
|
228 | 2 | return new URL(name); |
229 | } else { |
|
230 | 0 | return resourceUrl; |
231 | } |
|
232 | } |
|
233 | ||
234 | /** |
|
235 | * Attempts to load jelly.properties from the current directory, |
|
236 | * the users home directory or from the classpath |
|
237 | */ |
|
238 | protected void loadJellyProperties() { |
|
239 | 112 | InputStream is = null; |
240 | ||
241 | 112 | String userDir = System.getProperty("user.home"); |
242 | 112 | File f = new File(userDir + File.separator + "jelly.properties"); |
243 | 112 | loadProperties(f); |
244 | ||
245 | 112 | f = new File("jelly.properties"); |
246 | 112 | loadProperties(f); |
247 | ||
248 | ||
249 | 112 | is = ClassLoaderUtils.getClassLoader(getClass()).getResourceAsStream("jelly.properties"); |
250 | 112 | if (is != null) { |
251 | try { |
|
252 | 0 | loadProperties(is); |
253 | 0 | } |
254 | catch (Exception e) { |
|
255 | 0 | log.error( "Caught exception while loading jelly.properties from the classpath. Reason: " + e, e ); |
256 | } |
|
257 | } |
|
258 | 112 | } |
259 | ||
260 | /** |
|
261 | * Load properties from a file into the context |
|
262 | * @param f |
|
263 | */ |
|
264 | private void loadProperties(File f) { |
|
265 | 224 | InputStream is = null; |
266 | try { |
|
267 | 224 | if (f.exists()) { |
268 | 0 | is = new FileInputStream(f); |
269 | 0 | loadProperties(is); |
270 | } |
|
271 | 224 | } catch (Exception e) { |
272 | 0 | log.error( "Caught exception while loading: " + f.getName() + ". Reason: " + e, e ); |
273 | 0 | } finally { |
274 | 0 | if (is != null) { |
275 | try { |
|
276 | 0 | is.close(); |
277 | 0 | } catch (IOException e) { |
278 | 0 | if (log.isDebugEnabled()) log.debug("error closing property input stream", e); |
279 | 224 | } |
280 | } |
|
281 | } |
|
282 | 224 | } |
283 | ||
284 | /** |
|
285 | * Loads the properties from the given input stream |
|
286 | */ |
|
287 | protected void loadProperties(InputStream is) throws IOException { |
|
288 | 0 | JellyContext theContext = getJellyContext(); |
289 | 0 | Properties props = new Properties(); |
290 | 0 | props.load(is); |
291 | 0 | Enumeration propsEnum = props.propertyNames(); |
292 | 0 | while (propsEnum.hasMoreElements()) { |
293 | 0 | String key = (String) propsEnum.nextElement(); |
294 | 0 | String value = props.getProperty(key); |
295 | ||
296 | // @todo we should parse the value in case its an Expression |
|
297 | 0 | theContext.setVariable(key, value); |
298 | } |
|
299 | 0 | } |
300 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |