KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > ui > ImportantFilesNodeFactory


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.apisupport.project.ui;
21
22 import java.awt.Image JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.LinkedHashMap JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Set JavaDoc;
30 import javax.swing.event.ChangeListener JavaDoc;
31 import org.netbeans.api.project.Project;
32 import org.netbeans.modules.apisupport.project.NbModuleProject;
33 import org.netbeans.modules.apisupport.project.layers.LayerNode;
34 import org.netbeans.modules.apisupport.project.layers.LayerUtils;
35 import org.netbeans.modules.apisupport.project.metainf.ServiceNodeHandler;
36 import org.netbeans.modules.apisupport.project.suite.SuiteProject;
37 import org.netbeans.spi.project.ui.support.NodeFactory;
38 import org.netbeans.spi.project.ui.support.NodeList;
39 import org.openide.ErrorManager;
40 import org.openide.filesystems.FileChangeAdapter;
41 import org.openide.filesystems.FileChangeListener;
42 import org.openide.filesystems.FileEvent;
43 import org.openide.filesystems.FileObject;
44 import org.openide.filesystems.FileStateInvalidException;
45 import org.openide.filesystems.FileSystem;
46 import org.openide.loaders.DataObject;
47 import org.openide.loaders.DataObjectNotFoundException;
48 import org.openide.nodes.Children;
49 import org.openide.nodes.FilterNode;
50 import org.openide.nodes.Node;
51 import org.openide.util.NbBundle;
52 import org.openide.util.RequestProcessor;
53 import org.openide.util.Utilities;
54
55 /**
56  *
57  * @author mkleint
58  */

59 public class ImportantFilesNodeFactory implements NodeFactory {
60     /** Package private for unit tests. */
61     static final String JavaDoc IMPORTANT_FILES_NAME = "important.files"; // NOI18N
62
/** Package private for unit tests only. */
63     static final RequestProcessor RP = new RequestProcessor();
64     
65     /** Creates a new instance of ImportantFilesNodeFactory */
66     public ImportantFilesNodeFactory() {
67     }
68     
69     public NodeList createNodes(Project p) {
70         return new ImpFilesNL(p);
71     }
72
73     private static class ImpFilesNL implements NodeList<String JavaDoc> {
74         private Project project;
75         
76         public ImpFilesNL(Project p) {
77             project = p;
78         }
79     
80         public List JavaDoc<String JavaDoc> keys() {
81             return Collections.singletonList(IMPORTANT_FILES_NAME);
82         }
83
84         public void addChangeListener(ChangeListener JavaDoc l) {
85             //ignore, doesn't change
86
}
87
88         public void removeChangeListener(ChangeListener JavaDoc l) {
89             //ignore, doesn't change
90
}
91
92         public Node node(String JavaDoc key) {
93             assert key == IMPORTANT_FILES_NAME;
94             if (project instanceof NbModuleProject) {
95                 return new ImportantFilesNode((NbModuleProject)project);
96             }
97             if (project instanceof SuiteProject) {
98                 return new ImportantFilesNode(new SuiteImportantFilesChildren((SuiteProject)project));
99             }
100             return null;
101         }
102
103         public void addNotify() {
104         }
105
106         public void removeNotify() {
107         }
108     }
109     /**
110      * Show node "Important Files" with various config and docs files beneath it.
111      */

112     static final class ImportantFilesNode extends AnnotatedNode {
113         
114         public ImportantFilesNode(NbModuleProject project) {
115             super(new ImportantFilesChildren(project));
116         }
117         
118         ImportantFilesNode(Children ch) {
119             super(ch);
120         }
121         
122         public String JavaDoc getName() {
123             return IMPORTANT_FILES_NAME;
124         }
125         
126         private Image JavaDoc getIcon(boolean opened) {
127             Image JavaDoc badge = Utilities.loadImage("org/netbeans/modules/apisupport/project/resources/config-badge.gif", true);
128             return Utilities.mergeImages(UIUtil.getTreeFolderIcon(opened), badge, 8, 8);
129         }
130         
131         private static final String JavaDoc DISPLAY_NAME = NbBundle.getMessage(ModuleLogicalView.class, "LBL_important_files");
132         
133         public String JavaDoc getDisplayName() {
134             return annotateName(DISPLAY_NAME);
135         }
136         
137         public String JavaDoc getHtmlDisplayName() {
138             return computeAnnotatedHtmlDisplayName(DISPLAY_NAME, getFiles());
139         }
140         
141         public Image JavaDoc getIcon(int type) {
142             return annotateIcon(getIcon(false), type);
143         }
144         
145         public Image JavaDoc getOpenedIcon(int type) {
146             return annotateIcon(getIcon(true), type);
147         }
148         
149     }
150     
151     /**
152      * Actual list of important files.
153      */

154     private static final class ImportantFilesChildren extends Children.Keys {
155         
156         private List JavaDoc visibleFiles = new ArrayList JavaDoc();
157         private FileChangeListener fcl;
158         
159         /** Abstract location to display name. */
160         private static final java.util.Map JavaDoc<String JavaDoc,String JavaDoc> FILES = new LinkedHashMap JavaDoc();
161         static {
162             FILES.put("${manifest.mf}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_module_manifest"));
163             FILES.put("${javadoc.arch}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_arch_desc"));
164             FILES.put("${javadoc.apichanges}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_api_changes"));
165             FILES.put("${javadoc.overview}", NbBundle.getMessage(ModuleLogicalView.class, "LBL_javadoc_overview"));
166             FILES.put("build.xml", NbBundle.getMessage(ModuleLogicalView.class, "LBL_build.xml"));
167             FILES.put("nbproject/project.xml", NbBundle.getMessage(ModuleLogicalView.class, "LBL_project.xml"));
168             FILES.put("nbproject/project.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_project.properties"));
169             FILES.put("nbproject/private/private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_private.properties"));
170             FILES.put("nbproject/suite.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_suite.properties"));
171             FILES.put("nbproject/private/suite-private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_suite-private.properties"));
172             FILES.put("nbproject/platform.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_platform.properties"));
173             FILES.put("nbproject/private/platform-private.properties", NbBundle.getMessage(ModuleLogicalView.class, "LBL_platform-private.properties"));
174         }
175         
176         private final NbModuleProject project;
177         
178         public ImportantFilesChildren(NbModuleProject project) {
179             this.project = project;
180         }
181         
182         protected void addNotify() {
183             super.addNotify();
184             attachListeners();
185             refreshKeys();
186         }
187         
188         protected void removeNotify() {
189             setKeys(Collections.EMPTY_SET);
190             removeListeners();
191             super.removeNotify();
192         }
193         
194         protected Node[] createNodes(Object JavaDoc key) {
195             if (key instanceof String JavaDoc) {
196                 String JavaDoc loc = (String JavaDoc) key;
197                 String JavaDoc locEval = project.evaluator().evaluate(loc);
198                 FileObject file = project.getHelper().resolveFileObject(locEval);
199                 try {
200                     Node orig = DataObject.find(file).getNodeDelegate();
201                     return new Node[] {new SpecialFileNode(orig, (String JavaDoc) FILES.get(loc))};
202                 } catch (DataObjectNotFoundException e) {
203                     throw new AssertionError JavaDoc(e);
204                 }
205             } else if (key instanceof LayerUtils.LayerHandle) {
206                 return new Node[] {/* #68240 */ new SpecialFileNode(new LayerNode((LayerUtils.LayerHandle) key), null)};
207             } else if (key instanceof ServiceNodeHandler) {
208                 return new Node[]{((ServiceNodeHandler)key).createServiceRootNode()};
209             } else {
210                 throw new AssertionError JavaDoc(key);
211             }
212         }
213         
214         private void refreshKeys() {
215             Set JavaDoc<FileObject> files = new HashSet JavaDoc();
216             List JavaDoc newVisibleFiles = new ArrayList JavaDoc();
217             LayerUtils.LayerHandle handle = LayerUtils.layerForProject(project);
218             FileObject layerFile = handle.getLayerFile();
219             if (layerFile != null) {
220                 newVisibleFiles.add(handle);
221                 files.add(layerFile);
222             }
223             Iterator JavaDoc it = FILES.keySet().iterator();
224             while (it.hasNext()) {
225                 String JavaDoc loc = (String JavaDoc) it.next();
226                 String JavaDoc locEval = project.evaluator().evaluate(loc);
227                 if (locEval == null) {
228                     newVisibleFiles.remove(loc); // XXX why?
229
continue;
230                 }
231                 FileObject file = project.getHelper().resolveFileObject(locEval);
232                 if (file != null) {
233                     newVisibleFiles.add(loc);
234                     files.add(file);
235                 }
236             }
237             if (!isInitialized() || !newVisibleFiles.equals(visibleFiles)) {
238                 visibleFiles = newVisibleFiles;
239                 visibleFiles.add(project.getLookup().lookup(ServiceNodeHandler.class));
240                 RP.post(new Runnable JavaDoc() { // #72471
241
public void run() {
242                         setKeys(visibleFiles);
243                     }
244                 });
245                 ((ImportantFilesNode) getNode()).setFiles(files);
246             }
247         }
248         
249         private void attachListeners() {
250             try {
251                 if (fcl == null) {
252                     fcl = new FileChangeAdapter() {
253                         public void fileDataCreated(FileEvent fe) {
254                             refreshKeys();
255                         }
256                         public void fileDeleted(FileEvent fe) {
257                             refreshKeys();
258                         }
259                     };
260                     project.getProjectDirectory().getFileSystem().addFileChangeListener(fcl);
261                 }
262             } catch (FileStateInvalidException e) {
263                 assert false : e;
264             }
265         }
266         
267         private void removeListeners() {
268             if (fcl != null) {
269                 try {
270                     project.getProjectDirectory().getFileSystem().removeFileChangeListener(fcl);
271                 } catch (FileStateInvalidException e) {
272                     assert false : e;
273                 }
274                 fcl = null;
275             }
276         }
277         
278     }
279     /**
280      * Node to represent some special file in a project.
281      * Mostly just a wrapper around the normal data node.
282      */

283     static final class SpecialFileNode extends FilterNode {
284         
285         private final String JavaDoc displayName;
286         
287         public SpecialFileNode(Node orig, String JavaDoc displayName) {
288             super(orig);
289             this.displayName = displayName;
290         }
291         
292         public String JavaDoc getDisplayName() {
293             if (displayName != null) {
294                 return displayName;
295             } else {
296                 return super.getDisplayName();
297             }
298         }
299         
300         public boolean canRename() {
301             return false;
302         }
303         
304         public boolean canDestroy() {
305             return false;
306         }
307         
308         public boolean canCut() {
309             return false;
310         }
311         
312         public String JavaDoc getHtmlDisplayName() {
313             String JavaDoc result = null;
314             DataObject dob = (DataObject) getLookup().lookup(DataObject.class);
315             if (dob != null) {
316                 Set JavaDoc files = dob.files();
317                 result = computeAnnotatedHtmlDisplayName(getDisplayName(), files);
318             }
319             return result;
320         }
321         
322     }
323     
324     /**
325      * Annotates <code>htmlDisplayName</code>, if it is needed, and returns the
326      * result; <code>null</code> otherwise.
327      */

328     private static String JavaDoc computeAnnotatedHtmlDisplayName(
329             final String JavaDoc htmlDisplayName, final Set JavaDoc files) {
330         
331         String JavaDoc result = null;
332         if (files != null && files.iterator().hasNext()) {
333             try {
334                 FileObject fo = (FileObject) files.iterator().next();
335                 FileSystem.Status stat = fo.getFileSystem().getStatus();
336                 if (stat instanceof FileSystem.HtmlStatus) {
337                     FileSystem.HtmlStatus hstat = (FileSystem.HtmlStatus) stat;
338                     
339                     String JavaDoc annotated = hstat.annotateNameHtml(htmlDisplayName, files);
340                     
341                     // Make sure the super string was really modified (XXX why?)
342
if (!htmlDisplayName.equals(annotated)) {
343                         result = annotated;
344                     }
345                 }
346             } catch (FileStateInvalidException e) {
347                 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
348             }
349         }
350         return result;
351     }
352     
353     /**
354      * Actual list of important files.
355      */

