X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=getdown%2Fsrc%2Fgetdown%2Fcore%2Fsrc%2Fmain%2Fjava%2Fcom%2Fthreerings%2Fgetdown%2Ftools%2FJarDiff.java;fp=getdown%2Fsrc%2Fgetdown%2Fcore%2Fsrc%2Fmain%2Fjava%2Fcom%2Fthreerings%2Fgetdown%2Ftools%2FJarDiff.java;h=1cea0eacdeabae21bfea471aea5da3e164f76dd1;hb=8946f41687f4c822ac8d15ee8551f23f156735c4;hp=0000000000000000000000000000000000000000;hpb=f27f7be4c32780de615e2678f11a5e80702c5e25;p=jalview.git
diff --git a/getdown/src/getdown/core/src/main/java/com/threerings/getdown/tools/JarDiff.java b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/tools/JarDiff.java
new file mode 100644
index 0000000..1cea0ea
--- /dev/null
+++ b/getdown/src/getdown/core/src/main/java/com/threerings/getdown/tools/JarDiff.java
@@ -0,0 +1,449 @@
+//
+// Getdown - application installer, patcher and launcher
+// Copyright (C) 2004-2018 Getdown authors
+// https://github.com/threerings/getdown/blob/master/LICENSE
+
+/*
+ * @(#)JarDiff.java 1.7 05/11/17
+ *
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * -Redistribution of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * -Redistribution in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
+ * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
+ * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
+ * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
+ * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
+ * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
+ * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or intended
+ * for use in the design, construction, operation or maintenance of any
+ * nuclear facility.
+ */
+
+package com.threerings.getdown.tools;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * JarDiff is able to create a jar file containing the delta between two jar files (old and new).
+ * The delta jar file can then be applied to the old jar file to reconstruct the new jar file.
+ *
+ *
Refer to the JNLP spec for details on how this is done.
+ *
+ * @version 1.13, 06/26/03
+ */
+public class JarDiff implements JarDiffCodes
+{
+ private static final int DEFAULT_READ_SIZE = 2048;
+ private static byte[] newBytes = new byte[DEFAULT_READ_SIZE];
+ private static byte[] oldBytes = new byte[DEFAULT_READ_SIZE];
+
+ // The JARDiff.java is the stand-alone jardiff.jar tool. Thus, we do not depend on Globals.java
+ // and other stuff here. Instead, we use an explicit _debug flag.
+ private static boolean _debug;
+
+ /**
+ * Creates a patch from the two passed in files, writing the result to os.
+ */
+ public static void createPatch (String oldPath, String newPath,
+ OutputStream os, boolean minimal) throws IOException
+ {
+ try (JarFile2 oldJar = new JarFile2(oldPath);
+ JarFile2 newJar = new JarFile2(newPath)) {
+
+ HashMap moved = new HashMap<>();
+ 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)
+ for (JarEntry newEntry : newJar) {
+ 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 '
+ 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);
+ }
+ }
+ }
+ }
+
+ // SECOND PASS: = - -
+ //