KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > execution > Install


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.execution;
21
22 import java.awt.Dialog JavaDoc;
23 import java.awt.Dimension JavaDoc;
24 import java.awt.GridBagConstraints JavaDoc;
25 import java.awt.GridBagLayout JavaDoc;
26 import java.awt.Image JavaDoc;
27 import java.awt.Insets JavaDoc;
28 import java.awt.event.ActionEvent JavaDoc;
29 import java.awt.event.ActionListener JavaDoc;
30 import java.awt.event.WindowAdapter JavaDoc;
31 import java.beans.Introspector JavaDoc;
32 import java.beans.PropertyChangeEvent JavaDoc;
33 import java.beans.PropertyChangeListener JavaDoc;
34 import java.beans.PropertyEditorManager JavaDoc;
35 import java.util.ArrayList JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.Collections JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import javax.swing.Action JavaDoc;
41 import javax.swing.ActionMap JavaDoc;
42 import javax.swing.Icon JavaDoc;
43 import javax.swing.JButton JavaDoc;
44 import javax.swing.JLabel JavaDoc;
45 import javax.swing.JPanel JavaDoc;
46 import javax.swing.UIManager JavaDoc;
47 import javax.swing.event.ListDataEvent JavaDoc;
48 import javax.swing.event.ListDataListener JavaDoc;
49 import javax.swing.text.DefaultEditorKit JavaDoc;
50 import org.netbeans.TopSecurityManager;
51 import org.netbeans.progress.module.Controller;
52 import org.netbeans.progress.spi.InternalHandle;
53 import org.openide.DialogDescriptor;
54 import org.openide.DialogDisplayer;
55 import org.openide.awt.Mnemonics;
56 import org.openide.execution.ExecutorTask;
57 import org.openide.explorer.ExplorerManager;
58 import org.openide.explorer.ExplorerUtils;
59 import org.openide.explorer.view.ListView;
60 import org.openide.modules.ModuleInstall;
61 import org.openide.nodes.AbstractNode;
62 import org.openide.nodes.Children;
63 import org.openide.nodes.Node;
64 import org.openide.nodes.NodeEvent;
65 import org.openide.nodes.NodeListener;
66 import org.openide.nodes.NodeMemberEvent;
67 import org.openide.nodes.NodeReorderEvent;
68 import org.openide.util.Lookup;
69 import org.openide.util.Mutex;
70 import org.openide.util.NbBundle;
71 import org.openide.util.Utilities;
72 import org.openide.util.actions.SystemAction;
73
74 /**
75  * Registers security manager for execution.
76  * Also shows Pending Tasks dialog at shutdown time.
77  * Also adds/removes specific beaninfo and property editor search paths.
78  * @author Jesse Glick
79  */

