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 }