KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > extbrowser > UnixBrowserImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.extbrowser;
21
22 import java.awt.*;
23 import java.beans.*;
24 import java.io.*;
25 import java.net.*;
26 import javax.swing.*;
27
28 import org.openide.*;
29 import org.openide.awt.StatusDisplayer;
30 import org.openide.execution.NbProcessDescriptor;
31 import org.openide.util.NbBundle;
32
33 import org.openide.util.RequestProcessor;
34
35 /**
36  * The UnixBrowserImpl is implementation of browser that displays content in
37  * external program (Netscape). It is usable on Unix platform only because it
38  * uses command line option specific to this environment.
39  * Additionally it uses some XWindow utilities to get information about
40  * browser windows.
41  *
42  * @author Radim Kubacki
43  */

44 public class UnixBrowserImpl extends ExtBrowserImpl {
45     
46     /** Number of probes to get exit status of executed command.
47      * Status is checked after each second.
48      */

49     protected static final int CMD_TIMEOUT = 6;
50     
51     /** Creates modified NbProcessDescriptor that can be used to start
52      * browser process when <CODE>-remote openURL()</CODE> options
53      * cannot be used.
54      * @return command or <CODE>null</CODE>
55      * @param p Original command.
56      */

57     protected static NbProcessDescriptor createPatchedExecutable (NbProcessDescriptor p) {
58         NbProcessDescriptor newP = null;
59         
60         String JavaDoc [] args = org.openide.util.Utilities.parseParameters(p.getArguments());
61         if (args.length > 1) {
62             if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
63                 ExtWebBrowser.getEM().log("Old arguments: " + p.getArguments()); // NOI18N
64
}
65             StringBuffer JavaDoc newArgs = new StringBuffer JavaDoc ();
66             boolean found = false;
67             for (int i=0; i<args.length-1; i++) {
68                 if (newArgs.length() > 0) {
69                     newArgs.append(" "); // NOI18N
70
}
71                 if (args[i].indexOf("-remote") >= 0 // NOI18N
72
&& args[i+1].indexOf("openURL(") >=0) { // NOI18N
73
found = true;
74                     newArgs.append("\"{URL}\""); // NOI18N
75
}
76                 else {
77                     newArgs.append("\""+args[i]+"\""); // NOI18N
78
}
79             }
80             if (found) {
81                 newP = new NbProcessDescriptor (p.getProcessName(), newArgs.toString(), p.getInfo());
82             }
83             if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
84                 ExtWebBrowser.getEM().log("ProcessName: " + p.getProcessName()); // NOI18N
85
ExtWebBrowser.getEM().log("New arguments: " + newArgs.toString()); // NOI18N
86
}
87         }
88         return newP;
89     }
90
91     /** Creates new UnixBrowserImpl */
92     public UnixBrowserImpl () {
93         this (null);
94     }
95     
96     /** Creates new UnixBrowserImpl
97      * @param extBrowserFactory Associated browser factory to get settings from.
98      */

99     public UnixBrowserImpl (ExtWebBrowser extBrowserFactory) {
100         super();
101         this.extBrowserFactory = extBrowserFactory;
102         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
103             ExtWebBrowser.getEM().log("UnixBrowserImpl created from factory: " + extBrowserFactory); // NOI18N
104
}
105     }
106        
107     /**
108      * Sets current URL.</P>
109      *
110      * <P>If browser is running and we know window ID we call
111      * <CODE>browser_command -id _winID_ -raise -remote 'openURL(_url)'</CODE>
112      * else we start it with
113      * <CODE>browser_command _url_</CODE></P>
114      *
115      * @param url URL to show in the browser.
116      */

