001/* ----------------------------------------------------------------------------
002   The Kiwi Toolkit - A Java Class Library
003   Copyright (C) 1998-2004 Mark A. Lindner
004
005   This library is free software; you can redistribute it and/or
006   modify it under the terms of the GNU General Public License as
007   published by the Free Software Foundation; either version 2 of the
008   License, or (at your option) any later version.
009
010   This library is distributed in the hope that it will be useful,
011   but WITHOUT ANY WARRANTY; without even the implied warranty of
012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013   General Public License for more details.
014
015   You should have received a copy of the GNU General Public License
016   along with this library; if not, write to the Free Software
017   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
018   02111-1307, USA.
019 
020   The author may be contacted at: mark_a_lindner@yahoo.com
021   ----------------------------------------------------------------------------
022   $Log: WebBrowser.java,v $
023   Revision 1.4  2004/05/12 18:53:41  markl
024   comment block updates
025
026   Revision 1.3  2003/01/19 09:50:54  markl
027   Javadoc & comment header updates.
028
029   Revision 1.2  2002/08/11 09:57:21  markl
030   Version number change.
031
032   Revision 1.1  2002/08/11 09:50:49  markl
033   New class.
034   ----------------------------------------------------------------------------
035*/
036
037package kiwi.ui;
038
039import java.io.IOException;
040import java.text.MessageFormat;
041import java.util.*;
042import java.net.URL;
043
044/** A class that represents a web browser and provides URL opening capability.
045 * This class allows a Java program to open a URL in a web browser. It
046 * currently works on Windows and UNIX systems.
047 * <p>
048 * On Windows, the URL is opened in the default browser by invoking the
049 * command:
050 * <pre>
051 * rundll32 url.dll,FileProtocolHandler <i>url</i>
052 * </pre>
053 * This calling convention works on most variants of Windows, from Windows 98
054 * to Windows 2000. It has not been tested on Windows XP.
055 * <p>
056 * On UNIX, this class can launch (or send a remote command to) any
057 * Netscape-compatible browser which supports the ``-remote'' switch; this
058 * includes Netscape itself, Mozilla, and possibly other browsers. An attempt
059 * is first made to open the URL in a running browser, via a command like:
060 * <pre>
061 * netscape -remote openURL(<i>url</i>)
062 * </pre>
063 * and if that fails, an attempt is then made to launch the browser, via a
064 * command like:
065 * <pre>
066 * netscape <i>url</i>
067 * </pre>
068 * In the case of an error, an exception is thrown.
069 * <p>
070 * On MacOS, the equivalent result can be achieved by using the method:
071 *
072 * <pre>
073 * com.apple.mrj.MRJUtils.openURL(String url) throws IOException
074 * </pre>
075 *
076 * Since this call relies on an OS-specific class library, MacOS support has
077 * not been added to this class, as doing so would break the compilation on
078 * non-MacOS systems.
079 *
080 * @author Mark Lindner
081 *
082 * @since Kiwi 1.3.4
083 */
084
085public class WebBrowser
086  {
087  private boolean windows = false;
088  private String browserPath = null;
089  private static final String[] unixCommands
090    = { "{0} -remote openURL({1})", "{0} {1} &" };
091  private static final String[] unixBrowsers = { "mozilla", "netscape" };
092  private static final String[] windowsCommands
093    = { "rundll32 url.dll,FileProtocolHandler {1}" };
094  private static final String[] windowsBrowsers = { "" };
095
096  /**
097   * Construct a new <code>WebBrowser</code>, with no browser path specified.
098   * An attempt will be made to use mozilla or netscape, in that order. It
099   * will be assumed that a browser binary can be found in the command
100   * search path.
101   */
102  
103  public WebBrowser()
104    {
105    windows = isWindows();
106    }
107
108  /** Specify the path to a Netscape-compatible browser (such as Netscape,
109   * Mozilla, or any other browser that supports the ``-remote'' switch). It
110   * is assumed (but not required) that <i>path</i> is an absolute path to
111   * a browser executable.
112   * <p>
113   * This method has no effect on Windows systems.
114   *
115   * @param path The path to the browser.
116   */
117
118  public void setBrowserPath(String path)
119    {
120    if(! windows)
121      browserPath = path;
122    }
123
124  /** Open the specified URL in the web browser.
125   *
126   * @param url The URL to open.
127   * @throws java.io.IOException If the browser could not be launched.
128   */
129  
130  public void openURL(URL url) throws IOException
131    {
132    openURL(url.toString());
133    }
134  
135  /** Open the specified URL in the web browser.
136   *
137   * @param url The URL to open.
138   * @throws java.io.IOException If the browser could not be launched.
139   */
140
141  public void openURL(String url) throws IOException
142    {
143    String commands[] = (windows ? windowsCommands : unixCommands);
144    String browsers[] = (windows ? windowsBrowsers : unixBrowsers);
145    boolean ok = false;
146
147    if(!windows && (browserPath != null))
148      {
149      openURL(url, browserPath, commands);
150      return;
151      }
152    else
153      {
154      for(int i = 0; i < browsers.length; i++)
155        {
156        try
157          {
158          openURL(url, browsers[i], commands);
159          browserPath = browsers[i]; // save for next time
160          return;
161          }
162        catch(IOException ex) { /* ignore */ }
163        }
164
165      throw(new IOException("Unable to launch browser."));
166      }
167       
168    }
169
170  /*
171   */
172
173  private void openURL(String url, String browser,
174                       String commandList[]) throws IOException
175    {
176    String cmd;
177    int exitCode = 0;
178    Process p;
179    boolean wait = true;
180    
181    for(int i = 0; i < commandList.length; i++)
182      {
183      MessageFormat mf = new MessageFormat(commandList[i]);
184      cmd = mf.format(new Object[] { browser, url });
185
186      if(cmd.endsWith("&"))
187        {
188        wait = false;
189        cmd = cmd.substring(0, cmd.length() - 1);
190        }
191
192      System.err.println("browser command: " + cmd);
193
194      p = Runtime.getRuntime().exec(cmd);
195
196      if(wait)
197        {
198        for(;;)
199          {
200          try
201            {
202            exitCode = p.waitFor();
203            break;
204            }
205          catch(InterruptedException ex) { /* ignore */ }
206          }
207
208        if(exitCode == 0)
209          break;
210        }
211      }    
212    }
213  
214  /*
215   */
216
217  private boolean isWindows()
218    {
219    String os = System.getProperty("os.name");
220
221    return(os != null && os.startsWith("Windows"));
222    }
223
224  /*
225   * For testing...
226   */
227
228  /*
229
230  public static void main(String args[])
231    {
232    try
233      {
234      WebBrowser browser = new WebBrowser();
235      browser.setBrowserPath("/usr/local/bin/netscape");
236      browser.openURL("http://www.slashdot.org/");
237      }
238    catch(Exception ex)
239      {
240      ex.printStackTrace();
241      }
242    }
243
244  */
245  
246  }
247
248/* end of source file */