KickJava   Java API By Example, From Geeks To Geeks.

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


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.awt.event.*;
24 import java.beans.*;
25 import java.net.*;
26 import javax.swing.*;
27 import java.util.Timer JavaDoc;
28 import java.util.TimerTask JavaDoc;
29 import java.util.Vector JavaDoc;
30
31 import org.openide.DialogDisplayer;
32 import org.openide.NotifyDescriptor;
33 import org.openide.ErrorManager;
34 import org.openide.awt.StatusDisplayer;
35 import org.openide.execution.NbProcessDescriptor;
36 import org.openide.util.Utilities;
37 import org.openide.util.NbBundle;
38
39 import java.io.File JavaDoc;
40 import java.io.FileWriter JavaDoc;
41 import java.io.IOException JavaDoc;
42
43
44 /**
45  * Class that uses DDE to communicate with web browser through DDE.
46  * Currently three browsers are supported:
47  * <UL>
48  * <LI>Netscape Navigator</LI>
49  * <LI>Internet Explorer</LI>
50  * <LI>Mozilla</LI>
51  * </UL>
52  *
53  * <P>Limitations: Mozilla doesn't support WWW_Activate now
54  * IE has different implementation on Win9x and on WinNT/Win2000.
55  * WWW_Activate creates always new window on Win9x so we don't use it.
56  * Also it accepts only "0xFFFFFFFF" for WWW_Activate on WinNT/Win2K.
57  *
58  * <P>Documentation can be found
59  * <a HREF="http://developer.netscape.com/docs/manuals/communicator/DDE/ddevb.htm">
60  * here</a>.
61  *
62  * @author Radim Kubacki
63  */

64 public class NbDdeBrowserImpl extends ExtBrowserImpl {
65
66     /** DDE topic names */
67     private static final String JavaDoc WWW_ACTIVATE = "WWW_Activate"; // NOI18N
68
private static final String JavaDoc WWW_OPEN_URL = "WWW_OpenURL"; // NOI18N
69

70     private static final String JavaDoc EXTBROWSER_DLL = "extbrowser"; //NOI18N
71
private static final String JavaDoc EXTBROWSER_DLL_64BIT = "extbrowser64"; //NOI18N
72

73     static {
74         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
75             ExtWebBrowser.getEM().log(ErrorManager.INFORMATIONAL, "" + System.currentTimeMillis() + "> NbDdeBrowser: static initializer: ");
76         }
77         try {
78             if (org.openide.util.Utilities.isWindows()) {
79
80                 // should be 32 or 64 bit, but it may not be present on some jdks
81
String JavaDoc sunDataModel = System.getProperty("sun.arch.data.model"); //NOI8N
82
if (sunDataModel != null) {
83                     if ("64".equals(sunDataModel)) { //NOI18N
84
System.loadLibrary(EXTBROWSER_DLL_64BIT);
85                     } else {
86                         System.loadLibrary(EXTBROWSER_DLL);
87                     }
88                 } else {
89                     String JavaDoc javaVMName = System.getProperty("java.vm.name"); //NOI8N
90
if ((javaVMName != null) && (javaVMName.indexOf("64") > -1)) { //NOI18N
91
System.loadLibrary(EXTBROWSER_DLL_64BIT);
92                     } else {
93                         System.loadLibrary(EXTBROWSER_DLL);
94                     }
95                 }
96
97             }
98         } catch (Exception JavaDoc e) {
99             DialogDisplayer.getDefault ().notify (
100                 new NotifyDescriptor.Message(NbBundle.getMessage(NbDdeBrowserImpl.class, "ERR_cant_locate_dll"),
101                 NotifyDescriptor.INFORMATION_MESSAGE)
102             );
103         }
104     }
105             
106     /** native thread that displays URLs */
107     private static Thread JavaDoc nativeThread = null;
108     
109     /** runnable class that implements the work of nativeThread */
110     private static NbDdeBrowserImpl.URLDisplayer nativeRunnable = null;
111     
112     /** Creates new NbDdeBrowserImpl */
113     public NbDdeBrowserImpl (ExtWebBrowser extBrowserFactory) {
114         super ();
115         this.extBrowserFactory = extBrowserFactory;
116         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
117             ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "NbDdeBrowserImpl created with factory: " + extBrowserFactory); // NOI18N
118
}
119     }
120     
121     native private byte [] reqDdeMessage (String JavaDoc srv, String JavaDoc topic, String JavaDoc item, int timeout) throws NbBrowserException;
122     
123     /** finds registry entry for browser opening */
124     public native static String JavaDoc getBrowserPath (String JavaDoc browser) throws NbBrowserException;
125     
126     /** returns the command that executes default application for opening of
127      * .html files
128      */

