KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > ant > freeform > ui > ProjectNodeWrapper


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.ant.freeform.ui;
21
22 import java.awt.Image JavaDoc;
23 import java.awt.event.ActionEvent JavaDoc;
24 import java.beans.PropertyChangeEvent JavaDoc;
25 import java.beans.PropertyChangeListener JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.HashSet JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.Set JavaDoc;
35 import javax.swing.AbstractAction JavaDoc;
36 import javax.swing.Action JavaDoc;
37 import javax.swing.JSeparator JavaDoc;
38 import javax.swing.event.ChangeEvent JavaDoc;
39 import javax.swing.event.ChangeListener JavaDoc;
40 import org.netbeans.api.project.Project;
41 import org.netbeans.api.project.ProjectUtils;
42 import org.netbeans.api.project.SourceGroup;
43 import org.netbeans.api.project.Sources;
44 import org.openide.ErrorManager;
45 import org.openide.filesystems.FileObject;
46 import org.openide.filesystems.FileStateInvalidException;
47 import org.openide.filesystems.FileStatusEvent;
48 import org.openide.filesystems.FileStatusListener;
49 import org.openide.filesystems.FileSystem;
50 import org.openide.filesystems.FileUtil;
51 import org.openide.filesystems.Repository;
52 import org.openide.loaders.DataFolder;
53 import org.openide.loaders.DataObject;
54 import org.openide.loaders.DataObjectNotFoundException;
55 import org.openide.loaders.FolderLookup;
56 import org.openide.nodes.FilterNode;
57 import org.openide.nodes.Node;
58 import org.openide.util.Lookup;
59 import org.openide.util.RequestProcessor;
60 import org.openide.util.WeakListeners;
61
62
63 /**A wrapper node for project's root node that adds CVS badges+Project/Actions.
64  *
65  * This class should be moved into projectuiapi (org.netbeans.spi.project.ui.support)
66  * after some cleanup and adding tests.
67  *
68  * The intent is to make it package private and create a factory which will wrap
69  * provided node (project's logical view) with this wrapper to serve the CVS annotations.
70  *
71  * @author Jan Lahoda
72  */

73 public final class ProjectNodeWrapper extends FilterNode implements Runnable JavaDoc, FileStatusListener, ChangeListener JavaDoc, PropertyChangeListener JavaDoc {
74     
75     private Set JavaDoc<FileObject> files;
76     private Map JavaDoc<FileSystem,FileStatusListener> fileSystemListeners;
77     private RequestProcessor.Task task;
78     private final Object JavaDoc privateLock = new Object JavaDoc();
79     private boolean iconChange;
80     private boolean nameChange;
81     private ChangeListener JavaDoc sourcesListener;
82     private Map JavaDoc<SourceGroup,PropertyChangeListener JavaDoc> groupsListeners;
83     
84     public static final Action JavaDoc GENERIC_PROJECTS_ACTIONS_MARKER = new AbstractAction JavaDoc() {
85         public void actionPerformed(ActionEvent JavaDoc e) {
86         }
87     };
88     
89     public ProjectNodeWrapper(Node toWrap) {
90         super(toWrap);
91         setProjectFiles();
92     }
93     
94     public Action JavaDoc[] getActions(boolean context) {
95         Action JavaDoc[] actions = super.getActions(context);
96         
97         List JavaDoc<Action JavaDoc> result = new ArrayList JavaDoc<Action JavaDoc>();
98         
99         for (int cntr = 0; cntr < actions.length; cntr++) {
100             if (actions[cntr] != GENERIC_PROJECTS_ACTIONS_MARKER) {
101                 result.add(actions[cntr]);
102             } else {
103                 // honor 57874 contact:
104
try {
105                     Repository repository = Repository.getDefault();
106                     FileSystem sfs = repository.getDefaultFileSystem();
107                     FileObject fo = sfs.findResource("Projects/Actions"); // NOI18N
108
if (fo != null) {
109                         DataObject dobj = DataObject.find(fo);
110                         FolderLookup actionRegistry = new FolderLookup((DataFolder)dobj);
111                         Lookup lookup = actionRegistry.getLookup();
112                         Iterator JavaDoc<? extends Object JavaDoc> it = lookup.lookupAll(Object JavaDoc.class).iterator();
113                         if (it.hasNext()) {
114                             result.add(null);
115                         }
116                         while (it.hasNext()) {
117                             Object JavaDoc next = it.next();
118                             if (next instanceof Action JavaDoc) {
119                                 result.add((Action JavaDoc) next);
120                             } else if (next instanceof JSeparator JavaDoc) {
121                                 result.add(null);
122                             }
123                         }
124                     }
125                 } catch (DataObjectNotFoundException ex) {
126                     // data folder for exitinf fileobject expected
127
ErrorManager.getDefault().notify(ex);
128                 }
129             }
130         }
131         
132         return result.toArray(new Action JavaDoc[result.size()]);
133     }
134     
135     
136     protected final void setProjectFiles() {
137         Project prj = getLookup().lookup(Project.class);
138         
139         if (prj != null) {
140             setProjectFiles(prj);
141         } else {
142             ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, "Node: " + getOriginal() + " wrapped with ProjectNodeWrapper, but does not contain a Project in the lookup!");
143         }
144     }
145     
146     protected final void setProjectFiles(Project project) {
147         Sources sources = ProjectUtils.getSources(project); // returns singleton
148
if (sourcesListener == null) {
149             sourcesListener = WeakListeners.change(this, sources);
150             sources.addChangeListener(sourcesListener);
151         }
152         setGroups(Arrays.asList(sources.getSourceGroups(Sources.TYPE_GENERIC)));
153     }
154     
155     private final void setGroups(Collection JavaDoc<SourceGroup> groups) {
156         if (groupsListeners != null) {
157             for (Map.Entry JavaDoc<SourceGroup,PropertyChangeListener JavaDoc> entry : groupsListeners.entrySet()) {
158                 entry.getKey().removePropertyChangeListener(entry.getValue());
159             }
160         }
161         groupsListeners = new HashMap JavaDoc<SourceGroup,PropertyChangeListener JavaDoc>();
162         Set JavaDoc<FileObject> roots = new HashSet JavaDoc<FileObject>();
163         for (SourceGroup group : groups) {
164             PropertyChangeListener JavaDoc pcl = WeakListeners.propertyChange(this, group);
165             groupsListeners.put(group, pcl);
166             group.addPropertyChangeListener(pcl);
167             FileObject fo = group.getRootFolder();
168             roots.add(fo);
169         }
170         setFiles(roots);
171     }
172     
173     protected final void setFiles(Set JavaDoc<FileObject> files) {
174         if (fileSystemListeners != null) {
175             for (Map.Entry JavaDoc<FileSystem,FileStatusListener> entry : fileSystemListeners.entrySet()) {
176                 entry.getKey().removeFileStatusListener(entry.getValue());
177             }
178         }
179         
180         fileSystemListeners = new HashMap JavaDoc<FileSystem,FileStatusListener>();
181         this.files = files;
182         if (files == null) return;
183         
184         Set JavaDoc<FileSystem> hookedFileSystems = new HashSet JavaDoc<FileSystem>();
185         for (FileObject fo : files) {
186             try {
187                 FileSystem fs = fo.getFileSystem();
188                 if (hookedFileSystems.contains(fs)) {
189                     continue;
190                 }
191                 hookedFileSystems.add(fs);
192                 FileStatusListener fsl = FileUtil.weakFileStatusListener(this, fs);
193                 fs.addFileStatusListener(fsl);
194                 fileSystemListeners.put(fs, fsl);
195             } catch (FileStateInvalidException e) {
196                 ErrorManager err = ErrorManager.getDefault();
197                 err.annotate(e, "Can not get " + fo + " filesystem, ignoring..."); // NO18N
198
err.notify(ErrorManager.INFORMATIONAL, e);
199             }
200         }
201     }
202     
203 // public String getDisplayName() {
204
// String s = super.getDisplayName();
205
//
206
// if (files != null && files.iterator().hasNext()) {
207
// try {
208
// FileObject fo = (FileObject) files.iterator().next();
209
// s = fo.getFileSystem().getStatus().annotateName(s, files);
210
// } catch (FileStateInvalidException e) {
211
// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
212
// }
213
// }
214
//
215
// return s;
216
// }
217
//
218
// public String getHtmlDisplayName() {
219
// if (files != null && files.iterator().hasNext()) {
220
// try {
221
// FileObject fo = (FileObject) files.iterator().next();
222
// FileSystem.Status stat = fo.getFileSystem().getStatus();
223
// if (stat instanceof FileSystem.HtmlStatus) {
224
// FileSystem.HtmlStatus hstat = (FileSystem.HtmlStatus) stat;
225
//
226
// String result = hstat.annotateNameHtml(
227
// super.getHtmlDisplayName(), files);
228
//
229
// //Make sure the super string was really modified
230
// if (result != null && !result.equals(getDisplayName())) {
231
// return result;
232
// }
233
// }
234
// } catch (FileStateInvalidException e) {
235
// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
236
// }
237
// }
238
// return super.getHtmlDisplayName();
239
// }
240

