|
19 | 19 | import com.github.difflib.patch.Chunk;
|
20 | 20 | import com.github.difflib.patch.AbstractDelta;
|
21 | 21 | import com.github.difflib.patch.Patch;
|
| 22 | + |
22 | 23 | import java.util.ArrayList;
|
| 24 | +import java.util.HashMap; |
23 | 25 | import java.util.List;
|
| 26 | +import java.util.Map; |
24 | 27 | import java.util.Optional;
|
25 | 28 | import java.util.regex.Matcher;
|
26 | 29 | import java.util.regex.Pattern;
|
| 30 | +import java.util.stream.Collectors; |
27 | 31 |
|
28 | 32 | /**
|
29 | 33 | *
|
@@ -313,4 +317,151 @@ private static List<String> getDeltaText(AbstractDelta<String> delta) {
|
313 | 317 |
|
314 | 318 | private UnifiedDiffUtils() {
|
315 | 319 | }
|
| 320 | + |
| 321 | + /** |
| 322 | + * Compare the differences between two files and return to the original file and diff format |
| 323 | + * |
| 324 | + * (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. |
| 325 | + * You can see all the differences and unmodified places from the original file. |
| 326 | + * Also, this will be very easy and useful for making side-by-side comparison display applications, |
| 327 | + * for example, if you use diff2html (https://github.com/rtfpessoa/diff2html#usage) |
| 328 | + * Wait for tools to display your differences on html pages, you only need to insert the return value into your js code) |
| 329 | + * |
| 330 | + * @param original Original file content |
| 331 | + * @param revised revised file content |
| 332 | + * |
| 333 | + */ |
| 334 | + public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised) { |
| 335 | + return generateOriginalAndDiff(original, revised, null, null); |
| 336 | + } |
| 337 | + |
| 338 | + |
| 339 | + /** |
| 340 | + * Compare the differences between two files and return to the original file and diff format |
| 341 | + * |
| 342 | + * (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. |
| 343 | + * You can see all the differences and unmodified places from the original file. |
| 344 | + * Also, this will be very easy and useful for making side-by-side comparison display applications, |
| 345 | + * for example, if you use diff2html (https://github.com/rtfpessoa/diff2html#usage) |
| 346 | + * Wait for tools to display your differences on html pages, you only need to insert the return value into your js code) |
| 347 | + * |
| 348 | + * @param original Original file content |
| 349 | + * @param revised revised file content |
| 350 | + * @param originalFileName Original file name |
| 351 | + * @param revisedFileName revised file name |
| 352 | + */ |
| 353 | + public static List<String> generateOriginalAndDiff(List<String> original, List<String> revised, String originalFileName, String revisedFileName) { |
| 354 | + String originalFileNameTemp = originalFileName; |
| 355 | + String revisedFileNameTemp = originalFileName; |
| 356 | + if (originalFileNameTemp == null) { |
| 357 | + originalFileNameTemp = "original"; |
| 358 | + } |
| 359 | + if (revisedFileNameTemp == null) { |
| 360 | + revisedFileNameTemp = "revised"; |
| 361 | + } |
| 362 | + Patch<String> patch = DiffUtils.diff(original, revised); |
| 363 | + List<String> unifiedDiff = generateUnifiedDiff(originalFileNameTemp, revisedFileNameTemp, original, patch, 0); |
| 364 | + if (unifiedDiff.isEmpty()) { |
| 365 | + unifiedDiff.add("--- " + originalFileNameTemp); |
| 366 | + unifiedDiff.add("+++ " + revisedFileNameTemp); |
| 367 | + unifiedDiff.add("@@ -0,0 +0,0 @@"); |
| 368 | + } else if (unifiedDiff.size() >= 3 && !unifiedDiff.get(2).contains("@@ -1,")) { |
| 369 | + unifiedDiff.set(1, unifiedDiff.get(1)); |
| 370 | + unifiedDiff.add(2, "@@ -0,0 +0,0 @@"); |
| 371 | + } |
| 372 | + List<String> originalWithPrefix = original.stream().map(v -> " " + v).collect(Collectors.toList()); |
| 373 | + return insertOrig(originalWithPrefix, unifiedDiff); |
| 374 | + } |
| 375 | + |
| 376 | + //Insert the diff format to the original file |
| 377 | + private static List<String> insertOrig(List<String> original, List<String> unifiedDiff) { |
| 378 | + List<String> result = new ArrayList<>(); |
| 379 | + List<List<String>> diffList = new ArrayList<>(); |
| 380 | + List<String> diff = new ArrayList<>(); |
| 381 | + for (int i = 0; i < unifiedDiff.size(); i++) { |
| 382 | + String u = unifiedDiff.get(i); |
| 383 | + if (u.startsWith("@@") && !"@@ -0,0 +0,0 @@".equals(u) && !u.contains("@@ -1,")) { |
| 384 | + List<String> twoList = new ArrayList<>(); |
| 385 | + twoList.addAll(diff); |
| 386 | + diffList.add(twoList); |
| 387 | + diff.clear(); |
| 388 | + diff.add(u); |
| 389 | + continue; |
| 390 | + } |
| 391 | + if (i == unifiedDiff.size() - 1) { |
| 392 | + diff.add(u); |
| 393 | + List<String> twoList = new ArrayList<>(); |
| 394 | + twoList.addAll(diff); |
| 395 | + diffList.add(twoList); |
| 396 | + diff.clear(); |
| 397 | + break; |
| 398 | + } |
| 399 | + diff.add(u); |
| 400 | + } |
| 401 | + insertOrig(diffList, result, original); |
| 402 | + return result; |
| 403 | + } |
| 404 | + |
| 405 | + //Insert the diff format to the original file |
| 406 | + private static void insertOrig(List<List<String>> diffList, List<String> result, List<String> original) { |
| 407 | + for (int i = 0; i < diffList.size(); i++) { |
| 408 | + List<String> diff = diffList.get(i); |
| 409 | + List<String> nexDiff = i == diffList.size() - 1 ? null : diffList.get(i + 1); |
| 410 | + String simb = i == 0 ? diff.get(2) : diff.get(0); |
| 411 | + String nexSimb = nexDiff == null ? null : nexDiff.get(0); |
| 412 | + insert(result, diff); |
| 413 | + Map<String, Integer> map = getRowMap(simb); |
| 414 | + if (null != nexSimb) { |
| 415 | + Map<String, Integer> nexMap = getRowMap(nexSimb); |
| 416 | + int start = 0; |
| 417 | + if (map.get("orgRow") != 0) { |
| 418 | + start = map.get("orgRow") + map.get("orgDel") - 1; |
| 419 | + } |
| 420 | + int end = nexMap.get("revRow") - 2; |
| 421 | + insert(result, getOrigList(original, start, end)); |
| 422 | + } |
| 423 | + if (simb.contains("@@ -1,") && null == nexSimb && map.get("orgDel") != original.size()) { |
| 424 | + insert(result, getOrigList(original, 0, original.size() - 1)); |
| 425 | + } else if (null == nexSimb && (map.get("orgRow") + map.get("orgDel") - 1) < original.size()) { |
| 426 | + int start = map.get("orgRow") + map.get("orgDel") - 1; |
| 427 | + start = start == -1 ? 0 : start; |
| 428 | + insert(result, getOrigList(original, start, original.size() - 1)); |
| 429 | + } |
| 430 | + } |
| 431 | + } |
| 432 | + |
| 433 | + //Insert the unchanged content in the source file into result |
| 434 | + private static void insert(List<String> result, List<String> noChangeContent) { |
| 435 | + for (String ins : noChangeContent) { |
| 436 | + result.add(ins); |
| 437 | + } |
| 438 | + } |
| 439 | + |
| 440 | + //Parse the line containing @@ to get the modified line number to delete or add a few lines |
| 441 | + private static Map<String, Integer> getRowMap(String str) { |
| 442 | + Map<String, Integer> map = new HashMap<>(); |
| 443 | + if (str.startsWith("@@")) { |
| 444 | + String[] sp = str.split(" "); |
| 445 | + String org = sp[1]; |
| 446 | + String[] orgSp = org.split(","); |
| 447 | + map.put("orgRow", Integer.valueOf(orgSp[0].substring(1))); |
| 448 | + map.put("orgDel", Integer.valueOf(orgSp[1])); |
| 449 | + String[] revSp = org.split(","); |
| 450 | + map.put("revRow", Integer.valueOf(revSp[0].substring(1))); |
| 451 | + map.put("revAdd", Integer.valueOf(revSp[1])); |
| 452 | + } |
| 453 | + return map; |
| 454 | + } |
| 455 | + |
| 456 | + //Get the specified part of the line from the original file |
| 457 | + private static List<String> getOrigList(List<String> originalWithPrefix, int start, int end) { |
| 458 | + List<String> list = new ArrayList<>(); |
| 459 | + if (originalWithPrefix.size() >= 1 && start <= end && end < originalWithPrefix.size()) { |
| 460 | + int startTemp = start; |
| 461 | + for (; startTemp <= end; startTemp++) { |
| 462 | + list.add(originalWithPrefix.get(startTemp)); |
| 463 | + } |
| 464 | + } |
| 465 | + return list; |
| 466 | + } |
316 | 467 | }
|
0 commit comments