Skip to content

Commit cb2cc6f

Browse files
committed
Add generateOriginalAndDiff method and test class
1 parent 9f88cf9 commit cb2cc6f

2 files changed

Lines changed: 179 additions & 3 deletions

File tree

java-diff-utils/src/main/java/com/github/difflib/UnifiedDiffUtils.java

Lines changed: 140 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
import com.github.difflib.patch.Chunk;
2020
import com.github.difflib.patch.AbstractDelta;
2121
import com.github.difflib.patch.Patch;
22-
import java.util.ArrayList;
23-
import java.util.List;
24-
import java.util.Optional;
22+
23+
import java.util.*;
2524
import java.util.regex.Matcher;
2625
import java.util.regex.Pattern;
26+
import java.util.stream.Collectors;
2727

2828
/**
2929
*
@@ -313,4 +313,141 @@ private static List<String> getDeltaText(AbstractDelta<String> delta) {
313313

314314
private UnifiedDiffUtils() {
315315
}
316+
317+
/**
318+
* Compare the differences between two files and return to the original file and diff format
319+
*
320+
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
321+
* You can see all the differences and unmodified places from the original file.
322+
* Also, this will be very easy and useful for making side-by-side comparison display applications,
323+
* for example, if you use diff2html (https://github.com/rtfpessoa/diff2html#usage)
324+
* Wait for tools to display your differences on html pages, you only need to insert the return value into your js code)
325+
*
326+
* @param original Original file content
327+
* @param revised revised file content
328+
*
329+
*/
330+
public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised) {
331+
return generateOriginalAndDiff(original, revised, null, null);
332+
}
333+
334+
335+
/**
336+
* Compare the differences between two files and return to the original file and diff format
337+
*
338+
* (This method compares the original file with the comparison file to obtain a diff, and inserts the diff into the corresponding position of the original file.
339+
* You can see all the differences and unmodified places from the original file.
340+
* Also, this will be very easy and useful for making side-by-side comparison display applications,
341+
* for example, if you use diff2html (https://github.com/rtfpessoa/diff2html#usage)
342+
* Wait for tools to display your differences on html pages, you only need to insert the return value into your js code)
343+
*
344+
* @param original Original file content
345+
* @param revised revised file content
346+
* @param originalFileName Original file name
347+
* @param revisedFileName revised file name
348+
*/
349+
public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised, String originalFileName, String revisedFileName) {
350+
originalFileName = originalFileName == null ? "original" : originalFileName;
351+
revisedFileName = revisedFileName == null ? "revised" : revisedFileName;
352+
Patch<String> patch = com.github.difflib.DiffUtils.diff(original, revised);
353+
List<String> unifiedDiff = generateUnifiedDiff(originalFileName, revisedFileName, original, patch, 0);
354+
if (unifiedDiff.size() == 0) {
355+
unifiedDiff.add("--- " + originalFileName);
356+
unifiedDiff.add("+++ " + revisedFileName);
357+
unifiedDiff.add("@@ -0,0 +0,0 @@");
358+
} else if (unifiedDiff.size() >= 3 && !unifiedDiff.get(2).contains("@@ -1,")) {
359+
unifiedDiff.set(1, unifiedDiff.get(1));
360+
unifiedDiff.add(2, "@@ -0,0 +0,0 @@");
361+
}
362+
List<String> original1 = original.stream().map(v -> " " + v).collect(Collectors.toList());
363+
return insertOrig(original1, unifiedDiff);
364+
}
365+
366+
367+
//Insert the diff format to the original file
368+
private static List<String> insertOrig(List<String> original, List<String> unifiedDiff) {
369+
List<String> result = new ArrayList<>();
370+
List<List<String>> diffList = new ArrayList<>();
371+
List<String> d = new ArrayList<>();
372+
for (int i = 0; i < unifiedDiff.size(); i++) {
373+
String u = unifiedDiff.get(i);
374+
if (u.startsWith("@@") && !"@@ -0,0 +0,0 @@".equals(u) && !u.contains("@@ -1,")) {
375+
List<String> twoList = new ArrayList<>();
376+
twoList.addAll(d);
377+
diffList.add(twoList);
378+
d.clear();
379+
d.add(u);
380+
continue;
381+
}
382+
if (i == unifiedDiff.size() - 1) {
383+
d.add(u);
384+
List<String> twoList = new ArrayList<>();
385+
twoList.addAll(d);
386+
diffList.add(twoList);
387+
d.clear();
388+
break;
389+
}
390+
d.add(u);
391+
}
392+
for (int i = 0; i < diffList.size(); i++) {
393+
List<String> diff = diffList.get(i);
394+
List<String> nexDiff = i == diffList.size() - 1 ? null : diffList.get(i + 1);
395+
String simb = i == 0 ? diff.get(2) : diff.get(0);
396+
String nexSimb = nexDiff == null ? null : nexDiff.get(0);
397+
insert(result, diff);
398+
Map<String, Integer> map = getRowMap(simb);
399+
if (null != nexSimb) {
400+
Map<String, Integer> nexMap = getRowMap(nexSimb);
401+
int start = 0;
402+
if (map.get("orgRow") != 0) {
403+
start = map.get("orgRow") + map.get("orgDel") - 1;
404+
}
405+
int end = nexMap.get("revRow") - 2;
406+
insert(result, getOrigList(original, start, end));
407+
}
408+
409+
if (simb.contains("@@ -1,") && null == nexSimb && map.get("orgDel") != original.size()) {
410+
insert(result, getOrigList(original, 0, original.size() - 1));
411+
} else if (null == nexSimb && (map.get("orgRow") + map.get("orgDel") - 1) < original.size()) {
412+
int start = (map.get("orgRow") + map.get("orgDel") - 1);
413+
start = start == -1 ? 0 : start;
414+
insert(result, getOrigList(original, start, original.size() - 1));
415+
}
416+
}
417+
return result;
418+
}
419+
420+
//Insert the unchanged content in the source file into result
421+
private static void insert(List<String> result, List<String> noChangeContent) {
422+
for (String ins : noChangeContent) {
423+
result.add(ins);
424+
}
425+
}
426+
427+
//Parse the line containing @@ to get the modified line number to delete or add a few lines
428+
private static Map<String, Integer> getRowMap(String str) {
429+
Map<String, Integer> map = new HashMap<>();
430+
if (str.startsWith("@@")) {
431+
String[] sp = str.split(" ");
432+
String org = sp[1];
433+
String[] orgSp = org.split(",");
434+
map.put("orgRow", Integer.valueOf(orgSp[0].substring(1)));
435+
map.put("orgDel", Integer.valueOf(orgSp[1]));
436+
String[] revSp = org.split(",");
437+
map.put("revRow", Integer.valueOf(revSp[0].substring(1)));
438+
map.put("revAdd", Integer.valueOf(revSp[1]));
439+
}
440+
return map;
441+
}
442+
443+
//Get the specified part of the line from the original file
444+
private static List<String> getOrigList(List<String> original1, int start, int end) {
445+
List<String> list = new ArrayList<>();
446+
if (original1.size() >= 1 && start <= end && end < original1.size()) {
447+
for (; start <= end; start++) {
448+
list.add(original1.get(start));
449+
}
450+
}
451+
return list;
452+
}
316453
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.github.difflib.examples;
2+
3+
import com.github.difflib.TestConstants;
4+
import com.github.difflib.UnifiedDiffUtils;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.io.BufferedReader;
8+
import java.io.FileNotFoundException;
9+
import java.io.FileReader;
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
import static java.util.stream.Collectors.joining;
15+
16+
public class OriginalAndDiffTest {
17+
18+
@Test
19+
public void testGenerateOriginalAndDiff() throws IOException {
20+
List<String> origLines = fileToLines(TestConstants.MOCK_FOLDER + "original.txt");
21+
List<String> revLines = fileToLines(TestConstants.MOCK_FOLDER + "revised.txt");
22+
23+
List<String> originalAndDiff = UnifiedDiffUtils.generateOriginalAndDiff(origLines,revLines);
24+
System.out.println(originalAndDiff.stream().collect(joining("\n")));
25+
}
26+
27+
public static List<String> fileToLines(String filename) throws FileNotFoundException, IOException {
28+
List<String> lines = new ArrayList<>();
29+
String line = "";
30+
try (BufferedReader in = new BufferedReader(new FileReader(filename))) {
31+
while ((line = in.readLine()) != null) {
32+
lines.add(line);
33+
}
34+
}
35+
return lines;
36+
}
37+
38+
39+
}

0 commit comments

Comments
 (0)