/* BEGIN_HEADER Java TreeView
*
* $Author: alokito $
* $RCSfile: BrowserControl.java,v $
* $Revision: 1.15 $
* $Date: 2008-03-09 21:06:34 $
* $Name: $
*
* This file is part of Java TreeView
* Copyright (C) 2001-2003 Alok Saldanha, All Rights Reserved. Modified by Alex Segal 2004/08/13. Modifications Copyright (C) Lawrence Berkeley Lab.
*
* This software is provided under the GNU GPL Version 2. In particular,
*
* 1) If you modify a source file, make a comment in it containing your name and the date.
* 2) If you distribute a modified version, you must do it under the GPL 2.
* 3) Developers are encouraged but not required to notify the Java TreeView maintainers at alokito@users.sourceforge.net when they make a useful addition. It would be nice if significant contributions could be merged into the main distribution.
*
* A full copy of the license can be found in gpl.txt or online at
* http://www.gnu.org/licenses/gpl.txt
*
* END_HEADER
*/
package edu.stanford.genetics.treeview;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.URL;
/**
* Abstract class to allow platform-independant control of an external web browser
*
* @author Alok Saldanha <alok@genome.stanford.edu>
* @version $Revision: 1.15 $ $Date: 2008-03-09 21:06:34 $
*/
public abstract class BrowserControl {
// adapted from http://www.javaworld.com/javaworld/javatips/jw-javatip66.html
// shit, you would think they would object orient a bit more...
/**
* Method to display a url
*
* @param url String representing url
* @exception IOException Exceptions throw if display fails.
*/
public abstract void displayURL(String url) throws IOException;
/** Used to identify the windows platform. */
private final static String WIN_ID = "Windows";
/** Used to identify the mac platform. */
private final static String MAC_ID = "Mac";
/**
* Pops up a window with the html source of a url.
* Primarily for debugging.
*
* @param url url to show.
*/
public final static void showText(java.net.URL url) {
try {
Reader st = new InputStreamReader(url.openStream());
int ch;
TextArea mp = new TextArea();
ch = st.read();
while (ch != -1) {
char[] cbuf = new char[1];
cbuf[0] = (char) ch;
mp.append(new String(cbuf));
ch = st.read();
}
final Frame top = new Frame("Show URL");
top.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
top.dispose();
}
});
top.add(mp);
top.pack();
top.setVisible(true);
} catch (java.io.IOException e) {
}
}
/**
* Simple example, causes a browser window pop up.
*
* @param args no arguments required.
*/
public static void main(String[] args) {
try {
BrowserControl bc = getBrowserControl();
bc.displayURL("http://www.javaworld.com");
} catch (IOException x) {
// couldn't exec browser
System.err.println("Could not invoke browser, Caught: " + x);
}
}
public boolean isValidUrl(String urlString) {
try {
@SuppressWarnings("unused")
URL url = new URL(urlString);
// url.openConnection()... can test to see if live (throws IOException)
return true;
} catch (java.net.MalformedURLException e) {
return false;
}
}
/**
* Generates an appropriate <code>BrowserControl</code> for the current platform.
*
* @return A new <code>BrowserControl</code>
*/
public static BrowserControl getBrowserControl() {
// christ, need to detect os type...
String os = System.getProperty("os.name");
if (os == null) {
return new UnixBrowserControl();
}
if (os.startsWith(WIN_ID)) {
if (os.indexOf("NT") > 0) {
return new WinNTBrowserControl();
} else {
return new Win32BrowserControl();
}
}
if (os.startsWith(MAC_ID)) {
return new MacBrowserControl();
}
// default to unix style?
return new UnixBrowserControl();
}
}
/**
* Win32 browser control subclass for windows
*
* @author Alok Saldanha <alok@genome.stanford.edu>
* @version @version $Revision: 1.15 $ $Date: 2008-03-09 21:06:34 $
*/
class Win32BrowserControl extends BrowserControl {
/**
* Display a file in the system browser. If you want to display a file, you must
* include the absolute path name.
*
* @param url the file's url (the url must start with either "http://"
* or "file://").
* @exception IOException Not thrown by me
*/
public void displayURL(String url) throws IOException {
// This one was my original
// String cmd = WIN_PATH + " " + WIN_FLAG + " " + url;
// Matt suggested this
// String cmd = "start " + url;
// NT requires this
String cmd = "cmd /c start " + url;
// The problem with the above is that special shell characters, notably & | ( ) < > ^ ,
// need to be escape, or put in double quotes (which can be doubled to escape them,
// but I don't think that's necessary.)
// the problem with the below is that it doesn't work.
//String cmd = "cmd /c start \"" + url +"\"";
// Long term, the solution is probably to URI escape the string, although it's too late at this stage since we don't know what part is the search string.
if (isValidUrl(url) == false) {
cmd = url;
}
try {
Runtime.getRuntime().exec(cmd );
} catch (Exception e) {
cmd = "start " + url;
Runtime.getRuntime().exec(cmd);
}
}
/** The default system browser under windows. */
// private final static String WIN_PATH = "rundll32";
/** The flag to display a url.*/
// private final static String WIN_FLAG = "url.dll,FileProtocolHandler";
}
/**
* Win32 browser control subclass for windows
*
* @author Alok Saldanha <alok@genome.stanford.edu>
* @version @version $Revision: 1.15 $ $Date: 2008-03-09 21:06:34 $
*/
class WinNTBrowserControl extends BrowserControl {
private String WinEscape(String url) {
String cons = "&|()<>^,\"\\";
StringBuffer buf = new StringBuffer();
char [] inChars = url.toCharArray();
for (int i = 0; i < inChars.length; i++) {
if (cons.indexOf(inChars[i]) >= 0) {
buf.append("\\");
}
buf.append(inChars[i]);
}
return buf.toString();
}
/**
* Display a file in the system browser. If you want to display a file, you must
* include the absolute path name.
*
* @param url the file's url (the url must start with either "http://"
* or "file://").
* @exception IOException Not thrown by me
*/
public void displayURL(String url) throws IOException {
// This one was my original
// String cmd = WIN_PATH + " " + WIN_FLAG + " " + url;
// Matt suggested this
// String cmd = "start " + url;
// The problem with the above is that special shell characters, notably & | ( ) < > ^ ,
// need to be escape, or put in double quotes (which can be doubled to escape them,
// but I don't think that's necessary.)
// NT is confused by quotes...
String cmd = "cmd /c start " + WinEscape(url);
if (isValidUrl(url) == false) {
cmd = url;
}
Runtime.getRuntime().exec(cmd);
}
}
/**
* Subclass for unix
*
* @author Alok Saldanha <alok@genome.stanford.edu>
* @version @version $Revision: 1.15 $ $Date: 2008-03-09 21:06:34 $
*/
class UnixBrowserControl extends BrowserControl {
/**
* Display a file in netscape. If you want to display a file, you must include
* the absolute path name.
*
* @param url the file's url (the url must start with either "http://"
* or "file://").
* @exception IOException not thrown by me
*/
public void displayURL(String url) throws IOException {
String cmd = UNIX_PATH + " " + UNIX_FLAG + "(" + url + ")";
if (isValidUrl(url) == false) {
cmd = url;
}
try {
// Under Unix, Netscape has to be running for the "-remote"
// command to work. So, we try sending the command and
// check for an exit value. If the exit command is 0,
// it worked, otherwise we need to start the browser.
// cmd = 'netscape -remote openURL(http://www.javaworld.com)'
Process p = Runtime.getRuntime().exec(cmd);
// wait for exit code -- if it's 0, command worked,
// otherwise we need to start the browser up.
int exitCode = p.waitFor();
if (exitCode != 0) {
// Command failed, start up the browser
//cmd = "netscape \"http://www.javaworld.com\""
cmd = UNIX_PATH + " \"" + url + "\"";
System.out.println("Opening new netscape on unix can be flaky, paste this into a terminal if nothing happens... ");
System.out.println(cmd);
p = Runtime.getRuntime().exec(cmd);
}
} catch (InterruptedException x) {
System.err.println("Error bringing up browser, cmd='" +
cmd + "'");
System.err.println("Caught: " + x);
x.printStackTrace();
}
}
/** The default browser under unix.*/
private final static String UNIX_PATH = "netscape";
/** The flag to display a url.*/
private final static String UNIX_FLAG = "-remote openURL";
}
// I wonder if MacBrowserControl will use the right MRJ?
/**
* Subclass for mac
*
* @author Alok Saldanha <alok@genome.stanford.edu>
* @version @version $Revision: 1.15 $ $Date: 2008-03-09 21:06:34 $
*/
class MacBrowserControl extends BrowserControl {
/**
* Display a file in the system browser. If you want to display a file, you must
* include the absolute path name.
*
* @param url the file's url (the url must start with either "http://"
* or "file://").
* @exception IOException not thrown by me.
*/
public void displayURL(String url) throws IOException {
// System.out.println("Mac browser dislaying url " + url);
com.apple.mrj.MRJFileUtils.openURL(url);
}
}