|
19 | 19 | importcom.github.difflib.patch.Chunk;
|
20 | 20 | importcom.github.difflib.patch.AbstractDelta;
|
21 | 21 | importcom.github.difflib.patch.Patch;
|
| 22 | + |
22 | 23 | importjava.util.ArrayList;
|
| 24 | +importjava.util.HashMap; |
23 | 25 | importjava.util.List;
|
| 26 | +importjava.util.Map; |
24 | 27 | importjava.util.Optional;
|
25 | 28 | importjava.util.regex.Matcher;
|
26 | 29 | importjava.util.regex.Pattern;
|
| 30 | +importjava.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 | privateUnifiedDiffUtils() {
|
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 | +publicstaticList<String>generateOriginalAndDiff(List<String>original,List<String>revised) { |
| 335 | +returngenerateOriginalAndDiff(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 | +publicstaticList<String>generateOriginalAndDiff(List<String>original,List<String>revised,StringoriginalFileName,StringrevisedFileName) { |
| 354 | +StringoriginalFileNameTemp =originalFileName; |
| 355 | +StringrevisedFileNameTemp =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 | + }elseif (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 | +returninsertOrig(originalWithPrefix,unifiedDiff); |
| 374 | + } |
| 375 | + |
| 376 | +//Insert the diff format to the original file |
| 377 | +privatestaticList<String>insertOrig(List<String>original,List<String>unifiedDiff) { |
| 378 | +List<String>result =newArrayList<>(); |
| 379 | +List<List<String>>diffList =newArrayList<>(); |
| 380 | +List<String>diff =newArrayList<>(); |
| 381 | +for (inti =0;i <unifiedDiff.size();i++) { |
| 382 | +Stringu =unifiedDiff.get(i); |
| 383 | +if (u.startsWith("@@") && !"@@ -0,0 +0,0 @@".equals(u) && !u.contains("@@ -1,")) { |
| 384 | +List<String>twoList =newArrayList<>(); |
| 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 =newArrayList<>(); |
| 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 | +returnresult; |
| 403 | + } |
| 404 | + |
| 405 | +//Insert the diff format to the original file |
| 406 | +privatestaticvoidinsertOrig(List<List<String>>diffList,List<String>result,List<String>original) { |
| 407 | +for (inti =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 | +Stringsimb =i ==0 ?diff.get(2) :diff.get(0); |
| 411 | +StringnexSimb =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 | +intstart =0; |
| 417 | +if (map.get("orgRow") !=0) { |
| 418 | +start =map.get("orgRow") +map.get("orgDel") -1; |
| 419 | + } |
| 420 | +intend =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 | + }elseif (null ==nexSimb && (map.get("orgRow") +map.get("orgDel") -1) <original.size()) { |
| 426 | +intstart =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 | +privatestaticvoidinsert(List<String>result,List<String>noChangeContent) { |
| 435 | +for (Stringins :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 | +privatestaticMap<String,Integer>getRowMap(Stringstr) { |
| 442 | +Map<String,Integer>map =newHashMap<>(); |
| 443 | +if (str.startsWith("@@")) { |
| 444 | +String[]sp =str.split(" "); |
| 445 | +Stringorg =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 | +returnmap; |
| 454 | + } |
| 455 | + |
| 456 | +//Get the specified part of the line from the original file |
| 457 | +privatestaticList<String>getOrigList(List<String>originalWithPrefix,intstart,intend) { |
| 458 | +List<String>list =newArrayList<>(); |
| 459 | +if (originalWithPrefix.size() >=1 &&start <=end &&end <originalWithPrefix.size()) { |
| 460 | +intstartTemp =start; |
| 461 | +for (;startTemp <=end;startTemp++) { |
| 462 | +list.add(originalWithPrefix.get(startTemp)); |
| 463 | + } |
| 464 | + } |
| 465 | +returnlist; |
| 466 | + } |
316 | 467 | }
|