package org.josso.tooling.gshell.install.util;
import name.fraser.neil.plaintext.diff_match_patch;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
*/
public class DiffMatchPatchUtil {
private static final Log log = LogFactory.getLog(DiffMatchPatchUtil.class);
private static DiffMatchPatchUtil dMpUtil;
private diff_match_patch dmp;
private DiffMatchPatchUtil() {
dmp = new diff_match_patch();
}
public static DiffMatchPatchUtil getInstance() {
if (dMpUtil == null)
dMpUtil = new DiffMatchPatchUtil();
return dMpUtil;
}
public Object clone()
throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
/*
private String[] filesForDiff = {
"/index.php",
"/includes/functions.php",
"/includes/functions_user.php",
"/language/en/common.php",
"/styles/prosilver/template/index_body.html",
"/styles/prosilver/template/login_body.html"
};
*/
public void createPatchesForDirectories(String target_dir, String source_dir, String[] filesForDiff, String outPatchFile) {
int count = 0;
StringBuffer sbResult = new StringBuffer();
File filePatch = new File(outPatchFile);
try {
for (String fStr : filesForDiff) {
File targetFile = new File(target_dir + fStr);
File sourceFile = new File(source_dir + fStr);
count++;
String content_target = FileUtils.readFileToString(targetFile, null);
String content_source = FileUtils.readFileToString(sourceFile, null);
if (content_target != null && content_source != null) {
// An array of differences is computed which describe the
// transformation of content_source into content_target.
LinkedList<diff_match_patch.Diff> diffs = dmp.diff_main(content_source, content_target);
LinkedList<diff_match_patch.Patch> patches = dmp.patch_make(diffs);
sbResult.append("--------------------------------------------------\n");
sbResult.append("Patch " + count + " | (" + fStr + ")\n");
sbResult.append("--------------------------------------------------\n");
sbResult.append(dmp.patch_toText(patches) + "\n");
}
}
FileUtils.writeStringToFile(filePatch, sbResult.toString());
} catch (FileNotFoundException e) {
log.debug(e.getMessage());
} catch (IOException e) {
log.debug(e.getMessage());
}
}
/*
Creates hashmap with <FilePath, Patches>
*/
public HashMap<String, List<diff_match_patch.Patch>> getPatchesFromFile(String fileName) {
HashMap<String, List<diff_match_patch.Patch>> resultMap = new HashMap<String, List<diff_match_patch.Patch>>();
File srcFile = new File(fileName);
try {
String patchFileStr = FileUtils.readFileToString(srcFile, null);
String REGEX = "--------------------------------------------------\n";
Pattern p = Pattern.compile(REGEX);
String[] items = p.split(patchFileStr, 0);
String fileN = "";
for (int i = 0; i < items.length; i++) {
if (items[i].contains("Patch")) {
fileN = items[i].substring(items[i].indexOf("(") + 1, items[i].indexOf(")"));
String patch = items[i + 1];
List<diff_match_patch.Patch> patches = dmp.patch_fromText(patch);
if (!"".equals(fileN) && patches != null) {
resultMap.put(fileN, patches);
fileN = "";
}
}
}
} catch (IOException e) {
log.debug(e.getMessage());
}
return resultMap;
}
/*
Applies patches for one file
*/
public boolean applyPatch(String fileName, List<diff_match_patch.Patch> patches) {
File targetFile = new File(fileName);
LinkedList llPatches = new LinkedList<diff_match_patch.Patch>(patches);
boolean statusOk = true;
try {
String patchFileStr = FileUtils.readFileToString(targetFile, null);
Object[] resultArr = dmp.patch_apply(llPatches, patchFileStr);
String patchedText = (String) resultArr[0];
boolean[] pResults = (boolean[]) resultArr[1];
for (int i = 0; i < pResults.length; i++) {
statusOk = statusOk && pResults[i];
}
if (statusOk) {
FileUtils.writeStringToFile(targetFile, patchedText);
} else return false;
} catch (IOException e) {
log.debug(e.getMessage());
}
return true;
}
public static void main(String[] args) {
HashMap<String, List<diff_match_patch.Patch>> patchesMap = DiffMatchPatchUtil.getInstance().
getPatchesFromFile("/home/fish/tmp/patch.file");
String tgDir = "/home/fish/tmp/original/phpBB3";
Iterator kIter = patchesMap.keySet().iterator();
while (kIter.hasNext()) {
String fName = (String) kIter.next();
List<diff_match_patch.Patch> patches = patchesMap.get(fName);
boolean statusOk = DiffMatchPatchUtil.getInstance().applyPatch(new String(tgDir+fName), patches);
System.out.println("Filename: " + fName);
//System.out.println("Patch: " + patches);
System.out.println("Status: " + statusOk);
}
}
}