KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > nbbuild > CheckBundles


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.nbbuild;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.BufferedReader JavaDoc;
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.File JavaDoc;
26 import java.io.FileInputStream JavaDoc;
27 import java.io.FileReader JavaDoc;
28 import java.io.FilenameFilter JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.InputStream JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collection JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.HashSet JavaDoc;
35 import java.util.LinkedHashMap JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.TreeMap JavaDoc;
38 import java.util.jar.Attributes JavaDoc;
39 import java.util.jar.Manifest JavaDoc;
40 import javax.xml.parsers.SAXParser JavaDoc;
41 import javax.xml.parsers.SAXParserFactory JavaDoc;
42 import org.apache.tools.ant.BuildException;
43 import org.apache.tools.ant.Project;
44 import org.apache.tools.ant.Task;
45 import org.xml.sax.EntityResolver JavaDoc;
46 import org.xml.sax.InputSource JavaDoc;
47 import org.xml.sax.SAXException JavaDoc;
48 import org.xml.sax.XMLReader JavaDoc;
49 import org.xml.sax.helpers.DefaultHandler JavaDoc;
50
51 /** Task that scans Bundle.properties files for unused keys.
52  *
53  * @author Radim Kubacki
54  */

55 public class CheckBundles extends Task {
56     
57     private static HashSet JavaDoc knownKeys;
58     
59     private static String JavaDoc [] moduleKeys = new String JavaDoc [] {
60         "OpenIDE-Module-Name",
61         "OpenIDE-Module-Display-Category",
62         "OpenIDE-Module-Long-Description",
63         "OpenIDE-Module-Short-Description",
64         "OpenIDE-Module-Package-Dependency-Message"
65     };
66     
67     private File JavaDoc srcdir;
68
69     public void setSrcdir(File JavaDoc f) {
70         // Note: f will automatically be absolute (resolved from project basedir).
71
if (!f.isDirectory())
72             throw new IllegalArgumentException JavaDoc ("srcdir must be a directory");
73         
74         srcdir = f;
75     }
76
77     public void execute() throws BuildException {
78         log("Scanning "+srcdir.getAbsolutePath(), Project.MSG_VERBOSE);
79
80         Map JavaDoc<String JavaDoc,File JavaDoc> knownNames = parseManifest(srcdir);
81
82         Collection JavaDoc<File JavaDoc> bundles = new ArrayList JavaDoc<File JavaDoc>();
83         Map JavaDoc<File JavaDoc,String JavaDoc[]> sources = new TreeMap JavaDoc<File JavaDoc,String JavaDoc[]>();
84
85
86         try {
87             File JavaDoc dir = new File JavaDoc (srcdir, "src");
88             if (dir.exists())
89                 scanSubdirs(dir, bundles, sources);
90             dir = new File JavaDoc (srcdir, "libsrc");
91             if (dir.exists())
92                 scanSubdirs(dir, bundles, sources);
93             // XXX there are still a lot of unsplit bundles in e.g. core/src/
94
// referred to from other submodules
95
// XXX this technique does not work so well, though - should only scan
96
// them for source files, not bundles...
97
/*
98             File[] subdirs = srcdir.listFiles();
99             if (subdirs != null) {
100                 for (int i = 0; i < subdirs.length; i++) {
101                     if (subdirs[i].isDirectory()) {
102                         dir = new File(subdirs[i], "src");
103                         if (dir.exists()) {
104                             scanSubdirs(dir, bundles, sources);
105                         }
106                     }
107                 }
108             }
109              */

110             check (bundles, sources, knownNames);
111         }
112         catch (Exception JavaDoc e) {
113             throw new BuildException (e);
114         }
115     }
116     
117     private void scan (File JavaDoc file, Collection JavaDoc<File JavaDoc> bundles, Map JavaDoc<File JavaDoc,String JavaDoc[]> sources) throws Exception JavaDoc {
118         File JavaDoc bundle = new File JavaDoc (file, "Bundle.properties");
119         if (!bundle.exists()) {
120             log("No bundle in "+file.getAbsolutePath()+". OK", Project.MSG_VERBOSE);
121         }
122         else {
123             bundles.add (bundle);
124         }
125
126         addSources (file, sources);
127     }
128
129     private void check(Collection JavaDoc<File JavaDoc> bundles, Map JavaDoc<File JavaDoc,String JavaDoc[]> files, Map JavaDoc<String JavaDoc,File JavaDoc> knownNames) {
130         try {
131             for (File JavaDoc bundle : bundles) {
132                 for (Map.Entry JavaDoc<String JavaDoc,Integer JavaDoc> entry : entries(bundle).entrySet()) {
133                     String JavaDoc key = entry.getKey();
134                     int line = entry.getValue();
135                     log("Looking for "+key, Project.MSG_DEBUG);
136                     boolean found = false;
137                     // module info or file name from layer
138
if (bundle.equals (knownNames.get(key))) {
139                         log("Checked name "+key+" OK", Project.MSG_VERBOSE);
140                         found = true;
141                     }
142                     else {
143                         // java source in the same package
144
for (String JavaDoc src : files.get(bundle.getParentFile())) {
145                             if (src.indexOf("\"" + key+ "\"") >= 0) {
146                                 log("Checking "+key+" OK", Project.MSG_VERBOSE);
147                                 found = true;
148                                 break;
149                             }
150                         }
151                     }
152                     if (!found) {
153                         // try other java sources
154
// XXX should skip moduleKeys, etc.
155
for (Map.Entry JavaDoc<File JavaDoc,String JavaDoc[]> entry2 : files.entrySet()) {
156                             File JavaDoc dir = entry2.getKey();
157                             for (String JavaDoc src : entry2.getValue()) {
158                                 if (src.indexOf("\"" + key + "\"") >= 0) {
159                                     log(bundle.getPath() + ":" + line + ": " + key + " used from " + dir.getPath(), Project.MSG_WARN);
160                                     found = true;
161                                     break;
162                                 }
163                             }
164                         }
165                         if (!found) {
166                             log(bundle.getPath() + ":" + line + ": " + key + " NOT FOUND");
167                         }
168                     }
169                 }
170             
171             }
172         }
173         catch (Exception JavaDoc e) {
174             e.printStackTrace();
175         }
176     }
177     
178     private void scanSubdirs(File JavaDoc file, Collection JavaDoc<File JavaDoc> bundles, Map JavaDoc<File JavaDoc,String JavaDoc[]> srcs) throws Exception JavaDoc {
179         log("scanSubdirs "+file, Project.MSG_DEBUG);
180         File JavaDoc [] subdirs = file.listFiles(new FilenameFilter JavaDoc () {
181                 public boolean accept (File JavaDoc f, String JavaDoc name) {
182                     return new File JavaDoc(f, name).isDirectory();
183                 }
184             });
185         for (int i = 0; i<subdirs.length; i++) {
186             scan (subdirs[i], bundles, srcs);
187             scanSubdirs (subdirs[i], bundles, srcs);
188         }
189
190     }
191     
192     /** Adds dir -> array of source texts */
193     private void addSources(File JavaDoc dir, Map JavaDoc<File JavaDoc,String JavaDoc[]> map) throws Exception JavaDoc {
194         File JavaDoc [] files = dir.listFiles(new FilenameFilter JavaDoc () {
195                 public boolean accept(File JavaDoc dir, String JavaDoc name) {
196                     if (name.endsWith(".java")) {
197                         return true;
198                     }
199                     return false;
200                 }
201             });
202         String JavaDoc [] srcs = new String JavaDoc[files.length];
203         for (int i=0; i<files.length; i++) {
204             InputStream JavaDoc is = new BufferedInputStream JavaDoc (new FileInputStream JavaDoc(files[i]));
205             byte [] arr = new byte [2048];
206             srcs[i] = "";
207             int len;
208             while ((len = is.read(arr)) != -1) {
209                 srcs[i] = srcs[i]+ new String JavaDoc(arr, 0, len);
210             }
211         }
212         map.put(dir, srcs);
213         return;
214     }
215     
216     /**
217      * Get a list of keys in a bundle file, with accompanying line numbers.
218      */

219     private Map JavaDoc<String JavaDoc,Integer JavaDoc> entries(File JavaDoc bundle) throws IOException JavaDoc {
220         Map JavaDoc<String JavaDoc,Integer JavaDoc> entries = new LinkedHashMap JavaDoc<String JavaDoc,Integer JavaDoc>();
221         BufferedReader JavaDoc r = new BufferedReader JavaDoc (new FileReader JavaDoc (bundle));
222         String JavaDoc l;
223         boolean multi = false;
224         int line = 0;
225         while ((l = r.readLine()) != null) {
226             line++;
227             if (!l.startsWith("#")) {
228             
229                 int i = l.indexOf('=');
230                 if (i>0 && !multi) {
231                     String JavaDoc key = l.substring(0,i).trim();
232                     entries.put(key, line);
233                 }
234                 if (l.endsWith("\\"))
235                     multi = true;
236                 else
237                     multi = false;
238             }
239         }
240         return entries;
241     }
242
243     private Map JavaDoc<String JavaDoc,File JavaDoc> parseManifest(File JavaDoc dir) {
244         Map JavaDoc<String JavaDoc,File JavaDoc> files = new HashMap JavaDoc<String JavaDoc,File JavaDoc>(10);
245         try {
246             File JavaDoc mf = new File JavaDoc(srcdir, "manifest.mf");
247             if (!mf.exists()) {
248                 log("Manifest file not found", Project.MSG_VERBOSE);
249                 return files;
250             }
251             
252             log("Found manifest", Project.MSG_VERBOSE);
253             
254             Manifest JavaDoc m = new Manifest JavaDoc(new FileInputStream JavaDoc(mf));
255             Attributes JavaDoc attr = m.getMainAttributes();
256
257             // Try to find bundle
258
String JavaDoc lb = (attr == null) ? null : attr.getValue("OpenIDE-Module-Localizing-Bundle");
259             if (lb != null) {
260                 File JavaDoc lbundle = new File JavaDoc(srcdir.getAbsolutePath()+File.separator+"src"+File.separatorChar+lb);
261                 log("Recognized localizing bundle "+lbundle, Project.MSG_VERBOSE);
262                 for (int i=0; i<moduleKeys.length; i++) {
263                     files.put(moduleKeys[i], lbundle);
264                 }
265             }
266
267             // Try to find XML layer
268
String JavaDoc xml = (attr == null) ? null : attr.getValue("OpenIDE-Module-Layer");
269             File JavaDoc xmlFile = null;
270             if (xml != null) {
271                 xmlFile = new File JavaDoc (srcdir.getAbsolutePath()+File.separator+"src"+File.separator+xml);
272             }
273             if (xmlFile != null && xmlFile.exists()) {
274                 SAXParserFactory JavaDoc f = SAXParserFactory.newInstance();
275                 f.setValidating(false);
276                 SAXParser JavaDoc p = f.newSAXParser();
277                 XMLReader JavaDoc reader = p.getXMLReader();
278                 reader.setEntityResolver(new EntityResolver JavaDoc () {
279                         public InputSource JavaDoc resolveEntity (String JavaDoc publicId, String JavaDoc systemId)
280                         {
281                             log ("resolveEntity "+publicId+", "+systemId, Project.MSG_DEBUG);
282                             // if ("-//NetBeans//DTD Filesystem 1.0//EN".equals (publicId)
283
// || "-//NetBeans//DTD Filesystem 1.1//EN".equals (publicId))
284
return new InputSource JavaDoc (new ByteArrayInputStream JavaDoc(new byte[0]));
285                         }
286                     });
287                 reader.setContentHandler (new SAXHandler(files));
288                 reader.parse(new InputSource JavaDoc(xmlFile.toURI().toString()));
289             }
290         }
291         catch (Exception JavaDoc e) {
292             throw new BuildException(e);
293         }
294         
295         return files;
296     }
297     
298     private class SAXHandler extends DefaultHandler JavaDoc {
299
300         private String JavaDoc path;
301
302         private Map JavaDoc<String JavaDoc,File JavaDoc> map;
303         
304         public SAXHandler(Map JavaDoc<String JavaDoc,File JavaDoc> map) {
305             this.map = map;
306         }
307
308         public void startDocument() throws SAXException JavaDoc {
309             super.startDocument();
310             path = "";
311         }
312
313         public void endElement(String JavaDoc uri, String JavaDoc lname, String JavaDoc name) throws SAXException JavaDoc {
314             super.endElement(uri, lname, name);
315             if ("folder".equals(name) || "file".equals(name)) {
316                 int i = path.lastIndexOf('/');
317                 path = (i>0)? path.substring(0, i): "";
318             }
319         }
320
321         public void startElement(String JavaDoc uri, String JavaDoc lname, String JavaDoc name, org.xml.sax.Attributes JavaDoc attributes) throws SAXException JavaDoc {
322             super.startElement(uri, lname, name, attributes);
323             // log("Handling "+uri+", "+lname+", "+name+", "+attributes, Project.MSG_DEBUG);
324
if ("folder".equals(name) || "file".equals(name)) {
325                 String JavaDoc f = attributes.getValue("name");
326                 if (name != null) {
327                     path += (path.length()==0)? f: "/"+f;
328                 }
329             }
330             else if ("attr".equals(name)) {
331                 String JavaDoc a = attributes.getValue("name");
332                 if ("SystemFileSystem.localizingBundle".equals(a)) {
333                     String JavaDoc val = attributes.getValue("stringvalue");
334                     String JavaDoc lfilename = srcdir.getAbsolutePath()+File.separator+"src"+File.separator+val.replace('.',File.separatorChar)+".properties";
335                     File JavaDoc lfile = new File JavaDoc(lfilename);
336                     log("Recognized file "+path+" with name localized in "+lfile, Project.MSG_VERBOSE);
337                     for (int i=0; i<moduleKeys.length; i++) {
338                         map.put(path, lfile);
339                     }
340                 }
341             }
342         }
343
344     }
345 }
346
347
Popular Tags