KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > NbTopManager


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.core;
21
22 import java.awt.Dialog JavaDoc;
23 import java.awt.Toolkit JavaDoc;
24 import java.awt.Window JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.lang.reflect.Method JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.text.MessageFormat JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34 import java.util.prefs.PreferenceChangeEvent JavaDoc;
35 import java.util.prefs.PreferenceChangeListener JavaDoc;
36 import javax.swing.JDialog JavaDoc;
37 import javax.swing.SwingUtilities JavaDoc;
38 import javax.swing.event.ChangeEvent JavaDoc;
39 import javax.swing.event.ChangeListener JavaDoc;
40 import org.netbeans.TopSecurityManager;
41 import org.netbeans.core.startup.MainLookup;
42 import org.netbeans.core.startup.ModuleSystem;
43 import org.netbeans.core.startup.layers.SessionManager;
44 import org.netbeans.core.ui.SwingBrowser;
45 import org.openide.LifecycleManager;
46 import org.openide.NotifyDescriptor;
47 import org.openide.awt.HtmlBrowser;
48 import org.openide.cookies.SaveCookie;
49 import org.openide.loaders.DataObject;
50 import org.openide.util.Exceptions;
51 import org.openide.util.HelpCtx;
52 import org.openide.util.Lookup;
53 import org.openide.util.LookupEvent;
54 import org.openide.util.LookupListener;
55 import org.openide.util.Mutex;
56 import org.openide.util.NbBundle;
57 import org.openide.util.RequestProcessor;
58 import org.openide.util.Task;
59 import org.openide.util.lookup.InstanceContent;
60 import org.openide.windows.Mode;
61 import org.openide.windows.TopComponent;
62 import org.openide.windows.WindowManager;
63
64 /**
65  * Main switchboard for the NetBeans core.
66  * Manages startup sequence, holds references to important objects, etc.
67  */