80 public class Install extends ModuleInstall {
81     
82     private static final String JavaDoc BEANINFO_PATH
83             = "org.netbeans.core.execution.beaninfo"; // NOI18N
84
private static final String JavaDoc EDITOR_PATH
85             = "org.netbeans.core.execution.beaninfo.editors"; // NOI18N
86

87     public void restored() {
88         TopSecurityManager.register(SecMan.DEFAULT);
89         
90         // Add beaninfo search path.
91
String JavaDoc[] sp = Introspector.getBeanInfoSearchPath();
92         java.util.List JavaDoc<String JavaDoc> paths = Arrays.asList(sp);
93         if(!paths.contains(BEANINFO_PATH)) {
94             paths = new ArrayList JavaDoc<String JavaDoc>(paths);
95             paths.add(BEANINFO_PATH);
96             Introspector.setBeanInfoSearchPath(
97                     paths.toArray(new String JavaDoc[0]));
98         }
99         
100         // Add property editor search path.
101
sp = PropertyEditorManager.getEditorSearchPath();
102         paths = Arrays.asList(sp);
103         if(!paths.contains(EDITOR_PATH)) {
104             paths = new ArrayList JavaDoc<String JavaDoc>(paths);
105             paths.add(EDITOR_PATH);
106             PropertyEditorManager.setEditorSearchPath(
107                     paths.toArray(new String JavaDoc[0]));
108         }
109     }
110     
111     public void uninstalled() {
112         showPendingTasks();
113         
114         TopSecurityManager.unregister(SecMan.DEFAULT);
115         
116         // Remove beaninfo search path.
117
String JavaDoc[] sp = Introspector.getBeanInfoSearchPath();
118         java.util.List JavaDoc<String JavaDoc> paths = Arrays.asList(sp);
119         if(paths.contains(BEANINFO_PATH)) {
120             paths = new ArrayList JavaDoc<String JavaDoc>(paths);
121             paths.remove(BEANINFO_PATH);
122             Introspector.setBeanInfoSearchPath(
123                     paths.toArray(new String JavaDoc[0]));
124         }
125         
126         // Remove property editor seach path.
127
sp = PropertyEditorManager.getEditorSearchPath();
128         paths = Arrays.asList(sp);
129         if(paths.contains(EDITOR_PATH)) {
130             paths = new ArrayList JavaDoc<String JavaDoc>(paths);
131             paths.remove(EDITOR_PATH);
132             PropertyEditorManager.setEditorSearchPath(
133                     paths.toArray(new String JavaDoc[0]));
134         }
135     }
136     
137     public boolean closing() {
138         return showPendingTasks();
139     }
140     
141     /** A class that server as a pending dialog manager.
142      * It closes the dialog if there are no more pending tasks
143      * and also servers as the action listener for killing the tasks.
144      */

145     private static class PendingDialogCloser extends WindowAdapter JavaDoc implements Runnable JavaDoc,
146             PropertyChangeListener JavaDoc, ActionListener JavaDoc, NodeListener {
147         private Dialog JavaDoc[] dialogHolder;
148         private Object JavaDoc exitOption;
149         PendingDialogCloser(Dialog JavaDoc[] holder, Object JavaDoc exit) {
150             dialogHolder = holder;
151             exitOption = exit;
152         }
153         
154         public void run() {
155             dialogHolder[0].setVisible(false);
156         }
157         
158         // Beware: this may be called also from rootNode's prop changes
159
// Once all pending tasks are gone, close the dialog.
160
public void propertyChange(PropertyChangeEvent JavaDoc evt) {
161             if(ExplorerManager.PROP_EXPLORED_CONTEXT.equals(evt.getPropertyName())) {
162                 checkClose();
163             }
164         }
165         
166         // kill pending tasks and close the dialog
167
public void actionPerformed(ActionEvent JavaDoc evt) {
168             if(evt.getSource() == exitOption) {
169                 killPendingTasks();
170                 Mutex.EVENT.readAccess(this); // close in AWT
171
}
172         }
173         
174         public void childrenRemoved(NodeMemberEvent evt) {
175             checkClose();
176         }
177         
178         // Dialog was opened but pending tasks could disappear inbetween.
179
public void windowOpened(java.awt.event.WindowEvent JavaDoc evt) {
180             checkClose();
181         }
182         
183         /** Checks if there are pending tasks and closes (in AWT)
184          * the dialog if not. */

185         private void checkClose() {
186             if(dialogHolder[0] != null && getPendingTasks().isEmpty()) {
187                 Mutex.EVENT.readAccess(this);
188             }
189         }
190         
191         // noop - rest of node listener
192
public void childrenAdded(NodeMemberEvent ev) {}
193         public void childrenReordered(NodeReorderEvent ev) {}
194         public void nodeDestroyed(NodeEvent ev) {}
195         
196     }
197     
198     // Remainder moved from ExitDialog:
199

200     /** Shows dialog which waits for finishing of pending tasks,
201      * (currently actions only) and offers to user to leave IDE
202      * immediatelly interrupting those tasks.
203      * @return <code>true</code> if to continue with the action
204      * <code>false</code> if the action to cancel
205      */

206     private static boolean showPendingTasks() {
207         // Avoid showing the tasks in the dialog when either running internal tests
208
if (Boolean.getBoolean("netbeans.full.hack") // NOI18N
209
// or there are no pending tasks.
210
|| getPendingTasks().isEmpty()) {
211             return true;
212         }
213         
214         EM panel = new EM();
215         
216         Dialog JavaDoc[] dialog = new Dialog JavaDoc[1];
217         Node root = new AbstractNode(new PendingChildren());
218         
219         
220         JButton JavaDoc exitOption = new JButton JavaDoc();
221         Mnemonics.setLocalizedText(exitOption, NbBundle.getMessage(Install.class, "LAB_EndTasks"));
222         // No default button.
223
// exitOption.setDefaultCapable(false);
224
exitOption.getAccessibleContext().setAccessibleDescription(
225                 NbBundle.getMessage(Install.class, "ACSD_EndTasks"));
226         
227         PendingDialogCloser closer = new PendingDialogCloser(dialog, exitOption);
228         
229         panel.getExplorerManager().setRootContext(root);
230         // closer will autoclose the dialog if all pending tasks finish
231
panel.getExplorerManager().addPropertyChangeListener(closer);
232         
233         DialogDescriptor dd = new DialogDescriptor(
234                 panel,
235                 NbBundle.getMessage(Install.class, "CTL_PendingTitle"),
236                 true, // modal
237
new Object JavaDoc[] {
238             exitOption,
239             DialogDescriptor.CANCEL_OPTION
240         },
241                 exitOption,
242                 DialogDescriptor.DEFAULT_ALIGN,
243                 null,
244                 closer
245                 );
246         // #33135 - no Help button for this dialog
247
dd.setHelpCtx(null);
248         
249         if(!getPendingTasks().isEmpty()) {
250             root.addNodeListener(closer);
251             
252             dialog[0] = DialogDisplayer.getDefault().createDialog(dd);
253             
254             dialog[0].addWindowListener(closer);
255             
256             dialog[0].setVisible(true);
257             dialog[0].dispose();
258             
259             if(dd.getValue() == DialogDescriptor.CANCEL_OPTION
260                     || dd.getValue() == DialogDescriptor.CLOSED_OPTION) {
261                 return false;
262             }
263             
264         }
265         
266         return true;
267     }
268     
269     private static class EM extends JPanel JavaDoc implements ExplorerManager.Provider {
270         private ExplorerManager manager = new ExplorerManager();
271         private org.openide.util.Lookup lookup;
272         
273         public EM() {
274             manager = new ExplorerManager();
275             ActionMap JavaDoc map = getActionMap();
276             map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(manager));
277             map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(manager));
278             map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(manager));
279             map.put("delete", ExplorerUtils.actionDelete(manager, true)); // or false
280

