Package com.sun.star.script.framework.provider.beanshell

Source Code of com.sun.star.script.framework.provider.beanshell.ScriptImpl

/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ScriptProviderForBeanShell.java,v $
* $Revision: 1.11 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org.  If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
package com.sun.star.script.framework.provider.beanshell;

import com.sun.star.uno.XComponentContext;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.comp.loader.FactoryHelper;
import com.sun.star.frame.XModel;
import com.sun.star.uno.Type;
import com.sun.star.uno.Any;

import com.sun.star.reflection.InvocationTargetException;

import java.util.StringTokenizer;
import java.io.*;

import java.net.URL;

import bsh.Interpreter;

import com.sun.star.document.XScriptInvocationContext;
import com.sun.star.script.provider.XScript;
import com.sun.star.script.provider.ScriptErrorRaisedException;
import com.sun.star.script.provider.ScriptExceptionRaisedException;
import com.sun.star.script.provider.ScriptFrameworkErrorException;
import com.sun.star.script.provider.ScriptFrameworkErrorType;


import com.sun.star.script.framework.provider.*;
import com.sun.star.script.framework.log.*;
import com.sun.star.script.framework.container.ScriptMetaData;

public class ScriptProviderForBeanShell
{
    public static class _ScriptProviderForBeanShell extends ScriptProvider
    {
        public _ScriptProviderForBeanShell(XComponentContext ctx)
        {
            super (ctx, "BeanShell");
        }

        public XScript getScript( /*IN*/String scriptURI )
            throws com.sun.star.uno.RuntimeException,
                   ScriptFrameworkErrorException
        {
            ScriptMetaData scriptData = null;
            try
            {
                scriptData = getScriptData( scriptURI );
                ScriptImpl script = new ScriptImpl( m_xContext, scriptData, m_xModel, m_xInvocContext );
                return script;
            }
            catch ( com.sun.star.uno.RuntimeException re )
            {
                throw new ScriptFrameworkErrorException( "Failed to create script object: " + re.getMessage(),
                    null, scriptData.getLanguageName(), language, ScriptFrameworkErrorType.UNKNOWN );
            }
        }

        public boolean hasScriptEditor()
        {
            return true;
        }

        public ScriptEditor getScriptEditor()
        {
            return ScriptEditorForBeanShell.getEditor();
        }
    }

    /**
     * Returns a factory for creating the service.
     * This method is called by the <code>JavaLoader</code>
     * <p>
     *
     * @param  implName      the name of the implementation for which a service is desired
     * @param  multiFactory  the service manager to be used if needed
     * @param  regKey        the registryKey
     * @return               returns a <code>XSingleServiceFactory</code> for creating
     *                          the component
     * @see                  com.sun.star.comp.loader.JavaLoader
     */
    public static XSingleServiceFactory __getServiceFactory( String implName,
            XMultiServiceFactory multiFactory,
            XRegistryKey regKey )
    {
        XSingleServiceFactory xSingleServiceFactory = null;

        if ( implName.equals( ScriptProviderForBeanShell._ScriptProviderForBeanShell.class.getName() ) )
        {
            xSingleServiceFactory = FactoryHelper.getServiceFactory(
                ScriptProviderForBeanShell._ScriptProviderForBeanShell.class,
                "com.sun.star.script.ScriptProviderForBeanShell",
                multiFactory,
                regKey );
        }

        return xSingleServiceFactory;
    }


    /**
     * Writes the service information into the given registry key.
     * This method is called by the <code>JavaLoader</code>
     * <p>
     *
     * @param  regKey  the registryKey
     * @return         returns true if the operation succeeded
     * @see            com.sun.star.comp.loader.JavaLoader
     */
    public static boolean __writeRegistryServiceInfo( XRegistryKey regKey )
    {
        String impl = "com.sun.star.script.framework.provider.beanshell." +
            "ScriptProviderForBeanShell$_ScriptProviderForBeanShell";

        String service1 = "com.sun.star.script.provider." +
            "ScriptProvider";
        String service2 = "com.sun.star.script.provider." +
            "LanguageScriptProvider";
        String service3 = "com.sun.star.script.provider." +
            "ScriptProviderForBeanShell";
        String service4 = "com.sun.star.script.browse." +
            "BrowseNode";

        if ( FactoryHelper.writeRegistryServiceInfo(impl, service1, regKey) &&
            FactoryHelper.writeRegistryServiceInfo(impl, service2, regKey) &&
            FactoryHelper.writeRegistryServiceInfo(impl, service3, regKey) &&
            FactoryHelper.writeRegistryServiceInfo(impl, service4, regKey) )
        {
                return true;
        }
        return false;
    }

}

