Package org.mule.module.scripting.component

Source Code of org.mule.module.scripting.component.Scriptable

/*
* $Id: Scriptable.java 21597 2011-03-21 23:06:50Z dandiep $
* --------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/

package org.mule.module.scripting.component;

import org.mule.DefaultMuleEventContext;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleMessage;
import org.mule.api.context.MuleContextAware;
import org.mule.api.lifecycle.Initialisable;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.api.service.Service;
import org.mule.config.i18n.CoreMessages;
import org.mule.config.i18n.MessageFactory;
import org.mule.transport.NullPayload;
import org.mule.util.CollectionUtils;
import org.mule.util.IOUtils;
import org.mule.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.Map;
import java.util.Properties;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* A JSR 223 Script service. Allows any JSR 223 compliant script engines such as
* JavaScript, Groovy or Rhino to be embedded as Mule components.
*/
public class Scriptable implements Initialisable, MuleContextAware
{
    /** The actual body of the script */
    private String scriptText;
   
    /** A file from which the script will be loaded */
    private String scriptFile;
   
    /** Parameters to be made available to the script as variables */
    private Properties properties;

    /** The name of the JSR 223 scripting engine (e.g., "groovy") */
    private String scriptEngineName;

    /////////////////////////////////////////////////////////////////////////////
    // Internal variables, not exposed as properties
    /////////////////////////////////////////////////////////////////////////////

    /** A compiled version of the script, if the scripting engine supports it */
    private CompiledScript compiledScript;
   
    private ScriptEngine scriptEngine;
    private ScriptEngineManager scriptEngineManager;

    private MuleContext muleContext;
   
    protected transient Log logger = LogFactory.getLog(getClass());

    public Scriptable()
    {
        //For Stpring
    }

    public Scriptable(MuleContext muleContext)
    {
        this.muleContext = muleContext;
    }

    //For Spring
    public void setMuleContext(MuleContext context)
    {
        this.muleContext = context;
    }

    public void initialise() throws InitialisationException
    {
        scriptEngineManager = new ScriptEngineManager();

        // Create scripting engine
        if (scriptEngineName != null)
        {
            scriptEngine = createScriptEngineByName(scriptEngineName);
            if (scriptEngine == null)
            {
                throw new InitialisationException(MessageFactory.createStaticMessage("Scripting engine '" + scriptEngineName + "' not found.  Available engines are: " + listAvailableEngines()), this);
            }
        }
        // Determine scripting engine to use by file extension
        else if (scriptFile != null)
        {
            int i = scriptFile.lastIndexOf(".");
            if (i > -1)
            {
                logger.info("Script Engine name not set. Guessing by file extension.");
                String ext = scriptFile.substring(i + 1);
                scriptEngine = createScriptEngineByExtension(ext);
                if (scriptEngine == null)
                {
                    throw new InitialisationException(MessageFactory.createStaticMessage("File extension '" + ext + "' does not map to a scripting engine.  Available engines are: " + listAvailableEngines()), this);
                }
                else
                {
                    setScriptEngineName(scriptEngine.getFactory().getEngineName());
                }
            }
        }

        Reader script;
        // Load script from variable
        if (StringUtils.isNotBlank(scriptText))
        {
            script = new StringReader(scriptText);
        }
        // Load script from file
        else if (scriptFile != null)
        {
            InputStream is;
            try
            {
                is = IOUtils.getResourceAsStream(scriptFile, getClass());
            }
            catch (IOException e)
            {
                throw new InitialisationException(CoreMessages.cannotLoadFromClasspath(scriptFile), e, this);
            }
            if (is == null)
            {
                throw new InitialisationException(CoreMessages.cannotLoadFromClasspath(scriptFile), this);
            }
            script = new InputStreamReader(is);
        }
        else
        {
            throw new InitialisationException(CoreMessages.propertiesNotSet("scriptText, scriptFile"), this);
        }

        // Pre-compile script if scripting engine supports compilation.
        if (scriptEngine instanceof Compilable)
        {
            try
            {
                compiledScript = ((Compilable) scriptEngine).compile(script);
            }
            catch (ScriptException e)
            {
                throw new InitialisationException(e, this);
            }
        }
    }