281             lookup = ExplorerUtils.createLookup(manager, map);
282             
283             initComponent();
284         }
285         
286         private void initComponent() {
287             setLayout(new GridBagLayout JavaDoc());
288             
289             GridBagConstraints JavaDoc cons = new GridBagConstraints JavaDoc();
290             cons.gridx = 0;
291             cons.gridy = 0;
292             cons.weightx = 1.0D;
293             cons.fill = GridBagConstraints.HORIZONTAL;
294             cons.insets = new Insets JavaDoc(11, 11, 0, 12);
295             
296             JLabel JavaDoc label = new JLabel JavaDoc();
297             Mnemonics.setLocalizedText(label, NbBundle.getMessage(Install.class, "LAB_PendingTasks"));
298             
299             add(label, cons);
300             
301             cons.gridy = 1;
302             cons.weighty = 1.0D;
303             cons.fill = GridBagConstraints.BOTH;
304             cons.insets = new Insets JavaDoc(2, 11, 0, 12);
305             
306             ListView view = new ListView();
307             //#66881
308
view.setBorder(UIManager.getBorder("Nb.ScrollPane.border"));
309             label.setLabelFor(view);
310             
311             add(view, cons);
312             
313             view.getAccessibleContext().setAccessibleDescription(
314                     NbBundle.getMessage(Install.class, "ACSD_PendingTasks"));
315             getAccessibleContext().setAccessibleDescription(
316                     NbBundle.getMessage(Install.class, "ACSD_PendingTitle"));
317             
318             // set size requested by HIE guys
319
Dimension JavaDoc origSize = getPreferredSize();
320             setPreferredSize(new Dimension JavaDoc(origSize.width * 5 / 4, origSize.height));
321         }
322         
323         public ExplorerManager getExplorerManager() {
324             return manager;
325         }
326         public Lookup getLookup() {
327             return lookup;
328         }
329         public void addNotify() {
330             super.addNotify();
331             ExplorerUtils.activateActions(manager, true);
332         }
333         public void removeNotify() {
334             ExplorerUtils.activateActions(manager, false);
335             super.removeNotify();
336         }
337     }
338     
339     /** Gets pending (running) tasks. Used as keys
340      * for pending dialog root node children. Currently it gets pending
341      * actions only. */

