mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Compare commits
11 Commits
java-diff-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
696edc4c1a | ||
|
|
b4b13c5575 | ||
|
|
c42ba091c5 | ||
|
|
c6b79a67cf | ||
|
|
8a6206e3d4 | ||
|
|
ba008888ab | ||
|
|
9b13cc8199 | ||
|
|
1ef6162ec6 | ||
|
|
5e1a9bd06b | ||
|
|
8b70f76591 | ||
|
|
b117553de7 |
66
README.md
66
README.md
@@ -4,7 +4,7 @@
|
||||
|
||||
[](https://travis-ci.org/java-diff-utils/java-diff-utils)
|
||||
|
||||
[](https://github.com/java-diff-utils/java-diff-utils/actions?query=workflow%3A%22Java+CI+with+Maven%22)
|
||||
[](https://github.com/java-diff-utils/java-diff-utils/actions?query=workflow%3A%22Java+CI+with+Maven%22)
|
||||
|
||||
[](https://www.codacy.com/gh/java-diff-utils/java-diff-utils/dashboard?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
|
||||
|
||||
@@ -12,51 +12,51 @@
|
||||
|
||||
## Intro
|
||||
|
||||
Diff Utils library is an OpenSource library for performing the comparison operations between texts: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
|
||||
Diff Utils library is an open source library for performing comparison operations between texts: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
|
||||
|
||||
Main reason to build this library was the lack of easy-to-use libraries with all the usual stuff you need while working with diff files. Originally it was inspired by JRCS library and it's nice design of diff module.
|
||||
The main reason to build this library was the lack of easy-to-use libraries with all the usual stuff you need while working with diff files. Originally it was inspired by JRCS library and its nice design of diff module.
|
||||
|
||||
**This is originally a fork of java-diff-utils from Google Code Archive.**
|
||||
|
||||
## GPG Signature Validation
|
||||
|
||||
The gpg singing key in [KEYS] is used for this projects artifacts.
|
||||
The GPG signing key in [KEYS] is used for this project's artifacts.
|
||||
|
||||
## API
|
||||
|
||||
Javadocs of the actual release version: [JavaDocs java-diff-utils](https://java-diff-utils.github.io/java-diff-utils/4.10/docs/apidocs/)
|
||||
Javadocs of the actual release version: [Javadocs java-diff-utils](https://java-diff-utils.github.io/java-diff-utils/4.10/docs/apidocs/)
|
||||
|
||||
## Examples
|
||||
|
||||
Look [here](https://github.com/java-diff-utils/java-diff-utils/wiki) to find more helpful informations and examples.
|
||||
Look [here](https://github.com/java-diff-utils/java-diff-utils/wiki) to find more helpful information and examples.
|
||||
|
||||
These two outputs are generated using this java-diff-utils. The source code can also be found at the *Examples* page:
|
||||
These two outputs are generated using java-diff-utils. The source code can also be found on the [Examples](https://github.com/java-diff-utils/java-diff-utils/wiki/Examples) page:
|
||||
|
||||
**Producing a one liner including all difference information.**
|
||||
|
||||
```Java
|
||||
//create a configured DiffRowGenerator
|
||||
```java
|
||||
// Create a configured DiffRowGenerator
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(true)
|
||||
.oldTag(f -> "~") //introduce markdown style for strikethrough
|
||||
.newTag(f -> "**") //introduce markdown style for bold
|
||||
.oldTag(f -> "~") // Introduce markdown style for strikethrough
|
||||
.newTag(f -> "**") // Introduce markdown style for bold
|
||||
.build();
|
||||
|
||||
//compute the differences for two test texts.
|
||||
// Compute the differences for two test texts
|
||||
List<DiffRow> rows = generator.generateDiffRows(
|
||||
Arrays.asList("This is a test senctence."),
|
||||
Arrays.asList("This is a test sentence."),
|
||||
Arrays.asList("This is a test for diffutils."));
|
||||
|
||||
|
||||
System.out.println(rows.get(0).getOldLine());
|
||||
```
|
||||
|
||||
This is a test ~senctence~**for diffutils**.
|
||||
This is a test ~sentence~**for diffutils**.
|
||||
|
||||
**Producing a side by side view of computed differences.**
|
||||
**Producing a side-by-side view of computed differences.**
|
||||
|
||||
```Java
|
||||
```java
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
@@ -64,9 +64,9 @@ DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.newTag(f -> "**")
|
||||
.build();
|
||||
List<DiffRow> rows = generator.generateDiffRows(
|
||||
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
|
||||
Arrays.asList("This is a test sentence.", "This is the second line.", "And here is the finish."),
|
||||
Arrays.asList("This is a test for diffutils.", "This is the second line."));
|
||||
|
||||
|
||||
System.out.println("|original|new|");
|
||||
System.out.println("|--------|---|");
|
||||
for (DiffRow row : rows) {
|
||||
@@ -76,33 +76,33 @@ for (DiffRow row : rows) {
|
||||
|
||||
|original|new|
|
||||
|--------|---|
|
||||
|This is a test ~senctence~.|This is a test **for diffutils**.|
|
||||
|This is a test ~sentence~.|This is a test **for diffutils**.|
|
||||
|This is the second line.|This is the second line.|
|
||||
|~And here is the finish.~||
|
||||
|
||||
## Main Features
|
||||
|
||||
* computing the difference between two texts.
|
||||
* capable to hand more than plain ascii. Arrays or List of any type that implements hashCode() and equals() correctly can be subject to differencing using this library
|
||||
* patch and unpatch the text with the given patch
|
||||
* parsing the unified diff format
|
||||
* producing human-readable differences
|
||||
* inline difference construction
|
||||
* Computing the difference between two texts.
|
||||
* Capable of handling more than plain ASCII. Arrays or lists of any type that implement `hashCode()` and `equals()` correctly can be subject to differencing using this library
|
||||
* Patch and unpatch the text with the given patch
|
||||
* Parsing the unified diff format
|
||||
* Producing human-readable differences
|
||||
* Inline difference construction
|
||||
* Algorithms:
|
||||
* Myers Standard Algorithm
|
||||
* Myers standard algorithm
|
||||
* Myers with linear space improvement
|
||||
* HistogramDiff using JGit Library
|
||||
* HistogramDiff using the JGit library
|
||||
|
||||
### Algorithms
|
||||
|
||||
* Myer's diff
|
||||
* Myers diff
|
||||
* HistogramDiff
|
||||
|
||||
But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future.
|
||||
But it can easily be replaced by any other which is better for handling your texts. I have a plan to add the implementation of some in the future.
|
||||
|
||||
## Source Code conventions
|
||||
|
||||
Recently a checkstyle process was integrated into the build process. java-diff-utils follows the sun java format convention. There are no TABs allowed. Use spaces.
|
||||
Recently a checkstyle process was integrated into the build process. java-diff-utils follows the Sun Java format convention. There are no tabs allowed. Use spaces.
|
||||
|
||||
```java
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
@@ -123,7 +123,7 @@ This is a valid piece of source code:
|
||||
|
||||
### To Install
|
||||
|
||||
Just add the code below to your maven dependencies:
|
||||
Just add the code below to your Maven dependencies:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
@@ -133,7 +133,7 @@ Just add the code below to your maven dependencies:
|
||||
</dependency>
|
||||
```
|
||||
|
||||
or using gradle:
|
||||
or using Gradle:
|
||||
|
||||
```groovy
|
||||
// https://mvnrepository.com/artifact/io.github.java-diff-utils/java-diff-utils
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.16</version>
|
||||
<version>4.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>java-diff-utils-jgit</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.eclipse.jgit.diff.Sequence;
|
||||
import org.eclipse.jgit.diff.SequenceComparator;
|
||||
|
||||
/**
|
||||
* HistorgramDiff using JGit - Library. This one is much more performant than the original Myers
|
||||
* HistogramDiff using JGit - Library. This one is much more performant than the original Myers
|
||||
* implementation.
|
||||
*
|
||||
* @author toben
|
||||
@@ -36,7 +36,8 @@ import org.eclipse.jgit.diff.SequenceComparator;
|
||||
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
@Override
|
||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||
public List<Change> computeDiff(
|
||||
List<? extends T> source, List<? extends T> target, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(source, "source list must not be null");
|
||||
Objects.requireNonNull(target, "target list must not be null");
|
||||
if (progress != null) {
|
||||
@@ -92,9 +93,9 @@ class DataListComparator<T> extends SequenceComparator<DataList<T>> {
|
||||
|
||||
class DataList<T> extends Sequence {
|
||||
|
||||
final List<T> data;
|
||||
final List<? extends T> data;
|
||||
|
||||
public DataList(List<T> data) {
|
||||
public DataList(List<? extends T> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.16</version>
|
||||
<version>4.17-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils</artifactId>
|
||||
|
||||
@@ -57,7 +57,8 @@ public final class DiffUtils {
|
||||
* @param progress a {@link DiffAlgorithmListener} representing the progress listener. Can be {@code null}.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
||||
public static <T> Patch<T> diff(
|
||||
List<? extends T> original, List<? extends T> revised, DiffAlgorithmListener progress) {
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), progress);
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ public final class DiffUtils {
|
||||
* @param revised a {@link List} representing the revised sequence of elements. Must not be {@code null}.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
||||
public static <T> Patch<T> diff(List<? extends T> original, List<? extends T> revised) {
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null);
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ public final class DiffUtils {
|
||||
* @param includeEqualParts a {@link boolean} representing whether to include equal parts in the resulting patch.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
||||
public static <T> Patch<T> diff(List<? extends T> original, List<? extends T> revised, boolean includeEqualParts) {
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null, includeEqualParts);
|
||||
}
|
||||
|
||||
@@ -110,7 +111,8 @@ public final class DiffUtils {
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> source, List<T> target, BiPredicate<T, T> equalizer) {
|
||||
public static <T> Patch<T> diff(
|
||||
List<? extends T> source, List<? extends T> target, BiPredicate<? super T, ? super T> equalizer) {
|
||||
if (equalizer != null) {
|
||||
return DiffUtils.diff(source, target, DEFAULT_DIFF.create(equalizer));
|
||||
}
|
||||
@@ -118,7 +120,10 @@ public final class DiffUtils {
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(
|
||||
List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
||||
List<? extends T> original,
|
||||
List<? extends T> revised,
|
||||
DiffAlgorithmI<T> algorithm,
|
||||
DiffAlgorithmListener progress) {
|
||||
return diff(original, revised, algorithm, progress, false);
|
||||
}
|
||||
|
||||
@@ -135,8 +140,8 @@ public final class DiffUtils {
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(
|
||||
List<T> original,
|
||||
List<T> revised,
|
||||
List<? extends T> original,
|
||||
List<? extends T> revised,
|
||||
DiffAlgorithmI<T> algorithm,
|
||||
DiffAlgorithmListener progress,
|
||||
boolean includeEqualParts) {
|
||||
@@ -157,7 +162,8 @@ public final class DiffUtils {
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
||||
public static <T> Patch<T> diff(
|
||||
List<? extends T> original, List<? extends T> revised, DiffAlgorithmI<T> algorithm) {
|
||||
return diff(original, revised, algorithm, null);
|
||||
}
|
||||
|
||||
@@ -196,7 +202,7 @@ public final class DiffUtils {
|
||||
* @return the revised list.
|
||||
* @throws PatchFailedException if the patch cannot be applied.
|
||||
*/
|
||||
public static <T> List<T> patch(List<T> original, Patch<T> patch) throws PatchFailedException {
|
||||
public static <T> List<T> patch(List<? extends T> original, Patch<T> patch) throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
@@ -208,7 +214,7 @@ public final class DiffUtils {
|
||||
* @return the original list.
|
||||
* @throws PatchFailedException if the patch cannot be applied.
|
||||
*/
|
||||
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
|
||||
public static <T> List<T> unpatch(List<? extends T> revised, Patch<T> patch) {
|
||||
return patch.restore(revised);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,5 +25,5 @@ import java.util.function.BiPredicate;
|
||||
public interface DiffAlgorithmFactory {
|
||||
<T> DiffAlgorithmI<T> create();
|
||||
|
||||
<T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer);
|
||||
<T> DiffAlgorithmI<T> create(BiPredicate<? super T, ? super T> equalizer);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public interface DiffAlgorithmI<T> {
|
||||
* @param progress progress listener
|
||||
* @return
|
||||
*/
|
||||
List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress);
|
||||
List<Change> computeDiff(List<? extends T> source, List<? extends T> target, DiffAlgorithmListener progress);
|
||||
|
||||
/**
|
||||
* Simple extension to compute a changeset using arrays.
|
||||
|
||||
@@ -31,13 +31,13 @@ import java.util.function.BiPredicate;
|
||||
*/
|
||||
public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
private final BiPredicate<T, T> equalizer;
|
||||
private final BiPredicate<? super T, ? super T> equalizer;
|
||||
|
||||
public MyersDiff() {
|
||||
equalizer = Object::equals;
|
||||
}
|
||||
|
||||
public MyersDiff(final BiPredicate<T, T> equalizer) {
|
||||
public MyersDiff(final BiPredicate<? super T, ? super T> equalizer) {
|
||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||
this.equalizer = equalizer;
|
||||
}
|
||||
@@ -48,7 +48,8 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
* Return empty diff if get the error while procession the difference.
|
||||
*/
|
||||
@Override
|
||||
public List<Change> computeDiff(final List<T> source, final List<T> target, DiffAlgorithmListener progress) {
|
||||
public List<Change> computeDiff(
|
||||
final List<? extends T> source, final List<? extends T> target, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(source, "source list must not be null");
|
||||
Objects.requireNonNull(target, "target list must not be null");
|
||||
|
||||
@@ -71,9 +72,10 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
* @return A minimum {@link PathNode Path} accross the differences graph.
|
||||
* @throws DifferentiationFailedException if a diff path could not be found.
|
||||
* @throws IllegalStateException if a diff path could not be found.
|
||||
*/
|
||||
private PathNode buildPath(final List<T> orig, final List<T> rev, DiffAlgorithmListener progress) {
|
||||
private PathNode buildPath(
|
||||
final List<? extends T> orig, final List<? extends T> rev, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(orig, "original sequence is null");
|
||||
Objects.requireNonNull(rev, "revised sequence is null");
|
||||
|
||||
@@ -140,10 +142,10 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
* @return A {@link Patch} script corresponding to the path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
||||
* @throws IllegalStateException if a {@link Patch} could not be
|
||||
* built from the given path.
|
||||
*/
|
||||
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||
private List<Change> buildRevision(PathNode actualPath, List<? extends T> orig, List<? extends T> rev) {
|
||||
Objects.requireNonNull(actualPath, "path is null");
|
||||
Objects.requireNonNull(orig, "original sequence is null");
|
||||
Objects.requireNonNull(rev, "revised sequence is null");
|
||||
@@ -190,7 +192,7 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer) {
|
||||
public <T> DiffAlgorithmI<T> create(BiPredicate<? super T, ? super T> equalizer) {
|
||||
return new MyersDiff<>(equalizer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,19 +32,20 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
private final BiPredicate<T, T> equalizer;
|
||||
private final BiPredicate<? super T, ? super T> equalizer;
|
||||
|
||||
public MyersDiffWithLinearSpace() {
|
||||
equalizer = Object::equals;
|
||||
}
|
||||
|
||||
public MyersDiffWithLinearSpace(final BiPredicate<T, T> equalizer) {
|
||||
public MyersDiffWithLinearSpace(final BiPredicate<? super T, ? super T> equalizer) {
|
||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||
this.equalizer = equalizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||
public List<Change> computeDiff(
|
||||
List<? extends T> source, List<? extends T> target, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(source, "source list must not be null");
|
||||
Objects.requireNonNull(target, "target list must not be null");
|
||||
|
||||
@@ -200,10 +201,10 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
||||
final int[] vDown;
|
||||
final int[] vUp;
|
||||
final List<Change> script;
|
||||
final List<T> source;
|
||||
final List<T> target;
|
||||
final List<? extends T> source;
|
||||
final List<? extends T> target;
|
||||
|
||||
public DiffData(List<T> source, List<T> target) {
|
||||
public DiffData(List<? extends T> source, List<? extends T> target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
size = source.size() + target.size() + 2;
|
||||
@@ -237,7 +238,7 @@ public class MyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer) {
|
||||
public <T> DiffAlgorithmI<T> create(BiPredicate<? super T, ? super T> equalizer) {
|
||||
return new MyersDiffWithLinearSpace<>(equalizer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.github.difflib.patch;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This delta contains equal lines of data. Therefore nothing is to do in applyTo and restore.
|
||||
* This delta contains equal lines of data. Therefore, nothing is to do in applyTo and restore.
|
||||
* @author tobens
|
||||
*/
|
||||
public class EqualDelta<T> extends AbstractDelta<T> {
|
||||
@@ -49,6 +49,6 @@ public class EqualDelta<T> extends AbstractDelta<T> {
|
||||
|
||||
@Override
|
||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||
return new EqualDelta<T>(original, revised);
|
||||
return new EqualDelta<>(original, revised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public final class Patch<T> implements Serializable {
|
||||
* @return A new list containing the applied patch.
|
||||
* @throws PatchFailedException if the patch cannot be applied
|
||||
*/
|
||||
public List<T> applyTo(List<T> target) throws PatchFailedException {
|
||||
public List<T> applyTo(List<? extends T> target) throws PatchFailedException {
|
||||
List<T> result = new ArrayList<>(target);
|
||||
applyToExisting(result);
|
||||
return result;
|
||||
@@ -244,7 +244,7 @@ public final class Patch<T> implements Serializable {
|
||||
* @param target The list to copy and apply changes to.
|
||||
* @return A new list, containing the restored state.
|
||||
*/
|
||||
public List<T> restore(List<T> target) {
|
||||
public List<T> restore(List<? extends T> target) {
|
||||
List<T> result = new ArrayList<>(target);
|
||||
restoreToExisting(result);
|
||||
return result;
|
||||
@@ -294,12 +294,12 @@ public final class Patch<T> implements Serializable {
|
||||
return generate(original, revised, changes, false);
|
||||
}
|
||||
|
||||
private static <T> Chunk<T> buildChunk(int start, int end, List<T> data) {
|
||||
private static <T> Chunk<T> buildChunk(int start, int end, List<? extends T> data) {
|
||||
return new Chunk<>(start, new ArrayList<>(data.subList(start, end)));
|
||||
}
|
||||
|
||||
public static <T> Patch<T> generate(
|
||||
List<T> original, List<T> revised, List<Change> _changes, boolean includeEquals) {
|
||||
List<? extends T> original, List<? extends T> revised, List<Change> _changes, boolean includeEquals) {
|
||||
Patch<T> patch = new Patch<>(_changes.size());
|
||||
int startOriginal = 0;
|
||||
int startRevised = 0;
|
||||
|
||||
@@ -189,6 +189,8 @@ public final class DiffRowGenerator {
|
||||
private final Function<String, String> lineNormalizer;
|
||||
private final Function<String, String> processDiffs;
|
||||
private final Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger;
|
||||
// processor for equal (unchanged) lines
|
||||
private final Function<String, String> equalityProcessor;
|
||||
|
||||
private final boolean showInlineDiffs;
|
||||
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
|
||||
@@ -214,6 +216,7 @@ public final class DiffRowGenerator {
|
||||
lineNormalizer = builder.lineNormalizer;
|
||||
processDiffs = builder.processDiffs;
|
||||
inlineDeltaMerger = builder.inlineDeltaMerger;
|
||||
equalityProcessor = builder.equalityProcessor;
|
||||
|
||||
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
|
||||
|
||||
@@ -262,7 +265,8 @@ public final class DiffRowGenerator {
|
||||
|
||||
// Copy the final matching chunk if any.
|
||||
for (String line : original.subList(endPos, original.size())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
String processed = processEqualities(line);
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, processed, processed));
|
||||
}
|
||||
return diffRows;
|
||||
}
|
||||
@@ -276,7 +280,8 @@ public final class DiffRowGenerator {
|
||||
Chunk<String> rev = delta.getTarget();
|
||||
|
||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
String processed = processEqualities(line);
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, processed, processed));
|
||||
}
|
||||
|
||||
switch (delta.getType()) {
|
||||
@@ -496,6 +501,19 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for processing equal (unchanged) text segments.
|
||||
* Delegates to the builder-configured equalityProcessor if present.
|
||||
*
|
||||
* @author tusharsoni52
|
||||
* @param text
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
protected String processEqualities(final String text) {
|
||||
return equalityProcessor != null ? equalityProcessor.apply(text) : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class used for building the DiffRowGenerator.
|
||||
*
|
||||
@@ -521,6 +539,8 @@ public final class DiffRowGenerator {
|
||||
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
|
||||
private Function<InlineDeltaMergeInfo, List<AbstractDelta<String>>> inlineDeltaMerger =
|
||||
DEFAULT_INLINE_DELTA_MERGER;
|
||||
// Processor for equalities
|
||||
private Function<String, String> equalityProcessor = null;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
@@ -613,6 +633,20 @@ public final class DiffRowGenerator {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processor for equal (unchanged) text parts.
|
||||
* Allows applying the same escaping/transformation as for diffs.
|
||||
*
|
||||
* @author tusharsoni52
|
||||
* @param equalityProcessor
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public Builder processEqualities(Function<String, String> equalityProcessor) {
|
||||
this.equalityProcessor = equalityProcessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column width of generated lines of original and revised
|
||||
* texts.
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.github.difflib.text;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DiffRowGeneratorEqualitiesTest {
|
||||
|
||||
@Test
|
||||
public void testDefaultEqualityProcessingLeavesTextUnchanged() {
|
||||
DiffRowGenerator generator =
|
||||
DiffRowGenerator.create().showInlineDiffs(false).build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello world"), Arrays.asList("hello world"));
|
||||
|
||||
assertEquals(1, rows.size());
|
||||
assertEquals("hello world", rows.get(0).getOldLine());
|
||||
assertEquals("hello world", rows.get(0).getNewLine());
|
||||
assertEquals(DiffRow.Tag.EQUAL, rows.get(0).getTag());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomEqualityProcessingIsApplied() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(false)
|
||||
.processEqualities(text -> "[" + text + "]")
|
||||
.build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("A", "B"), Arrays.asList("A", "B"));
|
||||
|
||||
assertEquals(2, rows.size());
|
||||
assertEquals("[A]", rows.get(0).getOldLine());
|
||||
assertEquals("[B]", rows.get(1).getOldLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that processEqualities can be used to HTML-escape unchanged
|
||||
* lines while still working together with the default HTML-oriented
|
||||
* lineNormalizer.
|
||||
*/
|
||||
@Test
|
||||
public void testHtmlEscapingEqualitiesWorksWithDefaultNormalizer() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
.processEqualities(s -> s.replace("<", "<").replace(">", ">"))
|
||||
.build();
|
||||
|
||||
// both lines are equal -> Tag.EQUAL, processEqualities is invoked
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello <world>"), Arrays.asList("hello <world>"));
|
||||
|
||||
DiffRow row = rows.get(0);
|
||||
|
||||
assertTrue(row.getOldLine().contains("<world>"));
|
||||
assertTrue(row.getNewLine().contains("<world>"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures equalities are processed while inline diff markup is still
|
||||
* present somewhere in the line.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualitiesProcessedButInlineDiffStillPresent() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
.processEqualities(s -> "(" + s + ")")
|
||||
.build();
|
||||
|
||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("hello world"), Arrays.asList("hello there"));
|
||||
|
||||
DiffRow row = rows.get(0);
|
||||
|
||||
System.out.println("OLD = " + row.getOldLine());
|
||||
System.out.println("NEW = " + row.getNewLine());
|
||||
|
||||
// Row must be CHANGE
|
||||
assertEquals(DiffRow.Tag.CHANGE, row.getTag());
|
||||
|
||||
// Inline diff markup must appear
|
||||
assertTrue(
|
||||
row.getOldLine().contains("span") || row.getNewLine().contains("span"),
|
||||
"Expected inline <span> diff markup in old or new line");
|
||||
|
||||
// Equalities inside CHANGE row must NOT be wrapped by processEqualities
|
||||
// Option 3 does NOT modify inline equalities
|
||||
assertTrue(row.getOldLine().startsWith("hello "), "Equal (unchanged) inline segment should remain unchanged");
|
||||
}
|
||||
}
|
||||
4
pom.xml
4
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.16</version>
|
||||
<version>4.17-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>java-diff-utils-parent</name>
|
||||
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
|
||||
@@ -37,7 +37,7 @@
|
||||
<scm>
|
||||
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
|
||||
<tag>java-diff-utils-parent-4.16</tag>
|
||||
<tag>HEAD</tag>
|
||||
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
|
||||
Reference in New Issue
Block a user