protected void generateJarFile(File jarFile, boolean standAlone, File dir) throws IOException { Verbose.log("Generating jar file ... " + jarFile); FileOutputStream out = new FileOutputStream(jarFile); InputStream manifestIo = getManifest(); Manifest manifest = new Manifest(manifestIo); JarOutputStream jar = new JarOutputStream(out, manifest); int rootLen = dir.getAbsolutePath().length(); int len = "java".length(); for (File javaFile : javaFiles) { String fileName = javaFile.getPath(); String classFile = fileName.substring(0, fileName.length() - len) + "class"; String className = classFile.substring(rootLen + 1); addFileToJar(className, classFile, jar); String javaName = fileName.substring(rootLen + 1); addFileToJar(javaName, fileName, jar); } if (standAlone) { Verbose.log("Adding runtime classes to the jar"); addRuntimeClasses(jar); } jar.close(); out.close(); Verbose.log("Generated jar file " + jarFile); }
/** Create a jar file containing one or more entries. */ File createJar(File jar, String... entries) throws IOException { OutputStream out = new FileOutputStream(jar); try { JarOutputStream jos = new JarOutputStream(out); for (String e : entries) { jos.putNextEntry(new JarEntry(getPathForZipEntry(e))); jos.write(getBodyForEntry(e).getBytes()); } jos.close(); } finally { out.close(); } return jar; }
public static void unpack(File inFile) { JarOutputStream out = null; InputStream in = null; String inName = inFile.getPath(); String outName; if (inName.endsWith(".pack.gz")) { outName = inName.substring(0, inName.length() - 8); } else if (inName.endsWith(".pack")) { outName = inName.substring(0, inName.length() - 5); } else { outName = inName + ".unpacked"; } try { Pack200.Unpacker unpacker = Pack200.newUnpacker(); out = new JarOutputStream(new FileOutputStream(outName)); in = new FileInputStream(inName); if (inName.endsWith(".gz")) in = new GZIPInputStream(in); unpacker.unpack(in, out); } catch (IOException ex) { ex.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException ex) { System.err.println("Error closing file: " + ex.getMessage()); } } if (out != null) { try { out.flush(); out.close(); } catch (IOException ex) { System.err.println("Error closing file: " + ex.getMessage()); } } } }
/** Creates a patch from the two passed in files, writing the result to <code>os</code>. */ public static void createPatch(String oldPath, String newPath, OutputStream os, boolean minimal) throws IOException { JarFile2 oldJar = new JarFile2(oldPath); JarFile2 newJar = new JarFile2(newPath); try { Iterator entries; HashMap moved = new HashMap(); HashSet visited = new HashSet(); HashSet implicit = new HashSet(); HashSet moveSrc = new HashSet(); HashSet newEntries = new HashSet(); // FIRST PASS // Go through the entries in new jar and // determine which files are candidates for implicit moves // ( files that has the same filename and same content in old.jar // and new.jar ) // and for files that cannot be implicitly moved, we will either // find out whether it is moved or new (modified) entries = newJar.getJarEntries(); if (entries != null) { while (entries.hasNext()) { JarEntry newEntry = (JarEntry) entries.next(); String newname = newEntry.getName(); // Return best match of contents, will return a name match if possible String oldname = oldJar.getBestMatch(newJar, newEntry); if (oldname == null) { // New or modified entry if (_debug) { System.out.println("NEW: " + newname); } newEntries.add(newname); } else { // Content already exist - need to do a move // Should do implicit move? Yes, if names are the same, and // no move command already exist from oldJar if (oldname.equals(newname) && !moveSrc.contains(oldname)) { if (_debug) { System.out.println(newname + " added to implicit set!"); } implicit.add(newname); } else { // The 1.0.1/1.0 JarDiffPatcher cannot handle // multiple MOVE command with same src. // The work around here is if we are going to generate // a MOVE command with duplicate src, we will // instead add the target as a new file. This way // the jardiff can be applied by 1.0.1/1.0 // JarDiffPatcher also. if (!minimal && (implicit.contains(oldname) || moveSrc.contains(oldname))) { // generate non-minimal jardiff // for backward compatibility if (_debug) { System.out.println("NEW: " + newname); } newEntries.add(newname); } else { // Use newname as key, since they are unique if (_debug) { System.err.println("moved.put " + newname + " " + oldname); } moved.put(newname, oldname); moveSrc.add(oldname); } // Check if this disables an implicit 'move <oldname> <oldname>' if (implicit.contains(oldname) && minimal) { if (_debug) { System.err.println("implicit.remove " + oldname); System.err.println("moved.put " + oldname + " " + oldname); } implicit.remove(oldname); moved.put(oldname, oldname); moveSrc.add(oldname); } } } } } // if (entries != null) // SECOND PASS: <deleted files> = <oldjarnames> - <implicitmoves> - // <source of move commands> - <new or modified entries> ArrayList deleted = new ArrayList(); entries = oldJar.getJarEntries(); if (entries != null) { while (entries.hasNext()) { JarEntry oldEntry = (JarEntry) entries.next(); String oldName = oldEntry.getName(); if (!implicit.contains(oldName) && !moveSrc.contains(oldName) && !newEntries.contains(oldName)) { if (_debug) { System.err.println("deleted.add " + oldName); } deleted.add(oldName); } } } // DEBUG if (_debug) { // DEBUG: print out moved map entries = moved.keySet().iterator(); if (entries != null) { System.out.println("MOVED MAP!!!"); while (entries.hasNext()) { String newName = (String) entries.next(); String oldName = (String) moved.get(newName); System.out.println("key is " + newName + " value is " + oldName); } } // DEBUG: print out IMOVE map entries = implicit.iterator(); if (entries != null) { System.out.println("IMOVE MAP!!!"); while (entries.hasNext()) { String newName = (String) entries.next(); System.out.println("key is " + newName); } } } JarOutputStream jos = new JarOutputStream(os); // Write out all the MOVEs and REMOVEs createIndex(jos, deleted, moved); // Put in New and Modified entries entries = newEntries.iterator(); if (entries != null) { while (entries.hasNext()) { String newName = (String) entries.next(); if (_debug) { System.out.println("New File: " + newName); } writeEntry(jos, newJar.getEntryByName(newName), newJar); } } jos.finish(); jos.close(); } catch (IOException ioE) { throw ioE; } finally { try { oldJar.getJarFile().close(); } catch (IOException e1) { // ignore } try { newJar.getJarFile().close(); } catch (IOException e1) { // ignore } } // finally }