342     static Collection JavaDoc<?> getPendingTasks() {
343
344         ArrayList JavaDoc<Object JavaDoc> pendingTasks = new ArrayList JavaDoc<Object JavaDoc>( 10 ); // Action | ExecutorTask | InternalHandle
345
// XXX no access to running actions at the moment
346
//pendingTasks.addAll(CallableSystemAction.getRunningActions());
347
pendingTasks.addAll(org.netbeans.core.ModuleActions.getDefaultInstance().getRunningActions());
348         
349         ExecutionEngine ee = ExecutionEngine.getExecutionEngine();
350         if (ee != null) {
351             pendingTasks.addAll(ee.getRunningTasks());
352         }
353         
354         pendingTasks.addAll(Arrays.asList(Controller.getDefault().getModel().getHandles()));
355         
356         // [PENDING] When it'll be added another types of tasks (locks etc.)
357
// add them here to the list. Then you need to create also a nodes
358
// for them in PendingChildren.createNodes.
359

360         return pendingTasks;
361     }
362     
363     /** Ends penidng tasks. */
364     private static void killPendingTasks() {
365         // XXX
366
//CallableSystemAction.killRunningActions();
367
killRunningExecutors();
368         
369         // [PENDING] When it'll be added another types of tasks (locks etc.)
370
// kill them here.
371
}
372     
373     /** Tries to kill running executions */
374     private static void killRunningExecutors() {
375         ExecutionEngine ee = ExecutionEngine.getExecutionEngine();
376         if (ee == null) {
377             return;
378         }
379         ArrayList JavaDoc<ExecutorTask> tasks = new ArrayList JavaDoc<ExecutorTask>(ee.getRunningTasks());
380
381         for ( Iterator JavaDoc<ExecutorTask> it = tasks.iterator(); it.hasNext(); ) {
382             ExecutorTask et = it.next();
383             if ( !et.isFinished() ) {
384                 et.stop();
385             }
386         }
387         
388     }
389     
390     /** Children showing pending tasks. */
391     /* non private because of tests - was private before */
392     static class PendingChildren extends Children.Keys<Object JavaDoc /* Action|ExecutorTask|InternalHandle*/>
393             implements ExecutionListener, ListDataListener JavaDoc {
394         
395         /** Listens on changes of sources from getting the tasks from.
396          * Currently on module actions only. */

397         // private PropertyChangeListener propertyListener;
398

399         
400         /** Constructs new children. */
401         public PendingChildren() {
402             /* XXX no equiv yet in CallableSystemAction
403             propertyListener = new PropertyChangeListener() {
404                 public void propertyChange(PropertyChangeEvent evt) {
405                     if (ModuleActions.PROP_RUNNING_ACTIONS.equals(evt.getPropertyName())) {
406                         setKeys(getPendingTasks());
407                     }
408                 }
409             };
410              
411             ModuleActions.getDefault().addPropertyChangeListener(
412                 org.openide.util.WeakListeners.propertyChange (propertyListener, ModuleActions.getDefault())
413             );
414              */

415             
416             ExecutionEngine ee = ExecutionEngine.getExecutionEngine();
417             if (ee != null) {
418                 ee.addExecutionListener(this);
419             }
420             Controller.getDefault().getModel().addListDataListener(this);
421         }
422         
423         /** Implements superclass abstract method. Creates nodes from key.
424          * @return <code>PendingActionNode</code> if key is of
425          * <code>Action</code> type otherwise <code>null</code> */

426         protected Node[] createNodes(Object JavaDoc key) {
427             Node n = null;
428             if(key instanceof Action JavaDoc) {
429                 Action JavaDoc action = (Action JavaDoc)key;
430                 Icon JavaDoc icon = (action instanceof SystemAction) ?
431                     ((SystemAction)action).getIcon() : null;
432                 
433                 String JavaDoc actionName = (String JavaDoc)action.getValue(Action.NAME);
434                 if (actionName == null) actionName = ""; // NOI18N
435
actionName = org.openide.awt.Actions.cutAmpersand(actionName);
436                 n = new NoActionNode(icon, actionName, NbBundle.getMessage(
437                         Install.class, "CTL_ActionInProgress", actionName));
438             } else if (key instanceof ExecutorTask) {
439                 n = new NoActionNode(null, key.toString(),
440                         NbBundle.getMessage(Install.class, "CTL_PendingExternalProcess2",
441                         // getExecutionEngine() had better be non-null, since getPendingTasks gave an ExecutorTask:
442
ExecutionEngine.getExecutionEngine().getRunningTaskName((ExecutorTask) key))
443                         );
444             } else if (key instanceof InternalHandle) {
445                 n = new NoActionNode(null, ((InternalHandle)key).getDisplayName(), null);
446             }
447             return n == null ? null : new Node[] { n };
448         }
449         
450         /** Implements superclass abstract method. */
451         protected void addNotify() {
452             setKeys(getPendingTasks());
453             super.addNotify();
454         }
455         
456         /** Implements superclass abstract method. */
457         protected void removeNotify() {
458             setKeys(Collections.emptySet());
459             super.removeNotify();
460             ExecutionEngine ee = ExecutionEngine.getExecutionEngine();
461             if (ee != null) {
462                 ee.removeExecutionListener(this);
463             }
464             Controller.getDefault().getModel().removeListDataListener(this);
465         }
466         
467         // ExecutionListener implementation ------------------------------------
468

469         public void startedExecution( ExecutionEvent ev ) {
470             setKeys(getPendingTasks());
471         }
472         
473         public void finishedExecution( ExecutionEvent ev ) {
474             setKeys(getPendingTasks());
475         }
476         
477         public void intervalAdded(ListDataEvent JavaDoc e) {
478             setKeys(getPendingTasks());
479         }
480         
481         public void intervalRemoved(ListDataEvent JavaDoc e) {
482             setKeys(getPendingTasks());
483         }
484         
485         
486         public void contentsChanged(ListDataEvent JavaDoc e) {
487             setKeys(getPendingTasks());
488         }
489         
490     } // End of class PendingChildren.
491

492     /** Node without any actions. */
493     private static class NoActionNode extends AbstractNode {
494         private Image JavaDoc img;
495         
496         /** Creates node for action. */
497         public NoActionNode(Icon JavaDoc icon, String JavaDoc name, String JavaDoc display) {
498             super(Children.LEAF);
499             if (icon != null) img = Utilities.icon2Image(icon);
500             
501             setName(name);
502             if (display != null) setDisplayName(display);
503         }
504         
505         /** @return empty array of actions */
506         public Action JavaDoc[] getActions(boolean context) {
507             return new Action JavaDoc[0];
508         }
509         
510         /** @return provided icon or delegate to superclass if no icon provided.
511          */

512         public Image JavaDoc getIcon(int type) {
513             return img == null ? super.getIcon(type) : img;
514         }
515     }
516 }
517
Popular Tags