-package jalview.javascript;\r
-\r
-import java.net.URL;\r
-import java.util.Vector;\r
-\r
-import netscape.javascript.JSException;\r
-import netscape.javascript.JSObject;\r
-import jalview.bin.JalviewLite;\r
-\r
-public class JSFunctionExec implements Runnable\r
-{\r
- public JalviewLite jvlite;\r
-\r
- public JSFunctionExec(JalviewLite applet)\r
- {\r
- jvlite = applet;\r
- \r
- jsExecQueue = jvlite.getJsExecQueue();\r
- jvlite.setExecutor(this);\r
- }\r
- public void finalize() {\r
- jvlite=null;\r
- executor=null;\r
- if (jsExecQueue!=null)\r
- {\r
- jsExecQueue.clear();\r
- }\r
- jsExecQueue=null;\r
- }\r
- private Vector jsExecQueue;\r
-\r
- private Thread executor = null;\r
-\r
- public void stopQueue()\r
- {\r
- if (jsExecQueue != null)\r
- {\r
- Vector<JSFunctionExec> q=null;\r
- synchronized (jsExecQueue)\r
- {\r
- q = jsExecQueue;\r
- jsExecQueue = null;\r
- }\r
- if (q!=null ) {\r
- for (JSFunctionExec jx : q)\r
- {\r
- jx.jvlite=null;\r
- \r
- }\r
- q.removeAllElements();\r
- synchronized (q)\r
- {\r
- q.notifyAll();\r
- }\r
- }\r
- }\r
- jvlite=null;\r
- executor = null;\r
- }\r
-\r
- public void run()\r
- {\r
- while (jsExecQueue != null)\r
- {\r
- if (jsExecQueue.size() > 0)\r
- {\r
- Runnable r = (Runnable) jsExecQueue.elementAt(0);\r
- jsExecQueue.removeElementAt(0);\r
- try\r
- {\r
- r.run();\r
- } catch (Exception ex)\r
- {\r
- ex.printStackTrace();\r
- } catch (Error ex)\r
- {\r
- ex.printStackTrace();\r
- }\r
- }\r
- else\r
- {\r
- try\r
- {\r
- synchronized (jsExecQueue)\r
- {\r
- jsExecQueue.wait(1000);\r
- }\r
- } catch (Exception ex)\r
- {\r
- }\r
- ;\r
- }\r
- }\r
-\r
- }\r
-\r
- /**\r
- * execute a javascript callback synchronously\r
- * \r
- * @param _listener\r
- * @param objects\r
- * @throws Exception\r
- */\r
- public void executeJavascriptFunction(final String _listener,\r
- final Object[] objects) throws Exception\r
- {\r
- executeJavascriptFunction(false, _listener, objects);\r
- }\r
-\r
- /**\r
- * execute a javascript callback synchronously or asynchronously\r
- * \r
- * @param async\r
- * - true to execute asynchronously (do this for gui events)\r
- * @param _listener\r
- * - javascript function\r
- * @param objects\r
- * - arguments\r
- * @throws Exception\r
- * - only if call is synchronous\r
- */\r
- public void executeJavascriptFunction(final boolean async,\r
- final String _listener, Object[] arguments) throws Exception\r
- {\r
-\r
- executeJavascriptFunction(async, _listener, arguments, null);\r
-\r
- }\r
-\r
- public void executeJavascriptFunction(final boolean async,\r
- final String _listener, Object[] arguments, final String dbgMsg)\r
- throws Exception\r
- {\r
- final Object[] objects = new Object[arguments != null ? arguments.length\r
- : 0];\r
- if (arguments != null)\r
- {\r
- System.arraycopy(arguments, 0, objects, 0, arguments.length);\r
- }\r
- final Exception[] jsex = new Exception[1];\r
- Runnable exec = new Runnable()\r
- {\r
- public void run()\r
- {\r
- try\r
- {\r
- JSObject scriptObject = null;\r
- try\r
- {\r
- scriptObject = JSObject.getWindow(jvlite);\r
- } catch (Exception ex)\r
- {\r
- }\r
- ;\r
- if (scriptObject != null)\r
- {\r
- if (jvlite.debug && dbgMsg != null)\r
- {\r
- System.err.println(dbgMsg);\r
- }\r
- scriptObject.call(_listener, objects);\r
- }\r
- } catch (Exception jex)\r
- {\r
- // squash any malformedURLExceptions thrown by windows/safari\r
- if (!(jex instanceof java.net.MalformedURLException))\r
- {\r
- if (jvlite.debug)\r
- {\r
- System.err.println(jex);\r
- }\r
- if (jex instanceof netscape.javascript.JSException && jvlite.jsfallbackEnabled)\r
- {\r
- jsex[0] = (netscape.javascript.JSException) jex;\r
- if (jvlite.debug)\r
- {\r
- System.err.println("Falling back to javascript: url call");\r
- }\r
- StringBuffer sb = new StringBuffer("javascript:" + _listener\r
- + "(");\r
- for (int i = 0; objects != null && i < objects.length; i++)\r
- {\r
- if (i > 0)\r
- {\r
- sb.append(",");\r
- }\r
- sb.append("\"");\r
- // strip out nulls and complex objects that we can't pass this\r
- // way.\r
- if (objects[i] != null\r
- && !(objects[i].getClass().getName()\r
- .indexOf("jalview") == 0))\r
- {\r
- sb.append(objects[i].toString());\r
- }\r
- sb.append("\"");\r
- }\r
- sb.append(")");\r
- if (jvlite.debug)\r
- {\r
- System.err.println(sb.toString());\r
- }\r
- // alternate\r
- URL url = null;\r
- try\r
- {\r
- url = new URL(sb.toString());\r
- jvlite.getAppletContext().showDocument(url);\r
- jex = null;\r
- } catch (Exception uex)\r
- {\r
- jex = uex;\r
- }\r
- }\r
- if (jex != null)\r
- {\r
- if (async)\r
- {\r
- jex.printStackTrace();\r
- }\r
- else\r
- {\r
- jsex[0] = jex;\r
- }\r
- }\r
- ;\r
- }\r
-\r
- }\r
- }\r
- };\r
- if (async)\r
- {\r
- if (executor == null)\r
- {\r
- executor = new Thread(new JSFunctionExec(jvlite));\r
- executor.start();\r
- }\r
- synchronized (jsExecQueue)\r
- {\r
- jsExecQueue.addElement(exec);\r
- jsExecQueue.notify();\r
- }\r
- }\r
- else\r
- {\r
- // wat for executor to notify us if it's running.\r
- exec.run();\r
- if (jsex[0] != null)\r
- {\r
- throw (jsex[0]);\r
- }\r
- }\r
- }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.javascript;
+
+import jalview.bin.JalviewLite;
+
+import java.net.URL;
+import java.util.Vector;
+
+import netscape.javascript.JSObject;
+
+public class JSFunctionExec implements Runnable
+{
+ public JalviewLite jvlite;
+
+ public JSFunctionExec(JalviewLite applet)
+ {
+ jvlite = applet;
+
+ jsExecQueue = jvlite.getJsExecQueue();
+ jvlite.setExecutor(this);
+ }
+
+ @Override
+ protected void finalize() throws Throwable
+ {
+ jvlite = null;
+ executor = null;
+ if (jsExecQueue != null)
+ {
+ jsExecQueue.clear();
+ }
+ jsExecQueue = null;
+ super.finalize();
+ }
+
+ private Vector jsExecQueue;
+
+ private Thread executor = null;
+
+ public void stopQueue()
+ {
+ if (jsExecQueue != null)
+ {
+ Vector<JSFunctionExec> q = null;
+ synchronized (jsExecQueue)
+ {
+ q = jsExecQueue;
+ jsExecQueue = null;
+ }
+ if (q != null)
+ {
+ for (JSFunctionExec jx : q)
+ {
+ jx.jvlite = null;
+
+ }
+ q.removeAllElements();
+ synchronized (q)
+ {
+ q.notifyAll();
+ }
+ }
+ }
+ jvlite = null;
+ executor = null;
+ }
+
+ @Override
+ public void run()
+ {
+ while (jsExecQueue != null)
+ {
+ if (jsExecQueue.size() > 0)
+ {
+ Runnable r = (Runnable) jsExecQueue.elementAt(0);
+ jsExecQueue.removeElementAt(0);
+ try
+ {
+ r.run();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } catch (Error ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ else
+ {
+ try
+ {
+ synchronized (jsExecQueue)
+ {
+ jsExecQueue.wait(1000);
+ }
+ } catch (Exception ex)
+ {
+ }
+ ;
+ }
+ }
+
+ }
+
+ /**
+ * execute a javascript callback synchronously
+ *
+ * @param _listener
+ * @param objects
+ * @throws Exception
+ */
+ public void executeJavascriptFunction(final String _listener,
+ final Object[] objects) throws Exception
+ {
+ executeJavascriptFunction(false, _listener, objects);
+ }
+
+ /**
+ * execute a javascript callback synchronously or asynchronously
+ *
+ * @param async
+ * - true to execute asynchronously (do this for gui events)
+ * @param _listener
+ * - javascript function
+ * @param objects
+ * - arguments
+ * @throws Exception
+ * - only if call is synchronous
+ */
+ public void executeJavascriptFunction(final boolean async,
+ final String _listener, Object[] arguments) throws Exception
+ {
+
+ executeJavascriptFunction(async, _listener, arguments, null);
+
+ }
+
+ public void executeJavascriptFunction(final boolean async,
+ final String _listener, Object[] arguments, final String dbgMsg)
+ throws Exception
+ {
+ final Object[] objects = new Object[arguments != null ? arguments.length
+ : 0];
+ if (arguments != null)
+ {
+ System.arraycopy(arguments, 0, objects, 0, arguments.length);
+ }
+ final Exception[] jsex = new Exception[1];
+ Runnable exec = new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ JSObject scriptObject = null;
+ try
+ {
+ scriptObject = JSObject.getWindow(jvlite);
+ } catch (Exception ex)
+ {
+ }
+ ;
+ if (scriptObject != null)
+ {
+ if (jvlite.debug && dbgMsg != null)
+ {
+ System.err.println(dbgMsg);
+ }
+ scriptObject.call(_listener, objects);
+ }
+ } catch (Exception jex)
+ {
+ // squash any malformedURLExceptions thrown by windows/safari
+ if (!(jex instanceof java.net.MalformedURLException))
+ {
+ if (jvlite.debug)
+ {
+ System.err.println(jex);
+ }
+ if (jex instanceof netscape.javascript.JSException
+ && jvlite.jsfallbackEnabled)
+ {
+ jsex[0] = jex;
+ if (jvlite.debug)
+ {
+ System.err.println("Falling back to javascript: url call");
+ }
+ StringBuffer sb = new StringBuffer("javascript:" + _listener
+ + "(");
+ for (int i = 0; objects != null && i < objects.length; i++)
+ {
+ if (i > 0)
+ {
+ sb.append(",");
+ }
+ sb.append("\"");
+ // strip out nulls and complex objects that we can't pass this
+ // way.
+ if (objects[i] != null
+ && !(objects[i].getClass().getName()
+ .indexOf("jalview") == 0))
+ {
+ sb.append(objects[i].toString());
+ }
+ sb.append("\"");
+ }
+ sb.append(")");
+ if (jvlite.debug)
+ {
+ System.err.println(sb.toString());
+ }
+ // alternate
+ URL url = null;
+ try
+ {
+ url = new URL(sb.toString());
+ jvlite.getAppletContext().showDocument(url);
+ jex = null;
+ } catch (Exception uex)
+ {
+ jex = uex;
+ }
+ }
+ if (jex != null)
+ {
+ if (async)
+ {
+ jex.printStackTrace();
+ }
+ else
+ {
+ jsex[0] = jex;
+ }
+ }
+ ;
+ }
+
+ }
+ }
+ };
+ if (async)
+ {
+ if (executor == null)
+ {
+ executor = new Thread(new JSFunctionExec(jvlite));
+ executor.start();
+ }
+ synchronized (jsExecQueue)
+ {
+ jsExecQueue.addElement(exec);
+ jsExecQueue.notify();
+ }
+ }
+ else
+ {
+ // wat for executor to notify us if it's running.
+ exec.run();
+ if (jsex[0] != null)
+ {
+ throw (jsex[0]);
+ }
+ }
+ }
+
+}