KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > jdic > browser > NativeEventThread


1 /*
2  * Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is
3  * subject to license terms.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the Lesser GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA.
19  */

20
21 package org.jdesktop.jdic.browser;
22
23 import java.util.Vector JavaDoc;
24 import java.awt.*;
25 import javax.swing.SwingUtilities JavaDoc;
26 import java.security.*;
27 import java.io.*;
28
29 import org.jdesktop.jdic.browser.internal.WebBrowserUtil;
30 import org.jdesktop.jdic.init.JdicManager;
31 /**
32  * An internal class for dealing with the communication between WebBrowser
33  * & native browser.
34  *
35  * @see WebBrowser
36  *
37  * @author Kyle Yuan
38  * @version 0.1, 03/07/17
39  */

40 class NativeEventThread extends Thread JavaDoc
41 {
42     private Vector JavaDoc webBrowsers = new Vector JavaDoc();
43     // Event queue for events sent from Java to the native browser.
44
private Vector JavaDoc nativeEvents = new Vector JavaDoc();
45     private Process JavaDoc nativeBrowser;
46
47     boolean eventRetBool;
48     String JavaDoc eventRetString;
49
50     MsgClient messenger = new MsgClient();
51
52     NativeEventThread() {
53         super("EventThread");
54     }
55
56     void attachWebBrowser(WebBrowser webBrowser) {
57         int instanceNum = webBrowser.getInstanceNum();
58         if (instanceNum >= webBrowsers.size()) {
59             webBrowsers.setSize(instanceNum + 1);
60         }
61         webBrowsers.set(instanceNum, webBrowser);
62     }
63
64     public void run() {
65         // create native browser process
66
try {
67             if (WebBrowserUtil.getEmbedBinaryName() == null) {
68                 setBrowsersInitFailReason("The embedded browser binary is " +
69                         "not set.");
70                 WebBrowserUtil.trace("The embedded browser binary is not set, " +
71                         "system exit.");
72                 return;
73             }
74             String JavaDoc jvmVendor = System.getProperty("java.vm.vendor");
75             if (WebBrowserUtil.getEmbedBinaryName().endsWith("IeEmbed.exe")
76                     && jvmVendor.startsWith("Sun"))
77                 WebBrowserUtil.nativeSetEnv();
78             String JavaDoc filepath = JdicManager.getManager().getBinaryPath()+
79                 File.separator+WebBrowserUtil.getEmbedBinaryName();
80             final String JavaDoc cmd = (new File(filepath).exists()) ? filepath
81                     : WebBrowserUtil.getEmbedBinaryName();
82             WebBrowserUtil.trace("Executing " + cmd);
83             AccessController.doPrivileged(
84                 new PrivilegedExceptionAction() {
85                     public Object JavaDoc run() throws IOException {
86                         nativeBrowser = Runtime.getRuntime().exec(
87                                 new String JavaDoc[]{cmd, "-port=" + messenger.getPort()});
88                         new StreamGobbler(nativeBrowser.getErrorStream()).start();
89                         new StreamGobbler(nativeBrowser.getInputStream()).start();
90                         return null;
91                     }
92                 }
93             );
94         } catch (PrivilegedActionException e) {
95             setBrowsersInitFailReason("Can't find the native embedded browser.");
96             System.out.println("Can't execute the native embedded browser. " +
97                     "Error message: " + e.getCause().getMessage());
98             return;
99         }
100      
101         // create socket client and connect to socket server
102
try {
103             AccessController.doPrivileged(
104                 new PrivilegedExceptionAction() {
105                     public Object JavaDoc run() throws Exception JavaDoc {
106                         messenger.connect();
107                         return null;
108                     }
109                 }
110             );
111         } catch (PrivilegedActionException e) {
112             System.out.println("Can't connect to the native embedded " +
113                     "browser. Error message: " + e.getCause().getMessage());
114             setBrowsersInitFailReason("Can't connect to the native embedded " +
115                     "browser.");
116             return;
117         }
118
119         // main event loop
120
while (true) {
121             try {
122                 Thread.sleep(1);
123             } catch (Exception JavaDoc e) {
124             }
125
126             try {
127                 int exitValue = nativeBrowser.exitValue();
128                 WebBrowserUtil.trace("Native embedded browser died.");
129                 return;
130             } catch (IllegalThreadStateException JavaDoc e) {
131             }
132
133             try {
134                 processEvents();
135             } catch (Exception JavaDoc e) {
136                 WebBrowserUtil.trace("Exception occured when processEvent: "
137                         + e.getMessage());
138                 return;
139             }
140
141             try {
142                 messenger.portListening();
143                 processIncomingMessage(messenger.getMessage());
144             } catch (Exception JavaDoc e) {
145                 WebBrowserUtil.trace("Exception occured when portListening: "
146                         + e.getMessage());
147                 return;
148             }
149         }
150     }
151
152     private WebBrowser getWebBrowserFromInstance(int instance) {
153         try {
154             return (WebBrowser) webBrowsers.get(instance);
155         } catch (Exception JavaDoc e) {
156             return null;
157         }
158     }
159
160     private void notifyWebBrowser(int instance) {
161         WebBrowser browser = getWebBrowserFromInstance(instance);
162         if (null != browser) {
163             synchronized(browser) {
164                 browser.notify();
165             }
166         }
167     }
168
169     /*
170      * Processes events sent from Java to the native browser.
171      */

172     private void processEvents() {
173         int size = nativeEvents.size();
174         for (int i = 0; i < size; ++i) {
175             NativeEventData nativeEvent = (NativeEventData) nativeEvents.get(i);
176             if (processEvent(nativeEvent)) {
177                 nativeEvents.removeElementAt(i);
178                 break;
179             }
180         }
181     }
182
183     private boolean processEvent(NativeEventData nativeEvent) {
184         WebBrowser browser = getWebBrowserFromInstance(nativeEvent.instance);
185         if (null == browser) {
186             return true;
187         }
188
189         if (! browser.isInitialized() &&
190             (nativeEvent.type != NativeEventData.EVENT_INIT &&
191              nativeEvent.type != NativeEventData.EVENT_CREATEWINDOW)) {
192             return false;
193         }
194
195         WebBrowserUtil.trace("Got event: type = " + nativeEvent.type +
196                 " instance = " + nativeEvent.instance);
197
198         String JavaDoc msg = nativeEvent.instance + "," + nativeEvent.type + ",";
199         switch (nativeEvent.type) {
200             case NativeEventData.EVENT_INIT:
201             case NativeEventData.EVENT_DESTROYWINDOW:
202             case NativeEventData.EVENT_GOBACK:
203             case NativeEventData.EVENT_GOFORWARD:
204             case NativeEventData.EVENT_REFRESH:
205             case NativeEventData.EVENT_STOP:
206             case NativeEventData.EVENT_GETURL:
207             case NativeEventData.EVENT_FOCUSGAINED:
208             case NativeEventData.EVENT_FOCUSLOST:
209             case NativeEventData.EVENT_GETCONTENT:
210                 messenger.sendMessage(msg);
211                 break;
212             case NativeEventData.EVENT_SHUTDOWN:
213                 messenger.sendMessage(msg);
214                 break;
215             case NativeEventData.EVENT_CREATEWINDOW:
216                 int nativeWindow = browser.getNativeWindow();
217                 if (0 == nativeWindow) {
218                     WebBrowserUtil.trace("Can't get the JAWT window handler. " +
219                             "Make sure the environment variable JAVA_HOME " +
220                             "is set.");
221                 }
222                 else {
223                     msg += nativeWindow;
224                     messenger.sendMessage(msg);
225                 }
226                 break;
227             case NativeEventData.EVENT_SET_BOUNDS:
228                 msg += nativeEvent.rectValue.x + "," +
229                        nativeEvent.rectValue.y + "," +
230                        nativeEvent.rectValue.width + "," +
231                        nativeEvent.rectValue.height;
232                 messenger.sendMessage(msg);
233                 break;
234             case NativeEventData.EVENT_NAVIGATE:
235             case NativeEventData.EVENT_NAVIGATE_POST:
236             case NativeEventData.EVENT_NAVIGATE_POSTDATA:
237             case NativeEventData.EVENT_SETCONTENT:
238             case NativeEventData.EVENT_EXECUTESCRIPT:
239                 msg += nativeEvent.stringValue;
240                 messenger.sendMessage(msg);
241                 break;
242         }
243
244         return true;
245     }
246
247     static NativeEventData parseIncomingMessage(String JavaDoc msg) {
248         if (null == msg || 0 == msg.length()) {
249             return null;
250         }
251
252         int eventType = -1;
253         String JavaDoc stringValue = null;
254
255         int pos1 = msg.indexOf(",", 0);
256         int instance = Integer.parseInt(msg.substring(0, pos1));
257         int pos2 = msg.indexOf(",", pos1 + 1);
258         if (pos2 < 0) {
259             eventType = Integer.parseInt(msg.substring(pos1 + 1));
260         }
261         else {
262             eventType = Integer.parseInt(msg.substring(pos1 + 1, pos2));
263             if (pos2 + 1 < msg.length())
264                 stringValue = msg.substring(pos2 + 1);
265         }
266
267         return new NativeEventData(instance, eventType, stringValue);
268     }
269
270     /*
271      * Process an event received from the native browser
272      */

273     private void processIncomingMessage(String JavaDoc msg) {
274         NativeEventData eventData = parseIncomingMessage(msg);
275         if (eventData == null)
276             return;
277
278         WebBrowserUtil.trace("Got event from browser " + eventData.instance
279                 + ", " + eventData.type + ", " + eventData.stringValue);
280
281         if (WebBrowserEvent.WEBBROWSER_INIT_FAILED == eventData.type) {
282             setBrowsersInitFailReason(eventData.stringValue);
283             return;
284         }
285
286         if (eventData.instance < 0) {
287             return;
288         }
289
290         if (WebBrowserEvent.WEBBROWSER_RETURN_URL == eventData.type ||
291             WebBrowserEvent.WEBBROWSER_GETCONTENT == eventData.type ||
292             WebBrowserEvent.WEBBROWSER_EXECUTESCRIPT == eventData.type) {
293             eventRetString = eventData.stringValue;
294             notifyWebBrowser(eventData.instance);
295             return;
296         }
297
298         // anonymous inner class can only access final local variable
299
final WebBrowser browser = getWebBrowserFromInstance(eventData.instance);
300         if (null == browser) {
301             return;
302         }
303         
304         if (WebBrowserEvent.WEBBROWSER_INIT_WINDOW_SUCC == eventData.type) {
305             browser.setInitialized(true);
306             browser.setInitFailureMessage("");
307             return;
308         }
309
310         final WebBrowserEvent event = new WebBrowserEvent(browser,
311                 eventData.type, eventData.stringValue);
312
313         // For thread-safety reason, invokes the dispatchWebBrowserEvent method
314
// of WebBrowser.
315
Runnable JavaDoc dispatchEvent = new Runnable JavaDoc() {
316             public void run() {
317                 browser.dispatchWebBrowserEvent(event);
318             }
319         };
320
321         try {
322             SwingUtilities.invokeLater(dispatchEvent);
323         } catch (Exception JavaDoc e) {
324             WebBrowserUtil.trace("Exception occured when invokeLater. " +
325                     "Error message: " + e.getMessage());
326         }
327     }
328
329     synchronized void fireNativeEvent(int instance, int type) {
330         nativeEvents.addElement(new NativeEventData(instance, type));
331     }
332
333     synchronized void fireNativeEvent(int instance, int type,
334             Rectangle rectValue) {
335         nativeEvents.addElement(new NativeEventData(instance, type, rectValue));
336     }
337
338     synchronized void fireNativeEvent(int instance, int type,
339             String JavaDoc stringValue) {
340         nativeEvents.addElement(
341                 new NativeEventData(instance, type, stringValue));
342     }
343
344     void setBrowsersInitFailReason(String JavaDoc msg) {
345         ((WebBrowser)webBrowsers.elementAt(0)).setInitFailureMessage(msg);
346     }
347
348     class StreamGobbler extends Thread JavaDoc {
349         InputStream is;
350         
351         StreamGobbler(InputStream is) {
352             this.is = is;
353         }
354
355         public void run() {
356             try {
357                 InputStreamReader isr = new InputStreamReader(is);
358                 BufferedReader br = new BufferedReader(isr);
359                 String JavaDoc line = null;
360                 while ((line = br.readLine()) != null) {
361                     System.out.println("+++ Ctrace: " + line);
362                 }
363             } catch (IOException e) {
364                 e.printStackTrace();
365             }
366         }
367     }
368
369 } // end of class NativeEventThread
370
Popular Tags