KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > 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 JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Properties JavaDoc;
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 JavaDoc;
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: 155420 $
47  */

48 public class Jelly {
49     
50     /** The Log to which logging calls will be made. */
51     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 JavaDoc url;
58     
59     /** The URL of the root context for other scripts */
60     private URL JavaDoc rootContext;
61     
62     /** Whether we have loaded the properties yet */
63     private boolean loadedProperties = false;
64
65     /**
66      * whether to override the default namespace
67      */

68     private String JavaDoc defaultNamespaceURI = null;
69
70     /**
71      * whether or not to validate the Jelly script
72      */

73     private boolean validateXML = false;
74         
75     public Jelly() {
76     }
77
78     /**
79      * Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]
80      */

81     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
82
83         try {
84             if (args.length <= 0) {
85                 System.out.println("Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]");
86                 return;
87             }
88
89             // parse the command line options using CLI
90
// using a separate class to avoid unnecessary
91
// dependencies
92
CommandLineParser.getInstance().invokeCommandLineJelly(args);
93         }
94         catch (JellyException e) {
95             Throwable JavaDoc cause = e.getCause();
96
97             if (cause == null) {
98                 e.printStackTrace();
99             } else {
100                 cause.printStackTrace();
101             }
102         }
103     }
104     
105     
106     public static String JavaDoc getJellyVersion() {
107         return readBuildTimestampResource("jelly-version.txt");
108     }
109     
110     public static String JavaDoc getJellyBuildDate() {
111         return readBuildTimestampResource("jelly-build-date.txt");
112     }
113     
114     private static String JavaDoc readBuildTimestampResource(String JavaDoc name) {
115         java.io.Reader JavaDoc in = null;
116         try {
117             java.io.StringWriter JavaDoc w = new java.io.StringWriter JavaDoc();
118             in = new java.io.InputStreamReader JavaDoc(Jelly.class.getResourceAsStream(name),"utf-8");
119             int r;
120             while ( (r=in.read()) >= 0 ) {
121                 w.write((char) r);
122             }
123             return w.toString();
124         } catch(Exception JavaDoc ex) {
125             ex.printStackTrace();
126             try { in.close(); } catch(Exception JavaDoc e) {}
127             throw new IllegalStateException JavaDoc("Resource \"" + name + "\" not found.");
128         }
129     }
130     
131     
132
133     /**
134      * Compiles the script
135      */

136     public Script compileScript() throws JellyException {
137         if (! loadedProperties) {
138             loadedProperties = true;
139             loadJellyProperties();
140         }
141         
142         XMLParser parser = new XMLParser();
143         try {
144             parser.setContext(getJellyContext());
145         } catch (MalformedURLException JavaDoc e) {
146             throw new JellyException(e.toString());
147         }
148         
149         Script script = null;
150         try {
151             parser.setDefaultNamespaceURI(this.defaultNamespaceURI);
152             parser.setValidating(this.validateXML);
153             script = parser.parse(getUrl());
154             script = script.compile();
155             if (log.isDebugEnabled()) {
156                log.debug("Compiled script: " + getUrl());
157             }
158         } catch (IOException JavaDoc e) {
159             throw new JellyException("could not parse Jelly script",e);
160         } catch (SAXException JavaDoc e) {
161             throw new JellyException("could not parse Jelly script",e);
162         }
163         
164         return script;
165     }
166
167     
168     // Properties
169
//-------------------------------------------------------------------------
170

171     /**
172      * Sets the script URL to use as an absolute URL or a relative filename
173      */

174     public void setScript(String JavaDoc script) throws MalformedURLException JavaDoc {
175         setUrl(resolveURL(script));
176     }
177     
178     public URL JavaDoc getUrl() {
179         return url;
180     }
181     
182     /**
183      * Sets the script URL to use
184      */

185     public void setUrl(URL JavaDoc url) {
186         this.url = url;
187     }
188     
189     /**
190      * Gets the root context
191      */

192     public URL JavaDoc getRootContext() throws MalformedURLException JavaDoc {
193         if (rootContext == null) {
194             rootContext = new File JavaDoc(System.getProperty("user.dir")).toURL();
195         }
196         return rootContext;
197     }
198     
199     /**
200      * Sets the root context
201      */

