org.toobsframework.biz.scriptmanager.ScriptServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.toobsframework.biz.scriptmanager.ScriptServiceImpl.java

Source

/*
 * This file is licensed to the Toobs Framework Group under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The Toobs Framework Group licenses this file to You under the Apache 
 * License, Version 2.0 (the "License"); you may not use this file 
 * except in compliance with the License.  You may obtain a copy of the 
 * License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.toobsframework.biz.scriptmanager;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//import org.hibernate.Session;
//import org.hibernate.SessionFactory;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.WrappedException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.toobsframework.exception.PermissionException;
import org.toobsframework.exception.ValidationException;

@SuppressWarnings("unchecked")
public final class ScriptServiceImpl implements IScriptManager, BeanFactoryAware {

    private Log log = LogFactory.getLog(ScriptServiceImpl.class);

    private Map registry = new HashMap();

    private boolean doReload = true;

    private BeanFactory beanFactory;

    public ScriptServiceImpl() {
        super();
    }

    public Object runScript(String scriptName, Map params, Map outParams) throws ScriptException {
        Object result = null;
        // Setup script context and scope.
        Context ctx = Context.enter();
        Scriptable scope = new ImporterTopLevel(ctx);

        // Add Spring beanFactory for use in scripts.
        Object wrappedBeanFactory = Context.javaToJS(this.beanFactory, scope);
        ScriptableObject.putProperty(scope, "beanFactory", wrappedBeanFactory);
        Object wrappedLog = Context.javaToJS(this.log, scope);
        ScriptableObject.putProperty(scope, "log", wrappedLog);
        Object wrappedOutParams = Context.javaToJS(outParams, scope);
        ScriptableObject.putProperty(scope, "outParams", wrappedOutParams);

        // Add other parameters as passed in.
        if (null != params) {
            Iterator it = params.entrySet().iterator();
            while (it.hasNext()) {
                Entry thisEntry = (Entry) it.next();
                Object wrappedParam = Context.javaToJS(thisEntry.getValue(), scope);
                ScriptableObject.putProperty(scope, (String) thisEntry.getKey(), wrappedParam);
            }
        }

        // Get the script
        Script script = this.loadScript(scriptName, ctx);

        // Run script, return result.
        if (null != script) {
            result = script.exec(ctx, scope);
        } else {
            throw new ScriptException("Can't find script:" + scriptName);
        }

        return result;
    }

    public Object runScript(String action, String objectDao, String objectType, Map params, Map outParams)
            throws ScriptException, ValidationException, PermissionException {
        NativeJavaObject result = null;
        // Setup script context and scope.
        try {
            Context ctx = Context.enter();
            Scriptable scope = new ImporterTopLevel(ctx);

            // Add Spring beanFactory for use in scripts.
            Object wrappedBeanFactory = Context.javaToJS(this.beanFactory, scope);
            ScriptableObject.putProperty(scope, "beanFactory", wrappedBeanFactory);

            // Add log object to be used in scripts.
            Object wrappedLog = Context.javaToJS(this.log, scope);
            ScriptableObject.putProperty(scope, "log", wrappedLog);

            // Add action and objectType as parameters.
            Object wrappedAction = Context.javaToJS(action, scope);
            ScriptableObject.putProperty(scope, "action", wrappedAction);

            Object wrappedObjectDao = Context.javaToJS(objectDao, scope);
            ScriptableObject.putProperty(scope, "objectDao", wrappedObjectDao);

            if (beanFactory.containsBean(objectDao)) {
                Object wrappedObjectDaoImpl = Context.javaToJS(beanFactory.getBean(objectDao), scope);
                ScriptableObject.putProperty(scope, "objectDaoImpl", wrappedObjectDaoImpl);
            }

            if (objectType != null) {
                Object wrappedObjectType = Context.javaToJS(objectType, scope);
                ScriptableObject.putProperty(scope, "objectType", wrappedObjectType);
            }

            Object wrappedParams = Context.javaToJS(params, scope);
            ScriptableObject.putProperty(scope, "params", wrappedParams);

            Object wrappedOutParams = Context.javaToJS(outParams, scope);
            ScriptableObject.putProperty(scope, "outParams", wrappedOutParams);

            /* TODO Check there are no uses of SessionFactory in scripts 
            SessionFactory sessionFactory = (SessionFactory)beanFactory.getBean("sessionFactory");
            Session session = SessionFactoryUtils.getSession(sessionFactory, false);
                
            Object wrappedSession = Context.javaToJS(session, scope);
            ScriptableObject.putProperty(scope, "session", wrappedSession);
            */

            // Fetch the script with action_objecttype_bizScript.js as the pattern.
            // This includes using the more generic action_bizScript.js if an object
            // specific
            // override does not exist.
            String scriptName = action + "_" + objectType;
            Script script = this.loadScript(scriptName, ctx);

            if (null == script) {
                scriptName = action;
                script = this.loadScript(scriptName, ctx);
            }
            // Run script, return result.
            if (null != script) {
                try {
                    result = (NativeJavaObject) script.exec(ctx, scope);
                } catch (JavaScriptException e) {
                    Object eValue = ((JavaScriptException) e).getValue();
                    if (eValue instanceof NativeJavaObject) {
                        NativeJavaObject njo = (NativeJavaObject) ((JavaScriptException) e).getValue();
                        Throwable t = (Throwable) njo.unwrap();
                        if (t instanceof ValidationException) {
                            throw (ValidationException) t;
                        } else {
                            log.error("Wrapped Exception: " + t.getMessage(), t);
                            throw e;
                        }
                    } else {
                        throw e;
                    }
                } catch (WrappedException e) {
                    Throwable t = (Throwable) e.getWrappedException();
                    if (t instanceof ValidationException) {
                        throw (ValidationException) t;
                    } else if (t instanceof PermissionException) {
                        throw (PermissionException) t;
                    } else {
                        log.error("Wrapped Exception: " + t.getMessage(), t);
                        throw e;
                    }
                }
            } else {
                throw new ScriptException("Can't find script:" + action + "_" + objectType);
            }
        } finally {
            Context.exit();
        }
        if (result != null) {
            return result.unwrap();
        }

        return null;
    }

    private Script loadScript(String scriptName, Context ctx) throws ScriptException {
        Date initStart = new Date();
        ;

        if (registry.containsKey(scriptName) && !doReload) {
            return (Script) registry.get(scriptName);
        }
        Script script = null;

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        URL configFileURL = classLoader.getResource("script/" + scriptName + ".js");

        // If the file exists, read it.
        if (null != configFileURL) {
            try {
                InputStreamReader reader = new InputStreamReader(configFileURL.openStream());
                script = ctx.compileReader(reader, scriptName, 1, null);
            } catch (IOException e) {
                throw new ScriptException("Can't load script:" + scriptName);
            }
        }

        this.registry.put(scriptName, script);

        if (log.isDebugEnabled()) {
            Date initEnd = new Date();
            log.debug("Script [" + scriptName + "] - Compile Time: " + (initEnd.getTime() - initStart.getTime()));
        }
        return script;

    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public boolean isDoReload() {
        return doReload;
    }

    public void setDoReload(boolean doReload) {
        this.doReload = doReload;
    }

}