class ScriptImpl implements XScript
{
    private ScriptMetaData metaData;
    private XComponentContext m_xContext;
    private XMultiComponentFactory m_xMultiComponentFactory;
    private XModel m_xModel;
    private XScriptInvocationContext m_xInvocContext;
   
    ScriptImpl( XComponentContext ctx, ScriptMetaData metaData, XModel xModel,
            XScriptInvocationContext xContext ) throws com.sun.star.uno.RuntimeException
    {
        this.metaData = metaData;
        this.m_xContext = ctx;
        this.m_xModel = xModel;
        this.m_xInvocContext = xContext;

        try
        {
            this.m_xMultiComponentFactory = m_xContext.getServiceManager();
        }
        catch ( Exception e )
        {
            LogUtils.DEBUG( LogUtils.getTrace( e ) );
            throw new com.sun.star.uno.RuntimeException(
                "Error constructing  ScriptImpl [beanshell]: "
                + e.getMessage() );
        }

        LogUtils.DEBUG("ScriptImpl [beanshell] script data = " + metaData );
    }
        /**
         *                          documentStorageID and document reference
         *                          for use in script name resolving
         *
         * @param aParams           All parameters; pure, out params are
         *                          undefined in sequence, i.e., the value
         *                          has to be ignored by the callee
         *
         * @param aOutParamIndex    Out indices
         *
         * @param aOutParam         Out parameters
         *
         * @returns                 The value returned from the function
         *                          being invoked
         *
         * @throws IllegalArgumentException If there is no matching script name
         *
         * @throws CannotConvertException   If args do not match or cannot
         *                                  be converted the those of the
         *                                  invokee
         *
         * @throws InvocationTargetException If the running script throws
         *                                   an exception this information
         *                                   is captured and rethrown as
         *                                   this exception type.
         */

        public Object invoke( /*IN*/Object[] aParams,
                            /*OUT*/short[][] aOutParamIndex,
                            /*OUT*/Object[][] aOutParam )
            throws ScriptFrameworkErrorException,
                InvocationTargetException
        {
            // Initialise the out paramters - not used at the moment
            aOutParamIndex[0] = new short[0];
            aOutParam[0] = new Object[0];


            ClassLoader cl = null;
            URL sourceUrl = null;
            try {
                cl = ClassLoaderFactory.getURLClassLoader( metaData );
                sourceUrl = metaData.getSourceURL();
            }
            catch ( java.net.MalformedURLException mfu )
            {
                // Framework error
                throw new ScriptFrameworkErrorException(
                    mfu.getMessage(), null,
                    metaData.getLanguageName(), metaData.getLanguage(),
                    ScriptFrameworkErrorType.UNKNOWN );
            }
            catch ( NoSuitableClassLoaderException nsc )
            {
                // Framework error
                throw new ScriptFrameworkErrorException(
                    nsc.getMessage(), null,
                    metaData.getLanguageName(), metaData.getLanguage(),
                    ScriptFrameworkErrorType.UNKNOWN );
            }
            // Set class loader to be used for class files
            // and jar files
            Thread.currentThread().setContextClassLoader(cl);
            Interpreter interpreter = new Interpreter();

            interpreter.getNameSpace().clear();
            // Set class loader to be used by interpreter
            // to look for classes by source e.g. interpreter
            // will use this classloader to search classpath
            // for source file ( bla.java ) on import or reference
            interpreter.setClassLoader(cl);
            try {
                interpreter.set("XSCRIPTCONTEXT",
                    ScriptContext.createContext(m_xModel, m_xInvocContext,
                        m_xContext, m_xMultiComponentFactory));

                interpreter.set("ARGUMENTS", aParams);
            }
            catch (bsh.EvalError e) {
                // Framework error setting up context
                throw new ScriptFrameworkErrorException(
                    e.getMessage(), null,
                    metaData.getLanguageName(), metaData.getLanguage(),
                    ScriptFrameworkErrorType.UNKNOWN );
            }

            try {
                String source = null;
                Object result = null;

                ScriptEditorForBeanShell editor =
                    ScriptEditorForBeanShell.getEditor(
                       sourceUrl );

                if ( editor != null )
                {
                    result = editor.execute();

                    if (result == null)
                    {
                        return new Any(new Type(), null);
                    }
                    return result;
                }

                metaData.loadSource()
                source = metaData.getSource();

                if ( source == null || source.length() == 0 )
                {
                  throw new ScriptFrameworkErrorException(
                        "Failed to read script", null,
                      metaData.getLanguageName(), metaData.getLanguage(),
                      ScriptFrameworkErrorType.UNKNOWN );
                }
                result = interpreter.eval( source );

                if (result == null)
                {
                    return new Any(new Type(), null);
                }
                return result;
            }
            catch ( bsh.ParseException pe )
            {
                throw new InvocationTargetException( "Beanshell failed to parse " + metaData.getLanguageName(), null, processBshException( pe, metaData.getLanguageName() ) );
            }
            catch ( bsh.TargetError te )
            {
                throw new InvocationTargetException( "Beanshell uncaught exception for " + metaData.getLanguageName(), null, processBshException( te, metaData.getLanguageName() ) );
            }
            catch ( bsh.EvalError ex )
            {
                throw new InvocationTargetException( "Beanshell error for " + metaData.getLanguageName(), null, processBshException( ex, metaData.getLanguageName() ) );
            }
            catch ( Exception e )
            {
                throw new ScriptFrameworkErrorException(
                    "Failed to read script", null,
                    metaData.getLanguageName(), metaData.getLanguage(),
                    ScriptFrameworkErrorType.UNKNOWN );
            }
        }
        private void raiseEditor( int lineNum )
        {
            ScriptEditorForBeanShell editor = null;
            try
            {
                URL sourceUrl = metaData.getSourceURL();
                editor = ScriptEditorForBeanShell.getEditor( sourceUrl );
                if ( editor == null )
                {
                    editor = ScriptEditorForBeanShell.getEditor();
                    editor.edit(
                        ScriptContext.createContext(m_xModel, m_xInvocContext,
                            m_xContext, m_xMultiComponentFactory), metaData );
                    editor = ScriptEditorForBeanShell.getEditor( sourceUrl );
                }
                if ( editor != null )
                {
                    editor.indicateErrorLine( lineNum );
                }
            }
            catch( Exception ignore )
            {
            }
        }

