/**
*
*/
package jardiff;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author ejs
*
*/
public class JarDiff {
public static void main(String[] args) throws IOException {
if (args.length < 2) {
System.err.println("Run as: JarDiff [old.jar] [new.jar]\n"+
"\n"+
"Returns exit code 0 for same, 1 for different\n");
System.exit(1);
}
File file1 = new File(args[0]);
File file2 = new File(args[1]);
if (!file1.exists() || !file2.exists()) {
System.exit(1);
}
byte[] content1 = FileUtils.readInputStreamContentsAndClose(new FileInputStream(file1));
byte[] content2 = FileUtils.readInputStreamContentsAndClose(new FileInputStream(file2));
if (content1.length != content2.length) {
System.out.println("File lengths differ");
System.exit(1);
}
// files appear to differ -- but it could just be timestamps
Map<String, String> file1Hashes = getZipHashes(content1);
Map<String, String> file2Hashes = getZipHashes(content2);
boolean changed = false;
for (Map.Entry<String, String> ent1 : file1Hashes.entrySet()) {
String hash1 = ent1.getValue();
String hash2 = file2Hashes.get(ent1.getKey());
if (hash2 == null) {
System.out.println("added " + ent1.getKey());
changed = true;
}
else if (!hash1.equals(hash2)) {
System.out.println("changed " + ent1.getKey());
changed = true;
}
}
for (Map.Entry<String, String> ent2 : file2Hashes.entrySet()) {
String hash1 = file1Hashes.get(ent2.getKey());
if (hash1 == null) {
System.out.println("deleted " + ent2.getKey());
changed = true;
}
}
if (changed)
System.exit(1);
System.exit(0);
}
/**
* @param content1
* @return
* @throws IOException
*/
private static Map<String, String> getZipHashes(byte[] content) throws IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(content);
ZipInputStream zis = new ZipInputStream(bis);
Map<String, String> hashes = new LinkedHashMap<String, String>();
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
String crc = Long.toString(entry.getCrc());
hashes.put(entry.getName(), crc);
}
zis.closeEntry();
}
zis.close();
bis.close();
return hashes;
}
}