117     public void setURL(URL url) {
118         if (SwingUtilities.isEventDispatchThread ()) {
119             final URL newUrl = url;
120             RequestProcessor.getDefault ().post (
121                 new Runnable JavaDoc () {
122                     public void run () {
123                         UnixBrowserImpl.this.setURL (newUrl);
124                     }
125             });
126             return;
127         }
128         
129         NbProcessDescriptor cmd = extBrowserFactory.getBrowserExecutable (); // NOI18N
130
Process JavaDoc p;
131         StatusDisplayer sd = StatusDisplayer.getDefault ();
132         try {
133             // internal protocols cannot be displayed in external viewer
134
url = URLUtil.createExternalURL(url, false);
135             if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
136                 ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "External url: " + url); // NOI18N
137
}
138             
139             cmd = extBrowserFactory.getBrowserExecutable (); // NOI18N
140
if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
141                 ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Executable: " + cmd); // NOI18N
142
}
143             sd.setStatusText (NbBundle.getMessage (UnixBrowserImpl.class, "MSG_Running_command", cmd.getProcessName ()));
144             p = cmd.exec (new ExtWebBrowser.UnixBrowserFormat (url.toString ()));
145             
146             RequestProcessor.getDefault ().post (new Status (cmd, p, url), 1000);
147
148             URL old = this.url;
149             this.url = url;
150             pcs.firePropertyChange (PROP_URL, old, url);
151         }
152         catch (java.io.IOException JavaDoc ex) {
153             // occurs when executable is not found or not executable
154
DialogDisplayer.getDefault().notify(
155                 new NotifyDescriptor.Message (
156                 NbBundle.getMessage (UnixBrowserImpl.class, "MSG_Cant_run_netscape", new Object JavaDoc [] { cmd.getProcessName () }),
157                 NotifyDescriptor.Message.WARNING_MESSAGE)
158             );
159         }
160         catch (NumberFormatException JavaDoc ex) {
161             ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ex);
162         }
163         catch (java.lang.Exception JavaDoc ex) {
164             ErrorManager.getDefault ().notify (ex);
165         }
166     }
167    
168     /** Object that checks execution result
169      * of browser invocation request.
170      * <p>It can made another attempt to start the browser
171      * when error output contains information that communication
172      * through Xremote protocol failed.
173      */

