1 19 20 package org.netbeans.nbbuild; 21 22 import java.awt.Dimension ; 23 import java.io.BufferedOutputStream ; 24 import java.io.ByteArrayInputStream ; 25 import java.io.File ; 26 import java.io.FileFilter ; 27 import java.io.FileInputStream ; 28 import java.io.FileNotFoundException ; 29 import java.io.FileOutputStream ; 30 import java.io.FilenameFilter ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.PrintWriter ; 34 import java.util.ArrayList ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.StringTokenizer ; 38 39 import org.apache.tools.ant.BuildException; 40 import org.apache.tools.ant.DirectoryScanner; 41 import org.apache.tools.ant.Project; 42 import org.apache.tools.ant.taskdefs.Copy; 43 import org.apache.tools.ant.taskdefs.MatchingTask; 44 import org.apache.tools.ant.types.FileSet; 45 46 64 public class CopyIcons extends MatchingTask { 65 66 private int depth = 0; 67 private List <File > projectDirList = new ArrayList <File >(); 68 private List <ProjectIconInfo> prjIconInfoList = new ArrayList <ProjectIconInfo>(); 69 70 File baseDir = null; 71 public void setNbsrcroot(File f) { 72 baseDir = f; 73 } 74 75 File destDir = null; 76 public void setDestdir(File f) { 77 destDir = f; 78 } 79 80 int userDepth = 4; 81 public void setDepth(String s) { 82 userDepth = Integer.parseInt(s); 83 } 84 85 String iconIncludes = "src/**/*.png,src/**/*.gif"; 86 public void setIconincludes(String s) { 87 iconIncludes = s; 88 } 89 90 String iconExcludes = ""; 91 public void setIconexcludes(String s) { 92 iconExcludes = s; 93 } 94 95 String prjIncludes = ""; 96 public void setPrjincludes(String s) { 97 prjIncludes = s; 98 } 99 100 String prjExcludes = ""; 101 public void setPrjExcludes(String s) { 102 prjExcludes = s; 103 } 104 105 boolean showEmpty = false; 106 public void setShowempty(boolean b) { 107 showEmpty = b; 108 } 109 110 public void execute() throws BuildException { 111 if (baseDir == null || destDir == null) { 112 log("Nbsrcroot or destdir are not specified."); 113 return; 114 } 115 scanForProjectDirs(baseDir); 116 for (Iterator <File > iter = projectDirList.iterator(); iter.hasNext(); ) { 117 File f = iter.next(); 118 processProjectDir(f); 119 } 120 copyToDestDir(prjIconInfoList); 121 dumpListToHTML(prjIconInfoList); 122 } 123 124 private ImageInfo readImageInfo(File fl) throws IOException { 125 Dimension dim = null; 126 ImageInfo imageInfo = null; 127 ByteArrayInputStream bais = null; 128 try { 129 bais = readSomeBytes(fl); 130 if (isGIF(bais)) { 131 imageInfo = new ImageInfo(readGIFDimension(bais), ImageInfo.GIF); 132 } else if (isPNG(bais)) { 133 imageInfo = new ImageInfo(readPNGDimension(bais), ImageInfo.PNG); 134 } 135 } catch (IOException ex) { 136 ex.printStackTrace(); 137 } finally { 138 bais.close(); 139 } 140 return imageInfo; 141 } 142 143 private ByteArrayInputStream readSomeBytes(File fl) throws IOException { 144 byte buffer[] = new byte[30]; 145 FileInputStream fis = null; 146 fis = new FileInputStream (fl); 147 fis.read(buffer); 148 fis.close(); 149 return new ByteArrayInputStream (buffer); 150 } 151 152 private boolean isGIF(InputStream is) throws IOException { 153 is.reset(); 154 byte buf[]; 155 is.read(buf = new byte[3]); 156 int signatureBuffer[] = parseUnsigned(buf); 157 if (((char) signatureBuffer[0] == 'G') && 158 ((char) signatureBuffer[1] == 'I') && 159 ((char) signatureBuffer[2] == 'F')) { 160 return true; 161 } 162 return false; 163 } 164 165 private boolean isPNG(InputStream is) throws IOException { 166 is.reset(); 167 byte buf[]; 168 is.read(buf = new byte[8]); 169 int signatureBuffer[] = parseUnsigned(buf); 170 if ((signatureBuffer[0] == 137) && (signatureBuffer[1] == 80) && 172 (signatureBuffer[2] == 78) && 173 (signatureBuffer[3] == 71) && 174 (signatureBuffer[4] == 13) && 175 (signatureBuffer[5] == 10) && 176 (signatureBuffer[6] == 26) && 177 (signatureBuffer[7] == 10)) { 178 return true; 179 } 180 return false; 181 } 182 183 private Dimension readGIFDimension(InputStream is) throws IOException { 184 byte buf []; 185 is.read(new byte[3]); is.read(buf = new byte[2]); int widthBuf[] = parseUnsigned(buf); 188 int width = (widthBuf[1] << 8) + widthBuf[0]; 189 is.read(buf = new byte[2]); int heightBuf[] = parseUnsigned(buf); 191 int height = (heightBuf[1] << 8) + heightBuf[0]; 192 return new Dimension (width, height); 193 } 194 195 private Dimension readPNGDimension(InputStream is) throws IOException { 196 byte buf[]; 197 is.read(new byte[4]); is.read(new byte[4]); is.read(buf = new byte[4]); int widthBuf[] = parseUnsigned(buf); 201 int width = (widthBuf[0] << 24) + (widthBuf[1] << 16) + (widthBuf[2] << 8) + widthBuf[3]; 202 is.read(buf = new byte[4]); int heightBuf[] = parseUnsigned(buf); 204 int height = (heightBuf[0] << 24) + (heightBuf[1] << 16) + (heightBuf[2] << 8) + heightBuf[3]; 205 return new Dimension (width, height); 206 } 207 208 private static int[] parseUnsigned(byte[] src) { 209 int[] val = new int[src.length]; 210 for (int i = 0; i < src.length; i ++) { 211 val[i] = (src[i] < 0) && (src[i] >= -128) ? 256 + src[i] : src[i]; 212 } 213 return val; 214 } 215 216 218 229 231 private static class ImageInfo { 232 233 public static final int GIF = 1; 234 public static final int PNG = 2; 235 236 private Dimension dim; 237 private int type; 238 private String path; 239 private String ext; 240 241 public ImageInfo(Dimension dm, int tp) { 242 this(null, dm, tp); 243 } 244 245 public ImageInfo(String pth, Dimension dm, int tp) { 246 path = pth; 247 dim = dm; 248 type = tp; 249 } 250 251 public String getPath() { 252 return path; 253 } 254 255 public void setPath(String pth) { 256 path = pth; 257 } 258 259 public int getHeight() { 260 return dim.height; 261 } 262 263 public int getWidth() { 264 return dim.width; 265 } 266 267 public String getType() { 268 if (type == GIF) { 269 return "GIF"; 270 } else if (type == PNG) { 271 return "PNG"; 272 } 273 return ""; 274 } 275 276 public String getExt() { 277 return ext; 278 } 279 280 public String setExt(String ex) { 281 return ext = ex; 282 } 283 284 } 285 286 private static class ProjectIconInfo { 287 288 public String prjPath; 289 public List <ImageInfo> matchingIcons; 290 public List <ImageInfo> notmatchingIcons; 291 292 public ProjectIconInfo(String pth, List <ImageInfo> mi, List <ImageInfo> nmi) { 293 prjPath = pth; 294 matchingIcons = mi; 295 notmatchingIcons = nmi; 296 } 297 298 } 299 300 302 private void dumpListToHTML(List <ProjectIconInfo> lst) { 303 File reportFile = new File (destDir, "index.html"); 304 FileOutputStream fos = null; 305 try { 306 fos = new FileOutputStream (reportFile); 307 } catch (FileNotFoundException ex) { 308 ex.printStackTrace(); 309 } 310 PrintWriter pw = new PrintWriter (new BufferedOutputStream (fos)); 311 pw.println("<html>"); 312 pw.println("<head>"); 313 pw.println("<style type=\"text/css\">\nbody { font-family: Tahoma, Verdana, sans-serif }\n</style>"); 314 pw.println("</head>"); 315 pw.println("<body>"); 316 pw.println("<h2>List of icons in NetBeans projects</h2>"); 317 pw.println("<h3>NetBeans Source Root: " + baseDir + "<br/>"); 318 pw.println("Destination Directory: " + destDir + "</h3>"); 319 pw.println("<p style=\"width: 70%\"><b>Description:</b><br/> New Image is image in the Destination Directory, Orig. Image is image in NetBeans Source Root. " + 320 "By replacing the image in Destination Directory under coresponding module and path you can prepare rebranded " + 321 "icons in paralel directory structure and then copy them over to NetBeans Source Root. Orig. Image is " + 322 "in the table just for comparison and reference what image was already changed.</p>"); 323 for (Iterator <ProjectIconInfo> iter = prjIconInfoList.iterator(); iter.hasNext(); ) { 324 ProjectIconInfo info = iter.next(); 325 if (!showEmpty && info.matchingIcons.size() == 0) { 326 continue; 327 } 328 pw.println("<p>Module name: <b>" + info.prjPath + "</b></p>"); 329 pw.println("<p style=\"margin-left: 20px\">"); 330 if (info.matchingIcons.size() == 0) { 331 pw.println("<i>--- No icons ---</i>"); 332 pw.println("</p>"); 333 continue; 334 } 335 pw.println("<table width=\"80%\"border=\"1\" cellpadding=\"3\" cellspacing=\"0\">"); 336 pw.println("<tr><td><b>Resource Path</b></td>" + 337 "<td align=\"center\"><b> New Image </b></td>" + 338 "<td align=\"center\"><b> Orig. image </b></td>" + 339 "<td align=\"center\"><b> W x H </b></td>" + 340 "<td align=\"center\"><b> Extension </b></td>" + 341 "<td align=\"center\"><b> Real Type </b></td></tr>"); 342 for (Iterator <ImageInfo> goodIter = info.matchingIcons.iterator(); goodIter.hasNext(); ) { 343 ImageInfo goodInfo = goodIter.next(); 344 String iconPath = goodInfo.getPath(); 345 String copiedIconPath = info.prjPath + File.separator + iconPath; 346 String originalIconPath = baseDir.getAbsolutePath() + File.separator + info.prjPath + File.separator + iconPath; 347 pw.println("<tr>"); 348 pw.println("<td>"); 349 pw.println("<a HREF=\"" + copiedIconPath + "\">" + iconPath + "</a>"); 350 pw.println("</td>"); 351 pw.println("<td align=\"center\">"); 352 pw.println("<img SRC=\"" + copiedIconPath + "\"/>"); pw.println("</td>"); 354 pw.println("<td align=\"center\">"); 355 pw.println("<img SRC=\"file://" + originalIconPath + "\"/>"); pw.println("</td>"); 357 pw.println("<td align=\"center\">" + goodInfo.getWidth() + " x " + goodInfo.getHeight() + "</td>"); 358 pw.println("<td align=\"center\">" + goodInfo.getExt().toUpperCase() + "</td>"); 359 if (!goodInfo.getExt().equalsIgnoreCase(goodInfo.getType())) { 360 pw.println("<td align=\"center\"><font color=\"Orange\">" + goodInfo.getType() + "</font></td>"); 361 } else { 362 pw.println("<td align=\"center\">" + goodInfo.getType() + "</td>"); 363 } 364 pw.println("</tr>"); 365 } 366 pw.println("</table>"); 367 pw.println("</p>"); 368 } 369 pw.println("</body>"); 370 pw.println("</html>"); 371 pw.flush(); 372 pw.close(); 373 log("---> Report was written to file: " + reportFile.getAbsolutePath()); 374 } 375 376 private void copyToDestDir(List <ProjectIconInfo> prjInfoList) { 377 FileSet fs = null; 378 for (Iterator <ProjectIconInfo> iter = prjInfoList.iterator(); iter.hasNext(); ) { 379 fs = new FileSet(); 380 log("Setting basedir for fileset: " + baseDir, Project.MSG_VERBOSE); 381 ProjectIconInfo prjIconInfo = iter.next(); 382 fs.setDir(new File (baseDir, prjIconInfo.prjPath)); 383 int numFilesToCopy = prjIconInfo.matchingIcons.size() + prjIconInfo.notmatchingIcons.size(); 384 for (Iterator <ImageInfo> matchInfoIter = prjIconInfo.matchingIcons.iterator(); matchInfoIter.hasNext(); ) { 385 ImageInfo info = matchInfoIter.next(); 386 log("Adding file to matching fileset: " + info.getPath(), Project.MSG_VERBOSE); 387 fs.setIncludes(info.getPath()); 388 } 389 for (Iterator <ImageInfo> notmatchInfoIter = prjIconInfo.notmatchingIcons.iterator(); notmatchInfoIter.hasNext(); ) { 390 ImageInfo info = notmatchInfoIter.next(); 391 log("Adding file to notmatching fileset: " + info.getPath(), Project.MSG_VERBOSE); 392 fs.setIncludes(info.getPath()); 393 } 394 if (numFilesToCopy > 0) { 395 Copy copy = (Copy) getProject().createTask("copy"); 396 copy.addFileset(fs); 397 File dest = new File (destDir, prjIconInfo.prjPath); 398 dest.mkdir(); 399 copy.setTodir(dest); 400 copy.init(); 401 copy.setLocation(getLocation()); 402 copy.execute(); 403 } 404 } 405 } 406 407 409 private void scanForProjectDirs(File fl) { 410 if (depth > userDepth) return; 411 File allFiles[] = fl.listFiles(new FileFilter () { 415 public boolean accept(File pathname) { 416 if (pathname.isDirectory()) { 417 return true; 418 } 419 return false; 420 } 421 }); 422 depth++; 423 for (File f : allFiles) { 424 if (isProjectDir(f)) { 425 projectDirList.add(f); 427 log(f.toString(), Project.MSG_VERBOSE); 428 scanForProjectDirs(f); 429 } else { 430 scanForProjectDirs(f); 431 } 432 } 433 depth--; 434 } 435 436 private boolean isProjectDir(File fl) { 437 File prjDirs[] = fl.listFiles(new FilenameFilter () { 438 public boolean accept(File dir, String name) { 439 if ("nbproject".equals(name)) { 440 return true; 441 } 442 return false; 443 } 444 }); 445 if (prjDirs.length != 1) { 446 return false; 447 } 448 String prjFiles[] = prjDirs[0].list(new FilenameFilter () { 449 public boolean accept(File dir, String name) { 450 if ("project.xml".equals(name)) { 451 return true; 452 } 453 return false; 454 } 455 }); 456 if (prjFiles.length != 1) { 457 return false; 458 } 459 return true; 460 } 461 462 private void processProjectDir(File f) { 463 String prjPath = null; 464 prjPath = f.getAbsolutePath().substring(baseDir.getAbsolutePath().length() + 1); 468 log("Processing project dir: " + prjPath); 470 DirectoryScanner ds = new DirectoryScanner(); 471 ds.setBasedir(f); 472 ds.setIncludes(getAsArray(iconIncludes)); 473 ds.setExcludes(getAsArray(iconExcludes)); 474 ds.setCaseSensitive(false); 475 ds.scan(); 476 String [] files = ds.getIncludedFiles(); 477 log(" Found " + files.length + " files in " + f); 478 List <ImageInfo> goodIcons = new ArrayList <ImageInfo>(); 479 List <ImageInfo> badIcons = new ArrayList <ImageInfo>(); 480 for (String file : files) { 481 String ext = file.substring(file.lastIndexOf('.') + 1); 482 if (ext.equalsIgnoreCase("gif") || ext.equalsIgnoreCase("png")) { 483 File iconFile = new File (f, file); 484 try { 485 ImageInfo imageInfo = null; 486 imageInfo = readImageInfo(iconFile); 487 if (imageInfo != null) { 488 imageInfo.setPath(file); 489 imageInfo.setExt(ext); 490 int w = imageInfo.getWidth(); 491 int h = imageInfo.getHeight(); 492 if ((w == 8 && h == 8) || (w == 16 && h == 16) || 493 (w == 24 && h == 24) || (w == 32 && h == 32)) { 494 goodIcons.add(imageInfo); 495 } else { 496 badIcons.add(imageInfo); 497 } 498 } 499 } catch (IOException ex) { 500 ex.printStackTrace(); 501 } 502 } 503 } 504 ProjectIconInfo prjIconInfo = new ProjectIconInfo(prjPath, goodIcons, badIcons); 505 prjIconInfoList.add(prjIconInfo); 506 } 507 508 private String [] getAsArray(String s) { 509 List <String > list = new ArrayList <String >(); 510 for (StringTokenizer stok = new StringTokenizer (s, ","); stok.hasMoreTokens(); ) { 511 String token = stok.nextToken().trim(); 512 list.add(token); 513 } 514 return list.toArray(new String [list.size()]); 515 } 516 517 } 518 | Popular Tags |