241     public Image JavaDoc getIcon(int type) {
242         Image JavaDoc img = super.getIcon(type);
243         
244         if (files != null && files.iterator().hasNext()) {
245             try {
246                 FileObject fo = files.iterator().next();
247                 img = fo.getFileSystem().getStatus().annotateIcon(img, type, files);
248             } catch (FileStateInvalidException e) {
249                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
250             }
251         }
252         
253         return img;
254     }
255     
256     public Image JavaDoc getOpenedIcon(int type) {
257         Image JavaDoc img = super.getOpenedIcon(type);
258         
259         if (files != null && files.iterator().hasNext()) {
260             try {
261                 FileObject fo = files.iterator().next();
262                 img = fo.getFileSystem().getStatus().annotateIcon(img, type, files);
263             } catch (FileStateInvalidException e) {
264                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
265             }
266         }
267         
268         return img;
269     }
270     
271     public void run() {
272         boolean fireIcon;
273         boolean fireName;
274         synchronized (privateLock) {
275             fireIcon = iconChange;
276             fireName = nameChange;
277             iconChange = false;
278             nameChange = false;
279         }
280         if (fireIcon) {
281             fireIconChange();
282             fireOpenedIconChange();
283         }
284         if (fireName) {
285             fireDisplayNameChange(null, null);
286         }
287     }
288     
289     public void annotationChanged(FileStatusEvent event) {
290         if (task == null) {
291             task = RequestProcessor.getDefault().create(this);
292         }
293         
294         synchronized (privateLock) {
295             if ((iconChange == false && event.isIconChange()) || (nameChange == false && event.isNameChange())) {
296                 for (FileObject fo : files) {
297                     if (event.hasChanged(fo)) {
298                         iconChange |= event.isIconChange();
299                         nameChange |= event.isNameChange();
300                     }
301                 }
302             }
303         }
304         
305         task.schedule(50); // batch by 50 ms
306
}
307     
308     // sources change
309
public void stateChanged(ChangeEvent JavaDoc e) {
310         setProjectFiles();
311     }
312     
313     // group change
314
public void propertyChange(PropertyChangeEvent JavaDoc evt) {
315         setProjectFiles();
316     }
317     
318 }
319
Popular Tags