View Javadoc

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  package org.apache.commons.jelly.impl;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.File;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.io.OutputStreamWriter;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  
27  import org.apache.commons.jelly.Jelly;
28  import org.apache.commons.jelly.JellyContext;
29  import org.apache.commons.jelly.Script;
30  import org.apache.commons.jelly.TagLibrary;
31  import org.apache.commons.jelly.XMLOutput;
32  import org.apache.commons.jelly.parser.XMLParser;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.xml.sax.SAXException;
36  
37  /***
38   * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
39   *
40   * <p><code>Embedded</code> provides easy means to embed JellyEngine <br/>
41   * and use Jelly scripts within an application</p>
42   * A typical usage:<br/>
43   *  <code><br/>
44   *     Embedded embedded = new Embedded();<br/>
45   *     embedded.setOutputStream(new ByteArrayOutputStream());<br/>
46   *     embedded.setVariable("some-var","some-object");<br/>
47   *     .....<br/>
48   *     embedded.setScript(scriptAsString);<br/>
49   *     //or one can do.<br/>
50   *     //embedded.setScript(scriptAsInputStream);<br/>
51   *     <br/>
52   *     boolean bStatus=embedded.execute();<br/>
53   *     if(!bStatus) //if error<br/>
54   *     {<br/>
55   *         String errorMsg=embedded.getErrorMsg();<br/>
56   *     }<br/>
57   *  </code>  <br/>
58   *
59   * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
60   */
61  public class Embedded {
62      /*** Jelly Engine */
63      Jelly m_jellyEngine = new Jelly();
64      /*** JellyContext*/
65      private JellyContext m_context = new JellyContext();
66      /*** Compiled Script Object*/
67      private Script m_script;
68      /*** Input script as stream*/
69      private InputStream m_inputStream;
70      /*** Output Stream */
71      private OutputStream m_outputStream;
72      /*** Output(default System.out) */
73      private XMLOutput m_output =
74          XMLOutput.createXMLOutput(new OutputStreamWriter(System.out));
75      /*** Exception thrown during compilation of script*/
76      Exception m_scriptCompilationException;
77      /*** boolean value indicating whether the script has been successfully compiled or NOT */
78      boolean m_scriptCompiled = false;
79      /*** ErrorMsg*/
80      private String m_errorMsg;
81      /*** The Log to which logging calls will be made. */
82      private static final Log log = LogFactory.getLog(Embedded.class);
83  
84      /***
85       * Default Constructor
86       *
87       */
88      public Embedded() {
89          //m_context.setClassLoader(new TagLibraryClassLoader(m_context));
90      }
91  
92      /***
93       * Method setContext.
94       * @param context
95       */
96      public void setContext(JellyContext context) {
97          m_context = context;
98      }
99  
100     /***
101      * Method getContext.
102      * @return JellyContext
103      */
104     public JellyContext getContext() {
105         return m_context;
106     }
107 
108     /***
109      * Set a new variable within the context for the script to use.
110      * @param name
111      * @param value
112      */
113     public void setVariable(String name, Object value) {
114         m_context.setVariable(name, value);
115     }
116 
117     /***
118      * Set the input script
119      * @param scriptAsString
120      */
121     public void setScript(String scriptAsString) {
122 
123         try {
124             URL url = resolveURL(scriptAsString);
125             m_inputStream = url.openStream();
126         }
127         catch (MalformedURLException e) {
128             //Encapsulate the string within
129             m_inputStream = new ByteArrayInputStream(scriptAsString.getBytes());
130         }
131         catch (IOException e) {
132             //Error reading from the URL
133             m_inputStream = null;
134         }
135 
136         compileScriptAndKeep();
137 
138     }
139 
140     /***
141      * @return the URL for the relative file name or absolute URL
142      */
143     private URL resolveURL(String name) throws MalformedURLException {
144         File file = new File(name);
145         if (file.exists()) {
146             return file.toURL();
147         }
148         return new URL(name);
149     }
150 
151     /***
152      * Set the input stream
153      * @param scriptAsInputStream
154      */
155     public void setScript(InputStream scriptAsInputStream) {
156         m_inputStream = scriptAsInputStream;
157         compileScriptAndKeep();
158     }
159 
160     /***
161      * Compile the script
162      */
163     private void compileScriptAndKeep() {
164         XMLParser parser = new XMLParser();
165         parser.setContext(m_context);
166         m_scriptCompiled = false;
167         try {
168             m_script = parser.parse(m_inputStream);
169             m_script = m_script.compile();
170             m_scriptCompiled = true;
171         }
172         catch (IOException e) {
173             m_scriptCompilationException = e;
174         }
175         catch (SAXException e) {
176             m_scriptCompilationException = e;
177         }
178         catch (Exception e) {
179             m_scriptCompilationException = e;
180         }
181     }
182 
183     /***
184      * Method setOutputStream.
185      * @param outputStream
186      */
187     public void setOutputStream(OutputStream outputStream) {
188         m_outputStream = outputStream;
189         m_output =
190             XMLOutput.createXMLOutput(new OutputStreamWriter(m_outputStream));
191     }
192 
193     /***
194      * Registers the given tag library class name against the given namespace URI.
195      * The class will be loaded via the given ClassLoader
196      * This should be called before the parser is used.
197      */
198     public void registerTagLibrary(String namespaceURI, String className) {
199         if (m_context != null)
200             m_context.registerTagLibrary(namespaceURI, className);
201     }
202 
203     /***
204      * Registers the given tag library against the given namespace URI.
205      * This should be called before the parser is used.
206      */
207     public void registerTagLibrary(String namespaceURI, TagLibrary taglib) {
208         if (m_context != null)
209             m_context.registerTagLibrary(namespaceURI, taglib);
210     }
211 
212     /***
213      * Returns the errorMsg.
214      * @return String
215      */
216     public String getErrorMsg() {
217         return m_errorMsg;
218     }
219 
220     /***
221      * Sets the errorMsg.
222      * @param errorMsg The errorMsg to set
223      */
224     private void setErrorMsg(String errorMsg) {
225         m_errorMsg = errorMsg;
226     }
227 
228     /***
229      * Execute the jelly script and capture the errors (ifany)within.
230      *
231      * @throws JellyException
232      */
233     public boolean execute() {
234         if (log.isDebugEnabled())
235             log.debug("Starting Execution");
236         //If script has not been compiled then return the errorMsg that occured during compilation
237         if (!m_scriptCompiled) {
238             if (log.isErrorEnabled())
239                 log.error(m_scriptCompilationException.getMessage());
240             setErrorMsg(m_scriptCompilationException.getMessage());
241             return false;
242         }
243         if (m_inputStream == null) {
244             if (log.isErrorEnabled())
245                 log.error("[Error] Input script-resource NOT accessible");
246             setErrorMsg("[Error] Input script-resource NOT accessible");
247             return false;
248         }
249         try {
250             m_script.run(m_context, m_output);
251             m_outputStream.close();
252             m_output.flush();
253         }
254         catch (Exception e) {
255             if (log.isErrorEnabled())
256                 log.error(e.getMessage());
257             setErrorMsg(e.getMessage());
258             return false;
259         }
260         if (log.isDebugEnabled())
261             log.debug("Done Executing");
262         return true;
263     }
264 
265 }