202     public void setRootContext(URL JavaDoc rootContext) {
203         this.rootContext = rootContext;
204     }
205     
206     /**
207      * The context to use
208      */

209     public JellyContext getJellyContext() throws MalformedURLException JavaDoc {
210         if (context == null) {
211             // take off the name off the URL
212
String JavaDoc text = getUrl().toString();
213             int idx = text.lastIndexOf('/');
214             text = text.substring(0, idx + 1);
215             context = new JellyContext(getRootContext(), new URL JavaDoc(text));
216         }
217         return context;
218     }
219
220
221     /**
222      * Set the jelly namespace to use for unprefixed elements.
223      * Will be overridden by an explicit namespace in the
224      * XML document.
225      *
226      * @param namespace jelly namespace to use (e.g. 'jelly:core')
227      */

228     public void setDefaultNamespaceURI(String JavaDoc namespace) {
229         this.defaultNamespaceURI = namespace;
230     }
231
232     /**
233      * When set to true, the XML parser will attempt to validate
234      * the Jelly XML before converting it into a Script.
235      *
236      * @param validate whether or not to validate
237      */

238     public void setValidateXML(boolean validate) {
239         this.validateXML = validate;
240     }
241     
242     // Implementation methods
243
//-------------------------------------------------------------------------
244
/**
245      * @return the URL for the relative file name or absolute URL
246      */

247     protected URL JavaDoc resolveURL(String JavaDoc name) throws MalformedURLException JavaDoc {
248         
249         URL JavaDoc resourceUrl = ClassLoaderUtils.getClassLoader(getClass()).getResource(name);
250         if (resourceUrl == null)
251         {
252             File JavaDoc file = new File JavaDoc(name);
253             if (file.exists()) {
254                 return file.toURL();
255             }
256             return new URL JavaDoc(name);
257         } else {
258             return resourceUrl;
259         }
260     }
261
262     /**
263      * Attempts to load jelly.properties from the current directory,
264      * the users home directory or from the classpath
265      */

266     protected void loadJellyProperties() {
267         InputStream JavaDoc is = null;
268     
269         String JavaDoc userDir = System.getProperty("user.home");
270         File JavaDoc f = new File JavaDoc(userDir + File.separator + "jelly.properties");
271         loadProperties(f);
272     
273         f = new File JavaDoc("jelly.properties");
274         loadProperties(f);
275         
276         
277         is = ClassLoaderUtils.getClassLoader(getClass()).getResourceAsStream("jelly.properties");
278         if (is != null) {
279             try {
280                 loadProperties(is);
281             }
282             catch (Exception JavaDoc e) {
283                 log.error( "Caught exception while loading jelly.properties from the classpath. Reason: " + e, e );
284             }
285         }
286     }
287
288     /**
289      * Load properties from a file into the context
290      * @param f
291      */

292     private void loadProperties(File JavaDoc f) {
293         InputStream JavaDoc is = null;
294         try {
295             if (f.exists()) {
296                 is = new FileInputStream JavaDoc(f);
297                 loadProperties(is);
298             }
299         } catch (Exception JavaDoc e) {
300             log.error( "Caught exception while loading: " + f.getName() + ". Reason: " + e, e );
301         } finally {
302             if (is != null) {
303                 try {
304                     is.close();
305                 } catch (IOException JavaDoc e) {
306                     if (log.isDebugEnabled()) log.debug("error closing property input stream", e);
307                 }
308             }
309         }
310     }
311
312     /**
313      * Loads the properties from the given input stream
314      */

315     protected void loadProperties(InputStream JavaDoc is) throws IOException JavaDoc {
316         JellyContext theContext = getJellyContext();
317         Properties JavaDoc props = new Properties JavaDoc();
318         props.load(is);
319         Enumeration JavaDoc propsEnum = props.propertyNames();
320         while (propsEnum.hasMoreElements()) {
321             String JavaDoc key = (String JavaDoc) propsEnum.nextElement();
322             String JavaDoc value = props.getProperty(key);
323             
324             // @todo we should parse the value in case its an Expression
325
theContext.setVariable(key, value);
326         }
327     }
328 }
329
Popular Tags