From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- .../javascript/ScriptProviderForJavaScript.java | 330 +++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 scripting/java/com/sun/star/script/framework/provider/javascript/ScriptProviderForJavaScript.java (limited to 'scripting/java/com/sun/star/script/framework/provider/javascript/ScriptProviderForJavaScript.java') diff --git a/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptProviderForJavaScript.java b/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptProviderForJavaScript.java new file mode 100644 index 000000000..9465a646f --- /dev/null +++ b/scripting/java/com/sun/star/script/framework/provider/javascript/ScriptProviderForJavaScript.java @@ -0,0 +1,330 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF 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 . + */ +package com.sun.star.script.framework.provider.javascript; + +import com.sun.star.comp.loader.FactoryHelper; + +import com.sun.star.document.XScriptInvocationContext; + +import com.sun.star.frame.XModel; + +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; + +import com.sun.star.reflection.InvocationTargetException; + +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.script.framework.container.ScriptMetaData; +import com.sun.star.script.framework.log.LogUtils; +import com.sun.star.script.framework.provider.ClassLoaderFactory; +import com.sun.star.script.framework.provider.ScriptContext; +import com.sun.star.script.framework.provider.ScriptEditor; +import com.sun.star.script.framework.provider.ScriptProvider; +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.provider.XScript; + +import com.sun.star.uno.XComponentContext; + +import java.net.URL; + +import org.mozilla.javascript.Context; +import org.mozilla.javascript.ImporterTopLevel; +import org.mozilla.javascript.JavaScriptException; +import org.mozilla.javascript.Scriptable; + +public class ScriptProviderForJavaScript { + + public static class ScriptProviderForJavaScript_2 extends ScriptProvider { + + public ScriptProviderForJavaScript_2(XComponentContext ctx) { + super(ctx, "JavaScript"); + } + + @Override + 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); + } + } + + @Override + public boolean hasScriptEditor() { + return true; + } + + @Override + public ScriptEditor getScriptEditor() { + return ScriptEditorForJavaScript.getEditor(); + } + } + + /** + * Returns a factory for creating the service. + * This method is called by the JavaLoader + *

+ * + * @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 XSingleServiceFactory 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( + ScriptProviderForJavaScript.ScriptProviderForJavaScript_2.class.getName())) { + + xSingleServiceFactory = + FactoryHelper.getServiceFactory( + ScriptProviderForJavaScript.ScriptProviderForJavaScript_2.class, + "com.sun.star.script.provider.ScriptProviderForJavaScript", + multiFactory, regKey); + + } + + return xSingleServiceFactory; + } +} + +class ScriptImpl implements XScript { + + private final ScriptMetaData metaData; + private final XComponentContext m_xContext; + private XMultiComponentFactory m_xMultiComponentFactory; + private final XModel m_xModel; + private final XScriptInvocationContext m_xInvocContext; + + ScriptImpl(XComponentContext ctx, ScriptMetaData metaData, XModel xModel, + XScriptInvocationContext xInvocContext) throws + com.sun.star.uno.RuntimeException { + + this.metaData = metaData; + this.m_xContext = ctx; + this.m_xModel = xModel; + this.m_xInvocContext = xInvocContext; + + try { + this.m_xMultiComponentFactory = m_xContext.getServiceManager(); + } catch (Exception e) { + throw new com.sun.star.uno.RuntimeException(e); + } + + LogUtils.DEBUG("ScriptImpl [javascript] script data = " + metaData); + } + + /** + * The invoke method of the ScriptProviderForJavaScript runs the + * JavaScript script specified in the URI + * + * + * + * @param params 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 + * + * @return The value returned from the function + * being invoked + * + * @throws ScriptFrameworkErrorException If there is no matching script name + * + * + * @throws InvocationTargetException If the running script throws + * an exception this information + * is captured and rethrown as + * ScriptErrorRaisedException or + * ScriptExceptionRaisedException + */ + public Object invoke( + /*IN*/Object[] params, + /*OUT*/short[][] aOutParamIndex, + /*OUT*/Object[][] aOutParam) + throws ScriptFrameworkErrorException, InvocationTargetException { + + // Initialise the out parameters - not used at the moment + aOutParamIndex[0] = new short[0]; + aOutParam[0] = new Object[0]; + + ClassLoader cl = null; + + try { + cl = ClassLoaderFactory.getURLClassLoader(metaData); + metaData.getSourceURL(); + } catch (java.net.MalformedURLException mfu) { + throw new ScriptFrameworkErrorException( + mfu.getMessage(), null, + metaData.getLanguageName(), metaData.getLanguage(), + ScriptFrameworkErrorType.MALFORMED_URL); + } + + Context ctxt = null; + + try { + Object result = null; + + ScriptEditorForJavaScript editor = + ScriptEditorForJavaScript.getEditor(metaData.getSourceURL()); + + if (editor != null) { + result = editor.execute(); + + if (result != null && + result.getClass().getName().equals("org.mozilla.javascript.Undefined")) { + // Always return a string + // TODO revisit + return Context.toString(result); + } + + } + + String source; + + if (editor != null && editor.isModified()) { + LogUtils.DEBUG("GOT A MODIFIED SOURCE"); + source = editor.getText(); + } else { + metaData.loadSource(); + source = metaData.getSource(); + + } + + if (source == null || source.length() == 0) { + throw new ScriptFrameworkErrorException( + "Failed to read source data for script", null, + metaData.getLanguageName(), metaData.getLanguage(), + ScriptFrameworkErrorType.UNKNOWN); + } + + /* Set the context ClassLoader on the current thread to + be our custom ClassLoader. This is the suggested method + for setting up a ClassLoader to be used by the Rhino + interpreter + */ + if (cl != null) { + Thread.currentThread().setContextClassLoader(cl); + } + + // Initialize a Rhino Context object + ctxt = Context.enter(); + + /* The ImporterTopLevel ensures that importClass and + importPackage statements work in Javascript scripts + Make the XScriptContext available as a global variable + to the script + */ + ImporterTopLevel scope = new ImporterTopLevel(ctxt); + + Scriptable jsCtxt = + Context.toObject( + ScriptContext.createContext( + m_xModel, m_xInvocContext, m_xContext, + m_xMultiComponentFactory), + scope); + + scope.put("XSCRIPTCONTEXT", scope, jsCtxt); + + Scriptable jsArgs = Context.toObject(params, scope); + scope.put("ARGUMENTS", scope, jsArgs); + + result = ctxt.evaluateString(scope, source, "", 1, null); + result = Context.toString(result); + return result; + } catch (JavaScriptException jse) { + LogUtils.DEBUG("Caught JavaScriptException exception for JavaScript type = " + + jse.getClass()); + String message = jse.getMessage(); + Object wrap = jse.getValue(); + LogUtils.DEBUG("\t message " + message); + LogUtils.DEBUG("\t wrapped type " + wrap.getClass()); + LogUtils.DEBUG("\t wrapped toString " + wrap.toString()); + ScriptExceptionRaisedException se = new + ScriptExceptionRaisedException(message); + se.lineNum = -1; + se.language = "JavaScript"; + se.scriptName = metaData.getLanguageName(); + se.exceptionType = wrap.getClass().getName(); + se.language = metaData.getLanguage(); + LogUtils.DEBUG("ExceptionRaised exception "); + LogUtils.DEBUG("\t message " + se.getMessage()); + LogUtils.DEBUG("\t lineNum " + se.lineNum); + LogUtils.DEBUG("\t language " + se.language); + LogUtils.DEBUG("\t scriptName " + se.scriptName); + raiseEditor(se.lineNum); + throw new InvocationTargetException( + "JavaScript uncaught exception" + metaData.getLanguageName(), null, se); + } catch (Exception ex) { + LogUtils.DEBUG("Caught Exception " + ex); + LogUtils.DEBUG("rethrowing as ScriptFramework error"); + throw new ScriptFrameworkErrorException( + ex.getMessage(), null, metaData.getLanguageName(), + metaData.getLanguage(), ScriptFrameworkErrorType.UNKNOWN); + } finally { + if (ctxt != null) { + Context.exit(); + } + } + } + + private void raiseEditor(int lineNum) { + try { + URL sourceUrl = metaData.getSourceURL(); + + ScriptEditorForJavaScript editor = + ScriptEditorForJavaScript.getEditor(sourceUrl); + + if (editor == null) { + editor = ScriptEditorForJavaScript.getEditor(); + + editor.edit( + ScriptContext.createContext(m_xModel, m_xInvocContext, + m_xContext, m_xMultiComponentFactory), + metaData); + + editor = ScriptEditorForJavaScript.getEditor(sourceUrl); + } + + if (editor != null) { + System.out.println("** Have raised IDE for JavaScript, calling indicateErrorLine for line " + + lineNum); + editor.indicateErrorLine(lineNum); + } + } catch (java.net.MalformedURLException ignore) { + } + } +} -- cgit v1.2.3