001: /*
002: * Copyright 2002,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jelly.impl;
017:
018: import java.io.ByteArrayInputStream;
019: import java.io.File;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.io.OutputStreamWriter;
024: import java.net.MalformedURLException;
025: import java.net.URL;
026:
027: import org.apache.commons.jelly.Jelly;
028: import org.apache.commons.jelly.JellyContext;
029: import org.apache.commons.jelly.Script;
030: import org.apache.commons.jelly.TagLibrary;
031: import org.apache.commons.jelly.XMLOutput;
032: import org.apache.commons.jelly.parser.XMLParser;
033: import org.apache.commons.logging.Log;
034: import org.apache.commons.logging.LogFactory;
035: import org.xml.sax.SAXException;
036:
037: /**
038: * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
039: *
040: * <p><code>Embedded</code> provides easy means to embed JellyEngine <br/>
041: * and use Jelly scripts within an application</p>
042: * A typical usage:<br/>
043: * <code><br/>
044: * Embedded embedded = new Embedded();<br/>
045: * embedded.setOutputStream(new ByteArrayOutputStream());<br/>
046: * embedded.setVariable("some-var","some-object");<br/>
047: * .....<br/>
048: * embedded.setScript(scriptAsString);<br/>
049: * //or one can do.<br/>
050: * //embedded.setScript(scriptAsInputStream);<br/>
051: * <br/>
052: * boolean bStatus=embedded.execute();<br/>
053: * if(!bStatus) //if error<br/>
054: * {<br/>
055: * String errorMsg=embedded.getErrorMsg();<br/>
056: * }<br/>
057: * </code> <br/>
058: *
059: * @author <a href="mailto:vinayc@apache.org">Vinay Chandran</a>
060: */
061: public class Embedded {
062: /** Jelly Engine */
063: Jelly m_jellyEngine = new Jelly();
064: /** JellyContext*/
065: private JellyContext m_context = new JellyContext();
066: /** Compiled Script Object*/
067: private Script m_script;
068: /** Input script as stream*/
069: private InputStream m_inputStream;
070: /** Output Stream */
071: private OutputStream m_outputStream;
072: /** Output(default System.out) */
073: private XMLOutput m_output = XMLOutput
074: .createXMLOutput(new OutputStreamWriter(System.out));
075: /** Exception thrown during compilation of script*/
076: Exception m_scriptCompilationException;
077: /** boolean value indicating whether the script has been successfully compiled or NOT */
078: boolean m_scriptCompiled = false;
079: /** ErrorMsg*/
080: private String m_errorMsg;
081: /** The Log to which logging calls will be made. */
082: private static final Log log = LogFactory.getLog(Embedded.class);
083:
084: /**
085: * Default Constructor
086: *
087: */
088: public Embedded() {
089: //m_context.setClassLoader(new TagLibraryClassLoader(m_context));
090: }
091:
092: /**
093: * Method setContext.
094: * @param context
095: */
096: public void setContext(JellyContext context) {
097: m_context = context;
098: }
099:
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: } catch (MalformedURLException e) {
127: //Encapsulate the string within
128: m_inputStream = new ByteArrayInputStream(scriptAsString
129: .getBytes());
130: } catch (IOException e) {
131: //Error reading from the URL
132: m_inputStream = null;
133: }
134:
135: compileScriptAndKeep();
136:
137: }
138:
139: /**
140: * @return the URL for the relative file name or absolute URL
141: */
142: private URL resolveURL(String name) throws MalformedURLException {
143: File file = new File(name);
144: if (file.exists()) {
145: return file.toURL();
146: }
147: return new URL(name);
148: }
149:
150: /**
151: * Set the input stream
152: * @param scriptAsInputStream
153: */
154: public void setScript(InputStream scriptAsInputStream) {
155: m_inputStream = scriptAsInputStream;
156: compileScriptAndKeep();
157: }
158:
159: /**
160: * Compile the script
161: */
162: private void compileScriptAndKeep() {
163: XMLParser parser = new XMLParser();
164: parser.setContext(m_context);
165: m_scriptCompiled = false;
166: try {
167: m_script = parser.parse(m_inputStream);
168: m_script = m_script.compile();
169: m_scriptCompiled = true;
170: } catch (IOException e) {
171: m_scriptCompilationException = e;
172: } catch (SAXException e) {
173: m_scriptCompilationException = e;
174: } catch (Exception e) {
175: m_scriptCompilationException = e;
176: }
177: }
178:
179: /**
180: * Method setOutputStream.
181: * @param outputStream
182: */
183: public void setOutputStream(OutputStream outputStream) {
184: m_outputStream = outputStream;
185: m_output = XMLOutput.createXMLOutput(new OutputStreamWriter(
186: m_outputStream));
187: }
188:
189: /**
190: * Registers the given tag library class name against the given namespace URI.
191: * The class will be loaded via the given ClassLoader
192: * This should be called before the parser is used.
193: */
194: public void registerTagLibrary(String namespaceURI, String className) {
195: if (m_context != null)
196: m_context.registerTagLibrary(namespaceURI, className);
197: }
198:
199: /**
200: * Registers the given tag library against the given namespace URI.
201: * This should be called before the parser is used.
202: */
203: public void registerTagLibrary(String namespaceURI,
204: TagLibrary taglib) {
205: if (m_context != null)
206: m_context.registerTagLibrary(namespaceURI, taglib);
207: }
208:
209: /**
210: * Returns the errorMsg.
211: * @return String
212: */
213: public String getErrorMsg() {
214: return m_errorMsg;
215: }
216:
217: /**
218: * Sets the errorMsg.
219: * @param errorMsg The errorMsg to set
220: */
221: private void setErrorMsg(String errorMsg) {
222: m_errorMsg = errorMsg;
223: }
224:
225: /**
226: * Execute the jelly script and capture the errors (ifany)within.
227: *
228: * @throws JellyException
229: */
230: public boolean execute() {
231: if (log.isDebugEnabled())
232: log.debug("Starting Execution");
233: //If script has not been compiled then return the errorMsg that occured during compilation
234: if (!m_scriptCompiled) {
235: if (log.isErrorEnabled())
236: log.error(m_scriptCompilationException.getMessage());
237: setErrorMsg(m_scriptCompilationException.getMessage());
238: return false;
239: }
240: if (m_inputStream == null) {
241: if (log.isErrorEnabled())
242: log
243: .error("[Error] Input script-resource NOT accessible");
244: setErrorMsg("[Error] Input script-resource NOT accessible");
245: return false;
246: }
247: try {
248: m_script.run(m_context, m_output);
249: m_outputStream.close();
250: m_output.flush();
251: } catch (Exception e) {
252: if (log.isErrorEnabled())
253: log.error(e.getMessage());
254: setErrorMsg(e.getMessage());
255: return false;
256: }
257: if (log.isDebugEnabled())
258: log.debug("Done Executing");
259: return true;
260: }
261:
262: }
|