129     public native static String JavaDoc getDefaultOpenCommand() throws NbBrowserException;
130     
131     /** Sets current URL.
132      *
133      * @param url URL to show in the browser.
134      */

135     public synchronized void setURL(final URL url) {
136         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
137             ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "NbDdeBrowserImpl.setUrl: " + url); // NOI18N
138
}
139         if (nativeThread == null) {
140             nativeRunnable = new NbDdeBrowserImpl.URLDisplayer ();
141             nativeThread = new Thread JavaDoc(nativeRunnable, "URLdisplayer"); // NOI18N
142
nativeThread.start ();
143         }
144         nativeRunnable.postTask (new DisplayTask (url, this));
145     }
146     
147     /** Finds the name of DDE server.
148      * If <Default system browser> is set then it resolves it into either
149      * Netscape or IExplore
150      */

151     private String JavaDoc realDDEServer () {
152         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
153             ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "NbDdeBrowserImpl.realDDEServer"); // NOI18N
154
}
155         String JavaDoc srv = extBrowserFactory.getDDEServer ();
156         if (srv != null) {
157             return srv;
158         }
159         
160         try {
161             String JavaDoc cmd = getDefaultOpenCommand ();
162             if (cmd != null) {
163                 if (cmd.toUpperCase ().indexOf (ExtWebBrowser.IEXPLORE) >= 0) {
164                     return ExtWebBrowser.IEXPLORE;
165                 }
166
167                 if (cmd.toUpperCase ().indexOf ("NETSCP") >= 0) { // NOI18N
168
return ExtWebBrowser.NETSCAPE6;
169                 }
170                 
171                 if (cmd.toUpperCase ().indexOf (ExtWebBrowser.NETSCAPE) >= 0) {
172                     return ExtWebBrowser.NETSCAPE;
173                 }
174                 
175                 if (cmd.toUpperCase ().indexOf (ExtWebBrowser.MOZILLA) >= 0) {
176                     return ExtWebBrowser.MOZILLA;
177                 }
178
179                 if (cmd.toUpperCase ().indexOf (ExtWebBrowser.FIREFOX) >= 0) {
180                     return ExtWebBrowser.FIREFOX;
181                 }
182             }
183         } catch (Exception JavaDoc ex) {
184             // some problem in native code likely
185
ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ex);
186         }
187         // guess IE
188
return ExtWebBrowser.IEXPLORE;
189     }
190     
191     /** Getter for property activateTimeout.
192      * @return Value of property activateTimeout.
193      *
194      */

195     public int getActivateTimeout() {
196         return extBrowserFactory.getActivateTimeout();
197     }
198         
199     /** Getter for property openUrlTimeout.
200      * @return Value of property openUrlTimeout.
201      *
202      */

203     public int getOpenUrlTimeout() {
204         return extBrowserFactory.getOpenurlTimeout();
205     }
206         
207     /**
208      * Singleton for doing all DDE operations.
209      */

