File: BrowserLauncher.java

package info (click to toggle)
imagej 1.46a-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,248 kB
  • sloc: java: 89,778; sh: 311; xml: 51; makefile: 6
file content (153 lines) | stat: -rw-r--r-- 6,649 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package ij.plugin;
import ij.IJ;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.applet.Applet;

/**
 * This plugin implements the File/Import/URL command and the commands in the Help menu that 
 * open web pages. It is based on Eric Albert's cross-platform (Windows, Mac OS X and Unix) 
 * BrowserLauncher class.
 * <p>
 * BrowserLauncher is a class that provides one static method, openURL, which opens the default
 * web browser for the current user of the system to the given URL.  It may support other
 * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously
 * tested and is not guaranteed to work.
 * <p>
 * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms
 * that are not part of the standard JDK.  What we're trying to do, though, is to take something
 * that's frequently desirable but inherently platform-specific -- opening a default browser --
 * and allow programmers (you, for example) to do so without worrying about dropping into native
 * code or doing anything else similarly evil.
 * <p>
 * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without
 * modification or a need for additional libraries.  All classes that are required on certain
 * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not
 * found, will not cause this to do anything other than returning an error when opening the
 * browser.
 * <p>
 * This code is Copyright 1999-2001 by Eric Albert (ejalbert@cs.stanford.edu) and may be
 * redistributed or modified in any form without restrictions as long as the portion of this
 * comment from this paragraph through the end of the comment is not removed.  The author
 * requests that he be notified of any application, applet, or other binary that makes use of
 * this code, but that's more out of curiosity than anything and is not required.  This software
 * includes no warranty.  The author is not repsonsible for any loss of data or functionality
 * or any adverse or unexpected effects of using this software.
 * <p>
 * Credits:
 * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
 * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
 * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
 *
 * @author Eric Albert (<a href="mailto:ejalbert@cs.stanford.edu">ejalbert@cs.stanford.edu</a>)
 * @version 1.4b1 (Released June 20, 2001)
 */
public class BrowserLauncher implements PlugIn {
	/** The com.apple.mrj.MRJFileUtils class */
	private static Class mrjFileUtilsClass;
	/** The openURL method of com.apple.mrj.MRJFileUtils */
	private static Method openURL;
	private static boolean error;
	static {loadClasses();}


	/** Opens the specified URL (default is the ImageJ home page). */
	public void run(String theURL) {
		if (error) return;
		if (theURL==null || theURL.equals(""))
			theURL = IJ.URL;
		Applet applet = IJ.getApplet();
		if (applet!=null) {
			try {
				applet.getAppletContext().showDocument(new URL(theURL), "_blank" );
			} catch (Exception e) {}
			return;
		}
		try {openURL(theURL);}
		catch (IOException e) {}
	}

	/**
	 * Attempts to open the default web browser to the given URL.
	 * @param url The URL to open
	 * @throws IOException If the web browser could not be located or does not run
	 */
	public static void openURL(String url) throws IOException {
		String errorMessage = "";
		if (IJ.isMacOSX()) {
			if (IJ.isJava16())
				IJ.runMacro("exec('open', '"+url+"')");
			else {
				try {
					Method aMethod = mrjFileUtilsClass.getDeclaredMethod("sharedWorkspace", new Class[] {});
					Object aTarget = aMethod.invoke( mrjFileUtilsClass, new Object[] {});
					openURL.invoke(aTarget, new Object[] { new java.net.URL( url )}); 
				} catch (Exception e) {
					errorMessage = ""+e;
				}
			}
		} else if (IJ.isWindows()) {
			String cmd = "rundll32 url.dll,FileProtocolHandler " + url;
			if (System.getProperty("os.name").startsWith("Windows 2000"))
				cmd = "rundll32 shell32.dll,ShellExec_RunDLL " + url;
			Process process = Runtime.getRuntime().exec(cmd);
			// This avoids a memory leak on some versions of Java on Windows.
			// That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
			try {
				process.waitFor();
				process.exitValue();
			} catch (InterruptedException ie) {
				throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
			}
		} else {
				// Assume Linux or Unix
				// Based on BareBonesBrowserLaunch (http://www.centerkey.com/java/browser/)
				// The utility 'xdg-open' launches the URL in the user's preferred browser,
				// therefore we try to use it first, before trying to discover other browsers.
				String[] browsers = {"xdg-open", "netscape", "firefox", "konqueror", "mozilla", "opera", "epiphany", "lynx" };
				String browserName = null;
				try {
					for (int count=0; count<browsers.length && browserName==null; count++) {
						String[] c = new String[] {"which", browsers[count]};
						if (Runtime.getRuntime().exec(c).waitFor()==0)
							browserName = browsers[count];
					}
					if (browserName==null)
						ij.IJ.error("BrowserLauncher", "Could not find a browser");
					else
						Runtime.getRuntime().exec(new String[] {browserName, url});
				} catch (Exception e) {
					throw new IOException("Exception while launching browser: " + e.getMessage());
				}
		}
	}
	
	/**
	 * Called by a static initializer to load any classes, fields, and methods 
	 * required at runtime to locate the user's web browser.
	 */
	private static void loadClasses() {
		if (IJ.isMacOSX() && !IJ.isJava16() && IJ.getApplet()==null) {
			try {
				if (new File("/System/Library/Java/com/apple/cocoa/application/NSWorkspace.class").exists()) {
					ClassLoader classLoader = new URLClassLoader(new URL[]{new File("/System/Library/Java").toURL()});
					mrjFileUtilsClass = Class.forName("com.apple.cocoa.application.NSWorkspace", true, classLoader);
				} else
					mrjFileUtilsClass = Class.forName("com.apple.cocoa.application.NSWorkspace");
				openURL = mrjFileUtilsClass.getDeclaredMethod("openURL", new Class[] { java.net.URL.class });
			} catch (Exception e) {
				IJ.log("BrowserLauncher"+e);
				error = true;
			}
		}
	}

}