package org.bundlemaker.core.itestframework.internal.compare;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import junit.framework.Assert;
import org.bundlemaker.core.itestframework.internal.compare.name.fraser.neil.diff_match_patch;
import org.bundlemaker.core.itestframework.internal.compare.name.fraser.neil.diff_match_patch.Diff;
import org.bundlemaker.core.itestframework.utils.BundleMakerTestUtils;
/**
* <p>
* </p>
*
* @author Gerd Wütherich (gerd@gerd-wuetherich.de)
*/
public class FileDiffUtil {
/**
* <p>
* </p>
*
* @param expected
* @param actual
* @param htmlResult
*/
public static void assertArtifactModel(File expected, File actual, File htmlResult) {
try {
assertArtifactModel(new FileInputStream(expected), new FileInputStream(actual), htmlResult);
} catch (FileNotFoundException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
/**
* <p>
* </p>
*
* @param expected
* @param actual
* @param htmlResult
*/
public static void assertArtifactModel(InputStream expected, InputStream actual, File htmlResult) {
String expectedString = null;
String actualString = null;
expectedString = BundleMakerTestUtils.convertStreamToString(expected);
expectedString = expectedString.replace("\r\n", "\n");
actualString = BundleMakerTestUtils.convertStreamToString(actual);
actualString = actualString.replace("\r\n", "\n");
diff_match_patch patch = new diff_match_patch();
LinkedList<Diff> diffs = patch.diff_main(expectedString, actualString);
if (containsDiffs(diffs)) {
String html = diff_prettyHtml(diffs);
try {
FileWriter fileWriter = new FileWriter(htmlResult);
fileWriter.write(html);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
//
Assert.fail(String.format("Unexpected result. See '%s'.", htmlResult.getName()));
}
}
/**
* <p>
* </p>
*
* @param diffs
* @return
*/
private static boolean containsDiffs(LinkedList<Diff> diffs) {
//
for (Diff aDiff : diffs) {
switch (aDiff.operation) {
case INSERT:
return true;
case DELETE:
return true;
}
}
return false;
}
/**
* Convert a Diff list into a pretty HTML report.
*
* @param diffs
* LinkedList of Diff objects.
* @return HTML representation.
*/
private static String diff_prettyHtml(LinkedList<Diff> diffs) {
StringBuilder html = new StringBuilder();
for (Diff aDiff : diffs) {
// prepare the text for HTML
String text = aDiff.text.replace("&", "&").replace("<", "<").replace(">", ">").replace("\n", "<br>\n");
//
switch (aDiff.operation) {
case INSERT:
html.append("<span style=\"background:#e6ffe6;\">").append(text).append("</span>");
break;
case DELETE:
html.append("<span style=\"background:#ffe6e6;\">").append(text).append("</span>");
break;
case EQUAL:
html.append(text);
break;
}
}
StringBuilder builder = new StringBuilder();
boolean inChange = false;
String[] splitted = html.toString().split("<br>\n");
for (String split : splitted) {
if (isOpener(split)) {
inChange = true;
}
if (inChange && containsMarkedText(split)) {
builder.append(split);
builder.append("<br>\n");
}
if (isCloser(split)) {
inChange = false;
}
}
System.out.println("*****************************************************");
System.out.println(html.toString());
System.out.println(builder.toString());
return builder.toString();
}
private static boolean containsMarkedText(String split) {
int indexOpener = split.lastIndexOf("<span style=\"background:");
int indexCloser = split.lastIndexOf("</span>");
if (indexCloser == 0 && indexOpener == -1) {
return false;
}
return true;
}
/**
* <p>
* </p>
*
* @param split
* @return
*/
private static boolean isOpener(String split) {
int indexOpener = split.lastIndexOf("<span style=\"background:");
int indexCloser = split.lastIndexOf("</span>");
if (indexOpener == -1) {
return false;
}
if (indexCloser == -1) {
return true;
}
if (indexOpener > indexCloser) {
return true;
}
return false;
}
private static boolean isCloser(String split) {
int indexOpener = split.lastIndexOf("<span style=\"background:");
int indexCloser = split.lastIndexOf("</span>");
if (indexCloser == -1) {
return false;
}
if (indexOpener == -1) {
return true;
}
if (indexCloser > indexOpener) {
return true;
}
return false;
}
}