356     private static final class SuiteImportantFilesChildren extends Children.Keys<String JavaDoc> {
357         
358         private List JavaDoc<String JavaDoc> visibleFiles = new ArrayList JavaDoc();
359         private FileChangeListener fcl;
360         
361         /** Abstract location to display name. */
362         private static final java.util.Map JavaDoc<String JavaDoc,String JavaDoc> FILES = new LinkedHashMap JavaDoc();
363         static {
364             FILES.put("master.jnlp", NbBundle.getMessage(SuiteLogicalView.class,"LBL_jnlp_master"));
365             FILES.put("build.xml", NbBundle.getMessage(SuiteLogicalView.class,"LBL_build.xml"));
366             FILES.put("nbproject/project.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_project.properties"));
367             FILES.put("nbproject/private/private.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_private.properties"));
368             FILES.put("nbproject/platform.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_platform.properties"));
369             FILES.put("nbproject/private/platform-private.properties", NbBundle.getMessage(SuiteLogicalView.class,"LBL_platform-private.properties"));
370         }
371         
372         private final SuiteProject project;
373         
374         public SuiteImportantFilesChildren(SuiteProject project) {
375             this.project = project;
376         }
377         
378         protected void addNotify() {
379             super.addNotify();
380             attachListeners();
381             refreshKeys();
382         }
383         
384         protected void removeNotify() {
385             setKeys(Collections.EMPTY_SET);
386             removeListeners();
387             super.removeNotify();
388         }
389         
390         protected Node[] createNodes(String JavaDoc loc) {
391             String JavaDoc locEval = project.getEvaluator().evaluate(loc);
392             FileObject file = project.getHelper().resolveFileObject(locEval);
393             
394             try {
395                 Node orig = DataObject.find(file).getNodeDelegate();
396                 return new Node[] {new SpecialFileNode(orig, (String JavaDoc) FILES.get(loc))};
397             } catch (DataObjectNotFoundException e) {
398                 throw new AssertionError JavaDoc(e);
399             }
400         }
401         
402         private void refreshKeys() {
403             List JavaDoc<String JavaDoc> newVisibleFiles = new ArrayList JavaDoc();
404             Iterator JavaDoc it = FILES.keySet().iterator();
405             Set JavaDoc files = new HashSet JavaDoc();
406             while (it.hasNext()) {
407                 String JavaDoc loc = (String JavaDoc) it.next();
408                 String JavaDoc locEval = project.getEvaluator().evaluate(loc);
409                 if (locEval == null) {
410                     continue;
411                 }
412                 FileObject file = project.getHelper().resolveFileObject(locEval);
413                 if (file != null) {
414                     newVisibleFiles.add(loc);
415                     files.add(file);
416                 }
417             }
418             if (!isInitialized() || !newVisibleFiles.equals(visibleFiles)) {
419                 visibleFiles = newVisibleFiles;
420                 RP.post(new Runnable JavaDoc() { // #72471
421
public void run() {
422                         setKeys(visibleFiles);
423                     }
424                 });
425                 ((ImportantFilesNode) getNode()).setFiles(files); // #72439
426
}
427         }
428         
429         private void attachListeners() {
430             try {
431                 if (fcl == null) {
432                     fcl = new FileChangeAdapter() {
433                         public void fileDataCreated(FileEvent fe) {
434                             refreshKeys();
435                         }
436                         public void fileDeleted(FileEvent fe) {
437                             refreshKeys();
438                         }
439                     };
440                     project.getProjectDirectory().getFileSystem().addFileChangeListener(fcl);
441                 }
442             } catch (FileStateInvalidException e) {
443                 assert false : e;
444             }
445         }
446         
447         private void removeListeners() {
448             if (fcl != null) {
449                 try {
450                     project.getProjectDirectory().getFileSystem().removeFileChangeListener(fcl);
451                 } catch (FileStateInvalidException e) {
452                     assert false : e;
453                 }
454                 fcl = null;
455             }
456         }
457         
458     }
459     
460 }
461
Popular Tags