68 public abstract class NbTopManager {
69     /* masks to define the interactivity level */
70
71     /** initialize the main window?
72     * if not set the main window is not create nor shown.
73     */

74     public static final int IL_MAIN_WINDOW = 0x0001;
75     /** initialize window system?
76     * if not set the selected node is taken from the top manager.
77     */

78     public static final int IL_WINDOWS = 0x0002;
79     /** initialize workspaces when not created?
80     */

81     public static final int IL_WORKSPACES = 0x0004;
82
83
84     /** Initialize everything.
85     */

86     public static final int IL_ALL = 0xffff;
87     
88     /** Constructs a new manager.
89     */

90     public NbTopManager() {
91         assert defaultTopManager == null : "Only one instance allowed"; // NOI18N
92
defaultTopManager = this;
93         
94         Lookup lookup = Lookup.getDefault();
95         if (!(lookup instanceof MainLookup)) {
96             throw new ClassCastException JavaDoc("Wrong Lookup impl found: " + lookup);
97         }
98         ((MainLookup)lookup).startedNbTopManager();
99     }
100
101     /** Getter for instance of this manager.
102     */

103     public static NbTopManager get () {
104         assert defaultTopManager != null : "Must be initialized already"; // NOI18N
105
return defaultTopManager;
106     }
107     
108     /** Danger method for clients who think they want an NbTM but don't actually
109      * care whether it is ready or not. Should be removed eventually by getting
110      * rid of useless protected methods in this class, and using Lookup to find
111      * each configurable piece of impl.
112      * @return a maybe half-constructed NbTM
113      */

114     public static NbTopManager getUninitialized() {
115         return get();
116     }
117         
118     private static NbTopManager defaultTopManager;
119
120     /**
121      * Checks whether the top manager has been loaded already.
122      * Used during early startup sequence.
123      */

124     public static synchronized boolean isInitialized () {
125         return defaultTopManager != null;
126     }
127     
128     /** Test method to check whether some level of interactivity is enabled.
129      * XXX this method is unused; can it be deleted?
130     * @param il mask composed of the constants of IL_XXXX
131     * @return true if such level is enabled
132     */

133     public abstract boolean isInteractive (int il);
134     
135     //
136
// The main method allows access to registration service
137
//
138

139     /** Register new instance.
140      */

141     public final void register (Object JavaDoc obj) {
142         MainLookup.register (obj);
143     }
144     
145     /** Register new instance.
146      * @param obj source
147      * @param conv convertor which postponing an instantiation
148      */

149     public final <T,R> void register(T obj, InstanceContent.Convertor<T,R> conv) {
150         MainLookup.register (obj, conv);
151     }
152     
153     /** Unregisters the service.
154      */

155     public final void unregister (Object JavaDoc obj) {
156         MainLookup.unregister (obj);
157     }
158     /** Unregisters the service registered with a convertor.
159      */

160     public final <T,R> void unregister (T obj, InstanceContent.Convertor<T,R> conv) {
161         MainLookup.unregister (obj, conv);
162     }
163     
164     
165     //
166
// Implementation of methods from TopManager
167
//
168

169     /** Shows a specified HelpCtx in IDE's help window.
170     * @param helpCtx thehelp to be shown
171      * @deprecated Better to use org.netbeans.api.javahelp.Help
172     */

173     public void showHelp(HelpCtx helpCtx) {
174         // Awkward but should work.
175
try {
176             Class JavaDoc<?> c = (Lookup.getDefault().lookup(ClassLoader JavaDoc.class)).loadClass("org.netbeans.api.javahelp.Help"); // NOI18N
177
Object JavaDoc o = Lookup.getDefault().lookup(c);
178             if (o != null) {
179                 Method JavaDoc m = c.getMethod("showHelp", new Class JavaDoc[] {HelpCtx.class}); // NOI18N
180
m.invoke(o, new Object JavaDoc[] {helpCtx});
181                 return;
182             }
183         } catch (ClassNotFoundException JavaDoc cnfe) {
184             // ignore - maybe javahelp module is not installed, not so strange
185
} catch (Exception JavaDoc e) {
186             // potentially more serious
187
Logger.getLogger(NbTopManager.class.getName()).log(Level.WARNING, null, e);
188         }
189         // Did not work.
190
Toolkit.getDefaultToolkit().beep();
191     }
192
193     /**
194      * Implementation of URL displayer, which shows documents in the configured web browser.
195      */

196     public static final class NbURLDisplayer extends HtmlBrowser.URLDisplayer {
197         /** Default constructor for lookup. */
198         public NbURLDisplayer() {}
199         /** WWW browser window. */
200         private NbBrowser htmlViewer;
201         public void showURL(final URL JavaDoc u) {
202             Mutex.EVENT.readAccess(new Runnable JavaDoc() {
203                 public void run() {
204                     if (htmlViewer == null) {
205                         htmlViewer = new NbBrowser();
206                     }
207                     htmlViewer.showUrl(u);
208                 }
209             });
210         }
211     }
212
213
214     /**
215      * Default status displayer implementation; GUI is in StatusLine.
216      */

217     public static final class NbStatusDisplayer extends org.openide.awt.StatusDisplayer {
218         /** Default constructor for lookup. */
219         public NbStatusDisplayer() {}
220         private List JavaDoc<ChangeListener JavaDoc> listeners = null;
221         private String JavaDoc text = ""; // NOI18N
222
public void setStatusText(String JavaDoc text) {
223             ChangeListener JavaDoc[] _listeners;
224             synchronized (this) {
225                 this.text = text;
226                 if (listeners == null || listeners.isEmpty()) {
227                     return;
228                 } else {
229                     _listeners = listeners.toArray(new ChangeListener JavaDoc[listeners.size()]);
230                 }
231             }
232             ChangeEvent JavaDoc e = new ChangeEvent JavaDoc(this);
233             for (int i = 0; i < _listeners.length; i++) {
234                 _listeners[i].stateChanged(e);
235             }
236             Logger.getLogger(NbStatusDisplayer.class.getName()).log(Level.FINE, "Status text updated: {0}", text);
237         }
238         public synchronized String JavaDoc getStatusText() {
239             return text;
240         }
241         public synchronized void addChangeListener(ChangeListener JavaDoc l) {
242             if (listeners == null) listeners = new ArrayList JavaDoc<ChangeListener JavaDoc>();
243             listeners.add(l);
244         }
245         public synchronized void removeChangeListener(ChangeListener JavaDoc l) {
246             listeners.remove(l);
247         }
248     }
249
250     /** saves all opened objects */
251     private static void saveAll () {
252         DataObject dobj = null;
253         ArrayList JavaDoc<DataObject> bad = new ArrayList JavaDoc<DataObject> ();
254         DataObject[] modifs = DataObject.getRegistry ().getModified ();
255         if (modifs.length == 0) {
256             // Do not show MSG_AllSaved
257
return;
258         }
259         for (int i = 0; i < modifs.length; i++) {
260             try {
261                 dobj = modifs[i];
262                 SaveCookie sc = (SaveCookie) dobj.getCookie(SaveCookie.class);
263
264                 if (sc != null) {
265                     org.openide.awt.StatusDisplayer.getDefault().setStatusText(
266                         MessageFormat.format(
267                             NbBundle.getBundle(NbTopManager.class).getString(
268                                 "CTL_FMT_SavingMessage"
269                             ), new Object JavaDoc[]{dobj.getName()}
270                     ));
271                     sc.save();
272                 }
273             }
274             catch (IOException JavaDoc ex) {
275                 Logger.getLogger(NbTopManager.class.getName()).log(Level.WARNING, null, ex);
276                 bad.add(dobj);
277             }
278         }
279         NotifyDescriptor descriptor;
280         //recode this part to show only one dialog?
281
Iterator JavaDoc<DataObject> ee = bad.iterator ();
282         while (ee.hasNext ()) {
283             descriptor = new NotifyDescriptor.Message(
284                         MessageFormat.format (
285                             NbBundle.getBundle (NbTopManager.class).getString("CTL_Cannot_save"),
286                             new Object JavaDoc[] { ee.next().getPrimaryFile().getName() }
287                         )
288                     );
289             org.openide.DialogDisplayer.getDefault().notify (descriptor);
290         }
291         // notify user that everything is done
292
org.openide.awt.StatusDisplayer.getDefault().setStatusText(
293             NbBundle.getBundle (NbTopManager.class).getString ("MSG_AllSaved"));
294     }
295     
296     /** Interface describing basic control over window system.
297      * @since 1.15 */

298     public interface WindowSystem {
299         void show();
300         void hide();
301         void load();
302         void save();
303         void clear();
304     } // End of WindowSystem interface.
305

306     public static boolean isModalDialogPresent() {
307         return hasModalDialog(WindowManager.getDefault().getMainWindow())
308             // XXX Trick to get the shared frame instance.
309
|| hasModalDialog(new JDialog JavaDoc().getOwner());
310     }
311     
312     private static boolean hasModalDialog(Window JavaDoc w) {
313         Window JavaDoc[] ws = w.getOwnedWindows();
314         for(int i = 0; i < ws.length; i++) {
315             if(ws[i] instanceof Dialog JavaDoc && ((Dialog JavaDoc)ws[i]).isModal()) {
316                 return true;
317             } else if(hasModalDialog(ws[i])) {
318                 return true;
319             }
320         }
321         
322         return false;
323     }
324
325
326     
327     private static boolean doingExit=false;
328     public static void exit ( ) {
329         // #37160 So there is avoided potential clash between hiding GUI in AWT
330
// and accessing AWTTreeLock from saving routines (winsys).
331
if(SwingUtilities.isEventDispatchThread()) {
332             doExit();
333         } else {
334             SwingUtilities.invokeLater(new Runnable JavaDoc() {
335                 public void run() {
336                     doExit();
337                 }
338             });
339         }
340     }
341     
342     /**
343      * @return True if the IDE is shutting down.
344      */

345     public static boolean isExiting() {
346         return doingExit;
347     }
348     
349     private static void doExit() {
350         if (doingExit) {
351             return ;
352         }
353         doingExit = true;
354         // save all open files
355
try {
356             if ( System.getProperty ("netbeans.close") != null || ExitDialog.showDialog() ) {
357      
358                 final WindowSystem windowSystem = Lookup.getDefault().lookup(WindowSystem.class);
359                 
360                 // #29831: hide frames between closing() and close()
361
Runnable JavaDoc hideFrames = new Runnable JavaDoc() {
362                     public void run() {
363                         org.netbeans.CLIHandler.stopServer ();
364                 
365                         if(windowSystem != null) {
366                             windowSystem.hide();
367                             windowSystem.save();
368                         }
369                         if (Boolean.getBoolean("netbeans.close.when.invisible")) {
370                             // hook to permit perf testing of time to *apparently* shut down
371
TopSecurityManager.exit(0);
372                         }
373                     }
374                 };
375                 
376                 if (org.netbeans.core.startup.Main.getModuleSystem().shutDown(hideFrames)) {
377                     try {
378                         try {
379                             LoaderPoolNode.store();
380                         } catch (IOException JavaDoc ioe) {
381                             Logger.getLogger(NbTopManager.class.getName()).log(Level.WARNING, null, ioe);
382                         }
383 //#46940 -saving just once..
384
// // save window system, [PENDING] remove this after the winsys will
385
// // persist its state automaticaly
386
// if (windowSystem != null) {
387
// windowSystem.save();
388
// }
389
try {
390                             ((MainLookup)Lookup.getDefault()).storeCache();
391                         } catch (IOException JavaDoc ioe) {
392                             Logger.getLogger(NbTopManager.class.getName()).log(Level.WARNING, null, ioe);
393                         }
394                         SessionManager.getDefault().close();
395                     } catch (ThreadDeath JavaDoc td) {
396                         throw td;
397                     } catch (Throwable JavaDoc t) {
398                         // Do not let problems here prevent system shutdown. The module
399
// system is down; the IDE cannot be used further.
400
Exceptions.printStackTrace(t);
401                     }
402                     // #37231 Someone (e.g. Jemmy) can install its own EventQueue and then
403
// exit is dispatched through that proprietary queue and it
404
// can be refused by security check. So, we need to replan
405
// to RequestProcessor to avoid security problems.
406
Task exitTask = new Task(new Runnable JavaDoc() {
407                         public void run() {
408                             TopSecurityManager.exit(0);
409                         }
410                     });
411                     RequestProcessor.getDefault().post(exitTask);
412                     exitTask.waitFinished();
413                 }
414             }
415         } finally {
416             doingExit = false;
417         }
418     }
419
420     /**
421      * Default implementation of the lifecycle manager interface that knows
422      * how to save all modified DataObject's, and to exit the IDE safely.
423      */

424     public static final class NbLifecycleManager extends LifecycleManager {
425         /** Default constructor for lookup. */
426         public NbLifecycleManager() {}
427         public void saveAll() {
428             NbTopManager.saveAll();
429         }
430         public void exit() {
431             NbTopManager.exit();
432         }
433     }
434
435     /** Get the module subsystem. */
436     public abstract ModuleSystem getModuleSystem();
437     
438     public static Lookup getModuleLookup() {
439         return org.netbeans.core.startup.Main.getModuleSystem().getManager().getModuleLookup();
440     }
441
442     public static List JavaDoc getModuleJars() {
443         return org.netbeans.core.startup.Main.getModuleSystem().getModuleJars();
444     }
445
446     /**
447      * Able to reuse HtmlBrowserComponent.
448      */

449     public static class NbBrowser {
450         
451         private HtmlBrowserComponent brComp;
452         private PreferenceChangeListener JavaDoc idePCL;
453         private static Lookup.Result factoryResult;
454         
455         static {
456             factoryResult = Lookup.getDefault().lookupResult(HtmlBrowser.Factory.class);
457             factoryResult.allItems();
458             factoryResult.addLookupListener(new LookupListener() {
459                 public void resultChanged(LookupEvent ev) {
460                     ((NbURLDisplayer)org.openide.awt.HtmlBrowser.URLDisplayer.getDefault()).htmlViewer = null;
461                 }
462             });
463         }
464         
465         public NbBrowser() {
466             HtmlBrowser.Factory browser = IDESettings.getWWWBrowser();
467             if (browser == null) {
468                 // Fallback.
469
browser = new SwingBrowser();
470             }
471             // try if an internal browser is set and possibly try to reuse an
472
// existing component
473
if (browser.createHtmlBrowserImpl().getComponent() != null) {
474                 brComp = findOpenedBrowserComponent();
475             }
476             if (brComp == null) {
477                 brComp = new HtmlBrowserComponent(browser, true, true);
478                 brComp.putClientProperty("TabPolicy", "HideWhenAlone"); // NOI18N
479
}
480             setListener();
481         }
482
483         /**
484          * Tries to find already opened <code>HtmlBrowserComponent</code>. In
485          * the case of success returns the instance, null otherwise.
486          */

487         private HtmlBrowserComponent findOpenedBrowserComponent() {
488             for (Iterator JavaDoc it = WindowManager.getDefault().getModes().iterator(); it.hasNext(); ) {
489                 Mode m = (Mode) it.next();
490                 if ("editor".equals(m.getName())) { // NOI18N
491
TopComponent[] tcs = m.getTopComponents();
492                     for (int i = 0; i < tcs.length; i++) {
493                         if (tcs[i] instanceof HtmlBrowserComponent) {
494                             return (HtmlBrowserComponent) tcs[i];
495                         }
496                     }
497                     break;
498                 }
499             }
500             return null;
501         }
502
503         /** Show URL in browser
504          * @param url URL to be shown
505          */

506         private void showUrl(URL JavaDoc url) {
507             brComp.open();
508             brComp.requestActive();
509             brComp.setURL(url);
510         }
511
512         /**
513          * Sets listener that invalidates this as main IDE's browser if user changes the settings
514          */

515         private void setListener () {
516             if (idePCL != null) {
517                 return;
518             }
519             try {
520                 // listen on preffered browser change
521
idePCL = new PreferenceChangeListener JavaDoc() {
522                     public void preferenceChange(PreferenceChangeEvent JavaDoc evt) {
523                         if (IDESettings.PROP_WWWBROWSER.equals(evt.getKey())) {
524                             ((NbURLDisplayer) HtmlBrowser.URLDisplayer.getDefault()).htmlViewer = null;
525                             if (idePCL != null) {
526                                 IDESettings.getPreferences().removePreferenceChangeListener(idePCL);
527                                 idePCL = null;
528                                 brComp = null;
529                             }
530                         }
531                     }
532                 };
533                 IDESettings.getPreferences().addPreferenceChangeListener(idePCL);
534             }
535             catch (Exception JavaDoc ex) {
536                 Exceptions.printStackTrace(ex);
537             }
538         }
539     }
540 }
541
Popular Tags