-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathEarDiff.java
170 lines (136 loc) · 4.2 KB
/
EarDiff.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class EarDiff {
JarFile[] ears = new JarFile[2];
long startTime;
long elapsed;
public EarDiff(String file1, String file2) throws IOException {
ears[0] = new JarFile(file1);
ears[1] = new JarFile(file2);
startTime = System.currentTimeMillis();
}
/**
* Remove the CRC which is after the last colon
*
* @param codes
* @return
*/
public List<String> stripCRCs(List<String> codes) {
List<String> result = new ArrayList<String>();
for (String s : codes) {
result.add(s.substring(0, s.lastIndexOf(':')));
}
return result;
}
/**
* Extract an embedded jar file so that it can be scanned.
*
* @param jar
* @param jarEntry
* @param prefix
* @return
* @throws IOException
*/
public List<String> dumpEmbeddedJar(JarFile jar, JarEntry jarEntry, String prefix) throws IOException {
prefix += jarEntry.getName() + ":";
File tmpFile = File.createTempFile("JAR", "jar");
byte[] buffer = new byte[4096];
InputStream is = jar.getInputStream(jarEntry);
OutputStream os = new FileOutputStream(tmpFile);
int length = 0;
while ((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
os.close();
is.close();
return dumpJar(new JarFile(tmpFile), prefix);
}
/**
* Scan a jar file. If it is an embedded jar then pass a prefix.
*
* @param jar
* @param prefix
* @return
* @throws IOException
*/
public List<String> dumpJar(JarFile jar, String prefix) throws IOException {
List<String> codes = new ArrayList<String>();
for (JarEntry entry : Collections.list(jar.entries())) {
codes.add(prefix + entry.getName() + ":" + entry.getCrc());
if (entry.getName().toLowerCase().endsWith(".war") || entry.getName().toLowerCase().endsWith(".jar")) {
codes.addAll(dumpEmbeddedJar(jar, entry, prefix));
}
}
return codes;
}
/**
* Compare two ear files.
*
* @return true if files are identical
*/
public boolean compare() throws IOException {
List<String> codes1 = dumpJar(ears[0], "");
List<String> codes2 = dumpJar(ears[1], "");
// Throw away codes that have identical filenames and CRCs.
List<String> identical = new ArrayList<String>(codes1);
identical.retainAll(codes2);
codes1.removeAll(identical);
codes2.removeAll(identical);
System.out.println(identical.size() + " identical files found");
// Remove the CRCs from the files that are left
codes1 = stripCRCs(codes1);
codes2 = stripCRCs(codes2);
// If they are in both ears then the file has been changed.
// Otherwise it has been added/removed
List<String> changed = new ArrayList<String>(codes1);
changed.retainAll(codes2);
codes1.removeAll(changed);
codes2.removeAll(changed);
System.out.println("CHANGED:");
for (String code : changed) {
System.out.println(code);
}
System.out.println("Only in EAR1:");
for (String code : codes1) {
System.out.println(code);
}
System.out.println("Only in EAR2:");
for (String code : codes2) {
System.out.println(code);
}
elapsed = System.currentTimeMillis() - startTime;
return (codes1.size() + codes2.size() + changed.size() == 0);
}
public long getElapsedTime() {
return elapsed;
}
/**
* @param args
*/
public static void main(String[] args) {
boolean same = true;
long elapsed = 0;
try {
if (args != null && args.length == 2) {
System.out.println("Comparing " + args[0] + " against " + args[1]);
EarDiff diff = new EarDiff(args[0], args[1]);
same = diff.compare();
elapsed = diff.getElapsedTime();
} else {
System.out.println("Usage EarDiff <file1> <file2>");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Done " + (same ? "- no differences found" : "") + " in " + elapsed + " ms.");
}
}
}