        private ScriptErrorRaisedException processBshException( bsh.EvalError e, String script  )
        {
            LogUtils.DEBUG("Beanshell error RAW message " + e.getMessage());
            String message = e.getMessage()
            int usefullInfoIndex = message.lastIndexOf("\' :" );
            int lineNum = e.getErrorLineNumber();

            raiseEditor( lineNum );

            //String stackTrace = te.getScriptStackTrace();  // never seems to have any info??
            if ( usefullInfoIndex > -1 )
            {
                message = message.substring( usefullInfoIndex + 2 );
            }
            if ( e instanceof bsh.TargetError )
            {
                LogUtils.DEBUG("got instance of  TargetError");
                if ( usefullInfoIndex == -1 )
                {
                    message =  ( ( bsh.TargetError)e ).getTarget().getMessage();
                }
                String wrappedException = "";
                String full = e.toString();
                int index = full.indexOf( "Target exception:" );
                if ( index > -1 )
                {
                    String toParse = full.substring( index );
                    LogUtils.DEBUG("About to parse " + toParse );
                    StringTokenizer tokenizer = new StringTokenizer( full.substring( index ),":" );
                    if ( tokenizer.countTokens() > 2 )
                    {
                        LogUtils.DEBUG("First token = " + (String)tokenizer.nextElement());
                        wrappedException = (String)tokenizer.nextElement();
                        LogUtils.DEBUG("wrapped exception = = " + wrappedException );
                    }
                }
                ScriptExceptionRaisedException se = new ScriptExceptionRaisedException( message);
                se.lineNum = lineNum;
                se.scriptName = script;
                se.exceptionType = wrappedException;
                se.language = "BeanShell";
                LogUtils.DEBUG("UnCaught Exception error: " );
                LogUtils.DEBUG("\tscript: " + script );
                LogUtils.DEBUG("\tline: " + lineNum );
                LogUtils.DEBUG("\twrapped exception: " + wrappedException );
                LogUtils.DEBUG("\tmessage: " + message );
                return se;
            }
            else
            {
                LogUtils.DEBUG("Error or ParseError Exception error: " );
                LogUtils.DEBUG("\tscript: " + script );
                LogUtils.DEBUG("\tline: " + lineNum );
                LogUtils.DEBUG("\tmessage: " + message );
                return new ScriptErrorRaisedException( message, null, script, "BeanShell", lineNum );
            }
        }
}
TOP

Related Classes of com.sun.star.script.framework.provider.beanshell.ScriptImpl

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.