1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.BufferedInputStream ; 23 import java.io.BufferedReader ; 24 import java.io.ByteArrayInputStream ; 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.FileReader ; 28 import java.io.FilenameFilter ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.util.ArrayList ; 32 import java.util.Collection ; 33 import java.util.HashMap ; 34 import java.util.HashSet ; 35 import java.util.LinkedHashMap ; 36 import java.util.Map ; 37 import java.util.TreeMap ; 38 import java.util.jar.Attributes ; 39 import java.util.jar.Manifest ; 40 import javax.xml.parsers.SAXParser ; 41 import javax.xml.parsers.SAXParserFactory ; 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 ; 46 import org.xml.sax.InputSource ; 47 import org.xml.sax.SAXException ; 48 import org.xml.sax.XMLReader ; 49 import org.xml.sax.helpers.DefaultHandler ; 50 51 55 public class CheckBundles extends Task { 56 57 private static HashSet knownKeys; 58 59 private static String [] moduleKeys = new String [] { 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 srcdir; 68 69 public void setSrcdir(File f) { 70 if (!f.isDirectory()) 72 throw new IllegalArgumentException ("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 <String ,File > knownNames = parseManifest(srcdir); 81 82 Collection <File > bundles = new ArrayList <File >(); 83 Map <File ,String []> sources = new TreeMap <File ,String []>(); 84 85 86 try { 87 File dir = new File (srcdir, "src"); 88 if (dir.exists()) 89 scanSubdirs(dir, bundles, sources); 90 dir = new File (srcdir, "libsrc"); 91 if (dir.exists()) 92 scanSubdirs(dir, bundles, sources); 93 110 check (bundles, sources, knownNames); 111 } 112 catch (Exception e) { 113 throw new BuildException (e); 114 } 115 } 116 117 private void scan (File file, Collection <File > bundles, Map <File ,String []> sources) throws Exception { 118 File bundle = new File (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 <File > bundles, Map <File ,String []> files, Map <String ,File > knownNames) { 130 try { 131 for (File bundle : bundles) { 132 for (Map.Entry <String ,Integer > entry : entries(bundle).entrySet()) { 133 String key = entry.getKey(); 134 int line = entry.getValue(); 135 log("Looking for "+key, Project.MSG_DEBUG); 136 boolean found = false; 137 if (bundle.equals (knownNames.get(key))) { 139 log("Checked name "+key+" OK", Project.MSG_VERBOSE); 140 found = true; 141 } 142 else { 143 for (String 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 for (Map.Entry <File ,String []> entry2 : files.entrySet()) { 156 File dir = entry2.getKey(); 157 for (String 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 e) { 174 e.printStackTrace(); 175 } 176 } 177 178 private void scanSubdirs(File file, Collection <File > bundles, Map <File ,String []> srcs) throws Exception { 179 log("scanSubdirs "+file, Project.MSG_DEBUG); 180 File [] subdirs = file.listFiles(new FilenameFilter () { 181 public boolean accept (File f, String name) { 182 return new File (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 193 private void addSources(File dir, Map <File ,String []> map) throws Exception { 194 File [] files = dir.listFiles(new FilenameFilter () { 195 public boolean accept(File dir, String name) { 196 if (name.endsWith(".java")) { 197 return true; 198 } 199 return false; 200 } 201 }); 202 String [] srcs = new String [files.length]; 203 for (int i=0; i<files.length; i++) { 204 InputStream is = new BufferedInputStream (new FileInputStream (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 (arr, 0, len); 210 } 211 } 212 map.put(dir, srcs); 213 return; 214 } 215 216 219 private Map <String ,Integer > entries(File bundle) throws IOException { 220 Map <String ,Integer > entries = new LinkedHashMap <String ,Integer >(); 221 BufferedReader r = new BufferedReader (new FileReader (bundle)); 222 String 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 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 <String ,File > parseManifest(File dir) { 244 Map <String ,File > files = new HashMap <String ,File >(10); 245 try { 246 File mf = new File (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 m = new Manifest (new FileInputStream (mf)); 255 Attributes attr = m.getMainAttributes(); 256 257 String lb = (attr == null) ? null : attr.getValue("OpenIDE-Module-Localizing-Bundle"); 259 if (lb != null) { 260 File lbundle = new File (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 String xml = (attr == null) ? null : attr.getValue("OpenIDE-Module-Layer"); 269 File xmlFile = null; 270 if (xml != null) { 271 xmlFile = new File (srcdir.getAbsolutePath()+File.separator+"src"+File.separator+xml); 272 } 273 if (xmlFile != null && xmlFile.exists()) { 274 SAXParserFactory f = SAXParserFactory.newInstance(); 275 f.setValidating(false); 276 SAXParser p = f.newSAXParser(); 277 XMLReader reader = p.getXMLReader(); 278 reader.setEntityResolver(new EntityResolver () { 279 public InputSource resolveEntity (String publicId, String systemId) 280 { 281 log ("resolveEntity "+publicId+", "+systemId, Project.MSG_DEBUG); 282 return new InputSource (new ByteArrayInputStream (new byte[0])); 285 } 286 }); 287 reader.setContentHandler (new SAXHandler(files)); 288 reader.parse(new InputSource (xmlFile.toURI().toString())); 289 } 290 } 291 catch (Exception e) { 292 throw new BuildException(e); 293 } 294 295 return files; 296 } 297 298 private class SAXHandler extends DefaultHandler { 299 300 private String path; 301 302 private Map <String ,File > map; 303 304 public SAXHandler(Map <String ,File > map) { 305 this.map = map; 306 } 307 308 public void startDocument() throws SAXException { 309 super.startDocument(); 310 path = ""; 311 } 312 313 public void endElement(String uri, String lname, String name) throws SAXException { 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 uri, String lname, String name, org.xml.sax.Attributes attributes) throws SAXException { 322 super.startElement(uri, lname, name, attributes); 323 if ("folder".equals(name) || "file".equals(name)) { 325 String 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 a = attributes.getValue("name"); 332 if ("SystemFileSystem.localizingBundle".equals(a)) { 333 String val = attributes.getValue("stringvalue"); 334 String lfilename = srcdir.getAbsolutePath()+File.separator+"src"+File.separator+val.replace('.',File.separatorChar)+".properties"; 335 File lfile = new File (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 |