210     static class URLDisplayer implements Runnable JavaDoc { // NOI18N
211

212         private static final int ADDITIONAL_WAIT_TIMEOUT = 6000;
213     
214         /** FIFO of urls that should be displayed */
215         Vector JavaDoc tasks;
216         
217         /** flag for quiting of this thread */
218         boolean doProcessing = true;
219         
220         /** This is set to true during displaying of URL.
221          * Used by Timer to interrupt displaying and print error message
222          */

223         boolean isDisplaying = false;
224
225         private URLDisplayer () {
226             tasks = new Vector JavaDoc ();
227         }
228         
229         private void postTask (DisplayTask task) {
230             synchronized (this) {
231                 boolean shouldNotify = tasks.isEmpty ();
232                 tasks.add (task);
233                 if (shouldNotify) {
234                     notifyAll();
235                 }
236             }
237         }
238         
239         /**
240          * Returns next URL from queue that was posted for displaying.
241          * This method blocks other processing until there is an request
242          */

243         private synchronized DisplayTask getNextTask() throws InterruptedException JavaDoc {
244             do {
245                 
246                 if (!tasks.isEmpty ()) {
247                     return (DisplayTask)tasks.remove(0);
248                 }
249                 wait();
250                 
251             } while (true);
252         }
253         
254         public void run() {
255             if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
256                 ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "NbDdeBrowserImpl.run"); // NOI18N
257
}
258             while (doProcessing) {
259                 try {
260                     /** url to be displayed */
261                     DisplayTask task = getNextTask ();
262                    
263                     isDisplaying = true;
264                     Timer JavaDoc timer = new Timer JavaDoc ();
265                     timer.schedule (new TimerTask JavaDoc () {
266                         public void run() {
267                             if (isDisplaying) {
268                                 NbDdeBrowserImpl.nativeThread.interrupt();
269                                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
270                                     ExtWebBrowser.getEM().log("interrupted in URLDisplayer.run.TimerTask.run()"); // NOI18N
271
}
272                                 DialogDisplayer.getDefault().notify(
273                                 new NotifyDescriptor.Message(NbBundle.getMessage(NbDdeBrowserImpl.class, "MSG_win_browser_invocation_failed"),
274                                 NotifyDescriptor.INFORMATION_MESSAGE)
275                                 );
276                             }
277                         }
278                     }, /*task.browser.extBrowserFactory.getBrowserStartTimeout() + */ADDITIONAL_WAIT_TIMEOUT);
279                     dispatchURL (task);
280                     timer.cancel();
281                 } catch (InterruptedException JavaDoc ex) {
282                     ExtWebBrowser.getEM().log("interrupted in run(): " + ex); // NOI18N
283
// do nothing
284
} finally {
285                     isDisplaying = false;
286                 }
287             }
288         }
289
290         public void dispatchURL (DisplayTask task) {
291             if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
292                 ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " NbDdeBrowserImpl.dispatchURL: " + task); // NOI18N
293
}
294             try {
295                 
296                 URL url = task.url;
297                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
298                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " URLDispatcher.url: " + url); // NOI18N
299
}
300                 
301                 // internal protocols cannot be displayed in external viewer
302
url = URLUtil.createExternalURL(url, URLUtil.browserHandlesJarURLs(task.browser.realDDEServer())); // XXX support Netscape too?
303

304                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
305                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " url: " + url); // NOI18N
306
}
307
308                 String JavaDoc urlStr = url.toString();
309                 
310                 boolean triedStart = false;
311                 final int MAX_URL_LENGTH = 199;
312                 
313                 if ((urlStr != null) && (urlStr.length() > MAX_URL_LENGTH)) {
314                      urlStr = getFileUrl(urlStr);
315                 }
316
317                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
318                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " urlstr: " + urlStr); // NOI18N
319
}
320                 if (!win9xHack(task.browser.realDDEServer())) {
321                     StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage (NbDdeBrowserImpl.class, "MSG_activatingBrowser"));
322                     try {
323                         task.browser.reqDdeMessage(task.browser.realDDEServer(),WWW_ACTIVATE,"-1,0x0",task.browser.getActivateTimeout());
324                     } catch (NbBrowserException ex) {
325                         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
326                             ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "Exception, gonna start browser: " + ex); // NOI18N
327
}
328                         triedStart = true;
329                         startBrowser(task.browser.extBrowserFactory.getBrowserExecutable(), urlStr);
330                     }
331                 }
332                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
333                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " firstpart"); // NOI18N
334
}
335
336                 if (!triedStart) {
337                     StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(NbDdeBrowserImpl.class, "MSG_openingURLInBrowser", urlStr));
338                     String JavaDoc args1 = "\""+urlStr+"\",,-1,0x1,,,"; // NOI18N
339