    public void populateDefaultBindings(Bindings bindings)
    {
        if (properties != null)
        {
            bindings.putAll((Map) properties);
        }
        bindings.put("log", logger);
        //A place holder for a retuen result if the script doesn't return a result.
        //The script can overwrite this binding
        bindings.put("result", NullPayload.getInstance());
        bindings.put("muleContext", muleContext);
        bindings.put("registry", muleContext.getRegistry());
    }

    public void populateBindings(Bindings bindings, Object payload)
    {
        populateDefaultBindings(bindings);
        bindings.put("payload", payload);
        //For backward compatability. Usually used by the script transformer since
        //src maps with the argument passed into the transformer
        bindings.put("src", payload);
    }
   
    public void populateBindings(Bindings bindings, MuleMessage message)
    {
        populateDefaultBindings(bindings);
        if (message == null)
        {
            message = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
        }
        bindings.put("message", message);
        //This will get overwritten if populateBindings(Bindings bindings, MuleEvent event) is called
        //and not this method directly.
        bindings.put("payload", message.getPayload());
        //For backward compatability
        bindings.put("src", message.getPayload());
    }

    public void populateBindings(Bindings bindings, MuleEvent event)
    {
        populateBindings(bindings, event.getMessage());
        bindings.put("originalPayload", event.getMessage().getPayload());
        bindings.put("payload", event.getMessage().getPayload());
        bindings.put("eventContext", new DefaultMuleEventContext(event));
        bindings.put("id", event.getId());
        bindings.put("flowConstruct", event.getFlowConstruct());
        if (event.getFlowConstruct() instanceof Service)
        {
            bindings.put("service", event.getFlowConstruct());
        }
    }
   
    public Object runScript(Bindings bindings) throws ScriptException
    {
        Object result;
        try
        {
            RegistryLookupBindings registryLookupBindings = new RegistryLookupBindings(muleContext.getRegistry(), bindings);
            if (compiledScript != null)
            {
                result = compiledScript.eval(registryLookupBindings);
            }
            else
            {
                result = scriptEngine.eval(scriptText, registryLookupBindings);
            }

            // The result of the script can be returned directly or it can
            // be set as the variable "result".
            if (result == null)
            {
                result = registryLookupBindings.get("result");
            }
        }
        catch (ScriptException e)
        {
            // re-throw
            throw e;
        }
        catch (Exception ex)
        {
            throw new ScriptException(ex);
        }
        return result;
    }

    protected ScriptEngine createScriptEngineByName(String name)
    {
        return scriptEngineManager.getEngineByName(name);
    }

    protected ScriptEngine createScriptEngineByExtension(String ext)
    {
        return scriptEngineManager.getEngineByExtension(ext);
    }

    protected String listAvailableEngines()
    {
        return CollectionUtils.toString(scriptEngineManager.getEngineFactories(), false);
    }

    ////////////////////////////////////////////////////////////////////////////////
    // Getters and setters
    ////////////////////////////////////////////////////////////////////////////////

    public String getScriptText()
    {
        return scriptText;
    }

    public void setScriptText(String scriptText)
    {
        this.scriptText = scriptText;
    }

    public String getScriptFile()
    {
        return scriptFile;
    }

    public void setScriptFile(String scriptFile)
    {
        this.scriptFile = scriptFile;
    }

    public void setScriptEngineName(String scriptEngineName)
    {
        this.scriptEngineName = scriptEngineName;
    }

    public String getScriptEngineName()
    {
        return scriptEngineName;
    }
   
    public Properties getProperties()
    {
        return properties;
    }

    public void setProperties(Properties properties)
    {
        this.properties = properties;
    }
   
    public ScriptEngine getScriptEngine()
    {
        return scriptEngine;
    }

    protected void setScriptEngine(ScriptEngine scriptEngine)
    {
        this.scriptEngine = scriptEngine;
    }

    protected CompiledScript getCompiledScript()
    {
        return compiledScript;
    }

    protected void setCompiledScript(CompiledScript compiledScript)
    {
        this.compiledScript = compiledScript;
    }
}
TOP

Related Classes of org.mule.module.scripting.component.Scriptable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.