zip files support
This commit is contained in:
@@ -10,7 +10,7 @@ import java.io.IOException;
|
|||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
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.GarbageCollector;
|
||||||
import com.threerings.getdown.cache.ResourceCache;
|
import com.threerings.getdown.cache.ResourceCache;
|
||||||
@@ -112,7 +112,7 @@ public class PathBuilder
|
|||||||
|
|
||||||
if (!unpackedIndicator.exists()) {
|
if (!unpackedIndicator.exists()) {
|
||||||
try {
|
try {
|
||||||
FileUtil.unpackJar(new JarFile(cachedFile), cachedParent, false);
|
FileUtil.unpackJar(new ZipFile(cachedFile), cachedParent, false);
|
||||||
unpackedIndicator.createNewFile();
|
unpackedIndicator.createNewFile();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
log.warning("Failed to unpack native jar",
|
log.warning("Failed to unpack native jar",
|
||||||
|
|||||||
@@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
package com.threerings.getdown.data;
|
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.net.URL;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -13,13 +16,12 @@ import java.util.Comparator;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import com.threerings.getdown.util.FileUtil;
|
import com.threerings.getdown.util.FileUtil;
|
||||||
import com.threerings.getdown.util.ProgressObserver;
|
import com.threerings.getdown.util.ProgressObserver;
|
||||||
import com.threerings.getdown.util.StringUtil;
|
import com.threerings.getdown.util.StringUtil;
|
||||||
|
|
||||||
import static com.threerings.getdown.Log.log;
|
import static com.threerings.getdown.Log.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,23 +68,22 @@ public class Resource implements Comparable<Resource>
|
|||||||
// if this is a jar, we need to compute the digest in a "timestamp and file order" agnostic
|
// 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
|
// manner to properly correlate jardiff patched jars with their unpatched originals
|
||||||
if (isJar || isPacked200Jar){
|
if (isJar || isPacked200Jar){
|
||||||
File tmpJarFile = null;
|
ZipFile jar = null;
|
||||||
JarFile jar = null;
|
|
||||||
try {
|
try {
|
||||||
// if this is a compressed jar file, uncompress it to compute the jar file digest
|
// if this is a compressed jar file, uncompress it to compute the jar file digest
|
||||||
if (isPacked200Jar){
|
if (isPacked200Jar){
|
||||||
tmpJarFile = new File(target.getPath() + ".tmp");
|
File tmpJarFile = new File(target.getPath() + ".tmp");
|
||||||
FileUtil.unpackPacked200Jar(target, tmpJarFile);
|
tmpJarFile.deleteOnExit();
|
||||||
jar = new JarFile(tmpJarFile);
|
jar = FileUtil.unpackPacked200Jar(target, tmpJarFile);
|
||||||
} else{
|
} else{
|
||||||
jar = new JarFile(target);
|
jar = new ZipFile(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<JarEntry> entries = Collections.list(jar.entries());
|
List<? extends ZipEntry> entries = Collections.list(jar.entries());
|
||||||
Collections.sort(entries, ENTRY_COMP);
|
Collections.sort(entries, ENTRY_COMP);
|
||||||
|
|
||||||
int eidx = 0;
|
int eidx = 0;
|
||||||
for (JarEntry entry : entries) {
|
for (ZipEntry entry : entries) {
|
||||||
// old versions of the digest code skipped metadata
|
// old versions of the digest code skipped metadata
|
||||||
if (version < 2) {
|
if (version < 2) {
|
||||||
if (entry.getName().startsWith("META-INF")) {
|
if (entry.getName().startsWith("META-INF")) {
|
||||||
@@ -108,9 +109,6 @@ public class Resource implements Comparable<Resource>
|
|||||||
log.warning("Error closing jar", "path", target, "jar", jar, "error", ioe);
|
log.warning("Error closing jar", "path", target, "jar", jar, "error", ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tmpJarFile != null) {
|
|
||||||
FileUtil.deleteHarder(tmpJarFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -302,7 +300,7 @@ public class Resource implements Comparable<Resource>
|
|||||||
throw new IOException("Requested to unpack non-jar file '" + _local + "'.");
|
throw new IOException("Requested to unpack non-jar file '" + _local + "'.");
|
||||||
}
|
}
|
||||||
if (_isJar) {
|
if (_isJar) {
|
||||||
try (JarFile jar = new JarFile(_local)) {
|
try (ZipFile jar = new ZipFile(_local)) {
|
||||||
FileUtil.unpackJar(jar, _unpacked, _attrs.contains(Attr.CLEAN));
|
FileUtil.unpackJar(jar, _unpacked, _attrs.contains(Attr.CLEAN));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -341,11 +339,7 @@ public class Resource implements Comparable<Resource>
|
|||||||
|
|
||||||
@Override public boolean equals (Object other)
|
@Override public boolean equals (Object other)
|
||||||
{
|
{
|
||||||
if (other instanceof Resource) {
|
return other instanceof Resource && _path.equals(((Resource) other)._path);
|
||||||
return _path.equals(((Resource)other)._path);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int hashCode ()
|
@Override public int hashCode ()
|
||||||
@@ -368,7 +362,7 @@ public class Resource implements Comparable<Resource>
|
|||||||
|
|
||||||
protected static boolean isJar (String path)
|
protected static boolean isJar (String path)
|
||||||
{
|
{
|
||||||
return path.endsWith(".jar") || path.endsWith(".jar_new");
|
return path.endsWith(".jar") || path.endsWith(".jar_new") || path.endsWith(".zip");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean isPacked200Jar (String path)
|
protected static boolean isPacked200Jar (String path)
|
||||||
@@ -384,8 +378,8 @@ public class Resource implements Comparable<Resource>
|
|||||||
protected boolean _isJar, _isPacked200Jar;
|
protected boolean _isJar, _isPacked200Jar;
|
||||||
|
|
||||||
/** Used to sort the entries in a jar file. */
|
/** Used to sort the entries in a jar file. */
|
||||||
protected static final Comparator<JarEntry> ENTRY_COMP = new Comparator<JarEntry>() {
|
protected static final Comparator<ZipEntry> ENTRY_COMP = new Comparator<ZipEntry>() {
|
||||||
@Override public int compare (JarEntry e1, JarEntry e2) {
|
@Override public int compare (ZipEntry e1, ZipEntry e2) {
|
||||||
return e1.getName().compareTo(e2.getName());
|
return e1.getName().compareTo(e2.getName());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,15 +11,12 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
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.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
import java.security.MessageDigest;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import com.threerings.getdown.data.Application;
|
import com.threerings.getdown.data.Application;
|
||||||
import com.threerings.getdown.data.Digest;
|
import com.threerings.getdown.data.Digest;
|
||||||
@@ -91,15 +88,15 @@ public class Differ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createPatch (File patch, ArrayList<Resource> orsrcs,
|
protected static void createPatch(File patch, ArrayList<Resource> orsrcs,
|
||||||
ArrayList<Resource> nrsrcs, boolean verbose)
|
ArrayList<Resource> nrsrcs, boolean verbose)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
int version = Digest.VERSION;
|
int version = Digest.VERSION;
|
||||||
MessageDigest md = Digest.getMessageDigest(version);
|
MessageDigest md = Digest.getMessageDigest(version);
|
||||||
try (FileOutputStream fos = new FileOutputStream(patch);
|
try (FileOutputStream fos = new FileOutputStream(patch);
|
||||||
BufferedOutputStream buffered = new BufferedOutputStream(fos);
|
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
|
// for each file in the new application, it either already exists
|
||||||
// in the old application, or it is new
|
// in the old application, or it is new
|
||||||
@@ -168,17 +165,16 @@ public class Differ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected File rebuildJar (File target)
|
protected static File rebuildJar(File target) throws IOException
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
File temp = File.createTempFile("differ", "jar");
|
File temp = File.createTempFile("differ", "jar");
|
||||||
try (JarFile jar = new JarFile(target);
|
try (ZipFile jar = new ZipFile(target);
|
||||||
FileOutputStream tempFos = new FileOutputStream(temp);
|
FileOutputStream tempFos = new FileOutputStream(temp);
|
||||||
BufferedOutputStream tempBos = new BufferedOutputStream(tempFos);
|
BufferedOutputStream tempBos = new BufferedOutputStream(tempFos);
|
||||||
JarOutputStream jout = new JarOutputStream(tempBos)) {
|
ZipOutputStream jout = new ZipOutputStream(tempBos)) {
|
||||||
byte[] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
for (Enumeration< JarEntry > iter = jar.entries(); iter.hasMoreElements();) {
|
for (Enumeration<? extends ZipEntry> iter = jar.entries(); iter.hasMoreElements();) {
|
||||||
JarEntry entry = iter.nextElement();
|
ZipEntry entry = iter.nextElement();
|
||||||
entry.setCompressedSize(-1);
|
entry.setCompressedSize(-1);
|
||||||
jout.putNextEntry(entry);
|
jout.putNextEntry(entry);
|
||||||
try (InputStream in = jar.getInputStream(entry)) {
|
try (InputStream in = jar.getInputStream(entry)) {
|
||||||
@@ -193,8 +189,7 @@ public class Differ
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void jarDiff (File ofile, File nfile, JarOutputStream jout)
|
protected static void jarDiff(File ofile, File nfile, ZipOutputStream jout) throws IOException
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
JarDiff.createPatch(ofile.getPath(), nfile.getPath(), jout, false);
|
JarDiff.createPatch(ofile.getPath(), nfile.getPath(), jout, false);
|
||||||
}
|
}
|
||||||
@@ -202,8 +197,7 @@ public class Differ
|
|||||||
public static void main (String[] args)
|
public static void main (String[] args)
|
||||||
{
|
{
|
||||||
if (args.length < 2) {
|
if (args.length < 2) {
|
||||||
System.err.println(
|
System.err.println("Usage: Differ [-verbose] new_vers_dir old_vers_dir");
|
||||||
"Usage: Differ [-verbose] new_vers_dir old_vers_dir");
|
|
||||||
System.exit(255);
|
System.exit(255);
|
||||||
}
|
}
|
||||||
Differ differ = new Differ();
|
Differ differ = new Differ();
|
||||||
@@ -222,8 +216,7 @@ public class Differ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void pipe (File file, JarOutputStream jout)
|
protected static void pipe (File file, ZipOutputStream jout) throws IOException
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
try (FileInputStream fin = new FileInputStream(file)) {
|
try (FileInputStream fin = new FileInputStream(file)) {
|
||||||
StreamUtil.copy(fin, jout);
|
StreamUtil.copy(fin, jout);
|
||||||
|
|||||||
@@ -41,9 +41,17 @@
|
|||||||
|
|
||||||
package com.threerings.getdown.tools;
|
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.*;
|
||||||
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;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
@@ -66,18 +74,16 @@ public class JarDiff implements JarDiffCodes
|
|||||||
private static boolean _debug;
|
private static boolean _debug;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a patch from the two passed in files, writing the result to <code>os</code>.
|
* Creates a patch from the two passed in files, writing the result to {@code os}.
|
||||||
*/
|
*/
|
||||||
public static void createPatch (String oldPath, String newPath,
|
public static void createPatch (String oldPath, String newPath,
|
||||||
OutputStream os, boolean minimal) throws IOException
|
OutputStream os, boolean minimal) throws IOException
|
||||||
{
|
{
|
||||||
try (JarFile2 oldJar = new JarFile2(oldPath);
|
try (JarFile2 oldJar = new JarFile2(oldPath); JarFile2 newJar = new JarFile2(newPath)) {
|
||||||
JarFile2 newJar = new JarFile2(newPath)) {
|
final Map<String, String> moved = new HashMap<>();
|
||||||
|
final Set<String> implicit = new HashSet<>();
|
||||||
HashMap<String,String> moved = new HashMap<>();
|
final Set<String> moveSrc = new HashSet<>();
|
||||||
HashSet<String> implicit = new HashSet<>();
|
final Set<String> newEntries = new HashSet<>();
|
||||||
HashSet<String> moveSrc = new HashSet<>();
|
|
||||||
HashSet<String> newEntries = new HashSet<>();
|
|
||||||
|
|
||||||
// FIRST PASS
|
// FIRST PASS
|
||||||
// Go through the entries in new jar and
|
// Go through the entries in new jar and
|
||||||
@@ -86,7 +92,7 @@ public class JarDiff implements JarDiffCodes
|
|||||||
// and new.jar )
|
// and new.jar )
|
||||||
// and for files that cannot be implicitly moved, we will either
|
// and for files that cannot be implicitly moved, we will either
|
||||||
// find out whether it is moved or new (modified)
|
// find out whether it is moved or new (modified)
|
||||||
for (JarEntry newEntry : newJar) {
|
for (ZipEntry newEntry : newJar) {
|
||||||
String newname = newEntry.getName();
|
String newname = newEntry.getName();
|
||||||
|
|
||||||
// Return best match of contents, will return a name match if possible
|
// Return best match of contents, will return a name match if possible
|
||||||
@@ -122,7 +128,6 @@ public class JarDiff implements JarDiffCodes
|
|||||||
// for backward compatibility
|
// for backward compatibility
|
||||||
|
|
||||||
if (_debug) {
|
if (_debug) {
|
||||||
|
|
||||||
System.out.println("NEW: "+ newname);
|
System.out.println("NEW: "+ newname);
|
||||||
}
|
}
|
||||||
newEntries.add(newname);
|
newEntries.add(newname);
|
||||||
@@ -136,12 +141,9 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
// Check if this disables an implicit 'move <oldname> <oldname>'
|
// Check if this disables an implicit 'move <oldname> <oldname>'
|
||||||
if (implicit.contains(oldname) && minimal) {
|
if (implicit.contains(oldname) && minimal) {
|
||||||
|
|
||||||
if (_debug) {
|
if (_debug) {
|
||||||
System.err.println("implicit.remove " + oldname);
|
System.err.println("implicit.remove " + oldname);
|
||||||
|
|
||||||
System.err.println("moved.put " + oldname + " " + oldname);
|
System.err.println("moved.put " + oldname + " " + oldname);
|
||||||
|
|
||||||
}
|
}
|
||||||
implicit.remove(oldname);
|
implicit.remove(oldname);
|
||||||
moved.put(oldname, oldname);
|
moved.put(oldname, oldname);
|
||||||
@@ -153,8 +155,8 @@ public class JarDiff implements JarDiffCodes
|
|||||||
|
|
||||||
// SECOND PASS: <deleted files> = <oldjarnames> - <implicitmoves> -
|
// SECOND PASS: <deleted files> = <oldjarnames> - <implicitmoves> -
|
||||||
// <source of move commands> - <new or modified entries>
|
// <source of move commands> - <new or modified entries>
|
||||||
ArrayList<String> deleted = new ArrayList<>();
|
final List<String> deleted = new ArrayList<>();
|
||||||
for (JarEntry oldEntry : oldJar) {
|
for (ZipEntry oldEntry : oldJar) {
|
||||||
String oldName = oldEntry.getName();
|
String oldName = oldEntry.getName();
|
||||||
if (!implicit.contains(oldName) && !moveSrc.contains(oldName)
|
if (!implicit.contains(oldName) && !moveSrc.contains(oldName)
|
||||||
&& !newEntries.contains(oldName)) {
|
&& !newEntries.contains(oldName)) {
|
||||||
@@ -180,7 +182,7 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JarOutputStream jos = new JarOutputStream(os);
|
ZipOutputStream jos = new ZipOutputStream(os);
|
||||||
|
|
||||||
// Write out all the MOVEs and REMOVEs
|
// Write out all the MOVEs and REMOVEs
|
||||||
createIndex(jos, deleted, moved);
|
createIndex(jos, deleted, moved);
|
||||||
@@ -199,12 +201,11 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the index file out to <code>jos</code>.
|
* Writes the index file out to {@code jos}.
|
||||||
* <code>oldEntries</code> gives the names of the files that were removed,
|
* {@code oldEntries} gives the names of the files that were removed,
|
||||||
* <code>movedMap</code> maps from the new name to the old name.
|
* {@code movedMap} maps from the new name to the old name.
|
||||||
*/
|
*/
|
||||||
private static void createIndex (JarOutputStream jos, List<String> oldEntries,
|
private static void createIndex (ZipOutputStream jos, List<String> oldEntries, Map<String,String> movedMap)
|
||||||
Map<String,String> movedMap)
|
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
@@ -220,22 +221,22 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And those that have moved
|
// And those that have moved
|
||||||
for (String newName : movedMap.keySet()) {
|
for (Map.Entry<String, String> entry : movedMap.entrySet()) {
|
||||||
String oldName = movedMap.get(newName);
|
String oldName = entry.getValue();
|
||||||
writer.write(MOVE_COMMAND);
|
writer.write(MOVE_COMMAND);
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
writeEscapedString(writer, oldName);
|
writeEscapedString(writer, oldName);
|
||||||
writer.write(" ");
|
writer.write(" ");
|
||||||
writeEscapedString(writer, newName);
|
writeEscapedString(writer, entry.getKey());
|
||||||
writer.write("\r\n");
|
writer.write("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
jos.putNextEntry(new JarEntry(INDEX_NAME));
|
jos.putNextEntry(new ZipEntry(INDEX_NAME));
|
||||||
byte[] bytes = writer.toString().getBytes(UTF_8);
|
byte[] bytes = writer.toString().getBytes(UTF_8);
|
||||||
jos.write(bytes, 0, bytes.length);
|
jos.write(bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Writer writeEscapedString (Writer writer, String string)
|
protected static void writeEscapedString (Writer writer, String string)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -261,10 +262,9 @@ public class JarDiff implements JarDiffCodes
|
|||||||
writer.write(string);
|
writer.write(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
return writer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeEntry (JarOutputStream jos, JarEntry entry, JarFile2 file)
|
private static void writeEntry (ZipOutputStream jos, ZipEntry entry, JarFile2 file)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
try (InputStream data = file.getJarFile().getInputStream(entry)) {
|
try (InputStream data = file.getJarFile().getInputStream(entry)) {
|
||||||
@@ -278,31 +278,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<JarEntry>, Closeable
|
private static class JarFile2 implements Iterable<ZipEntry>, Closeable
|
||||||
{
|
{
|
||||||
private JarFile _jar;
|
private ZipFile _jar;
|
||||||
private List<JarEntry> _entries;
|
private List<ZipEntry> _entries;
|
||||||
private HashMap<String,JarEntry> _nameToEntryMap;
|
private HashMap<String,ZipEntry> _nameToEntryMap;
|
||||||
private HashMap<Long,LinkedList<JarEntry>> _crcToEntryMap;
|
private HashMap<Long,LinkedList<ZipEntry>> _crcToEntryMap;
|
||||||
|
|
||||||
public JarFile2 (String path) throws IOException {
|
public JarFile2 (String path) throws IOException {
|
||||||
_jar = new JarFile(new File(path));
|
_jar = new ZipFile(new File(path));
|
||||||
index();
|
index();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JarFile getJarFile () {
|
public ZipFile getJarFile () {
|
||||||
return _jar;
|
return _jar;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from interface Iterable<JarEntry>
|
// from interface Iterable<ZipEntry>
|
||||||
@Override
|
@Override
|
||||||
public Iterator<JarEntry> iterator () {
|
public Iterator<ZipEntry> iterator () {
|
||||||
return _entries.iterator();
|
return _entries.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JarEntry getEntryByName (String name) {
|
public ZipEntry getEntryByName (String name) {
|
||||||
return _nameToEntryMap.get(name);
|
return _nameToEntryMap.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ public class JarDiff implements JarDiffCodes
|
|||||||
return retVal;
|
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
|
// check for same name and same content, return name if found
|
||||||
if (contains(file, entry)) {
|
if (contains(file, entry)) {
|
||||||
return (entry.getName());
|
return (entry.getName());
|
||||||
@@ -360,9 +360,8 @@ public class JarDiff implements JarDiffCodes
|
|||||||
return (hasSameContent(file,entry));
|
return (hasSameContent(file,entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains (JarFile2 f, JarEntry e) throws IOException {
|
public boolean contains (JarFile2 f, ZipEntry e) throws IOException {
|
||||||
|
ZipEntry thisEntry = getEntryByName(e.getName());
|
||||||
JarEntry thisEntry = getEntryByName(e.getName());
|
|
||||||
|
|
||||||
// Look up name in 'this' Jar2File - if not exist return false
|
// Look up name in 'this' Jar2File - if not exist return false
|
||||||
if (thisEntry == null)
|
if (thisEntry == null)
|
||||||
@@ -379,17 +378,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;
|
String thisName = null;
|
||||||
Long crcL = Long.valueOf(entry.getCrc());
|
Long crcL = entry.getCrc();
|
||||||
// check if this jar contains files with the passed in entry's crc
|
// check if this jar contains files with the passed in entry's crc
|
||||||
if (_crcToEntryMap.containsKey(crcL)) {
|
if (_crcToEntryMap.containsKey(crcL)) {
|
||||||
// get the Linked List with files with the crc
|
// get the Linked List with files with the crc
|
||||||
LinkedList<JarEntry> ll = _crcToEntryMap.get(crcL);
|
LinkedList<ZipEntry> ll = _crcToEntryMap.get(crcL);
|
||||||
// go through the list and check for content match
|
// go through the list and check for content match
|
||||||
ListIterator<JarEntry> li = ll.listIterator(0);
|
ListIterator<ZipEntry> li = ll.listIterator(0);
|
||||||
while (li.hasNext()) {
|
while (li.hasNext()) {
|
||||||
JarEntry thisEntry = li.next();
|
ZipEntry thisEntry = li.next();
|
||||||
// check for content match
|
// check for content match
|
||||||
try (InputStream oldIS = getJarFile().getInputStream(thisEntry);
|
try (InputStream oldIS = getJarFile().getInputStream(thisEntry);
|
||||||
InputStream newIS = file.getJarFile().getInputStream(entry)) {
|
InputStream newIS = file.getJarFile().getInputStream(entry)) {
|
||||||
@@ -404,7 +403,7 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void index () throws IOException {
|
private void index () throws IOException {
|
||||||
Enumeration<JarEntry> entries = _jar.entries();
|
Enumeration<? extends ZipEntry> entries = _jar.entries();
|
||||||
|
|
||||||
_nameToEntryMap = new HashMap<>();
|
_nameToEntryMap = new HashMap<>();
|
||||||
_crcToEntryMap = new HashMap<>();
|
_crcToEntryMap = new HashMap<>();
|
||||||
@@ -414,9 +413,9 @@ public class JarDiff implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
if (entries != null) {
|
if (entries != null) {
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry entry = entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
long crc = entry.getCrc();
|
long crc = entry.getCrc();
|
||||||
Long crcL = Long.valueOf(crc);
|
Long crcL = crc;
|
||||||
if (_debug) {
|
if (_debug) {
|
||||||
System.out.println("\t" + entry.getName() + " CRC " + crc);
|
System.out.println("\t" + entry.getName() + " CRC " + crc);
|
||||||
}
|
}
|
||||||
@@ -427,13 +426,13 @@ public class JarDiff implements JarDiffCodes
|
|||||||
// generate the CRC to entries map
|
// generate the CRC to entries map
|
||||||
if (_crcToEntryMap.containsKey(crcL)) {
|
if (_crcToEntryMap.containsKey(crcL)) {
|
||||||
// key exist, add the entry to the correcponding linked list
|
// key exist, add the entry to the correcponding linked list
|
||||||
LinkedList<JarEntry> ll = _crcToEntryMap.get(crcL);
|
LinkedList<ZipEntry> ll = _crcToEntryMap.get(crcL);
|
||||||
ll.add(entry);
|
ll.add(entry);
|
||||||
_crcToEntryMap.put(crcL, ll);
|
_crcToEntryMap.put(crcL, ll);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// create a new entry in the hashmap for the new key
|
// create a new entry in the hashmap for the new key
|
||||||
LinkedList<JarEntry> ll = new LinkedList<JarEntry>();
|
LinkedList<ZipEntry> ll = new LinkedList<ZipEntry>();
|
||||||
ll.add(entry);
|
ll.add(entry);
|
||||||
_crcToEntryMap.put(crcL, ll);
|
_crcToEntryMap.put(crcL, ll);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,22 +11,18 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.LineNumberReader;
|
import java.io.LineNumberReader;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.zip.ZipFile;
|
||||||
import java.util.jar.JarFile;
|
import java.util.zip.ZipOutputStream;
|
||||||
import java.util.jar.JarOutputStream;
|
|
||||||
|
|
||||||
import com.threerings.getdown.util.ProgressObserver;
|
import com.threerings.getdown.util.ProgressObserver;
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,25 +41,23 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
*
|
*
|
||||||
* @throws IOException if any problem occurs during patching.
|
* @throws IOException if any problem occurs during patching.
|
||||||
*/
|
*/
|
||||||
public void patchJar (String jarPath, String diffPath, File target, ProgressObserver observer)
|
public static void patchJar(String jarPath, String diffPath, File target, ProgressObserver observer)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
File oldFile = new File(jarPath), diffFile = new File(diffPath);
|
File oldFile = new File(jarPath), diffFile = new File(diffPath);
|
||||||
|
try (ZipFile oldJar = new ZipFile(oldFile);
|
||||||
try (JarFile oldJar = new JarFile(oldFile);
|
ZipFile jarDiff = new ZipFile(diffFile);
|
||||||
JarFile jarDiff = new JarFile(diffFile);
|
ZipOutputStream jos = new ZipOutputStream(new FileOutputStream(target))) {
|
||||||
JarOutputStream jos = new JarOutputStream(new FileOutputStream(target))) {
|
final Set<String> ignoreSet = new HashSet<>();
|
||||||
|
final Map<String, String> renameMap = new HashMap<>();
|
||||||
Set<String> ignoreSet = new HashSet<>();
|
|
||||||
Map<String, String> renameMap = new HashMap<>();
|
|
||||||
determineNameMapping(jarDiff, ignoreSet, renameMap);
|
determineNameMapping(jarDiff, ignoreSet, renameMap);
|
||||||
|
|
||||||
// get all keys in renameMap
|
// get all keys in renameMap
|
||||||
String[] keys = renameMap.keySet().toArray(new String[renameMap.size()]);
|
String[] keys = renameMap.keySet().toArray(new String[renameMap.size()]);
|
||||||
|
|
||||||
// Files to implicit move
|
// Files to implicit move
|
||||||
Set<String> oldjarNames = new HashSet<>();
|
final Set<String> oldjarNames = new HashSet<>();
|
||||||
Enumeration<JarEntry> oldEntries = oldJar.entries();
|
Enumeration<? extends ZipEntry> oldEntries = oldJar.entries();
|
||||||
if (oldEntries != null) {
|
if (oldEntries != null) {
|
||||||
while (oldEntries.hasMoreElements()) {
|
while (oldEntries.hasMoreElements()) {
|
||||||
oldjarNames.add(oldEntries.nextElement().getName());
|
oldjarNames.add(oldEntries.nextElement().getName());
|
||||||
@@ -83,10 +77,10 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
size -= ignoreSet.size();
|
size -= ignoreSet.size();
|
||||||
|
|
||||||
// Add content from JARDiff
|
// Add content from JARDiff
|
||||||
Enumeration<JarEntry> entries = jarDiff.entries();
|
Enumeration<? extends ZipEntry> entries = jarDiff.entries();
|
||||||
if (entries != null) {
|
if (entries != null) {
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry entry = entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
if (!INDEX_NAME.equals(entry.getName())) {
|
if (!INDEX_NAME.equals(entry.getName())) {
|
||||||
updateObserver(observer, currentEntry, size);
|
updateObserver(observer, currentEntry, size);
|
||||||
currentEntry++;
|
currentEntry++;
|
||||||
@@ -114,15 +108,14 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
// Apply move <oldName> <newName> command
|
// Apply move <oldName> <newName> command
|
||||||
String oldName = renameMap.get(newName);
|
String oldName = renameMap.get(newName);
|
||||||
|
|
||||||
// Get source JarEntry
|
// Get source ZipEntry
|
||||||
JarEntry oldEntry = oldJar.getJarEntry(oldName);
|
ZipEntry oldEntry = oldJar.getEntry(oldName);
|
||||||
if (oldEntry == null) {
|
if (oldEntry == null) {
|
||||||
String moveCmd = MOVE_COMMAND + oldName + " " + newName;
|
throw new IOException("error.badmove: " + MOVE_COMMAND + oldName + " " + newName);
|
||||||
throw new IOException("error.badmove: " + moveCmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create dest JarEntry
|
// Create dest ZipEntry
|
||||||
JarEntry newEntry = new JarEntry(newName);
|
ZipEntry newEntry = new ZipEntry(newName);
|
||||||
newEntry.setTime(oldEntry.getTime());
|
newEntry.setTime(oldEntry.getTime());
|
||||||
newEntry.setSize(oldEntry.getSize());
|
newEntry.setSize(oldEntry.getSize());
|
||||||
newEntry.setCompressedSize(oldEntry.getCompressedSize());
|
newEntry.setCompressedSize(oldEntry.getCompressedSize());
|
||||||
@@ -149,33 +142,29 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// implicit move
|
// implicit move
|
||||||
Iterator<String> iEntries = oldjarNames.iterator();
|
for (String name : oldjarNames) {
|
||||||
if (iEntries != null) {
|
ZipEntry entry = oldJar.getEntry(name);
|
||||||
while (iEntries.hasNext()) {
|
if (entry == null) {
|
||||||
String name = iEntries.next();
|
// names originally retrieved from the JAR, so this should never happen
|
||||||
JarEntry entry = oldJar.getJarEntry(name);
|
throw new AssertionError("JAR entry not found: " + 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);
|
||||||
|
currentEntry++;
|
||||||
|
writeEntry(jos, entry, oldJar);
|
||||||
}
|
}
|
||||||
updateObserver(observer, currentEntry, size);
|
updateObserver(observer, currentEntry, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateObserver (ProgressObserver observer, double currentSize, double size)
|
protected static void updateObserver(ProgressObserver observer, double currentSize, double size)
|
||||||
{
|
{
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
observer.progress((int)(100*currentSize/size));
|
observer.progress((int)(100*currentSize/size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void determineNameMapping (
|
protected static void determineNameMapping(
|
||||||
JarFile jarDiff, Set<String> ignoreSet, Map<String, String> renameMap)
|
ZipFile jarDiff, Set<String> ignoreSet, Map<String, String> renameMap)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
InputStream is = jarDiff.getInputStream(jarDiff.getEntry(INDEX_NAME));
|
InputStream is = jarDiff.getInputStream(jarDiff.getEntry(INDEX_NAME));
|
||||||
@@ -183,8 +172,7 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
throw new IOException("error.noindex");
|
throw new IOException("error.noindex");
|
||||||
}
|
}
|
||||||
|
|
||||||
LineNumberReader indexReader =
|
LineNumberReader indexReader = new LineNumberReader(new InputStreamReader(is, UTF_8));
|
||||||
new LineNumberReader(new InputStreamReader(is, UTF_8));
|
|
||||||
String line = indexReader.readLine();
|
String line = indexReader.readLine();
|
||||||
if (line == null || !line.equals(VERSION_HEADER)) {
|
if (line == null || !line.equals(VERSION_HEADER)) {
|
||||||
throw new IOException("jardiff.error.badheader: " + line);
|
throw new IOException("jardiff.error.badheader: " + line);
|
||||||
@@ -219,12 +207,11 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> getSubpaths (String path)
|
protected static List<String> getSubpaths(String path)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
int length = path.length();
|
int length = path.length();
|
||||||
ArrayList<String> sub = new ArrayList<>();
|
final List<String> sub = new ArrayList<>();
|
||||||
|
|
||||||
while (index < length) {
|
while (index < length) {
|
||||||
while (index < length && Character.isWhitespace
|
while (index < length && Character.isWhitespace
|
||||||
(path.charAt(index))) {
|
(path.charAt(index))) {
|
||||||
@@ -264,7 +251,7 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeEntry (JarOutputStream jos, JarEntry entry, JarFile file)
|
protected static void writeEntry(ZipOutputStream jos, ZipEntry entry, ZipFile file)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
try (InputStream data = file.getInputStream(entry)) {
|
try (InputStream data = file.getInputStream(entry)) {
|
||||||
@@ -272,10 +259,10 @@ public class JarDiffPatcher implements JarDiffCodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeEntry (JarOutputStream jos, JarEntry entry, InputStream data)
|
protected static void writeEntry(ZipOutputStream jos, ZipEntry entry, InputStream data)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
jos.putNextEntry(new JarEntry(entry.getName()));
|
jos.putNextEntry(new ZipEntry(entry.getName()));
|
||||||
|
|
||||||
// Read the entry
|
// Read the entry
|
||||||
int size = data.read(newBytes);
|
int size = data.read(newBytes);
|
||||||
|
|||||||
@@ -9,16 +9,13 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.jar.JarEntry;
|
|
||||||
import java.util.jar.JarFile;
|
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import com.threerings.getdown.util.FileUtil;
|
import com.threerings.getdown.util.FileUtil;
|
||||||
import com.threerings.getdown.util.ProgressObserver;
|
import com.threerings.getdown.util.ProgressObserver;
|
||||||
import com.threerings.getdown.util.StreamUtil;
|
import com.threerings.getdown.util.StreamUtil;
|
||||||
|
|
||||||
import static com.threerings.getdown.Log.log;
|
import static com.threerings.getdown.Log.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,10 +52,10 @@ public class Patcher
|
|||||||
_obs = obs;
|
_obs = obs;
|
||||||
_plength = patch.length();
|
_plength = patch.length();
|
||||||
|
|
||||||
try (JarFile file = new JarFile(patch)) {
|
try (ZipFile file = new ZipFile(patch)) {
|
||||||
Enumeration<JarEntry> entries = file.entries(); // old skool!
|
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry entry = entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
String path = entry.getName();
|
String path = entry.getName();
|
||||||
long elength = entry.getCompressedSize();
|
long elength = entry.getCompressedSize();
|
||||||
|
|
||||||
@@ -96,7 +93,7 @@ public class Patcher
|
|||||||
return path.substring(0, path.length() - suffix.length());
|
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
|
// create our copy buffer if necessary
|
||||||
if (_buffer == null) {
|
if (_buffer == null) {
|
||||||
@@ -124,8 +121,7 @@ public class Patcher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void patchFile (JarFile file, ZipEntry entry,
|
protected void patchFile (ZipFile file, ZipEntry entry, File appdir, String path)
|
||||||
File appdir, String path)
|
|
||||||
{
|
{
|
||||||
File target = new File(appdir, path);
|
File target = new File(appdir, path);
|
||||||
File patch = new File(appdir, entry.getName());
|
File patch = new File(appdir, entry.getName());
|
||||||
@@ -158,7 +154,7 @@ public class Patcher
|
|||||||
|
|
||||||
// now apply the patch to create the new target file
|
// now apply the patch to create the new target file
|
||||||
patcher = new JarDiffPatcher();
|
patcher = new JarDiffPatcher();
|
||||||
patcher.patchJar(otarget.getPath(), patch.getPath(), target, obs);
|
JarDiffPatcher.patchJar(otarget.getPath(), patch.getPath(), target, obs);
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (patcher == null) {
|
if (patcher == null) {
|
||||||
|
|||||||
@@ -5,10 +5,26 @@
|
|||||||
|
|
||||||
package com.threerings.getdown.util;
|
package com.threerings.getdown.util;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.BufferedOutputStream;
|
||||||
import java.util.*;
|
import java.io.BufferedReader;
|
||||||
import java.util.jar.*;
|
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.GZIPInputStream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
import com.threerings.getdown.Log;
|
import com.threerings.getdown.Log;
|
||||||
import static com.threerings.getdown.Log.log;
|
import static com.threerings.getdown.Log.log;
|
||||||
@@ -16,7 +32,7 @@ import static com.threerings.getdown.Log.log;
|
|||||||
/**
|
/**
|
||||||
* File related utilities.
|
* 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
|
* Gets the specified source file to the specified destination file by hook or crook. Windows
|
||||||
@@ -104,7 +120,9 @@ public class FileUtil
|
|||||||
{
|
{
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
try (BufferedReader bin = new BufferedReader(in)) {
|
try (BufferedReader bin = new BufferedReader(in)) {
|
||||||
for (String line = null; (line = bin.readLine()) != null; lines.add(line)) {}
|
for (String line; (line = bin.readLine()) != null;) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
@@ -114,28 +132,28 @@ public class FileUtil
|
|||||||
* @param cleanExistingDirs if true, all files in all directories contained in {@code jar} will
|
* @param cleanExistingDirs if true, all files in all directories contained in {@code jar} will
|
||||||
* be deleted prior to unpacking the jar.
|
* be deleted prior to unpacking the jar.
|
||||||
*/
|
*/
|
||||||
public static void unpackJar (JarFile jar, File target, boolean cleanExistingDirs)
|
public static void unpackJar (ZipFile jar, File target, boolean cleanExistingDirs) throws IOException
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
if (cleanExistingDirs) {
|
if (cleanExistingDirs) {
|
||||||
Enumeration<?> entries = jar.entries();
|
Enumeration<? extends ZipEntry> entries = jar.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry entry = (JarEntry)entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
File efile = new File(target, entry.getName());
|
File efile = new File(target, entry.getName());
|
||||||
if (efile.exists()) {
|
if (efile.exists()) {
|
||||||
for (File f : efile.listFiles()) {
|
for (File f : efile.listFiles()) {
|
||||||
if (!f.isDirectory())
|
if (!f.isDirectory()) {
|
||||||
f.delete();
|
f.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Enumeration<?> entries = jar.entries();
|
Enumeration<? extends ZipEntry> entries = jar.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry entry = (JarEntry)entries.nextElement();
|
ZipEntry entry = entries.nextElement();
|
||||||
File efile = new File(target, entry.getName());
|
File efile = new File(target, entry.getName());
|
||||||
|
|
||||||
// if we're unpacking a normal jar file, it will have special path
|
// if we're unpacking a normal jar file, it will have special path
|
||||||
@@ -169,10 +187,10 @@ public class FileUtil
|
|||||||
* Unpacks a pack200 packed jar file from {@code packedJar} into {@code target}. If {@code
|
* 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.
|
* 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);
|
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") ||
|
boolean gz = (packedJar.getName().endsWith(".gz") ||
|
||||||
packedJar.getName().endsWith(".gz_new"));
|
packedJar.getName().endsWith(".gz_new"));
|
||||||
try (InputStream packJarIn2 = (gz ? new GZIPInputStream(packJarIn) : packJarIn)) {
|
try (InputStream packJarIn2 = (gz ? new GZIPInputStream(packJarIn) : packJarIn)) {
|
||||||
@@ -180,6 +198,7 @@ public class FileUtil
|
|||||||
unpacker.unpack(packJarIn2, jarOut);
|
unpacker.unpack(packJarIn2, jarOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return new JarFile(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user