340                     try {
341                         Thread.sleep(500); // trying hack for bug #42438 - Browser executes twice which is a Mozilla bug
342
task.browser.reqDdeMessage(task.browser.realDDEServer(),WWW_OPEN_URL,args1,task.browser.getOpenUrlTimeout());
343                     } catch (NbBrowserException ex) {
344                         if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
345                             ExtWebBrowser.getEM().log("Restarting browser."); // NOI18N
346
}
347                         startBrowser(task.browser.extBrowserFactory.getBrowserExecutable(), urlStr);
348                     } catch (InterruptedException JavaDoc ex) {
349                         // just ignore
350
}
351                 }
352                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
353                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " secondpart"); // NOI18N
354
}
355
356                 URL oldUrl = task.browser.url;
357                 task.browser.url = url;
358                 task.browser.pcs.firePropertyChange(PROP_URL, oldUrl, url);
359
360             } catch (Exception JavaDoc ex) {
361                 final Exception JavaDoc ex1 = ex;
362                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
363                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + " Interrupted in URLDisplayer.dispatchURL.end"); // NOI18N
364
}
365                 ErrorManager.getDefault ().annotate(ex1, NbBundle.getMessage(NbDdeBrowserImpl.class, "MSG_win_browser_invocation_failed"));
366                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
367                     public void run() {
368                         ErrorManager.getDefault ().notify (ex1);
369                     }
370                 });
371             }
372         }
373         
374         
375         /**
376          *
377          */

378         private String JavaDoc getFileUrl(String JavaDoc url) {
379             if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
380                 ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "Gonna get redirect file for long url: " + url);
381             }
382             String JavaDoc newurl = null;
383             FileWriter JavaDoc fw = null;
384             File JavaDoc f = null;
385             
386             int retries = 10;
387             
388             while ((f == null) && (retries > 0)) {
389                 retries--;
390                 try {
391                     f = File.createTempFile("extbrowser", ".html"); // NOI18N
392
if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
393                         ExtWebBrowser.getEM().log("file: " + f); // NOI18N
394
}
395                     if (f != null) {
396                         fw = new FileWriter JavaDoc(f);
397                         if (f.canWrite()) {
398                             String JavaDoc s1 = org.openide.util.NbBundle.getMessage(NbDdeBrowserImpl.class, "TXT_RedirectURL1"); //NOI18N
399
String JavaDoc s2 = org.openide.util.NbBundle.getMessage(NbDdeBrowserImpl.class, "TXT_RedirectURL2"); //NOI18N
400
String JavaDoc s = s1.concat(url).concat(s2);
401                             fw.write(s);
402                             fw.flush();
403                         }
404                         newurl = "file:/" + f.getAbsolutePath(); // NOI18N
405
}
406                 } catch (IOException JavaDoc ioe) {
407                      ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "" + System.currentTimeMillis() + ioe.toString());
408                 } finally {
409                     if (fw != null) {
410                         try {
411                             fw.close();
412                         } catch (IOException JavaDoc ioe) {
413                             ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "" + System.currentTimeMillis() + ioe.toString());
414                         }
415                     }
416                 }
417             }
418             if (newurl != null) {
419                 if (ExtWebBrowser.getEM().isLoggable(ErrorManager.INFORMATIONAL)) {
420                     ExtWebBrowser.getEM().log("" + System.currentTimeMillis() + "New URL: " + newurl); // NOI18N
421
}
422                 return newurl;
423             }
424             return url;
425         }
426         
427         /**
428          * Checks for IExplorer & Win9x combination.
429          */

430         private boolean win9xHack (String JavaDoc browser) {
431             return browser.equals(ExtWebBrowser.IEXPLORE)
432                    && (Utilities.getOperatingSystem() == Utilities.OS_WIN98
433                       || Utilities.getOperatingSystem() == Utilities.OS_WIN95);
434         }
435
436         /**
437          * Utility function that tries to start new browser process.
438          *
439          * It is used when WWW_Activate or WWW_OpenURL fail
440          */

441         private void startBrowser(NbProcessDescriptor cmd, String JavaDoc url) throws java.io.IOException JavaDoc {
442             StatusDisplayer.getDefault ().setStatusText (NbBundle.getMessage(NbDdeBrowserImpl.class, "MSG_startingBrowser", url));
443             cmd.exec(new ExtWebBrowser.UnixBrowserFormat(url));
444         }
445     }
446
447     /** Encapsulating class for URL and browser that asks for its displaying */
448     private static class DisplayTask {
449         URL url;
450         NbDdeBrowserImpl browser;
451         
452         DisplayTask (URL url, NbDdeBrowserImpl browser) {
453             this.url = url;
454             this.browser = browser;
455         }
456     }
457 }
458
Popular Tags