KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > apisupport > project > layers > BadgingSupport


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.apisupport.project.layers;
21
22 import java.awt.Image JavaDoc;
23 import java.awt.Toolkit JavaDoc;
24 import java.beans.BeanInfo JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Properties JavaDoc;
32 import java.util.Set JavaDoc;
33 import javax.swing.Action JavaDoc;
34 import javax.swing.JSeparator JavaDoc;
35 import org.netbeans.api.java.classpath.ClassPath;
36 import org.netbeans.modules.apisupport.project.Util;
37 import org.openide.ErrorManager;
38 import org.openide.awt.Actions;
39 import org.openide.cookies.InstanceCookie;
40 import org.openide.filesystems.FileAttributeEvent;
41 import org.openide.filesystems.FileChangeListener;
42 import org.openide.filesystems.FileEvent;
43 import org.openide.filesystems.FileObject;
44 import org.openide.filesystems.FileRenameEvent;
45 import org.openide.filesystems.FileStateInvalidException;
46 import org.openide.filesystems.FileStatusEvent;
47 import org.openide.filesystems.FileStatusListener;
48 import org.openide.filesystems.FileSystem;
49 import org.openide.filesystems.FileUtil;
50 import org.openide.filesystems.URLMapper;
51 import org.openide.loaders.DataObject;
52 import org.openide.util.NbBundle;
53 import org.openide.util.RequestProcessor;
54 import org.openide.util.actions.Presenter;
55
56 /**
57  * Handles addition of badges to a filesystem a la system filesystem.
58  * Specifically interprets SystemFileSystem.localizingBundle and
59  * SystemFileSystem.icon (and SystemFileSystem.icon32).
60  * Also tries to provide display labels for InstanceDataObject's.
61  * Parts copied from org.netbeans.core.projects.SystemFileSystem.
62  * @author Jesse Glick
63  */

