diff --git a/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java b/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java index 67ea645..ae18990 100644 --- a/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java +++ b/core/src/main/java/com/threerings/getdown/cache/GarbageCollector.java @@ -6,6 +6,8 @@ package com.threerings.getdown.cache; import java.io.File; + +import com.threerings.getdown.data.Resource; import com.threerings.getdown.util.FileUtil; /** @@ -55,9 +57,9 @@ public class GarbageCollector if (subdirs != null) { for (File dir : subdirs) { if (dir.isDirectory()) { - // Get all the native jars in the directory (there should only be one) + // Get all the native jars or zips in the directory (there should only be one) for (File file : dir.listFiles()) { - if (!file.getName().endsWith(".jar")) { + if (!Resource.isJar(file) && !Resource.isZip(file)) { continue; } File cachedFile = getCachedFile(file); diff --git a/core/src/main/java/com/threerings/getdown/data/PathBuilder.java b/core/src/main/java/com/threerings/getdown/data/PathBuilder.java index b0a1dc9..57e9275 100644 --- a/core/src/main/java/com/threerings/getdown/data/PathBuilder.java +++ b/core/src/main/java/com/threerings/getdown/data/PathBuilder.java @@ -10,7 +10,7 @@ import java.io.IOException; import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.TimeUnit; -import java.util.jar.JarFile; +import java.util.zip.ZipFile; import com.threerings.getdown.cache.GarbageCollector; import com.threerings.getdown.cache.ResourceCache; @@ -112,7 +112,7 @@ public class PathBuilder if (!unpackedIndicator.exists()) { try { - FileUtil.unpackJar(new JarFile(cachedFile), cachedParent, false); + FileUtil.unpackJar(new ZipFile(cachedFile), cachedParent, false); unpackedIndicator.createNewFile(); } catch (IOException ioe) { log.warning("Failed to unpack native jar", diff --git a/core/src/main/java/com/threerings/getdown/data/Resource.java b/core/src/main/java/com/threerings/getdown/data/Resource.java index 3e2f446..b45e326 100644 --- a/core/src/main/java/com/threerings/getdown/data/Resource.java +++ b/core/src/main/java/com/threerings/getdown/data/Resource.java @@ -5,7 +5,10 @@ package com.threerings.getdown.data; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.security.MessageDigest; import java.util.Collections; @@ -13,13 +16,12 @@ import java.util.Comparator; import java.util.EnumSet; import java.util.List; import java.util.Locale; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import com.threerings.getdown.util.FileUtil; import com.threerings.getdown.util.ProgressObserver; import com.threerings.getdown.util.StringUtil; - import static com.threerings.getdown.Log.log; /** @@ -60,29 +62,29 @@ public class Resource implements Comparable byte[] buffer = new byte[DIGEST_BUFFER_SIZE]; int read; - boolean isJar = isJar(target.getPath()); - boolean isPacked200Jar = isPacked200Jar(target.getPath()); + boolean isZip = isJar(target) || isZip(target); // jar is a zip too + boolean isPacked200Jar = isPacked200Jar(target); // if this is a jar, we need to compute the digest in a "timestamp and file order" agnostic // manner to properly correlate jardiff patched jars with their unpatched originals - if (isJar || isPacked200Jar){ + if (isPacked200Jar || isZip){ File tmpJarFile = null; - JarFile jar = null; + ZipFile zip = null; try { - // if this is a compressed jar file, uncompress it to compute the jar file digest + // if this is a compressed zip file, uncompress it to compute the zip file digest if (isPacked200Jar){ tmpJarFile = new File(target.getPath() + ".tmp"); - FileUtil.unpackPacked200Jar(target, tmpJarFile); - jar = new JarFile(tmpJarFile); + tmpJarFile.deleteOnExit(); + zip = FileUtil.unpackPacked200Jar(target, tmpJarFile); } else{ - jar = new JarFile(target); + zip = new ZipFile(target); } - List entries = Collections.list(jar.entries()); + List entries = Collections.list(zip.entries()); Collections.sort(entries, ENTRY_COMP); int eidx = 0; - for (JarEntry entry : entries) { + for (ZipEntry entry : entries) { // old versions of the digest code skipped metadata if (version < 2) { if (entry.getName().startsWith("META-INF")) { @@ -91,7 +93,7 @@ public class Resource implements Comparable } } - try (InputStream in = jar.getInputStream(entry)) { + try (InputStream in = zip.getInputStream(entry)) { while ((read = in.read(buffer)) != -1) { md.update(buffer, 0, read); } @@ -101,11 +103,11 @@ public class Resource implements Comparable } } finally { - if (jar != null) { + if (zip != null) { try { - jar.close(); + zip.close(); } catch (IOException ioe) { - log.warning("Error closing jar", "path", target, "jar", jar, "error", ioe); + log.warning("Error closing zip", "path", target, "zip", zip, "error", ioe); } } if (tmpJarFile != null) { @@ -135,14 +137,13 @@ public class Resource implements Comparable _remote = remote; _local = local; _localNew = new File(local.toString() + "_new"); - String lpath = _local.getPath(); - _marker = new File(lpath + "v"); + _marker = new File(_local.getPath() + "v"); _attrs = attrs; - _isJar = isJar(lpath); - _isPacked200Jar = isPacked200Jar(lpath); + _isZip = isJar(local) || isZip(local); + _isPacked200Jar = isPacked200Jar(local); boolean unpack = attrs.contains(Attr.UNPACK); - if (unpack && _isJar) { + if (unpack && _isZip) { _unpacked = _local.getParentFile(); } else if(unpack && _isPacked200Jar) { String dotJar = ".jar", lname = _local.getName(); @@ -298,11 +299,11 @@ public class Resource implements Comparable public void unpack () throws IOException { // sanity check - if (!_isJar && !_isPacked200Jar) { + if (!_isZip && !_isPacked200Jar) { throw new IOException("Requested to unpack non-jar file '" + _local + "'."); } - if (_isJar) { - try (JarFile jar = new JarFile(_local)) { + if (_isZip) { + try (ZipFile jar = new ZipFile(_local)) { FileUtil.unpackJar(jar, _unpacked, _attrs.contains(Attr.CLEAN)); } } else { @@ -366,26 +367,34 @@ public class Resource implements Comparable } } - protected static boolean isJar (String path) + public static boolean isJar (File file) { + String path = file.getName(); return path.endsWith(".jar") || path.endsWith(".jar_new"); } - protected static boolean isPacked200Jar (String path) + public static boolean isPacked200Jar (File file) { + String path = file.getName(); return path.endsWith(".jar.pack") || path.endsWith(".jar.pack_new") || path.endsWith(".jar.pack.gz")|| path.endsWith(".jar.pack.gz_new"); } + public static boolean isZip (File file) + { + String path = file.getName(); + return path.endsWith(".zip") || path.endsWith(".zip_new"); + } + protected String _path; protected URL _remote; protected File _local, _localNew, _marker, _unpacked; protected EnumSet _attrs; - protected boolean _isJar, _isPacked200Jar; + protected boolean _isZip, _isPacked200Jar; /** Used to sort the entries in a jar file. */ - protected static final Comparator ENTRY_COMP = new Comparator() { - @Override public int compare (JarEntry e1, JarEntry e2) { + protected static final Comparator ENTRY_COMP = new Comparator() { + @Override public int compare (ZipEntry e1, ZipEntry e2) { return e1.getName().compareTo(e2.getName()); } }; diff --git a/core/src/main/java/com/threerings/getdown/tools/Differ.java b/core/src/main/java/com/threerings/getdown/tools/Differ.java index c2e740b..97a7d29 100644 --- a/core/src/main/java/com/threerings/getdown/tools/Differ.java +++ b/core/src/main/java/com/threerings/getdown/tools/Differ.java @@ -11,15 +11,12 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; - +import java.security.MessageDigest; import java.util.ArrayList; import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; - -import java.security.MessageDigest; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; import com.threerings.getdown.data.Application; import com.threerings.getdown.data.Digest; @@ -99,7 +96,7 @@ public class Differ MessageDigest md = Digest.getMessageDigest(version); try (FileOutputStream fos = new FileOutputStream(patch); BufferedOutputStream buffered = new BufferedOutputStream(fos); - JarOutputStream jout = new JarOutputStream(buffered)) { + ZipOutputStream jout = new ZipOutputStream(buffered)) { // for each file in the new application, it either already exists // in the old application, or it is new @@ -172,13 +169,13 @@ public class Differ throws IOException { File temp = File.createTempFile("differ", "jar"); - try (JarFile jar = new JarFile(target); - FileOutputStream tempFos = new FileOutputStream(temp); - BufferedOutputStream tempBos = new BufferedOutputStream(tempFos); - JarOutputStream jout = new JarOutputStream(tempBos)) { + try (ZipFile jar = new ZipFile(target); + FileOutputStream tempFos = new FileOutputStream(temp); + BufferedOutputStream tempBos = new BufferedOutputStream(tempFos); + ZipOutputStream jout = new ZipOutputStream(tempBos)) { byte[] buffer = new byte[4096]; - for (Enumeration< JarEntry > iter = jar.entries(); iter.hasMoreElements();) { - JarEntry entry = iter.nextElement(); + for (Enumeration iter = jar.entries(); iter.hasMoreElements();) { + ZipEntry entry = iter.nextElement(); entry.setCompressedSize(-1); jout.putNextEntry(entry); try (InputStream in = jar.getInputStream(entry)) { @@ -193,7 +190,7 @@ public class Differ return temp; } - protected void jarDiff (File ofile, File nfile, JarOutputStream jout) + protected void jarDiff (File ofile, File nfile, ZipOutputStream jout) throws IOException { JarDiff.createPatch(ofile.getPath(), nfile.getPath(), jout, false); @@ -222,8 +219,7 @@ public class Differ } } - protected static void pipe (File file, JarOutputStream jout) - throws IOException + protected static void pipe (File file, ZipOutputStream jout) throws IOException { try (FileInputStream fin = new FileInputStream(file)) { StreamUtil.copy(fin, jout); diff --git a/core/src/main/java/com/threerings/getdown/tools/JarDiff.java b/core/src/main/java/com/threerings/getdown/tools/JarDiff.java index 1cea0ea..734fc9c 100644 --- a/core/src/main/java/com/threerings/getdown/tools/JarDiff.java +++ b/core/src/main/java/com/threerings/getdown/tools/JarDiff.java @@ -41,9 +41,17 @@ package com.threerings.getdown.tools; -import java.io.*; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; +import java.io.Writer; import java.util.*; -import java.util.jar.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; import static java.nio.charset.StandardCharsets.UTF_8; @@ -86,7 +94,7 @@ public class JarDiff implements JarDiffCodes // and new.jar ) // and for files that cannot be implicitly moved, we will either // find out whether it is moved or new (modified) - for (JarEntry newEntry : newJar) { + for (ZipEntry newEntry : newJar) { String newname = newEntry.getName(); // Return best match of contents, will return a name match if possible @@ -154,7 +162,7 @@ public class JarDiff implements JarDiffCodes // SECOND PASS: = - - // - ArrayList deleted = new ArrayList<>(); - for (JarEntry oldEntry : oldJar) { + for (ZipEntry oldEntry : oldJar) { String oldName = oldEntry.getName(); if (!implicit.contains(oldName) && !moveSrc.contains(oldName) && !newEntries.contains(oldName)) { @@ -180,7 +188,7 @@ public class JarDiff implements JarDiffCodes } } - JarOutputStream jos = new JarOutputStream(os); + ZipOutputStream jos = new ZipOutputStream(os); // Write out all the MOVEs and REMOVEs createIndex(jos, deleted, moved); @@ -203,7 +211,7 @@ public class JarDiff implements JarDiffCodes * oldEntries gives the names of the files that were removed, * movedMap maps from the new name to the old name. */ - private static void createIndex (JarOutputStream jos, List oldEntries, + private static void createIndex (ZipOutputStream jos, List oldEntries, Map movedMap) throws IOException { @@ -220,17 +228,17 @@ public class JarDiff implements JarDiffCodes } // And those that have moved - for (String newName : movedMap.keySet()) { - String oldName = movedMap.get(newName); + for (Map.Entry entry : movedMap.entrySet()) { + String oldName = entry.getValue(); writer.write(MOVE_COMMAND); writer.write(" "); writeEscapedString(writer, oldName); writer.write(" "); - writeEscapedString(writer, newName); + writeEscapedString(writer, entry.getKey()); writer.write("\r\n"); } - jos.putNextEntry(new JarEntry(INDEX_NAME)); + jos.putNextEntry(new ZipEntry(INDEX_NAME)); byte[] bytes = writer.toString().getBytes(UTF_8); jos.write(bytes, 0, bytes.length); } @@ -264,7 +272,7 @@ public class JarDiff implements JarDiffCodes return writer; } - private static void writeEntry (JarOutputStream jos, JarEntry entry, JarFile2 file) + private static void writeEntry (ZipOutputStream jos, ZipEntry entry, JarFile2 file) throws IOException { try (InputStream data = file.getJarFile().getInputStream(entry)) { @@ -278,31 +286,31 @@ public class JarDiff implements JarDiffCodes } /** - * JarFile2 wraps a JarFile providing some convenience methods. + * JarFile2 wraps a ZipFile providing some convenience methods. */ - private static class JarFile2 implements Iterable, Closeable + private static class JarFile2 implements Iterable, Closeable { - private JarFile _jar; - private List _entries; - private HashMap _nameToEntryMap; - private HashMap> _crcToEntryMap; + private ZipFile _jar; + private List _entries; + private HashMap _nameToEntryMap; + private HashMap> _crcToEntryMap; public JarFile2 (String path) throws IOException { - _jar = new JarFile(new File(path)); + _jar = new ZipFile(new File(path)); index(); } - public JarFile getJarFile () { + public ZipFile getJarFile () { return _jar; } - // from interface Iterable + // from interface Iterable @Override - public Iterator iterator () { + public Iterator iterator () { return _entries.iterator(); } - public JarEntry getEntryByName (String name) { + public ZipEntry getEntryByName (String name) { return _nameToEntryMap.get(name); } @@ -350,7 +358,7 @@ public class JarDiff implements JarDiffCodes return retVal; } - public String getBestMatch (JarFile2 file, JarEntry entry) throws IOException { + public String getBestMatch (JarFile2 file, ZipEntry entry) throws IOException { // check for same name and same content, return name if found if (contains(file, entry)) { return (entry.getName()); @@ -360,9 +368,8 @@ public class JarDiff implements JarDiffCodes return (hasSameContent(file,entry)); } - public boolean contains (JarFile2 f, JarEntry e) throws IOException { - - JarEntry thisEntry = getEntryByName(e.getName()); + public boolean contains (JarFile2 f, ZipEntry e) throws IOException { + ZipEntry thisEntry = getEntryByName(e.getName()); // Look up name in 'this' Jar2File - if not exist return false if (thisEntry == null) @@ -379,17 +386,17 @@ public class JarDiff implements JarDiffCodes } } - public String hasSameContent (JarFile2 file, JarEntry entry) throws IOException { + public String hasSameContent (JarFile2 file, ZipEntry entry) throws IOException { String thisName = null; Long crcL = Long.valueOf(entry.getCrc()); // check if this jar contains files with the passed in entry's crc if (_crcToEntryMap.containsKey(crcL)) { // get the Linked List with files with the crc - LinkedList ll = _crcToEntryMap.get(crcL); + LinkedList ll = _crcToEntryMap.get(crcL); // go through the list and check for content match - ListIterator li = ll.listIterator(0); + ListIterator li = ll.listIterator(0); while (li.hasNext()) { - JarEntry thisEntry = li.next(); + ZipEntry thisEntry = li.next(); // check for content match try (InputStream oldIS = getJarFile().getInputStream(thisEntry); InputStream newIS = file.getJarFile().getInputStream(entry)) { @@ -404,7 +411,7 @@ public class JarDiff implements JarDiffCodes } private void index () throws IOException { - Enumeration entries = _jar.entries(); + Enumeration entries = _jar.entries(); _nameToEntryMap = new HashMap<>(); _crcToEntryMap = new HashMap<>(); @@ -414,7 +421,7 @@ public class JarDiff implements JarDiffCodes } if (entries != null) { while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); + ZipEntry entry = entries.nextElement(); long crc = entry.getCrc(); Long crcL = Long.valueOf(crc); if (_debug) { @@ -427,13 +434,13 @@ public class JarDiff implements JarDiffCodes // generate the CRC to entries map if (_crcToEntryMap.containsKey(crcL)) { // key exist, add the entry to the correcponding linked list - LinkedList ll = _crcToEntryMap.get(crcL); + LinkedList ll = _crcToEntryMap.get(crcL); ll.add(entry); _crcToEntryMap.put(crcL, ll); } else { // create a new entry in the hashmap for the new key - LinkedList ll = new LinkedList(); + LinkedList ll = new LinkedList<>(); ll.add(entry); _crcToEntryMap.put(crcL, ll); } diff --git a/core/src/main/java/com/threerings/getdown/tools/JarDiffPatcher.java b/core/src/main/java/com/threerings/getdown/tools/JarDiffPatcher.java index b5a0a17..859d73e 100644 --- a/core/src/main/java/com/threerings/getdown/tools/JarDiffPatcher.java +++ b/core/src/main/java/com/threerings/getdown/tools/JarDiffPatcher.java @@ -11,22 +11,18 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; - import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; - -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; import com.threerings.getdown.util.ProgressObserver; - import static java.nio.charset.StandardCharsets.UTF_8; /** @@ -49,11 +45,9 @@ public class JarDiffPatcher implements JarDiffCodes throws IOException { File oldFile = new File(jarPath), diffFile = new File(diffPath); - - try (JarFile oldJar = new JarFile(oldFile); - JarFile jarDiff = new JarFile(diffFile); - JarOutputStream jos = new JarOutputStream(new FileOutputStream(target))) { - + try (ZipFile oldJar = new ZipFile(oldFile); + ZipFile jarDiff = new ZipFile(diffFile); + ZipOutputStream jos = new ZipOutputStream(new FileOutputStream(target))) { Set ignoreSet = new HashSet<>(); Map renameMap = new HashMap<>(); determineNameMapping(jarDiff, ignoreSet, renameMap); @@ -63,7 +57,7 @@ public class JarDiffPatcher implements JarDiffCodes // Files to implicit move Set oldjarNames = new HashSet<>(); - Enumeration oldEntries = oldJar.entries(); + Enumeration oldEntries = oldJar.entries(); if (oldEntries != null) { while (oldEntries.hasMoreElements()) { oldjarNames.add(oldEntries.nextElement().getName()); @@ -83,10 +77,10 @@ public class JarDiffPatcher implements JarDiffCodes size -= ignoreSet.size(); // Add content from JARDiff - Enumeration entries = jarDiff.entries(); + Enumeration entries = jarDiff.entries(); if (entries != null) { while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); + ZipEntry entry = entries.nextElement(); if (!INDEX_NAME.equals(entry.getName())) { updateObserver(observer, currentEntry, size); currentEntry++; @@ -114,15 +108,15 @@ public class JarDiffPatcher implements JarDiffCodes // Apply move command String oldName = renameMap.get(newName); - // Get source JarEntry - JarEntry oldEntry = oldJar.getJarEntry(oldName); + // Get source ZipEntry + ZipEntry oldEntry = oldJar.getEntry(oldName); if (oldEntry == null) { String moveCmd = MOVE_COMMAND + oldName + " " + newName; throw new IOException("error.badmove: " + moveCmd); } - // Create dest JarEntry - JarEntry newEntry = new JarEntry(newName); + // Create dest ZipEntry + ZipEntry newEntry = new ZipEntry(newName); newEntry.setTime(oldEntry.getTime()); newEntry.setSize(oldEntry.getSize()); newEntry.setCompressedSize(oldEntry.getCompressedSize()); @@ -149,19 +143,15 @@ public class JarDiffPatcher implements JarDiffCodes } // implicit move - Iterator iEntries = oldjarNames.iterator(); - if (iEntries != null) { - while (iEntries.hasNext()) { - String name = iEntries.next(); - JarEntry entry = oldJar.getJarEntry(name); - if (entry == null) { - // names originally retrieved from the JAR, so this should never happen - throw new AssertionError("JAR entry not found: " + name); - } - updateObserver(observer, currentEntry, size); - currentEntry++; - writeEntry(jos, entry, oldJar); + for (String name : oldjarNames) { + ZipEntry entry = oldJar.getEntry(name); + if (entry == null) { + // names originally retrieved from the JAR, so this should never happen + throw new AssertionError("JAR entry not found: " + name); } + updateObserver(observer, currentEntry, size); + currentEntry++; + writeEntry(jos, entry, oldJar); } updateObserver(observer, currentEntry, size); } @@ -175,7 +165,7 @@ public class JarDiffPatcher implements JarDiffCodes } protected void determineNameMapping ( - JarFile jarDiff, Set ignoreSet, Map renameMap) + ZipFile jarDiff, Set ignoreSet, Map renameMap) throws IOException { InputStream is = jarDiff.getInputStream(jarDiff.getEntry(INDEX_NAME)); @@ -264,7 +254,7 @@ public class JarDiffPatcher implements JarDiffCodes return sub; } - protected void writeEntry (JarOutputStream jos, JarEntry entry, JarFile file) + protected void writeEntry (ZipOutputStream jos, ZipEntry entry, ZipFile file) throws IOException { try (InputStream data = file.getInputStream(entry)) { @@ -272,10 +262,10 @@ public class JarDiffPatcher implements JarDiffCodes } } - protected void writeEntry (JarOutputStream jos, JarEntry entry, InputStream data) + protected void writeEntry (ZipOutputStream jos, ZipEntry entry, InputStream data) throws IOException { - jos.putNextEntry(new JarEntry(entry.getName())); + jos.putNextEntry(new ZipEntry(entry.getName())); // Read the entry int size = data.read(newBytes); diff --git a/core/src/main/java/com/threerings/getdown/tools/Patcher.java b/core/src/main/java/com/threerings/getdown/tools/Patcher.java index 4ead59b..fc39426 100644 --- a/core/src/main/java/com/threerings/getdown/tools/Patcher.java +++ b/core/src/main/java/com/threerings/getdown/tools/Patcher.java @@ -9,16 +9,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; - import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import com.threerings.getdown.util.FileUtil; import com.threerings.getdown.util.ProgressObserver; import com.threerings.getdown.util.StreamUtil; - import static com.threerings.getdown.Log.log; /** @@ -55,10 +52,10 @@ public class Patcher _obs = obs; _plength = patch.length(); - try (JarFile file = new JarFile(patch)) { - Enumeration entries = file.entries(); // old skool! + try (ZipFile file = new ZipFile(patch)) { + Enumeration entries = file.entries(); while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); + ZipEntry entry = entries.nextElement(); String path = entry.getName(); long elength = entry.getCompressedSize(); @@ -96,7 +93,7 @@ public class Patcher return path.substring(0, path.length() - suffix.length()); } - protected void createFile (JarFile file, ZipEntry entry, File target) + protected void createFile (ZipFile file, ZipEntry entry, File target) { // create our copy buffer if necessary if (_buffer == null) { @@ -124,7 +121,7 @@ public class Patcher } } - protected void patchFile (JarFile file, ZipEntry entry, + protected void patchFile (ZipFile file, ZipEntry entry, File appdir, String path) { File target = new File(appdir, path); diff --git a/core/src/main/java/com/threerings/getdown/util/FileUtil.java b/core/src/main/java/com/threerings/getdown/util/FileUtil.java index ec9d887..06ac41c 100644 --- a/core/src/main/java/com/threerings/getdown/util/FileUtil.java +++ b/core/src/main/java/com/threerings/getdown/util/FileUtil.java @@ -5,10 +5,26 @@ package com.threerings.getdown.util; -import java.io.*; -import java.util.*; -import java.util.jar.*; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Pack200; import java.util.zip.GZIPInputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import com.threerings.getdown.Log; import static com.threerings.getdown.Log.log; @@ -16,7 +32,7 @@ import static com.threerings.getdown.Log.log; /** * File related utilities. */ -public class FileUtil +public final class FileUtil { /** * Gets the specified source file to the specified destination file by hook or crook. Windows @@ -114,13 +130,12 @@ public class FileUtil * @param cleanExistingDirs if true, all files in all directories contained in {@code jar} will * be deleted prior to unpacking the jar. */ - public static void unpackJar (JarFile jar, File target, boolean cleanExistingDirs) - throws IOException + public static void unpackJar (ZipFile jar, File target, boolean cleanExistingDirs) throws IOException { if (cleanExistingDirs) { - Enumeration entries = jar.entries(); + Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { - JarEntry entry = (JarEntry)entries.nextElement(); + ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) { File efile = new File(target, entry.getName()); if (efile.exists()) { @@ -133,9 +148,9 @@ public class FileUtil } } - Enumeration entries = jar.entries(); + Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { - JarEntry entry = (JarEntry)entries.nextElement(); + ZipEntry entry = entries.nextElement(); File efile = new File(target, entry.getName()); // if we're unpacking a normal jar file, it will have special path @@ -169,10 +184,10 @@ public class FileUtil * Unpacks a pack200 packed jar file from {@code packedJar} into {@code target}. If {@code * packedJar} has a {@code .gz} extension, it will be gunzipped first. */ - public static void unpackPacked200Jar (File packedJar, File target) throws IOException + public static JarFile unpackPacked200Jar (File packedJar, File target) throws IOException { try (InputStream packJarIn = new FileInputStream(packedJar); - JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(target))) { + JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(target))) { boolean gz = (packedJar.getName().endsWith(".gz") || packedJar.getName().endsWith(".gz_new")); try (InputStream packJarIn2 = (gz ? new GZIPInputStream(packJarIn) : packJarIn)) { @@ -180,6 +195,7 @@ public class FileUtil unpacker.unpack(packJarIn2, jarOut); } } + return new JarFile(target); } /** diff --git a/core/src/test/java/com/threerings/getdown/cache/GarbageCollectorTest.java b/core/src/test/java/com/threerings/getdown/cache/GarbageCollectorTest.java index d5a3937..6834ff9 100644 --- a/core/src/test/java/com/threerings/getdown/cache/GarbageCollectorTest.java +++ b/core/src/test/java/com/threerings/getdown/cache/GarbageCollectorTest.java @@ -7,23 +7,41 @@ package com.threerings.getdown.cache; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import java.util.concurrent.TimeUnit; -import org.junit.*; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; - -import static org.junit.Assert.*; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeTrue; /** * Validates that cache garbage is collected and deleted correctly. */ +@RunWith(Parameterized.class) public class GarbageCollectorTest { + @Parameterized.Parameters(name = "{0}") + public static Collection data() { + return Arrays.asList(new Object[][] { + { ".jar" }, + { ".zip" } + }); + } + + @Parameterized.Parameter + public String extension; + @Before public void setupFiles () throws IOException { - _cachedFile = _folder.newFile("abc123.jar"); - _lastAccessedFile = _folder.newFile("abc123.jar" + ResourceCache.LAST_ACCESSED_FILE_SUFFIX); + _cachedFile = _folder.newFile("abc123" + extension); + _lastAccessedFile = _folder.newFile("abc123" + extension + ResourceCache.LAST_ACCESSED_FILE_SUFFIX); } @Test public void shouldDeleteCacheEntryIfRetentionPeriodIsReached () diff --git a/core/src/test/java/com/threerings/getdown/cache/ResourceCacheTest.java b/core/src/test/java/com/threerings/getdown/cache/ResourceCacheTest.java index 860c72a..93ad683 100644 --- a/core/src/test/java/com/threerings/getdown/cache/ResourceCacheTest.java +++ b/core/src/test/java/com/threerings/getdown/cache/ResourceCacheTest.java @@ -7,26 +7,44 @@ package com.threerings.getdown.cache; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import java.util.concurrent.TimeUnit; -import org.junit.*; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; - -import static org.junit.Assert.*; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * Asserts the correct functionality of the {@link ResourceCache}. */ +@RunWith(Parameterized.class) public class ResourceCacheTest { + @Parameterized.Parameters(name = "{0}") + public static Collection data() { + return Arrays.asList(new Object[][] { + { ".jar" }, + { ".zip" } + }); + } + + @Parameterized.Parameter + public String extension; + @Before public void setupCache () throws IOException { - _fileToCache = _folder.newFile("filetocache.jar"); + _fileToCache = _folder.newFile("filetocache" + extension); _cache = new ResourceCache(_folder.newFolder(".cache")); } @Test public void shouldCacheFile () throws IOException { - assertEquals("abc123.jar", cacheFile().getName()); + assertEquals("abc123" + extension, cacheFile().getName()); } private File cacheFile() throws IOException @@ -36,7 +54,7 @@ public class ResourceCacheTest @Test public void shouldTrackFileUsage () throws IOException { - String name = "abc123.jar" + ResourceCache.LAST_ACCESSED_FILE_SUFFIX; + String name = "abc123" + extension + ResourceCache.LAST_ACCESSED_FILE_SUFFIX; File lastAccessedFile = new File(cacheFile().getParentFile(), name); assertTrue(lastAccessedFile.exists()); }