KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > actions > FileSystemAction


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.openide.actions;
21
22
23 import java.awt.event.ActionEvent JavaDoc;
24 import java.beans.*;
25 import java.util.*;
26 import javax.swing.*;
27 import org.openide.awt.JInlineMenu;
28 import org.openide.filesystems.*;
29 import org.openide.loaders.*;
30 import org.openide.nodes.Node;
31 import org.openide.util.*;
32 import org.openide.util.actions.*;
33 import org.openide.util.lookup.*;
34 import org.openide.windows.TopComponent;
35 import org.openide.windows.WindowManager;
36
37 /** Action that presents standard file system-related actions.
38 * Listens until a node representing a {@link DataObject}
39 * is selected and then retrieves {@link SystemAction}s from its
40 * {@link FileSystem}.
41 *
42 * @author Jaroslav Tulach
43 */

44 public class FileSystemAction extends SystemAction
45 implements ContextAwareAction, Presenter.Menu, Presenter.Popup {
46     /** empty array of menu items */
47     static JMenuItem[] NONE = new JMenuItem[] {};
48
49     /** computes the nodes.
50      */

51     private static Node[] nodes (Lookup lookup) {
52         Collection<? extends Node> c;
53
54         if (lookup != null) {
55             c = lookup.lookupAll(Node.class);
56         } else {
57             c = Collections.emptyList();
58         }
59         return c.toArray(new Node[c.size()]);
60     }
61
62     /** Creates menu for currently selected nodes.
63     * @param popUp create popup or normal menu
64     * @param n nodes to work with or null
65     */

66     static JMenuItem[] createMenu (boolean popUp, Lookup lookup) {
67         Node[] n = nodes (lookup);
68         
69         if (n == null) {
70             n = WindowManager.getDefault ().getRegistry ().getActivatedNodes ();
71         }
72         
73         
74         Map<FileSystem,Set<FileObject>> fsSet = new HashMap<FileSystem,Set<FileObject>>();
75
76         if (n != null) {
77             for (Node node : n) {
78                 DataObject obj = node.getCookie(DataObject.class);
79                  while (obj instanceof DataShadow)
80                      obj = ((DataShadow) obj).getOriginal();
81                  if (obj != null) {
82                      try {
83                          FileSystem fs = obj.getPrimaryFile ().getFileSystem ();
84                          Set<FileObject> foSet = fsSet.get(fs);
85                          if (foSet == null ) {
86                              fsSet.put(fs, foSet = new LinkedHashSet<FileObject>());
87                          }
88                          foSet.addAll(obj.files ());
89                      } catch (FileStateInvalidException ex) {continue;}
90                  }
91             }
92             /* At present not allowed to construct actions for selected nodes on more filesystems - its safe behaviour
93              * If this restriction will be considered as right solution, then code of this method can be simplified
94              */

95             if (fsSet.size () == 0 || fsSet.size() > 1) {
96                 return createMenu(Enumerations.<Action>empty(), popUp, lookup);
97             }
98             
99             List<SystemAction> result = new LinkedList<SystemAction>();
100             Set<FileObject> backSet = new LinkedHashSet<FileObject>();
101             for (Map.Entry<FileSystem,Set<FileObject>> entry : fsSet.entrySet()) {
102
103                 FileSystem fs = entry.getKey();
104                 Set<FileObject> foSet = entry.getValue();
105                 List<FileObject> backupList = new LinkedList<FileObject>(foSet);
106                 Iterator<FileObject> it = backupList.iterator ();
107                 while (it.hasNext ()) {
108                     FileObject fo = it.next ();
109                     try {
110                         if (fo.getFileSystem () != fs) {
111                             it.remove ();
112                         }
113                     } catch (FileStateInvalidException ex) {
114                         it.remove ();
115                     }
116                 }
117                 backSet.addAll(backupList);
118                 result.addAll(Arrays.asList(fs.getActions (backSet)));
119             }
120             
121             
122             return createMenu (Collections.enumeration (result), popUp, createProxyLookup(lookup, backSet)/*lookup*/);
123         }
124         return NONE;
125     }
126
127     private static ProxyLookup createProxyLookup(final Lookup lookup, final Set<FileObject> backSet) {
128         return new ProxyLookup(lookup, Lookups.fixed((Object JavaDoc[])backSet.toArray(new FileObject [backSet.size()])));
129     }
130
131     /** Creates list of menu items that should be used for given
132     * data object.
133     * @param en enumeration of SystemAction that should be added
134     * into the menu if enabled and if not duplicated
135     */

136     static JMenuItem[] createMenu(Enumeration<? extends Action> en, boolean popUp, Lookup lookup) {
137         en = Enumerations.removeDuplicates (en);
138
139         List<JMenuItem> items = new ArrayList<JMenuItem>();
140         while (en.hasMoreElements ()) {
141             Action a = en.nextElement();
142             
143             // Retrieve context sensitive action instance if possible.
144
if(lookup != null && a instanceof ContextAwareAction) {
145                 a = ((ContextAwareAction)a).createContextAwareInstance(lookup);
146             }
147             
148             boolean enabled = false;
149             try {
150                 enabled = a.isEnabled();
151             } catch (RuntimeException JavaDoc e) {
152                 Exceptions.attachMessage(e,
153                                          "Guilty action: " +
154                                          a.getClass().getName()); // NOI18N
155
Exceptions.printStackTrace(e);
156             }
157             if (enabled) {
158                 JMenuItem item = null;
159                 if (popUp) {
160                     if (a instanceof Presenter.Popup) {
161                         item = ((Presenter.Popup)a).getPopupPresenter ();
162                     }
163                 } else {
164                     if (a instanceof Presenter.Menu) {
165                         item = ((Presenter.Menu)a).getMenuPresenter ();
166                     }
167                 }
168                 // test if we obtained the item
169
if (item != null) {
170                     items.add (item);
171                 }
172             }
173         }
174         JMenuItem[] array = new JMenuItem [items.size ()];
175         items.toArray (array);
176         return array;
177     }
178
179     public JMenuItem getMenuPresenter () {
180         return new Menu (false, null);
181     }
182
183     public JMenuItem getPopupPresenter () {
184         return new Menu (true, null);
185     }
186
187     public String JavaDoc getName () {
188         return NbBundle.getMessage(DataObject.class, "ACT_FileSystemAction");
189     }
190
191     public HelpCtx getHelpCtx () {
192         return new HelpCtx (FileSystemAction.class);
193     }
194
195     /* Do nothing.
196     * This action itself does nothing, it only presents other actions.
197     * @param ev ignored
198     */

199     public void actionPerformed(ActionEvent JavaDoc e) {
200         assert false : "ActionEvt: " + e;
201     }
202     
203     /** Implements <code>ContextAwareAction</code> interface method. */
204     public Action createContextAwareInstance(Lookup actionContext) {
205         return new DelegateAction(actionContext);
206     }
207     
208
209     /** Presenter for this action.
210     */

211     private static class Menu extends JInlineMenu implements PropertyChangeListener {
212         /** menu presenter (true) or popup presenter (false) */
213         private boolean popup;
214         /** last registered items */
215         private JMenuItem[] last = NONE;
216         /** context for actions or null */
217         private Lookup lookup;
218
219         static final long serialVersionUID =2650151487189209766L;
220
221         /** Creates new instance for menu/popup presenter.
222         * @param popup true if this should represent popup
223         * @param arr nodes to work with or null if global one should be used
224         */

225         Menu (boolean popup, Lookup lookup) {
226             this.popup = popup;
227             this.lookup = lookup;
228             
229             changeMenuItems (createMenu (popup, lookup));
230
231             if (lookup == null) {
232                 // listen only when nodes not provided
233
TopComponent.Registry r = WindowManager.getDefault ().getRegistry ();
234
235                 r.addPropertyChangeListener (
236                     WeakListeners.propertyChange (this, r)
237                 );
238             }
239         }
240
241         /** Changes the selection to new items.
242         * @param items the new items
243         */

244         synchronized void changeMenuItems (JMenuItem[] items) {
245             removeListeners (last);
246             addListeners (items);
247             last = items;
248             setMenuItems (items);
249         }
250
251
252         /** Add listeners to menu items.
253         * @param items the items
254         */

255         private void addListeners (JMenuItem[] items) {
256             int len = items.length;
257             for (int i = 0; i < len; i++) {
258                 items[i].addPropertyChangeListener (this);
259             }
260         }
261
262         /** Remove all listeners from menu items.
263         * @param items the items
264         */

265         private void removeListeners (JMenuItem[] items) {
266             int len = items.length;
267             for (int i = 0; i < len; i++) {
268                 items[i].removePropertyChangeListener (this);
269             }
270         }
271         
272         boolean needsChange = false;
273         
274         public void addNotify() {
275             if (needsChange) {
276                 changeMenuItems (createMenu (popup, lookup));
277                 needsChange = false;
278             }
279             super.addNotify();
280         }
281
282         public void removeNotify() {
283             removeListeners (last);
284             last = NONE;
285         }
286
287         public void propertyChange (PropertyChangeEvent ev) {
288             String JavaDoc name = ev.getPropertyName ();
289             if (
290                 name == null ||
291                 name.equals (SystemAction.PROP_ENABLED) ||
292                 name.equals (TopComponent.Registry.PROP_ACTIVATED_NODES)
293             ) {
294                 // change items later
295
needsChange = true;
296             }
297         }
298     }
299     
300     /** Context aware action implementation. */
301     private static final class DelegateAction extends AbstractAction
302     implements Presenter.Menu, Presenter.Popup {
303         /** lookup to work with */
304         private Lookup lookup;
305
306         public DelegateAction(Lookup lookup) {
307             this.lookup = lookup;
308         }
309
310
311         /** @return menu presenter. */
312         public JMenuItem getMenuPresenter () {
313             return new FileSystemAction.Menu (false, lookup);
314         }
315
316         /** @return popup presenter. */
317         public JMenuItem getPopupPresenter () {
318             return new FileSystemAction.Menu (true, lookup);
319         }
320         
321         public void actionPerformed(ActionEvent JavaDoc e) {
322             assert false : e;
323         }
324         
325     } // end of DelegateAction
326

327 }
328
Popular Tags