1 11 package org.eclipse.update.internal.jarprocessor; 12 13 import java.io.*; 14 import java.util.*; 15 import java.util.jar.*; 16 17 21 public class JarProcessor { 22 private List steps = new ArrayList(); 23 private String workingDirectory = ""; private int depth = -1; 25 private boolean verbose = false; 26 private boolean processAll = false; 27 private LinkedList containingInfs = new LinkedList(); 28 29 static public JarProcessor getUnpackProcessor(Properties properties) { 30 if (!canPerformUnpack()) 31 throw new UnsupportedOperationException (); 32 JarProcessor processor = new JarProcessor(); 33 processor.addProcessStep(new UnpackStep(properties)); 34 return processor; 35 } 36 37 static public JarProcessor getPackProcessor(Properties properties) { 38 if (!canPerformPack()) 39 throw new UnsupportedOperationException (); 40 JarProcessor processor = new JarProcessor(); 41 processor.addProcessStep(new PackStep(properties)); 42 return processor; 43 } 44 45 static public boolean canPerformPack() { 46 return PackStep.canPack(); 47 } 48 49 static public boolean canPerformUnpack() { 50 return UnpackStep.canUnpack(); 51 } 52 53 public String getWorkingDirectory() { 54 return workingDirectory; 55 } 56 57 public void setWorkingDirectory(String dir) { 58 if(dir != null) 59 workingDirectory = dir; 60 } 61 62 public void setVerbose(boolean verbose) { 63 this.verbose = verbose; 64 } 65 66 public void setProcessAll(boolean all){ 67 this.processAll = all; 68 } 69 70 public void addProcessStep(IProcessStep step) { 71 steps.add(step); 72 } 73 74 public void clearProcessSteps() { 75 steps.clear(); 76 } 77 78 88 private void recreateJar(JarFile jar, JarOutputStream outputJar, Map replacements, File directory, Properties inf) throws IOException { 89 InputStream in = null; 90 boolean marked = false; 91 try { 92 Enumeration entries = jar.entries(); 93 for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) { 94 File replacement = null; 95 JarEntry newEntry = null; 96 if (replacements.containsKey(entry.getName())) { 97 String name = (String ) replacements.get(entry.getName()); 98 replacement = new File(directory, name); 99 if (name != null) { 100 if (replacement.exists()) { 101 try { 102 in = new BufferedInputStream(new FileInputStream(replacement)); 103 newEntry = new JarEntry(name); 104 } catch (Exception e) { 105 if (verbose) { 106 e.printStackTrace(); 107 System.out.println("Warning: Problem reading " +replacement.getPath() + ", using " + jar.getName() + File.separator + entry.getName() + " instead."); 108 } 109 } 110 } else if (verbose) { 111 System.out.println("Warning: " + replacement.getPath() + " not found, using " + jar.getName() + File.separator + entry.getName() + " instead."); 112 } 113 } 114 } 115 if (newEntry == null) { 116 try { 117 in = new BufferedInputStream(jar.getInputStream(entry)); 118 newEntry = new JarEntry(entry.getName()); 119 } catch( Exception e ) { 120 if(verbose) { 121 e.printStackTrace(); 122 System.out.println("ERROR: problem reading " + entry.getName() + " from " + jar.getName()); 123 } 124 continue; 125 } 126 } 127 newEntry.setTime(entry.getTime()); 128 outputJar.putNextEntry(newEntry); 129 if (entry.getName().equals(Utils.MARK_FILE_NAME)) { 130 Utils.storeProperties(inf, outputJar); 132 marked = true; 133 } else { 134 Utils.transferStreams(in, outputJar, false); 135 } 136 outputJar.closeEntry(); 137 in.close(); 138 139 if (replacement != null) { 141 replacement.delete(); 142 } 143 } 144 if (!marked) { 145 JarEntry entry = new JarEntry(Utils.MARK_FILE_NAME); 146 outputJar.putNextEntry(entry); 147 Utils.storeProperties(inf, outputJar); 148 outputJar.closeEntry(); 149 } 150 } finally { 151 Utils.close(outputJar); 152 Utils.close(jar); 153 Utils.close(in); 154 } 155 } 156 157 private String recursionEffect(String entryName) { 158 String result = null; 159 for (Iterator iter = steps.iterator(); iter.hasNext();) { 160 IProcessStep step = (IProcessStep) iter.next(); 161 162 result = step.recursionEffect(entryName); 163 if (result != null) 164 entryName = result; 165 } 166 return result; 167 } 168 169 private void extractEntries(JarFile jar, File tempDir, Map data, Properties inf) throws IOException { 170 if(inf != null ) { 171 if(inf.containsKey(Utils.MARK_EXCLUDE_CHILDREN)){ 173 String excludeChildren = inf.getProperty(Utils.MARK_EXCLUDE_CHILDREN); 174 if( Boolean.valueOf(excludeChildren).booleanValue() ) 175 if(verbose){ 176 for(int i = 0; i <= depth; i++) 177 System.out.print(" "); System.out.println("Children of " + jar.getName() + "are excluded from processing."); 179 } 180 return; 181 } 182 } 183 184 Enumeration entries = jar.entries(); 185 if (entries.hasMoreElements()) { 186 for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) { 187 String name = entry.getName(); 188 String newName = recursionEffect(name); 189 if (newName != null) { 190 if(verbose){ 191 for(int i = 0; i <= depth; i++) 192 System.out.print(" "); System.out.println("Processing nested file: " + name); } 195 File extracted = new File(tempDir, name); 197 File parentDir = extracted.getParentFile(); 198 if (!parentDir.exists()) 199 parentDir.mkdirs(); 200 201 InputStream in = null; 202 OutputStream out = null; 203 try { 204 in = jar.getInputStream(entry); 205 out = new BufferedOutputStream(new FileOutputStream(extracted)); 206 Utils.transferStreams(in, out, true); } finally { 208 Utils.close(in); 209 Utils.close(out); 210 } 211 extracted.setLastModified(entry.getTime()); 212 213 containingInfs.addFirst(inf); 215 String dir = getWorkingDirectory(); 216 setWorkingDirectory(parentDir.getCanonicalPath()); 217 File result = processJar(extracted); 218 219 newName = name.substring(0, name.length() - extracted.getName().length()) + result.getName(); 220 data.put(name, newName); 221 222 setWorkingDirectory(dir); 223 containingInfs.removeFirst(); 224 225 if (!name.equals(newName)) 227 extracted.delete(); 228 } 229 } 230 } 231 } 232 233 private File preProcess(File input, File tempDir) { 234 File result = null; 235 for (Iterator iter = steps.iterator(); iter.hasNext();) { 236 IProcessStep step = (IProcessStep) iter.next(); 237 result = step.preProcess(input, tempDir, containingInfs); 238 if (result != null) 239 input = result; 240 } 241 return input; 242 } 243 244 private File postProcess(File input, File tempDir) { 245 File result = null; 246 for (Iterator iter = steps.iterator(); iter.hasNext();) { 247 IProcessStep step = (IProcessStep) iter.next(); 248 result = step.postProcess(input, tempDir, containingInfs); 249 if (result != null) 250 input = result; 251 } 252 return input; 253 } 254 255 private void adjustInf(File input, Properties inf) { 256 for (Iterator iter = steps.iterator(); iter.hasNext();) { 257 IProcessStep step = (IProcessStep) iter.next(); 258 step.adjustInf(input, inf, containingInfs); 259 } 260 } 261 262 public File processJar(File input) throws IOException { 263 ++depth; 264 long lastModified = input.lastModified(); 265 File workingDir = new File(getWorkingDirectory()); 266 if (!workingDir.exists()) 267 workingDir.mkdirs(); 268 269 boolean skip = Utils.shouldSkipJar(input, processAll, verbose); 270 if (depth == 0 && verbose) { 271 if (skip) 272 System.out.println("Skipping " + input.getPath()); else { 274 System.out.print("Running "); for (Iterator iter = steps.iterator(); iter.hasNext();) { 276 IProcessStep step = (IProcessStep) iter.next(); 277 System.out.print(step.getStepName() + " "); } 279 System.out.println("on " + input.getPath()); } 281 } 282 283 if (skip) { 284 --depth; 286 return input; 287 } 288 289 File workingFile = preProcess(input, workingDir); 291 292 File tempDir = null; 294 if (depth == 0) { 295 tempDir = new File(workingDir, "temp." + workingFile.getName()); } else { 297 File parent = workingDir.getParentFile(); 298 tempDir = new File(parent, "temp_" + depth + '_' + workingFile.getName()); } 300 301 JarFile jar = new JarFile(workingFile, false); 302 Map replacements = new HashMap(); 303 Properties inf = Utils.getEclipseInf(workingFile, verbose); 304 extractEntries(jar, tempDir, replacements, inf); 305 306 if (inf != null) 307 adjustInf(workingFile, inf); 308 309 File tempJar = null; 312 tempJar = new File(tempDir, workingFile.getName()); 313 File parent = tempJar.getParentFile(); 314 if (!parent.exists()) 315 parent.mkdirs(); 316 JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(tempJar))); 317 recreateJar(jar, jarOut, replacements, tempDir, inf); 318 319 jar.close(); 320 if (tempJar != null) { 321 if (!workingFile.equals(input)) { 322 workingFile.delete(); 323 } 324 workingFile = tempJar; 325 } 326 327 File result = postProcess(workingFile, workingDir); 329 330 normalize(result, workingDir); 332 333 if (!result.equals(workingFile) && !workingFile.equals(input)) 334 workingFile.delete(); 335 if (!result.getParentFile().equals(workingDir)) { 336 File finalFile = new File(workingDir, result.getName()); 337 if (finalFile.exists()) 338 finalFile.delete(); 339 result.renameTo(finalFile); 340 result = finalFile; 341 } 342 343 if (tempDir.exists()) 344 Utils.clear(tempDir); 345 346 result.setLastModified(lastModified); 347 --depth; 348 return result; 349 } 350 351 private void normalize(File input, File workingDirectory) { 352 if(input.getName().endsWith(Utils.PACKED_SUFFIX)) { 353 return; 355 } 356 try { 357 File tempJar = new File(workingDirectory, "temp_" + input.getName()); JarFile jar = null; 359 try { 360 jar = new JarFile(input, false); 361 } catch (JarException e) { 362 return ; 364 } 365 JarOutputStream jarOut = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(tempJar))); 366 InputStream in = null; 367 try { 368 Enumeration entries = jar.entries(); 369 for (JarEntry entry = (JarEntry) entries.nextElement(); entry != null; entry = entries.hasMoreElements() ? (JarEntry) entries.nextElement() : null) { 370 JarEntry newEntry = new JarEntry(entry.getName()); 371 newEntry.setTime(entry.getTime()); 372 in = new BufferedInputStream(jar.getInputStream(entry)); 373 jarOut.putNextEntry(newEntry); 374 Utils.transferStreams(in, jarOut, false); 375 jarOut.closeEntry(); 376 in.close(); 377 } 378 } finally { 379 Utils.close(jarOut); 380 Utils.close(jar); 381 Utils.close(in); 382 } 383 tempJar.setLastModified(input.lastModified()); 384 input.delete(); 385 tempJar.renameTo(input); 386 } catch (IOException e) { 387 if (verbose) { 388 System.out.println("Error normalizing jar " + input.getName()); e.printStackTrace(); 390 } 391 } 392 } 393 } 394 | Popular Tags |