64 final class BadgingSupport implements FileSystem.Status, FileChangeListener {
65     
66     /** for branding/localization like "_f4j_ce_ja"; never null, but may be "" */
67     private String JavaDoc suffix = "";
68     /** classpath in which to look up resources; may be null but then nothing will be found... */
69     private ClassPath classpath;
70     private final FileSystem fs;
71     private final FileChangeListener fileChangeListener;
72     private final List JavaDoc<FileStatusListener> listeners = new ArrayList JavaDoc();
73     
74     public BadgingSupport(FileSystem fs) {
75         this.fs = fs;
76         fileChangeListener = FileUtil.weakFileChangeListener(this, null);
77         fs.addFileChangeListener(fileChangeListener);
78     }
79     
80     public void setClasspath(ClassPath classpath) {
81         this.classpath = classpath;
82     }
83     
84     public void setSuffix(String JavaDoc suffix) {
85         this.suffix = suffix;
86     }
87     
88     public void addFileStatusListener(FileStatusListener l) {
89         listeners.add(l);
90     }
91     
92     public void removeFileStatusListener(FileStatusListener l) {
93         listeners.remove(l);
94     }
95     
96     private void fireFileStatusChanged(FileStatusEvent e) {
97         Iterator JavaDoc it = listeners.iterator();
98         while (it.hasNext()) {
99             ((FileStatusListener) it.next()).annotationChanged(e);
100         }
101     }
102     
103     public String JavaDoc annotateName(String JavaDoc name, Set JavaDoc files) {
104         return annotateNameGeneral(name, files, suffix, fileChangeListener, classpath);
105     }
106     
107     private static String JavaDoc annotateNameGeneral(String JavaDoc name, Set JavaDoc files, String JavaDoc suffix, FileChangeListener fileChangeListener, ClassPath cp) {
108         Iterator JavaDoc it = files.iterator();
109         while (it.hasNext()) {
110             FileObject fo = (FileObject) it.next();
111             String JavaDoc bundleName = (String JavaDoc) fo.getAttribute("SystemFileSystem.localizingBundle"); // NOI18N
112
if (bundleName != null) {
113                 try {
114                     URL JavaDoc[] u = LayerUtils.currentify(new URL JavaDoc("nbresloc:/" + // NOI18N
115
bundleName.replace('.', '/') +
116                             ".properties"), // NOI18N
117
suffix, cp);
118                     for (int i = 0; i < u.length; i++) {
119                     InputStream JavaDoc is = u[i].openStream();
120                     try {
121                         Properties JavaDoc p = new Properties JavaDoc();
122                         p.load(is);
123                         String JavaDoc key = fo.getPath();
124                         String JavaDoc val = p.getProperty(key);
125                         // Listen to changes in the origin file if any...
126
FileObject ufo = URLMapper.findFileObject(u[i]);
127                         if (ufo != null) {
128                             ufo.removeFileChangeListener(fileChangeListener);
129                             ufo.addFileChangeListener(fileChangeListener);
130                             // In case a sibling bundle is added, that may be relevant:
131
ufo.getParent().removeFileChangeListener(fileChangeListener);
132                             ufo.getParent().addFileChangeListener(fileChangeListener);
133                         }
134                         if (val != null) {
135                             if (fo.getPath().startsWith("Menu/")) { // NOI18N
136
// Special-case menu folders to trim the mnemonics, since they are ugly.
137
return Actions.cutAmpersand(val);
138                             } else {
139                                 return val;
140                             }
141                         }
142                         // if null, fine--normal for key to not be found
143
} finally {
144                         is.close();
145                     }
146                     }
147                 } catch (IOException JavaDoc ioe) {
148                     // For debugging; SFS will rather notify a problem separately...
149
Util.err.notify(ErrorManager.INFORMATIONAL, ioe);
150                     return NbBundle.getMessage(BadgingSupport.class, "LBL_no_such_bundle", name, bundleName);
151                 }
152             }
153             if (fo.hasExt("instance")) { // NOI18N
154
return getInstanceLabel(fo);
155             }
156             if (fo.hasExt("shadow")) { // NOI18N
157
Object JavaDoc originalFile = fo.getAttribute("originalFile"); // NOI18N
158
if (originalFile != null && originalFile instanceof String JavaDoc) {
159                     FileObject orig;
160                     try {
161                         orig = fo.getFileSystem().findResource((String JavaDoc) originalFile);
162                     } catch (FileStateInvalidException e) {
163                         orig = null;
164                     }
165                     if (orig != null && orig.hasExt("instance")) { // NOI18N
166
return getInstanceLabel(orig);
167                     }
168                 }
169             }
170         }
171         return name;
172     }
173     
174     private static String JavaDoc getInstanceLabel(FileObject fo) {
175         try {
176             // First try to load it in current IDE, as this handles most platform cases OK.
177
InstanceCookie ic = (InstanceCookie) DataObject.find(fo).getCookie(InstanceCookie.class);
178             if (ic != null) {
179                 Object JavaDoc o = ic.instanceCreate();
180                 if (o instanceof Action JavaDoc) {
181                     String JavaDoc name = (String JavaDoc) ((Action JavaDoc) o).getValue(Action.NAME);
182                     if (name != null) {
183                         return Actions.cutAmpersand(name);
184                     } else {
185                         return toStringOf(o);
186                     }
187                 } else if (o instanceof Presenter.Menu) {
188                     return ((Presenter.Menu) o).getMenuPresenter().getText();
189                 } else if (o instanceof JSeparator JavaDoc) {
190                     return NbBundle.getMessage(BadgingSupport.class, "LBL_separator");
191                 } else {
192                     return toStringOf(o);
193                 }
194             }
195         } catch (IOException JavaDoc e) {
196             // ignore, OK
197
} catch (ClassNotFoundException JavaDoc e) {
198             // ignore, OK
199
}
200         // OK, probably a developed module, so take a guess.
201
String JavaDoc clazz = (String JavaDoc) fo.getAttribute("instanceClass"); // NOI18N
202
if (clazz == null) {
203             clazz = fo.getName().replace('-', '.');
204         }
205         String JavaDoc instanceCreate = (String JavaDoc) fo.getAttribute("literal:instanceCreate"); // NOI18N
206
if (instanceCreate != null && instanceCreate.startsWith("new:")) { // NOI18N
207
clazz = instanceCreate.substring("new:".length()); // NOI18N
208
} else if (instanceCreate != null && instanceCreate.startsWith("method:")) { // NOI18N
209
String JavaDoc factoryDisplayLabel = instanceCreate.substring(instanceCreate.lastIndexOf('.', instanceCreate.lastIndexOf('.') - 1) + 1);
210             return NbBundle.getMessage(BadgingSupport.class, "LBL_instance_from", factoryDisplayLabel);
211         }
212         String JavaDoc clazzDisplayLabel = clazz.substring(clazz.lastIndexOf('.') + 1);
213         return NbBundle.getMessage(BadgingSupport.class, "LBL_instance_of", clazzDisplayLabel);
214     }
215     private static String JavaDoc toStringOf(Object JavaDoc o) {
216         String JavaDoc s = o.toString();
217         if ((o.getClass().getName() + "@" + Integer.toHexString(o.hashCode())).equals(s)) {
218             // Does not override toString, so no point in using pkg.Clazz@123456.
219
String JavaDoc clazz = o.getClass().getName();
220             String JavaDoc clazzDisplayLabel = clazz.substring(clazz.lastIndexOf('.') + 1);
221             return NbBundle.getMessage(BadgingSupport.class, "LBL_instance_of", clazzDisplayLabel);
222         } else {
223             return s;
224         }
225     }
226     
227     public Image JavaDoc annotateIcon(Image JavaDoc icon, int type, Set JavaDoc files) {
228         return annotateIconGeneral(icon, type, files, suffix, fileChangeListener, classpath);
229     }
230     
231     private static Image JavaDoc annotateIconGeneral(Image JavaDoc icon, int type, Set JavaDoc files, String JavaDoc suffix,
232             FileChangeListener fileChangeListener, ClassPath cp) {
233         String JavaDoc attr;
234         if (type == BeanInfo.ICON_COLOR_16x16) {
235             attr = "SystemFileSystem.icon"; // NOI18N
236
} else if (type == BeanInfo.ICON_COLOR_32x32) {
237             attr = "SystemFileSystem.icon32"; // NOI18N
238
} else {
239             return icon;
240         }
241         Iterator JavaDoc it = files.iterator();
242         while (it.hasNext()) {
243             FileObject fo = (FileObject) it.next();
244             Object JavaDoc value = fo.getAttribute(attr);
245             if (value instanceof Image JavaDoc) {
246                 // #18832
247
return (Image JavaDoc)value;
248             }
249             if (value != null) {
250                 try {
251                     URL JavaDoc[] u = LayerUtils.currentify((URL JavaDoc) value, suffix, cp);
252                     FileObject ufo = URLMapper.findFileObject(u[0]);
253                     if (ufo != null) {
254                         ufo.removeFileChangeListener(fileChangeListener);
255                         ufo.addFileChangeListener(fileChangeListener);
256                     }
257                     return Toolkit.getDefaultToolkit().getImage(u[0]);
258                 } catch (Exception JavaDoc e) {
259                     //e.printStackTrace(LayerDataNode.getErr());
260
Util.err.notify(ErrorManager.INFORMATIONAL, e);
261                 }
262             }
263         }
264         return icon;
265     }
266     
267     // Listen to changes in
268
// bundles & icons used to annotate names. If these change,
269
// the filesystem needs to show something else. Properly we would
270
// keep track of *which* file changed and thus which of our resources
271
// is affected. Practically this would be a lot of work and gain
272
// very little.
273
public void fileDeleted(FileEvent fe) {
274         // not ineresting here
275
}
276     public void fileFolderCreated(FileEvent fe) {
277         // does not apply to us
278
}
279     public void fileDataCreated(FileEvent fe) {
280         // In case a file was created that makes an annotation be available.
281
// We are listening to the parent folder, so if e.g. a new branded variant
282
// of a bundle is added, the display ought to be refreshed accordingly.
283
someFileChange();
284     }
285     public void fileAttributeChanged(FileAttributeEvent fe) {
286         someFileChange();
287     }
288     public void fileRenamed(FileRenameEvent fe) {
289         someFileChange();
290     }
291     public void fileChanged(FileEvent fe) {
292         someFileChange();
293     }
294     private void someFileChange() {
295         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
296             public void run() {
297                 // If used as nbres: annotation, fire status change.
298
fireFileStatusChanged(new FileStatusEvent(fs, true, true));
299             }
300         });
301     }
302
303 }
304
Popular Tags