174     private class Status implements Runnable JavaDoc {
175         
176         /** Message printed when invocation fails even though the
177          * application runs, but there's no browser window (only mail client, e.g.).
178          */

179         private static final String JavaDoc FAILURE_MSG_BADWINDOW = "BadWindow"; // NOI18N
180

181         /** Message printed when invocation fails because the application does not run. */
182         private static final String JavaDoc FAILURE_MSG = "No running window found."; // NOI18N
183

184         /** Originally executed command. */
185         private NbProcessDescriptor cmd;
186         
187         /** Handle to executed process. */
188         private Process JavaDoc p;
189         
190         /** URL to be displayed. */
191         private URL url;
192         
193         /** Retries counter. */
194         private int retries = CMD_TIMEOUT;
195         
196         /** Creates Status object to check execution result
197          * of browser invocation request.
198          * @param cmd Originally executed command.
199          * @param p Process that is checked.
200          * @param url Displayed URL that can be used when another attempt
201          * to start the browser is made or <CODE>null</CODE>.
202          */

203         public Status (NbProcessDescriptor cmd, Process JavaDoc p, URL url) {
204             this. cmd = cmd;
205             this.p = p;
206             this.url = url;
207         }
208         
209         /** Checks whether process is correctly executed.
210          * If it returns bad exit code or prints know error message
211          * it is re-executed once again.
212          * If the execution is not finished during timeout message is displayed.
213          */

214         public void run () {
215             boolean retried = false;
216             if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
217                 ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Retried: " + retried); // NOI18N
218
}
219             int exitStatus = 1;
220             Reader r = new InputStreamReader (p.getErrorStream ());
221             try {
222                 exitStatus = p.exitValue();
223                 if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
224                     ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Command executed. exitValue = " + exitStatus); // NOI18N
225
}
226             } catch (IllegalThreadStateException JavaDoc ex) {
227                 retries--;
228                 if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
229                     ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Retries: " + retries); // NOI18N
230
ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Time: " + System.currentTimeMillis()); // NOI18N
231
}
232                 if (retries > 0) {
233                     RequestProcessor.getDefault().post(this, 1000);
234                     return;
235                 } else {
236                     if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
237                         ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Command not finished yet"); // NOI18N
238
}
239                 }
240             }
241
242             // hack : Netscape exits with 0 on Linux even if there is no window
243
if (exitStatus == 0 && org.openide.util.Utilities.getOperatingSystem() == org.openide.util.Utilities.OS_LINUX) {
244                 final int LEN = 2048;
245                 char [] buff = new char [LEN];
246                 int l;
247                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
248                 try {
249                     while ((l = r.read (buff, 0, LEN)) != -1) {
250                         sb.append (buff, 0, l);
251                     }
252                     if (sb.toString ().indexOf (FAILURE_MSG) >= 0) {
253                         if (ExtWebBrowser.getEM ().isLoggable (ErrorManager.INFORMATIONAL)) {
254                             ExtWebBrowser.getEM ().log (ErrorManager.INFORMATIONAL, "Browser output: \""+FAILURE_MSG+"\""); // NOI18N
255
}
256                         exitStatus = 2;
257                     }
258                 } catch (java.io.IOException JavaDoc ioe) {
259                     // suppose it was executed
260
ExtWebBrowser.getEM ().notify(ErrorManager.WARNING, ioe);
261                 }
262             }
263             
264             // mozilla & netscape exits with 1 on Linux if there's mail window present,
265
// but there's no browser window - the URL is shown correctly, though
266
if (exitStatus == 1 && org.openide.util.Utilities.getOperatingSystem() == org.openide.util.Utilities.OS_LINUX) {
267                 final int LEN = 2048;
268                 char [] buff = new char [LEN];
269                 int l;
270                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
271                 try {
272                     while ((l = r.read (buff, 0, LEN)) != -1) {
273                         sb.append (buff, 0, l);
274                     }
275                     if (sb.toString ().indexOf (FAILURE_MSG_BADWINDOW) >= 0) {
276                         if (ExtWebBrowser.getEM().isLoggable (ErrorManager.INFORMATIONAL)) {
277                             ExtWebBrowser.getEM().log (ErrorManager.INFORMATIONAL, "Browser output: \""+FAILURE_MSG_BADWINDOW+"\""); // NOI18N
278
}
279                         exitStatus = 0;
280                     }
281                 } catch (java.io.IOException JavaDoc ioe) {
282                     // suppose it was executed
283
ExtWebBrowser.getEM ().notify(ErrorManager.WARNING, ioe);
284                 }
285             }
286             
287             if (exitStatus == 2) {
288                 try {
289                     NbProcessDescriptor startCmd = UnixBrowserImpl.createPatchedExecutable(cmd);
290                     if (startCmd != null) {
291                         retried = true;
292                         StatusDisplayer.getDefault().
293                             setStatusText (NbBundle.getMessage (UnixBrowserImpl.class, "MSG_Running_command", startCmd.getProcessName ()));
294                         Process JavaDoc pr = startCmd.exec (new ExtWebBrowser.UnixBrowserFormat (url.toString ()));
295
296                         // do not care about result now
297
// RequestProcessor.getDefault ().post (new Status (startCmd, pr, null), 1000);
298
}
299                 }
300                 catch (java.io.IOException JavaDoc ioe) {
301                     // suppose it was executed
302
ExtWebBrowser.getEM ().notify(ErrorManager.WARNING, ioe);
303                 }
304             }
305             
306             if (exitStatus != 0 && !retried) {
307                 DialogDisplayer.getDefault().notify(
308                     new NotifyDescriptor.Message (
309                     NbBundle.getMessage (UnixBrowserImpl.class, "MSG_Cant_run_netscape", new Object JavaDoc [] { cmd.getProcessName () }),
310                     NotifyDescriptor.Message.WARNING_MESSAGE)
311                 );
312                 return;
313             }
314
315         }
316     }
317 }
318
Popular Tags