📄 nativeeventthread.java
字号:
/*
* Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is
* subject to license terms.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.jdesktop.jdic.browser;
import java.util.Vector;
import java.awt.*;
import javax.swing.SwingUtilities;
import java.security.*;
import java.io.*;
import org.jdesktop.jdic.browser.internal.WebBrowserUtil;
import org.jdesktop.jdic.init.JdicManager;
/**
* An internal class for dealing with the communication between WebBrowser
* & native browser.
*
* @see WebBrowser
*
* @author Kyle Yuan
* @version 0.1, 03/07/17
*/
class NativeEventThread extends Thread
{
private Vector webBrowsers = new Vector();
// Event queue for events sent from Java to the native browser.
private Vector nativeEvents = new Vector();
private Process nativeBrowser;
boolean eventRetBool;
String eventRetString;
MsgClient messenger = new MsgClient();
NativeEventThread() {
super("EventThread");
}
void attachWebBrowser(WebBrowser webBrowser) {
int instanceNum = webBrowser.getInstanceNum();
if (instanceNum >= webBrowsers.size()) {
webBrowsers.setSize(instanceNum + 1);
}
webBrowsers.set(instanceNum, webBrowser);
}
public void run() {
// create native browser process
try {
if (WebBrowserUtil.getEmbedBinaryName() == null) {
setBrowsersInitFailReason("The embedded browser binary is " +
"not set.");
WebBrowserUtil.trace("The embedded browser binary is not set, " +
"system exit.");
return;
}
String jvmVendor = System.getProperty("java.vm.vendor");
String cmd = WebBrowserUtil.getEmbedBinaryName();
if(cmd.endsWith("IeEmbed.exe") && jvmVendor.startsWith("Sun"))
WebBrowserUtil.nativeSetEnv();
WebBrowserUtil.trace("Executing " + cmd);
nativeBrowser = JdicManager.exec(
new String[]{cmd, "-port=" + messenger.getPort()});
new StreamGobbler(nativeBrowser.getErrorStream()).start();
new StreamGobbler(nativeBrowser.getInputStream()).start();
} catch (PrivilegedActionException e) {
setBrowsersInitFailReason("Can't find the native embedded browser.");
System.out.println("Can't execute the native embedded browser. " +
"Error message: " + e.getCause().getMessage());
return;
}
// create socket client and connect to socket server
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws Exception {
messenger.connect();
return null;
}
}
);
} catch (PrivilegedActionException e) {
System.out.println("Can't connect to the native embedded " +
"browser. Error message: " + e.getCause().getMessage());
setBrowsersInitFailReason("Can't connect to the native embedded " +
"browser.");
return;
}
// main event loop
while (true) {
try {
Thread.sleep(1);
} catch (Exception e) {
}
try {
int exitValue = nativeBrowser.exitValue();
WebBrowserUtil.trace("Native embedded browser died.");
return;
} catch (IllegalThreadStateException e) {
}
try {
processEvents();
} catch (Exception e) {
WebBrowserUtil.trace("Exception occured when processEvent: "
+ e.getMessage());
return;
}
try {
messenger.portListening();
processIncomingMessage(messenger.getMessage());
} catch (Exception e) {
WebBrowserUtil.trace("Exception occured when portListening: "
+ e.getMessage());
return;
}
}
}
private WebBrowser getWebBrowserFromInstance(int instance) {
try {
return (WebBrowser) webBrowsers.get(instance);
} catch (Exception e) {
return null;
}
}
private void notifyWebBrowser(int instance) {
WebBrowser browser = getWebBrowserFromInstance(instance);
if (null != browser) {
synchronized(browser) {
browser.notify();
}
}
}
/*
* Processes events sent from Java to the native browser.
*/
private void processEvents() {
int size = nativeEvents.size();
for (int i = 0; i < size; ++i) {
NativeEventData nativeEvent = (NativeEventData) nativeEvents.get(i);
if (processEvent(nativeEvent)) {
nativeEvents.removeElementAt(i);
break;
}
}
}
private boolean processEvent(NativeEventData nativeEvent) {
WebBrowser browser = getWebBrowserFromInstance(nativeEvent.instance);
if (null == browser) {
return true;
}
if (! browser.isInitialized() &&
(nativeEvent.type != NativeEventData.EVENT_INIT &&
nativeEvent.type != NativeEventData.EVENT_CREATEWINDOW)) {
return false;
}
WebBrowserUtil.trace("Got event: type = " + nativeEvent.type +
" instance = " + nativeEvent.instance);
String msg = nativeEvent.instance + "," + nativeEvent.type + ",";
switch (nativeEvent.type) {
case NativeEventData.EVENT_INIT:
case NativeEventData.EVENT_DESTROYWINDOW:
case NativeEventData.EVENT_GOBACK:
case NativeEventData.EVENT_GOFORWARD:
case NativeEventData.EVENT_REFRESH:
case NativeEventData.EVENT_STOP:
case NativeEventData.EVENT_GETURL:
case NativeEventData.EVENT_FOCUSGAINED:
case NativeEventData.EVENT_FOCUSLOST:
case NativeEventData.EVENT_GETCONTENT:
messenger.sendMessage(msg);
break;
case NativeEventData.EVENT_SHUTDOWN:
messenger.sendMessage(msg);
break;
case NativeEventData.EVENT_CREATEWINDOW:
int nativeWindow = browser.getNativeWindow();
if (0 == nativeWindow) {
WebBrowserUtil.trace("Can't get the JAWT window handler. " +
"Make sure the environment variable JAVA_HOME " +
"is set.");
}
else {
msg += nativeWindow;
messenger.sendMessage(msg);
}
break;
case NativeEventData.EVENT_SET_BOUNDS:
msg += nativeEvent.rectValue.x + "," +
nativeEvent.rectValue.y + "," +
nativeEvent.rectValue.width + "," +
nativeEvent.rectValue.height;
messenger.sendMessage(msg);
break;
case NativeEventData.EVENT_NAVIGATE:
case NativeEventData.EVENT_NAVIGATE_POST:
case NativeEventData.EVENT_NAVIGATE_POSTDATA:
case NativeEventData.EVENT_SETCONTENT:
case NativeEventData.EVENT_EXECUTESCRIPT:
msg += nativeEvent.stringValue;
messenger.sendMessage(msg);
break;
}
return true;
}
static NativeEventData parseIncomingMessage(String msg) {
if (null == msg || 0 == msg.length()) {
return null;
}
int eventType = -1;
String stringValue = null;
int pos1 = msg.indexOf(",", 0);
int instance = Integer.parseInt(msg.substring(0, pos1));
int pos2 = msg.indexOf(",", pos1 + 1);
if (pos2 < 0) {
eventType = Integer.parseInt(msg.substring(pos1 + 1));
}
else {
eventType = Integer.parseInt(msg.substring(pos1 + 1, pos2));
if (pos2 + 1 < msg.length())
stringValue = msg.substring(pos2 + 1);
}
return new NativeEventData(instance, eventType, stringValue);
}
/*
* Process an event received from the native browser
*/
private void processIncomingMessage(String msg) {
NativeEventData eventData = parseIncomingMessage(msg);
if (eventData == null)
return;
WebBrowserUtil.trace("Got event from browser " + eventData.instance
+ ", " + eventData.type + ", " + eventData.stringValue);
if (WebBrowserEvent.WEBBROWSER_INIT_FAILED == eventData.type) {
setBrowsersInitFailReason(eventData.stringValue);
return;
}
if (eventData.instance < 0) {
return;
}
if (WebBrowserEvent.WEBBROWSER_RETURN_URL == eventData.type ||
WebBrowserEvent.WEBBROWSER_GETCONTENT == eventData.type ||
WebBrowserEvent.WEBBROWSER_EXECUTESCRIPT == eventData.type ||
WebBrowserEvent.WEBBROWSER_DESTROYWINDOW_SUCC == eventData.type ) {
eventRetString = eventData.stringValue;
notifyWebBrowser(eventData.instance);
return;
}
// anonymous inner class can only access final local variable
final WebBrowser browser = getWebBrowserFromInstance(eventData.instance);
if (null == browser) {
return;
}
if (WebBrowserEvent.WEBBROWSER_INIT_WINDOW_SUCC == eventData.type) {
browser.setInitialized(true);
browser.setInitFailureMessage("");
return;
}
final WebBrowserEvent event = new WebBrowserEvent(browser,
eventData.type, eventData.stringValue);
// For thread-safety reason, invokes the dispatchWebBrowserEvent method
// of WebBrowser.
Runnable dispatchEvent = new Runnable() {
public void run() {
browser.dispatchWebBrowserEvent(event);
}
};
try {
SwingUtilities.invokeLater(dispatchEvent);
} catch (Exception e) {
WebBrowserUtil.trace("Exception occured when invokeLater. " +
"Error message: " + e.getMessage());
}
}
synchronized void fireNativeEvent(int instance, int type) {
nativeEvents.addElement(new NativeEventData(instance, type));
}
synchronized void fireNativeEvent(int instance, int type,
Rectangle rectValue) {
nativeEvents.addElement(new NativeEventData(instance, type, rectValue));
}
synchronized void fireNativeEvent(int instance, int type,
String stringValue) {
nativeEvents.addElement(
new NativeEventData(instance, type, stringValue));
}
void setBrowsersInitFailReason(String msg) {
((WebBrowser)webBrowsers.elementAt(0)).setInitFailureMessage(msg);
}
class StreamGobbler extends Thread {
InputStream is;
StreamGobbler(InputStream is) {
this.is = is;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println("+++ Ctrace: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} // end of class NativeEventThread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -