1 17 18 package org.netbeans.nbbuild; 19 20 import java.awt.image.BufferedImage ; 21 import java.io.BufferedWriter ; 22 import java.io.File ; 23 import java.io.FileWriter ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.net.URL ; 27 import java.text.MessageFormat ; 28 import java.util.Set ; 29 import java.util.SortedSet ; 30 import java.util.TreeSet ; 31 import javax.imageio.ImageIO ; 32 import org.apache.tools.ant.BuildException; 33 import org.apache.tools.ant.Project; 34 import org.apache.tools.ant.Task; 35 import org.apache.tools.ant.types.FileSet; 36 37 41 public class PrintIcon extends Task { 42 private FileSet first; 43 private FileSet second; 44 45 46 47 48 49 public PrintIcon() { 50 } 51 52 private File duplicates; 53 public void setDuplicates(File f) { 54 duplicates = f; 55 } 56 57 private File difference; 58 public void setDifference(File f) { 59 difference = f; 60 } 61 62 66 public FileSet createFirstPool() { 67 if (first != null) { 68 throw new BuildException(); 69 } 70 first = new FileSet(); 71 return first; 72 } 73 74 public FileSet createSecondPool() { 75 if (second != null) { 76 throw new BuildException(); 77 } 78 second = new FileSet(); 79 return second; 80 } 81 82 @Override 83 public void execute() throws BuildException { 84 if (first == null) { 85 throw new BuildException("You need to specify firstpool element for this task!"); } 87 88 try { 89 90 SortedSet <IconInfo> firstSet = new TreeSet <IconInfo>(); 91 for (String f : first.getDirectoryScanner(getProject()).getIncludedFiles()) { 92 File baseDir = first.getDir(getProject()); 93 File file = new File (baseDir, f); 94 firstSet.add(new IconInfo(file.toURI().toURL(), getProject())); 95 } 96 97 SortedSet <IconInfo> sndSet = new TreeSet <IconInfo>(); 98 if (second != null) { 99 for (String f : second.getDirectoryScanner(getProject()).getIncludedFiles()) { 100 File baseDir = second.getDir(getProject()); 101 File file = new File (baseDir, f); 102 sndSet.add(new IconInfo(file.toURI().toURL(), getProject())); 103 } 104 } 105 106 if (duplicates != null) { 107 Set <IconInfo> both = new TreeSet <IconInfo>(firstSet); 108 both.addAll(sndSet); 109 110 BufferedWriter os = new BufferedWriter (new FileWriter (duplicates)); 111 IconInfo prev = null; 112 boolean prevPrinted = false; 113 for (IconInfo info : both) { 114 IconInfo p = prev; 115 prev = info; 116 if (p == null || p.hash != info.hash) { 117 prevPrinted = false; 118 continue; 119 } 120 121 if (!prevPrinted) { 122 os.write(p.toString()); 123 os.newLine(); 124 prevPrinted = true; 125 } 126 127 os.write(info.toString()); 128 os.newLine(); 129 } 130 os.close(); 131 } 132 if (difference != null) { 133 SortedSet <IconInfo> union = new TreeSet <IconInfo>(firstSet); 134 union.addAll(sndSet); 135 136 BufferedWriter os = new BufferedWriter (new FileWriter (difference)); 137 for (IconInfo info : union) { 138 if (!contains(firstSet, info.hash)) { 139 os.write('+'); 140 os.write(info.toString()); 141 os.newLine(); 142 continue; 143 } 144 if (!contains(sndSet, info.hash)) { 145 os.write('-'); 146 os.write(info.toString()); 147 os.newLine(); 148 continue; 149 } 150 } 151 os.close(); 152 } 153 154 } catch (IOException ex) { 155 throw new BuildException(ex); 156 } 157 158 } 159 160 private static boolean contains(SortedSet <IconInfo> set, int hashCode) { 161 IconInfo fake = new IconInfo("", "", hashCode); 162 Set <IconInfo> greaterOrEqual = set.tailSet(fake); 163 if (greaterOrEqual.isEmpty()) { 164 return false; 165 } 166 IconInfo first = greaterOrEqual.iterator().next(); 167 return hashCode == first.hash; 168 } 169 170 static final int hash(Throwable t) { 171 String msg = t.getMessage(); 172 if (msg != null) { 173 return 7 + msg.hashCode(); 174 } 175 return 5 + t.getClass().hashCode(); 176 } 177 178 private static final class IconInfo implements Comparable <IconInfo> { 179 final String name; 180 final String path; 181 final int hash; 182 183 public IconInfo(URL from, Project p) throws IOException { 184 this.path = from.toExternalForm(); 185 int last = this.path.lastIndexOf('/'); 186 assert last >= 0; 187 this.name = this.path.substring(last + 1); 188 189 p.log("Parsing " + from, Project.MSG_VERBOSE); 190 BufferedImage image; 191 int hash; 192 try { 193 InputStream is = from.openStream(); 194 image = ImageIO.read(is); 195 is.close(); 196 int w = image.getWidth(); 197 int h = image.getHeight(); 198 hash = w * 3 + h * 7; 199 200 for (int i = 0; i < w; i++) { 201 for (int j = 0; j < h; j++) { 202 int rgb = image.getRGB(i, j); 203 hash += (rgb >> 2); 204 } 205 } 206 } catch (IOException e) { 207 p.log("Broken icon at " + from, Project.MSG_WARN); 208 hash = hash(e); 209 } catch (IndexOutOfBoundsException ex) { 210 p.log("Broken icon at " + from, Project.MSG_WARN); 211 hash = hash(ex); 212 } 213 214 this.hash = hash; 215 } 216 217 public IconInfo(String name, String path, int hash) { 218 this.name = name; 219 this.path = path; 220 this.hash = hash; 221 } 222 223 @Override 224 public int hashCode() { 225 return hash; 226 } 227 228 @Override 229 public boolean equals(Object obj) { 230 if (obj == null) 231 return false; 232 if (getClass() != obj.getClass()) 233 return false; 234 final IconInfo other = (IconInfo) obj; 235 236 if (this.path != other.path && 237 (this.path == null || !this.path.equals(other.path))) 238 return false; 239 if (this.hash != other.hash) 240 return false; 241 return true; 242 } 243 244 public int compareTo(IconInfo another) { 245 if (hash != another.hash) { 246 return hash - another.hash; 247 } 248 249 return path.compareTo(another.path); 250 } 251 252 public String toString() { 253 String h = Integer.toHexString(hash); 254 if (h.length() < 8) { 255 h = "00000000".substring(h.length()) + h; 256 } 257 String n = name; 258 if (n.length() < 30) { 259 n = n + " ".substring(n.length()); 260 } 261 262 return MessageFormat.format("{0} {1} {2}", h, n, path); 263 } 264 } } 266 | Popular Tags |