1 /**
2  * The utillib library.
3  * More information is available at http://www.jinchess.com/.
4  * Copyright (C) 2002 Alexander Maryanovsky.
5  * All rights reserved.
6  *
7  * The utillib library is free software; you can redistribute
8  * it and/or modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * The utillib library is distributed in the hope that it will
13  * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with utillib library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 package free.util;
23 
24 // Originally adapted from
25 // http://www.javaworld.com/javaworld/javatips/jw-javatip66.html
26 
27 import java.awt.*;
28 import java.awt.event.*;
29 import java.applet.AppletContext;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InterruptedIOException;
33 import java.net.URL;
34 import java.util.Properties;
35 import java.util.StringTokenizer;
36 
37 /**
38  * A simple, static class to display a URL in the system browser.
39  * <UL>
40  *   <LI> Windows - The default browser will be opened via
41  *        <code>rundll32 url.dll,FileProtocolHandler url</code>
42  *   <LI> Mac OS X - The <code>open</code> command is used to open the url in
43  *        the default browser.
44  *   <LI> Classic MacOS - Netscape is used.
45  *   <LI> All other platforms - The command specified by the BROWSER environment
46  *        variable is executed, with <code>%s</code> in it replaced by the URL.
47  *        If $BROWSER is not specified, mozilla is tried.
48  * </UL>
49  */
50 
51 public class BrowserControl{
52 
53 
54 
55   /**
56    * A Properties hashtable containing the environment variables and their
57    * values.
58    */
59 
60   private static Properties environment = null;
61 
62 
63 
64   /**
65    * The context of the applet we're running within, if any.
66    */
67 
68   private static AppletContext appletContext = null;
69 
70 
71 
72   /**
73    * Display a file in the system browser. If you want to display a
74    * file, you must include the absolute path name. Returns whether successful.
75    *
76    * @param url the file's url
77    */
78 
displayURL(String url)79   public static boolean displayURL(String url){
80     try{
81       if (appletContext != null){ // Running in an applet.
82         appletContext.showDocument(new URL(url), "_blank");
83       }
84       else if (PlatformUtils.isWindows()){
85         if (url.endsWith(".html")||url.endsWith(".htm")){
86 
87           // url-encode the last character because windows refuses to display URLs
88           // ending with ".html" or ".htm", but works fine
89           // for ".htm%6c" or ".ht%6d"
90           int lastChar = url.charAt(url.length()  -1);
91           url = url.substring(0, url.length() - 1) + "%" + Integer.toHexString(lastChar);
92         }
93         String cmd = "rundll32 url.dll,FileProtocolHandler "+url;
94         Runtime.getRuntime().exec(cmd);
95       }
96       else if (PlatformUtils.isMacOSX()){
97         String [] commandLine = new String[]{"open", url};
98         Runtime.getRuntime().exec(commandLine);
99       }
100       else if (PlatformUtils.isMacOS()){
101         String [] commandLine = new String[]{"netscape", url};
102         Runtime.getRuntime().exec(commandLine);
103       }
104       else{
105         synchronized(BrowserControl.class){
106           if (environment == null){
107             environment = new Properties();
108             try{
109               Process env = Runtime.getRuntime().exec("env");
110               InputStream in = env.getInputStream();
111               try{
112                 environment.load(in);
113               } finally{
114                   in.close();
115                 }
116             } catch (IOException e){e.printStackTrace();}
117           }
118         }
119 
120         String browsers = environment.getProperty("BROWSER");
121         if ((browsers == null) || ("".equals(browsers))){
122           return tryMozilla(url);
123         }
124 
125         StringTokenizer tokenizer = new StringTokenizer(browsers, ":");
126         if (!tokenizer.hasMoreTokens())
127           return false;
128 
129         String browser = tokenizer.nextToken();
130         int percentPercentIndex;
131         while ((percentPercentIndex = browser.indexOf("%%")) != -1)
132           browser = browser.substring(0, percentPercentIndex)+"%"+browser.substring(percentPercentIndex+3);
133         int urlIndex = browser.indexOf("%s");
134         String commandline;
135         if (urlIndex != -1)
136           commandline = browser.substring(0, urlIndex)+url+browser.substring(urlIndex+2);
137         else
138           commandline = browser+" "+url;
139         Runtime.getRuntime().exec(commandline);
140       }
141     } catch (IOException e){
142         return false;
143       }
144 
145     return true;
146   }
147 
148 
149 
150 
151   /**
152    * Tries to open the specified URL in mozilla.
153    */
154 
tryMozilla(String url)155   public static boolean tryMozilla(String url){
156     try{
157       String [] cmd = new String[]{"mozilla", "-remote",  "openURL("+url+", new-tab)"};
158       Process p = Runtime.getRuntime().exec(cmd);
159       if (p == null)
160         return false;
161 
162       try{
163         // wait for exit code -- if it's 0, command worked,
164         // otherwise we need to start the browser up.
165         int exitCode = p.waitFor();
166 
167         if (exitCode != 0){
168           // Command failed, start up the browser
169           cmd = new String[]{"mozilla ", url};
170           p = Runtime.getRuntime().exec(cmd);
171         }
172       }
173       catch(InterruptedException x){
174         System.err.println("Error bringing up browser, cmd='" + cmd + "'");
175         System.err.println("Caught: " + x);
176         throw new InterruptedIOException(x.getMessage());
177       }
178     } catch (IOException e){
179         return false;
180       }
181 
182     return true;
183   }
184 
185 
186 
187   /**
188    * Brings up the default mailer with the given address in the "to:" field.
189    * Returns whether successful.
190    */
191 
displayMailer(String address)192   public static boolean displayMailer(String address){
193     try{
194       if (appletContext == null){
195         if (PlatformUtils.isLinux()){
196           synchronized(BrowserControl.class){
197             if (environment == null){
198               try{
199                 environment = new Properties();
200                 Process env = Runtime.getRuntime().exec("env");
201                 environment.load(env.getInputStream());
202               } catch (IOException e){}
203             }
204           }
205 
206           String mailer = environment.getProperty("MAILER");
207           if (mailer != null){
208             Runtime.getRuntime().exec(mailer + " " + address);
209             return true;
210           }
211         }
212       }
213     } catch (IOException e){
214         return false;
215       }
216 
217     return displayURL("mailto:" + address);
218   }
219 
220 
221 
222 
223   /**
224    * Displays an error dialog to the user appropriate to when the
225    * <code>displayURL</code> call fails. If <code>modal</code> is true, this
226    * method will block until the user closes the dialog. The specified parent
227    * component must have a <code>Frame</code> parent.
228    */
229 
showDisplayBrowserFailedDialog(String url, Component parent, boolean modal)230   public static void showDisplayBrowserFailedDialog(String url, Component parent, boolean modal){
231     final Dialog dialog = new Dialog(AWTUtilities.frameForComponent(parent), "Error displaying URL", modal);
232     dialog.setLayout(new BorderLayout(5, 5));
233     dialog.add(new Label("Unable to show URL - please copy/paste it into your browser:"), BorderLayout.NORTH);
234     TextField urlTextField = new TextField(url);
235     urlTextField.setEditable(false);
236     dialog.add(urlTextField, BorderLayout.CENTER);
237 
238     Button okButton = new Button("OK");
239     okButton.addActionListener(new ActionListener(){
240       public void actionPerformed(ActionEvent evt){
241         dialog.dispose();
242       }
243     });
244     Panel okButtonPanel = new Panel(new FlowLayout());
245     okButtonPanel.add(okButton);
246     dialog.add(okButtonPanel, BorderLayout.SOUTH);
247 
248     AWTUtilities.centerWindow(dialog, parent);
249     dialog.setVisible(true);
250   }
251 
252 
253 
254   /**
255    * Displays an error dialog to the user appropriate to when the
256    * <code>displayMailer</code> call fails. If <code>modal</code> is true, this
257    * method will block until the user closes the dialog. The specified parent
258    * component must have a <code>Frame</code> parent.
259    */
260 
showDisplayMailerFailedDialog(String address, Component parent, boolean modal)261   public static void showDisplayMailerFailedDialog(String address, Component parent, boolean modal){
262     final Dialog dialog = new Dialog(AWTUtilities.frameForComponent(parent), "Error displaying mailer", modal);
263     dialog.setLayout(new BorderLayout(5, 5));
264     dialog.add(new Label("Unable to display mailer - please copy/paste the address into your mailer:"), BorderLayout.NORTH);
265     TextField addressTextField = new TextField(address);
266     addressTextField.setEditable(false);
267     dialog.add(addressTextField, BorderLayout.CENTER);
268 
269     Button okButton = new Button("OK");
270     okButton.addActionListener(new ActionListener(){
271       public void actionPerformed(ActionEvent evt){
272         dialog.dispose();
273       }
274     });
275     Panel okButtonPanel = new Panel(new FlowLayout());
276     okButtonPanel.add(okButton);
277     dialog.add(okButtonPanel, BorderLayout.SOUTH);
278 
279     AWTUtilities.centerWindow(dialog, parent);
280     dialog.setVisible(true);
281   }
282 
283 
284 
285   /**
286    * Passes the <code>AppletContext</code> to <code>BrowserControl</code>.
287    * That <code>AppletContext</code> will then be used for opening URLs.
288    */
289 
setAppletContext(AppletContext appletContext)290   public static void setAppletContext(AppletContext appletContext){
291     BrowserControl.appletContext = appletContext;
292   }
293 
294 
295 
296   /**
297    * Displays a small awt dialog to test URL opening.
298    */
299 
main(String [] args)300   public static void main(String [] args){
301     Frame f = new Frame("BrowserControl Test");
302     f.setLocation(100, 100);
303     f.setLayout(new BorderLayout());
304     Panel p = new Panel(new FlowLayout());
305     p.add(new Label("URL: "));
306     final TextField tf = new TextField(50);
307     p.add(tf);
308     f.add(p, BorderLayout.CENTER);
309     Button b = new Button("Open URL");
310     ActionListener actionListener = new ActionListener(){
311       public void actionPerformed(ActionEvent evt){
312         displayURL(tf.getText());
313       }
314     };
315 
316     b.addActionListener(actionListener);
317     tf.addActionListener(actionListener);
318 
319     Panel p2 = new Panel(new FlowLayout());
320     p2.add(b);
321     f.add(p2, BorderLayout.SOUTH);
322 
323 
324     f.pack();
325     f.setVisible(true);
326 
327     f.addWindowListener(new WindowAdapter(){
328       public void windowClosing(WindowEvent evt){
329         System.exit(0);
330       }
331     });
332   }
333 
334 
335 
336 }
337