avoid 1.5 specific methods
[jalview.git] / src / jalview / javascript / JSFunctionExec.java
1 package jalview.javascript;
2
3 import java.net.URL;
4 import java.util.Vector;
5
6 import netscape.javascript.JSException;
7 import netscape.javascript.JSObject;
8 import jalview.bin.JalviewLite;
9
10 public class JSFunctionExec implements Runnable
11 {
12   JalviewLite jvlite;
13
14   public JSFunctionExec(JalviewLite applet)
15   {
16     jvlite = applet;
17   }
18
19   private static Vector jsExecQueue;
20
21   private static Thread executor = null;
22
23   public static void stopQueue()
24   {
25     if (jsExecQueue != null)
26     {
27       Vector q = jsExecQueue;
28       jsExecQueue = null;
29       q.removeAllElements();
30       executor.notify();
31       executor = null;
32     }
33   }
34
35   public void run()
36   {
37     while (jsExecQueue != null)
38     {
39       if (jsExecQueue.size() > 0)
40       {
41         Runnable r = (Runnable) jsExecQueue.elementAt(0);
42         jsExecQueue.removeElementAt(0);
43         try
44         {
45           r.run();
46         } catch (Exception ex)
47         {
48           ex.printStackTrace();
49         } catch (Error ex)
50         {
51           ex.printStackTrace();
52         }
53       }
54       else
55       {
56         try
57         {
58           synchronized (jsExecQueue)
59           {
60             jsExecQueue.wait(1000);
61           }
62         } catch (Exception ex)
63         {
64         }
65         ;
66       }
67     }
68
69   }
70
71   /**
72    * execute a javascript callback asynchronously
73    * 
74    * @param _listener
75    * @param objects
76    * @throws Exception
77    */
78   public void executeJavascriptFunction(final String _listener,
79           final Object[] objects) throws Exception
80   {
81     executeJavascriptFunction(false, _listener, objects);
82   }
83
84   /**
85    * execute a javascript callback synchronously or asynchronously
86    * 
87    * @param async
88    *          - true to execute asynchronously (do this for gui events)
89    * @param _listener
90    *          - javascript function
91    * @param objects
92    *          - arguments
93    * @throws Exception
94    *           - only if call is synchronous
95    */
96   public void executeJavascriptFunction(final boolean async,
97           final String _listener, Object[] arguments) throws Exception
98   {
99
100     executeJavascriptFunction(async, _listener, arguments, null);
101
102   }
103
104   public void executeJavascriptFunction(final boolean async,
105           final String _listener, Object[] arguments, final String dbgMsg)
106           throws Exception
107   {
108     final Object[] objects = new Object[arguments != null ? arguments.length
109             : 0];
110     if (arguments != null)
111     {
112       System.arraycopy(arguments, 0, objects, 0, arguments.length);
113     }
114     final Exception[] jsex = new Exception[1];
115     Runnable exec = new Runnable()
116     {
117       public void run()
118       {
119         try
120         {
121           JSObject scriptObject = null;
122           try
123           {
124             scriptObject = JSObject.getWindow(jvlite);
125           } catch (Exception ex)
126           {
127           }
128           ;
129           if (scriptObject != null)
130           {
131             if (jvlite.debug && dbgMsg != null)
132             {
133               System.err.println(dbgMsg);
134             }
135             scriptObject.call(_listener, objects);
136           }
137         } catch (Exception jex)
138         {
139           // squash any malformedURLExceptions thrown by windows/safari
140           if (!(jex instanceof java.net.MalformedURLException))
141           {
142             if (jvlite.debug)
143             {
144               System.err.println(jex);
145             }
146             if (jex instanceof netscape.javascript.JSException)
147             {
148               jsex[0] = (netscape.javascript.JSException) jex;
149               if (jvlite.debug)
150               {
151                 System.err.println("Falling back to javascript: url call");
152               }
153               StringBuffer sb = new StringBuffer("javascript:" + _listener
154                       + "(");
155               for (int i = 0; objects != null && i < objects.length; i++)
156               {
157                 if (i > 0)
158                 {
159                   sb.append(",");
160                 }
161                 sb.append("\"");
162                 // strip out nulls and complex objects that we can't pass this
163                 // way.
164                 if (objects[i] != null
165                         && !(objects[i].getClass().getName()
166                                 .indexOf("jalview") == 0))
167                 {
168                   sb.append(objects[i].toString());
169                 }
170                 sb.append("\"");
171               }
172               sb.append(")");
173               if (jvlite.debug)
174               {
175                 System.err.println(sb.toString());
176               }
177               // alternate
178               URL url = null;
179               try
180               {
181                 url = new URL(sb.toString());
182                 jvlite.getAppletContext().showDocument(url);
183                 jex = null;
184               } catch (Exception uex)
185               {
186                 jex = uex;
187               }
188             }
189             if (jex != null)
190             {
191               if (async)
192               {
193                 jex.printStackTrace();
194               }
195               else
196               {
197                 jsex[0] = jex;
198               }
199             }
200             ;
201           }
202
203         }
204       }
205     };
206     if (async)
207     {
208       if (JSFunctionExec.executor == null)
209       {
210         JSFunctionExec.jsExecQueue = new Vector();
211         JSFunctionExec.executor = new Thread(new JSFunctionExec(jvlite));
212         executor.start();
213       }
214       synchronized (jsExecQueue)
215       {
216         jsExecQueue.addElement(exec);
217         jsExecQueue.notify();
218       }
219     }
220     else
221     {
222       exec.run();
223       if (jsex[0] != null)
224       {
225         throw (jsex[0]);
226       }
227     }
228   }
229
230 }