summaryrefslogtreecommitdiff
path: root/scripting/java/com/sun/star/script/framework/provider/beanshell
diff options
context:
space:
mode:
Diffstat (limited to 'scripting/java/com/sun/star/script/framework/provider/beanshell')
-rwxr-xr-xscripting/java/com/sun/star/script/framework/provider/beanshell/PlainSourceView.java247
-rw-r--r--scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java412
-rwxr-xr-xscripting/java/com/sun/star/script/framework/provider/beanshell/ScriptProviderForBeanShell.java383
-rw-r--r--scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceModel.java141
-rw-r--r--scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceView.java35
-rw-r--r--scripting/java/com/sun/star/script/framework/provider/beanshell/template.bsh48
6 files changed, 1266 insertions, 0 deletions
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/PlainSourceView.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/PlainSourceView.java
new file mode 100755
index 000000000000..509da1623f53
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/PlainSourceView.java
@@ -0,0 +1,247 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 javax.swing.JTextArea;
+import javax.swing.JScrollPane;
+import javax.swing.JComponent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.DocumentEvent;
+
+import java.awt.Graphics;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.Dimension;
+
+public class PlainSourceView extends JScrollPane
+ implements ScriptSourceView, DocumentListener {
+
+ private ScriptSourceModel model;
+ private JTextArea ta;
+ private GlyphGutter gg;
+ private int linecount;
+ private boolean isModified = false;
+
+ public PlainSourceView(ScriptSourceModel model) {
+ this.model = model;
+ initUI();
+ model.setView(this);
+ }
+
+ public void clear() {
+ ta.setText("");
+ }
+
+ public void update() {
+ /* Remove ourselves as a DocumentListener while loading the source
+ so we don't get a storm of DocumentEvents during loading */
+ ta.getDocument().removeDocumentListener(this);
+
+ if (isModified == false)
+ {
+ int pos = ta.getCaretPosition();
+ ta.setText(model.getText());
+ try {
+ ta.setCaretPosition(pos);
+ }
+ catch (IllegalArgumentException iae) {
+ // do nothing and allow JTextArea to set it's own position
+ }
+ }
+
+ // scroll to currentPosition of the model
+ try {
+ int line = ta.getLineStartOffset(model.getCurrentPosition());
+ Rectangle rect = ta.modelToView(line);
+ ta.scrollRectToVisible(rect);
+ }
+ catch (Exception e) {
+ // couldn't scroll to line, do nothing
+ }
+
+ gg.repaint();
+
+ // Add back the listener
+ ta.getDocument().addDocumentListener(this);
+ }
+
+ public boolean isModified() {
+ return isModified;
+ }
+
+ public void setModified(boolean value) {
+ isModified = value;
+ }
+
+ private void initUI() {
+ ta = new JTextArea();
+ ta.setRows(15);
+ ta.setColumns(40);
+ ta.setLineWrap(false);
+ ta.insert(model.getText(), 0);
+ linecount = ta.getLineCount();
+
+ gg = new GlyphGutter(this);
+
+ setViewportView(ta);
+ setRowHeaderView(gg);
+
+ ta.getDocument().addDocumentListener(this);
+ }
+
+ /* Implementation of DocumentListener interface */
+ public void insertUpdate(DocumentEvent e) {
+ doChanged(e);
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ doChanged(e);
+ }
+
+ public void changedUpdate(DocumentEvent e) {
+ doChanged(e);
+ }
+
+ /* If the number of lines in the JTextArea has changed then update the
+ GlyphGutter */
+ public void doChanged(DocumentEvent e) {
+ isModified = true;
+
+ if (linecount != ta.getLineCount()) {
+ gg.update();
+ linecount = ta.getLineCount();
+ }
+ }
+
+ public String getText() {
+ return ta.getText();
+ }
+
+ public JTextArea getTextArea() {
+ return ta;
+ }
+
+ public int getCurrentPosition() {
+ return model.getCurrentPosition();
+ }
+}
+
+class GlyphGutter extends JComponent {
+
+ private PlainSourceView view;
+ private final String DUMMY_STRING = "99";
+
+ GlyphGutter(PlainSourceView view) {
+ this.view = view;
+ update();
+ }
+
+ public void update() {
+ JTextArea textArea = view.getTextArea();
+ Font font = textArea.getFont();
+ setFont(font);
+
+ FontMetrics metrics = getFontMetrics(font);
+ int h = metrics.getHeight();
+ int lineCount = textArea.getLineCount() + 1;
+
+ String dummy = Integer.toString(lineCount);
+ if (dummy.length() < 2) {
+ dummy = DUMMY_STRING;
+ }
+
+ Dimension d = new Dimension();
+ d.width = metrics.stringWidth(dummy) + 16;
+ d.height = lineCount * h + 100;
+ setPreferredSize(d);
+ setSize(d);
+ }
+
+ public void paintComponent(Graphics g) {
+ JTextArea textArea = view.getTextArea();
+
+ Font font = textArea.getFont();
+ g.setFont(font);
+
+ FontMetrics metrics = getFontMetrics(font);
+ Rectangle clip = g.getClipBounds();
+
+ g.setColor(getBackground());
+ g.fillRect(clip.x, clip.y, clip.width, clip.height);
+
+ int ascent = metrics.getMaxAscent();
+ int h = metrics.getHeight();
+ int lineCount = textArea.getLineCount() + 1;
+
+ int startLine = clip.y / h;
+ int endLine = (clip.y + clip.height) / h + 1;
+ int width = getWidth();
+ if (endLine > lineCount) {
+ endLine = lineCount;
+ }
+
+ for (int i = startLine; i < endLine; i++) {
+ String text;
+ text = Integer.toString(i + 1) + " ";
+ int w = metrics.stringWidth(text);
+ int y = i * h;
+ g.setColor(Color.blue);
+ g.drawString(text, 0, y + ascent);
+ int x = width - ascent;
+
+ // if currentPosition is not -1 then a red arrow will be drawn
+ if (i == view.getCurrentPosition()) {
+ drawArrow(g, ascent, x, y);
+ }
+ }
+ }
+
+ private void drawArrow(Graphics g, int ascent, int x, int y) {
+ Polygon arrow = new Polygon();
+ int dx = x;
+ y += ascent - 10;
+ int dy = y;
+ arrow.addPoint(dx, dy + 3);
+ arrow.addPoint(dx + 5, dy + 3);
+ for (x = dx + 5; x <= dx + 10; x++, y++) {
+ arrow.addPoint(x, y);
+ }
+ for (x = dx + 9; x >= dx + 5; x--, y++) {
+ arrow.addPoint(x, y);
+ }
+ arrow.addPoint(dx + 5, dy + 7);
+ arrow.addPoint(dx, dy + 7);
+
+ g.setColor(Color.red);
+ g.fillPolygon(arrow);
+ g.setColor(Color.black);
+ g.drawPolygon(arrow);
+ }
+};
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java
new file mode 100644
index 000000000000..4fd5d85ac28d
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptEditorForBeanShell.java
@@ -0,0 +1,412 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+
+import java.awt.FlowLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+import java.util.HashMap;
+
+import com.sun.star.script.provider.XScriptContext;
+import com.sun.star.script.framework.provider.ScriptEditor;
+import com.sun.star.script.framework.container.ScriptMetaData;
+import com.sun.star.script.framework.provider.ClassLoaderFactory;
+
+public class ScriptEditorForBeanShell
+ implements ScriptEditor, ActionListener
+{
+ private JFrame frame;
+ private String filename;
+
+ private ScriptSourceModel model;
+ private ScriptSourceView view;
+
+ private XScriptContext context;
+ private URL scriptURL = null;
+ private ClassLoader cl = null;
+
+ // global ScriptEditorForBeanShell returned for getEditor() calls
+ private static ScriptEditorForBeanShell theScriptEditorForBeanShell;
+
+ // global list of ScriptEditors, key is URL of file being edited
+ private static Map BEING_EDITED = new HashMap();
+
+ // template for new BeanShell scripts
+ private static String BSHTEMPLATE;
+
+ // try to load the template for BeanShell scripts
+ static {
+ try {
+ URL url =
+ ScriptEditorForBeanShell.class.getResource("template.bsh");
+
+ InputStream in = url.openStream();
+ StringBuffer buf = new StringBuffer();
+ byte[] b = new byte[1024];
+ int len = 0;
+
+ while ((len = in.read(b)) != -1) {
+ buf.append(new String(b, 0, len));
+ }
+
+ in.close();
+
+ BSHTEMPLATE = buf.toString();
+ }
+ catch (IOException ioe) {
+ BSHTEMPLATE = "// BeanShell script";
+ }
+ catch (Exception e) {
+ BSHTEMPLATE = "// BeanShell script";
+ }
+ }
+
+ /**
+ * Returns the global ScriptEditorForBeanShell instance.
+ */
+ public static ScriptEditorForBeanShell getEditor()
+ {
+ if (theScriptEditorForBeanShell == null)
+ {
+ synchronized(ScriptEditorForBeanShell.class)
+ {
+ if (theScriptEditorForBeanShell == null)
+ {
+ theScriptEditorForBeanShell =
+ new ScriptEditorForBeanShell();
+ }
+ }
+ }
+ return theScriptEditorForBeanShell;
+ }
+
+ /**
+ * Get the ScriptEditorForBeanShell instance for this URL
+ *
+ * @param url The URL of the script source file
+ *
+ * @return The ScriptEditorForBeanShell associated with
+ * the given URL if one exists, otherwise null.
+ */
+ public static ScriptEditorForBeanShell getEditor(URL url)
+ {
+ return (ScriptEditorForBeanShell)BEING_EDITED.get(url);
+ }
+
+ /**
+ * Returns whether or not the script source being edited in this
+ * ScriptEditorForBeanShell has been modified
+ */
+ public boolean isModified()
+ {
+ return view.isModified();
+ }
+
+ /**
+ * Returns the text being displayed in this ScriptEditorForBeanShell
+ *
+ * @return The text displayed in this ScriptEditorForBeanShell
+ */
+ public String getText()
+ {
+ return view.getText();
+ }
+
+ /**
+ * Returns the template text for BeanShell scripts
+ *
+ * @return The template text for BeanShell scripts
+ */
+ public String getTemplate() {
+ return BSHTEMPLATE;
+ }
+
+ /**
+ * Returns the default extension for BeanShell scripts
+ *
+ * @return The default extension for BeanShell scripts
+ */
+ public String getExtension() {
+ return "bsh";
+ }
+
+
+ /**
+ * Indicates the line where error occured
+ *
+ */
+ public void indicateErrorLine( int lineNum )
+ {
+ model.indicateErrorLine( lineNum );
+ }
+ /**
+ * Executes the script edited by the editor
+ *
+ */
+ public Object execute() throws Exception {
+ frame.toFront();
+ return model.execute( context, cl );
+ }
+ /**
+ * Opens an editor window for the specified ScriptMetaData.
+ * If an editor window is already open for that data it will be
+ * moved to the front.
+ *
+ * @param metadata The metadata describing the script
+ * @param context The context in which to execute the script
+ *
+ */
+ public void edit(XScriptContext context, ScriptMetaData entry) {
+
+ if (entry != null ) {
+ try {
+ ClassLoader cl = null;
+ try {
+ cl = ClassLoaderFactory.getURLClassLoader( entry );
+ }
+ catch (Exception ignore) // TODO re-examine error handling
+ {
+ }
+ String sUrl = entry.getParcelLocation();
+ if ( !sUrl.endsWith( "/" ) )
+ {
+ sUrl += "/";
+ }
+ sUrl += entry.getLanguageName();
+ URL url = entry.getSourceURL();
+
+ // check if there is already an editing session for this script
+ if (BEING_EDITED.containsKey(url))
+ {
+ ScriptEditorForBeanShell editor =
+ (ScriptEditorForBeanShell) BEING_EDITED.get(url);
+
+ editor.frame.toFront();
+ }
+ else
+ {
+ new ScriptEditorForBeanShell(context, cl, url);
+ }
+ }
+ catch (IOException ioe) {
+ showErrorMessage( "Error loading file: " + ioe.getMessage() );
+ }
+ }
+ }
+
+ private ScriptEditorForBeanShell() {
+ }
+
+ private ScriptEditorForBeanShell(XScriptContext context, ClassLoader cl,
+ URL url)
+ {
+ this.context = context;
+ this.scriptURL = url;
+ this.model = new ScriptSourceModel(url);
+ this.filename = url.getFile();
+ this.cl = cl;
+ try {
+ Class c = Class.forName(
+ "org.openoffice.netbeans.editor.NetBeansSourceView");
+
+ Class[] types = new Class[] { ScriptSourceModel.class };
+
+ java.lang.reflect.Constructor ctor = c.getConstructor(types);
+
+ if (ctor != null) {
+ Object[] args = new Object[] { this.model };
+ this.view = (ScriptSourceView) ctor.newInstance(args);
+ }
+ else {
+ this.view = new PlainSourceView(model);
+ }
+ }
+ catch (java.lang.Error err) {
+ this.view = new PlainSourceView(model);
+ }
+ catch (Exception e) {
+ this.view = new PlainSourceView(model);
+ }
+
+ this.model.setView(this.view);
+ initUI();
+ frame.show();
+
+ BEING_EDITED.put(url, this);
+ }
+
+ private void showErrorMessage(String message) {
+ JOptionPane.showMessageDialog(frame, message,
+ "Error", JOptionPane.ERROR_MESSAGE);
+ }
+
+ private void initUI() {
+ frame = new JFrame("BeanShell Debug Window: " + filename);
+ frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ frame.addWindowListener(
+ new WindowAdapter()
+ {
+ public void windowClosing(WindowEvent e) {
+ doClose();
+ }
+ }
+ );
+
+ String[] labels = {"Run", "Clear", "Save", "Close"};
+ JPanel p = new JPanel();
+ p.setLayout(new FlowLayout());
+
+ for (int i = 0; i < labels.length; i++) {
+ JButton b = new JButton(labels[i]);
+ b.addActionListener(this);
+ p.add(b);
+
+ if (labels[i].equals("Save") && filename == null) {
+ b.setEnabled(false);
+ }
+ }
+
+ frame.getContentPane().add((JComponent)view, "Center");
+ frame.getContentPane().add(p, "South");
+ frame.pack();
+ frame.setSize(590, 480);
+ frame.setLocation(300, 200);
+ }
+
+ private void doClose() {
+ if (view.isModified()) {
+ int result = JOptionPane.showConfirmDialog(frame,
+ "The script has been modified. " +
+ "Do you want to save the changes?");
+
+ if (result == JOptionPane.CANCEL_OPTION)
+ {
+ // don't close the window, just return
+ return;
+ }
+ else if (result == JOptionPane.YES_OPTION)
+ {
+ boolean saveSuccess = saveTextArea();
+ if (saveSuccess == false)
+ {
+ return;
+ }
+ }
+ }
+ frame.dispose();
+ shutdown();
+ }
+
+ private boolean saveTextArea() {
+ boolean result = true;
+
+ if (!view.isModified()) {
+ return true;
+ }
+
+ OutputStream fos = null;
+ try {
+ String s = view.getText();
+ fos = scriptURL.openConnection().getOutputStream();
+ if ( fos != null) {
+ fos.write(s.getBytes());
+ }
+ else
+ {
+ showErrorMessage(
+ "Error saving script: Could not open stream for file" );
+ result = false;
+ }
+ view.setModified(false);
+ }
+ catch (IOException ioe) {
+ showErrorMessage( "Error saving script: " + ioe.getMessage() );
+ result = false;
+ }
+ catch (Exception e) {
+ showErrorMessage( "Error saving script: " + e.getMessage() );
+ result = false;
+ }
+ finally {
+ if (fos != null) {
+ try {
+ fos.flush();
+ if ( fos != null )
+ {
+ fos.close();
+ }
+ }
+ catch (IOException ignore) {
+ }
+ }
+ }
+ return result;
+ }
+
+ private void shutdown()
+ {
+ if (BEING_EDITED.containsKey(scriptURL)) {
+ BEING_EDITED.remove(scriptURL);
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("Run")) {
+ try
+ {
+ execute();
+ }
+ catch (Exception invokeException ) {
+ showErrorMessage(invokeException.getMessage());
+ }
+ }
+ else if (e.getActionCommand().equals("Close")) {
+ doClose();
+ }
+ else if (e.getActionCommand().equals("Save")) {
+ saveTextArea();
+ }
+ else if (e.getActionCommand().equals("Clear")) {
+ view.clear();
+ }
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptProviderForBeanShell.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptProviderForBeanShell.java
new file mode 100755
index 000000000000..95c727881427
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptProviderForBeanShell.java
@@ -0,0 +1,383 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.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;
+ }
+}
+
+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.MALFORMED_URL );
+ }
+ 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.NO_SUCH_SCRIPT );
+ }
+ 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 );
+ }
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceModel.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceModel.java
new file mode 100644
index 000000000000..05b2850f33a8
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceModel.java
@@ -0,0 +1,141 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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 java.io.InputStream;
+import java.io.IOException;
+
+import java.net.URL;
+
+import com.sun.star.script.provider.XScriptContext;
+
+public class ScriptSourceModel {
+
+ private int currentPosition = -1;
+ private URL file = null;
+ private ScriptSourceView view = null;
+
+ public ScriptSourceModel(URL file ) {
+ this.file = file;
+ }
+
+ private String load() throws IOException {
+ StringBuffer buf = new StringBuffer();
+ InputStream in = file.openStream();
+
+ byte[] contents = new byte[1024];
+ int len = 0;
+
+ while ((len = in.read(contents, 0, 1024)) != -1) {
+ buf.append(new String(contents, 0, len));
+ }
+
+ try {
+ in.close();
+ }
+ catch (IOException ignore) {
+ }
+
+ return buf.toString();
+ }
+
+ public String getText() {
+ String result = "";
+
+ try {
+ result = load();
+ }
+ catch (IOException ioe) {
+ // do nothing, empty string will be returned
+ }
+
+ return result;
+ }
+
+ public int getCurrentPosition() {
+ return this.currentPosition;
+ }
+
+ public void setView(ScriptSourceView view) {
+ this.view = view;
+ }
+
+ public Object execute(final XScriptContext context, ClassLoader cl )
+ throws Exception
+ {
+ Object result = null;
+ // Thread execThread = new Thread() {
+ // public void run() {
+ if ( cl != null )
+ {
+ // sets this threads class loader
+ // hopefully any threads spawned by this
+ // will inherit this cl
+ // this enables any class files imported
+ // from the interpreter to be loaded
+ // note: setting the classloader on the
+ // interpreter has a slightly different
+ // meaning in that the classloader for
+ // the interpreter seems only to look for
+ // source files ( bla.java ) in the classpath
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ bsh.Interpreter interpreter = new bsh.Interpreter();
+ if ( cl != null )
+ {
+ // additionally set class loader on the interpreter
+ // to allow it to load java classes defined in source
+ // files e.g. bla.java
+ interpreter.getNameSpace().clear();
+ }
+
+
+ // reset position
+ currentPosition = -1;
+ view.update();
+
+ interpreter.set("XSCRIPTCONTEXT", context);
+ interpreter.set("ARGUMENTS", new Object[0]);
+
+ if (view.isModified()) {
+ result = interpreter.eval(view.getText());
+ }
+ else {
+ result = interpreter.eval(getText());
+ }
+ // }
+ // };
+ // execThread.start();
+ return result;
+ }
+ public void indicateErrorLine( int lineNum )
+ {
+ System.out.println("Beanshell indicateErrorLine " + lineNum );
+ currentPosition = lineNum - 1;
+ view.update();
+ }
+}
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceView.java b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceView.java
new file mode 100644
index 000000000000..22b4e375aa05
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/ScriptSourceView.java
@@ -0,0 +1,35 @@
+/*************************************************************************
+*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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;
+
+public interface ScriptSourceView {
+ public void clear();
+ public void update();
+ public boolean isModified();
+ public void setModified(boolean value);
+ public String getText();
+}
diff --git a/scripting/java/com/sun/star/script/framework/provider/beanshell/template.bsh b/scripting/java/com/sun/star/script/framework/provider/beanshell/template.bsh
new file mode 100644
index 000000000000..03cb114d79b7
--- /dev/null
+++ b/scripting/java/com/sun/star/script/framework/provider/beanshell/template.bsh
@@ -0,0 +1,48 @@
+/*
+ Import standard OpenOffice.org API classes. For more information on
+ these classes and the OpenOffice.org API, see the OpenOffice.org
+ Developers Guide at:
+
+ http://api.openoffice.org/
+*/
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XModel;
+
+/*
+ Import XScriptContext class. An instance of this class is available
+ to all BeanShell scripts in the global variable "XSCRIPTCONTEXT". This
+ variable can be used to access the document for which this script
+ was invoked.
+
+ Methods available are:
+
+ XSCRIPTCONTEXT.getDocument() returns XModel
+ XSCRIPTCONTEXT.getInvocationContext() returns XScriptInvocationContext or NULL
+ XSCRIPTCONTEXT.getDesktop() returns XDesktop
+ XSCRIPTCONTEXT.getComponentContext() returns XComponentContext
+
+ For more information on using this class see the scripting
+ developer guides at:
+
+ http://api.openoffice.org/docs/DevelopersGuide/ScriptingFramework/ScriptingFramework.xhtml
+*/
+
+// Hello World in BeanShell
+import com.sun.star.text.XTextDocument;
+import com.sun.star.text.XText;
+import com.sun.star.text.XTextRange;
+
+oDoc = UnoRuntime.queryInterface(XModel.class,XSCRIPTCONTEXT.getInvocationContext());
+if ( oDoc == null )
+ oDoc = XSCRIPTCONTEXT.getDocument();
+
+xTextDoc = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class,oDoc);
+xText = xTextDoc.getText();
+xTextRange = xText.getEnd();
+xTextRange.setString( "Hello World (in BeanShell)" );
+
+// BeanShell OpenOffice.org scripts should always return 0
+return 0;