package org.eclipse.wst.jsdt.core.tools.comparators; | |
import java.io.BufferedWriter; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.io.Writer; | |
import java.util.ArrayList; | |
public final class DirectoryComparator { | |
private static void collectAllFiles(File root, ArrayList collector) { | |
File[] files = root.listFiles(); | |
for (int i = 0; i < files.length; i++) { | |
final File currentFile = files[i]; | |
if (currentFile.isDirectory()) { | |
collectAllFiles(currentFile, collector); | |
} else { | |
collector.add(currentFile); | |
} | |
} | |
} | |
private static File[] getAllFiles(File root) { | |
ArrayList files = new ArrayList(); | |
if (root.isDirectory()) { | |
collectAllFiles(root, files); | |
File[] result = new File[files.size()]; | |
files.toArray(result); | |
return result; | |
} else { | |
return null; | |
} | |
} | |
public static void main(String[] args) { | |
if (args.length != 3) { | |
System.out.println("Usage: firstDirectory secondDirectory logFile"); | |
return; | |
} | |
new DirectoryComparator(args).compare(); | |
} | |
private boolean abortComparison; | |
private File firstDirectory; | |
private File resultFile; | |
private File secondDirectory; | |
private Writer writer; | |
private static final int DEFAULT_READING_SIZE = 8192; | |
public DirectoryComparator(String[] args) { | |
this.firstDirectory = new File(args[0]); | |
this.secondDirectory = new File(args[1]); | |
this.resultFile = new File(args[2]); | |
this.abortComparison = false; | |
if (!firstDirectory.isDirectory()) { | |
System.out.println("The first argument has to be a directory"); | |
this.abortComparison = true; | |
} | |
if (!secondDirectory.isDirectory()) { | |
System.out.println("The second argument has to be a directory"); | |
this.abortComparison = true; | |
} | |
if (resultFile.isDirectory()) { | |
System.out.println("The third argument has to be a file"); | |
this.abortComparison = true; | |
} | |
} | |
public void compare() { | |
if (this.abortComparison) { return; } | |
File[] files = getAllFiles(firstDirectory); | |
if (files == null) { return; } | |
File[] secondFiles = getAllFiles(secondDirectory); | |
if (secondFiles == null) { return; } | |
final String firstDirectoryAbsolutePath = firstDirectory | |
.getAbsolutePath(); | |
final String secondDirectoryAbsolutePath = secondDirectory | |
.getAbsolutePath(); | |
if (resultFile.exists()) { | |
if (!resultFile.delete()) { | |
System.out.println("Could not delete " + resultFile); | |
return; | |
} | |
} | |
if (secondFiles.length != files.length) { | |
final String errorMessage = "Different number of jars files:\n" | |
+ "\t" + secondFiles.length + " in " | |
+ secondDirectoryAbsolutePath + "\n" + "\t" + files.length | |
+ " in " + firstDirectoryAbsolutePath + "\n"; | |
logError(errorMessage); | |
} | |
for (int i = 0, max = files.length; i < max; i++) { | |
String currentFile = files[i].getAbsolutePath(); | |
String firstFileName = currentFile; | |
// extract the second file name | |
String secondFileName = secondDirectoryAbsolutePath | |
+ File.separator | |
+ currentFile | |
.substring(firstDirectoryAbsolutePath.length() + 1); | |
if (new File(secondFileName).exists()) { | |
if (firstFileName.toLowerCase().endsWith(".jar")) { | |
new JarFileComparator(new String[] { firstFileName, | |
secondFileName, resultFile.getAbsolutePath() }) | |
.compare(); | |
} else { | |
// do a binary compare byte per byte | |
File firstFile = new File(firstFileName); | |
File secondFile = new File(secondFileName); | |
byte[] contentsFile1 = getBytes(firstFile); | |
byte[] contentsFile2 = getBytes(secondFile); | |
if (!equals(contentsFile1, contentsFile2)) { | |
logError("DIFFERENT CONTENTS: " + firstFile.getName() | |
+ "\n"); | |
} | |
} | |
} else { | |
logError(secondFileName + " doesn't exist"); | |
} | |
} | |
System.out.println("DONE. Check the file " | |
+ resultFile.getAbsolutePath() + " to see the result."); | |
if (this.writer != null) { | |
try { | |
writer.flush(); | |
writer.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
private boolean equals(byte[] contentsFile1, byte[] contentsFile2) { | |
if (contentsFile1 == null) { return contentsFile2 == null; } | |
if (contentsFile2 == null) return false; | |
int contentsFile1Length = contentsFile1.length; | |
int contentsFile2Length = contentsFile2.length; | |
if (contentsFile1Length != contentsFile2Length) return false; | |
for (int i = 0; i < contentsFile1Length; i++) { | |
if (contentsFile1[i] != contentsFile2[i]) { return false; } | |
} | |
return true; | |
} | |
public byte[] getBytes(File file) { | |
byte[] contents; | |
try { | |
contents = new byte[0]; | |
int contentsLength = 0; | |
int amountRead = -1; | |
FileInputStream stream = new FileInputStream(file); | |
do { | |
int amountRequested = Math.max(stream.available(), | |
DEFAULT_READING_SIZE); // read at least 8K | |
// resize contents if needed | |
if (contentsLength + amountRequested > contents.length) { | |
System.arraycopy(contents, 0, | |
contents = new byte[contentsLength | |
+ amountRequested], 0, contentsLength); | |
} | |
// read as many bytes as possible | |
amountRead = stream.read(contents, contentsLength, | |
amountRequested); | |
if (amountRead > 0) { | |
// remember length of contents | |
contentsLength += amountRead; | |
} | |
} while (amountRead != -1); | |
// resize contents if necessary | |
if (contentsLength < contents.length) { | |
System.arraycopy(contents, 0, | |
contents = new byte[contentsLength], 0, contentsLength); | |
} | |
return contents; | |
} catch (FileNotFoundException e) { | |
e.printStackTrace(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
private void logError(String message) { | |
try { | |
if (this.writer == null) { | |
this.writer = new BufferedWriter(new FileWriter( | |
this.resultFile, true)); | |
} | |
writer.write(message); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |