mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
removed inheritance for pathnode
This commit is contained in:
@@ -38,7 +38,9 @@ public interface DiffAlgorithm<T> {
|
||||
* @param revised The revised sequence. Must not be {@code null}.
|
||||
* @return The patch representing the diff of the given sequences. Never {@code null}.
|
||||
*/
|
||||
public Patch<T> diff(T[] original, T[] revised) throws DiffException;
|
||||
public default Patch<T> diff(T[] original, T[] revised) throws DiffException {
|
||||
return diff(Arrays.asList(original), Arrays.asList(revised));
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original sequence and the revised sequence and returns it
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*-
|
||||
* #%L
|
||||
* java-diff-utils
|
||||
* %%
|
||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package difflib.algorithm.myers;
|
||||
|
||||
/**
|
||||
* A diffnode in a diffpath.
|
||||
* <p>
|
||||
* A DiffNode and its previous node mark a delta between two input sequences, that is, two differing
|
||||
* subsequences between (possibly zero length) matching sequences.
|
||||
*
|
||||
* {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression of diffpaths, as each
|
||||
* snake is represented by a single {@link Snake Snake} node and each contiguous series of
|
||||
* insertions and deletions is represented by a single {@link DiffNode DiffNodes}.
|
||||
*
|
||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||
*
|
||||
*/
|
||||
public final class DiffNode extends PathNode {
|
||||
|
||||
/**
|
||||
* Constructs a DiffNode.
|
||||
* <p>
|
||||
* DiffNodes are compressed. That means that the path pointed to by the <code>prev</code>
|
||||
* parameter will be followed using {@link PathNode#previousSnake} until a non-diff node is
|
||||
* found.
|
||||
*
|
||||
* @param the position in the original sequence
|
||||
* @param the position in the revised sequence
|
||||
* @param prev the previous node in the path.
|
||||
*/
|
||||
public DiffNode(int i, int j, PathNode prev) {
|
||||
super(i, j, (prev == null ? null : prev.previousSnake()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return false, always
|
||||
*/
|
||||
@Override
|
||||
public boolean isSnake() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -74,16 +74,6 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
this.equalizer = equalizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return Returns an empty diff if get the error while procession the difference.
|
||||
*/
|
||||
@Override
|
||||
public Patch<T> diff(final T[] original, final T[] revised) throws DiffException {
|
||||
return diff(Arrays.asList(original), Arrays.asList(revised));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -93,7 +83,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
public Patch<T> diff(final List<T> original, final List<T> revised) throws DiffException {
|
||||
Objects.requireNonNull(original, "original list must not be null");
|
||||
Objects.requireNonNull(revised, "revised list must not be null");
|
||||
|
||||
|
||||
PathNode path = buildPath(original, revised);
|
||||
return buildRevision(path, original, revised);
|
||||
}
|
||||
@@ -121,7 +111,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
final int middle = size / 2;
|
||||
final PathNode diagonal[] = new PathNode[size];
|
||||
|
||||
diagonal[middle + 1] = new Snake(0, -1, null);
|
||||
diagonal[middle + 1] = new PathNode(0, -1, true, null);
|
||||
for (int d = 0; d < MAX; d++) {
|
||||
for (int k = -d; k <= d; k += 2) {
|
||||
final int kmiddle = middle + k;
|
||||
@@ -142,17 +132,15 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
|
||||
int j = i - k;
|
||||
|
||||
PathNode node = new DiffNode(i, j, prev);
|
||||
PathNode node = new PathNode(i, j, false, prev);
|
||||
|
||||
// orig and rev are zero-based
|
||||
// but the algorithm is one-based
|
||||
// that's why there's no +1 when indexing the sequences
|
||||
while (i < N && j < M && equalizer.equals(orig.get(i), rev.get(j))) {
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
if (i > node.i) {
|
||||
node = new Snake(i, j, node);
|
||||
|
||||
if (i != node.i) {
|
||||
node = new PathNode(i, j, true, node);
|
||||
}
|
||||
|
||||
diagonal[kmiddle] = node;
|
||||
@@ -162,7 +150,6 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
}
|
||||
}
|
||||
diagonal[middle + d - 1] = null;
|
||||
|
||||
}
|
||||
// According to Myers, this cannot happen
|
||||
throw new DifferentiationFailedException("could not find a diff path");
|
||||
|
||||
@@ -22,13 +22,13 @@ package difflib.algorithm.myers;
|
||||
/**
|
||||
* A node in a diffpath.
|
||||
*
|
||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||
*
|
||||
* @see DiffNode
|
||||
* @see Snake
|
||||
*
|
||||
*/
|
||||
public abstract class PathNode {
|
||||
public final class PathNode {
|
||||
|
||||
/**
|
||||
* Position in the original sequence.
|
||||
@@ -43,6 +43,8 @@ public abstract class PathNode {
|
||||
*/
|
||||
public final PathNode prev;
|
||||
|
||||
public final boolean snake;
|
||||
|
||||
/**
|
||||
* Concatenates a new path node with an existing diffpath.
|
||||
*
|
||||
@@ -50,18 +52,20 @@ public abstract class PathNode {
|
||||
* @param j The position in the revised sequence for the new node.
|
||||
* @param prev The previous node in the path.
|
||||
*/
|
||||
public PathNode(int i, int j, PathNode prev) {
|
||||
public PathNode(int i, int j, boolean snake, PathNode prev) {
|
||||
this.i = i;
|
||||
this.j = j;
|
||||
this.prev = prev;
|
||||
if (snake) {
|
||||
this.prev = prev;
|
||||
} else {
|
||||
this.prev = (prev == null ? null : prev.previousSnake());
|
||||
}
|
||||
this.snake = snake;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this node a {@link Snake Snake node}?
|
||||
*
|
||||
* @return true if this is a {@link Snake Snake node}
|
||||
*/
|
||||
public abstract boolean isSnake();
|
||||
public boolean isSnake() {
|
||||
return snake;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a bootstrap node?
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*-
|
||||
* #%L
|
||||
* java-diff-utils
|
||||
* %%
|
||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
package difflib.algorithm.myers;
|
||||
|
||||
/**
|
||||
* Represents a snake in a diffpath.
|
||||
* <p>
|
||||
*
|
||||
* {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression of diffpaths, as each
|
||||
* snake is represented by a single {@link Snake Snake} node and each contiguous series of
|
||||
* insertions and deletions is represented by a single {@link DiffNode DiffNodes}.
|
||||
*
|
||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||
*
|
||||
*/
|
||||
public final class Snake extends PathNode {
|
||||
|
||||
/**
|
||||
* Constructs a snake node.
|
||||
*
|
||||
* @param the position in the original sequence
|
||||
* @param the position in the revised sequence
|
||||
* @param prev the previous node in the path.
|
||||
*/
|
||||
public Snake(int i, int j, PathNode prev) {
|
||||
super(i, j, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @return true always
|
||||
*/
|
||||
@Override
|
||||
public boolean isSnake() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -145,11 +145,19 @@ public class DiffUtilsTest {
|
||||
assertEquals(1, patch.getDeltas().size());
|
||||
}
|
||||
|
||||
private static List<String> readStringListFromInputStream(InputStream is) throws IOException {
|
||||
public static List<String> readStringListFromInputStream(InputStream is) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) {
|
||||
|
||||
return reader.lines().collect(toList());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiffMyersExample1() throws DiffException {
|
||||
final Patch<String> patch = DiffUtils.diff(Arrays.asList("A","B","C","A","B","B","A"), Arrays.asList("C","B","A","B","A","C"));
|
||||
assertNotNull(patch);
|
||||
assertEquals(4, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
}
|
||||
}
|
||||
|
||||
66
src/test/java/difflib/algorithm/myers/MyersDiffTest.java
Normal file
66
src/test/java/difflib/algorithm/myers/MyersDiffTest.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2017 java-diff-utils.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package difflib.algorithm.myers;
|
||||
|
||||
import difflib.DiffUtils;
|
||||
import difflib.algorithm.DiffException;
|
||||
import difflib.patch.Patch;
|
||||
import java.util.Arrays;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public class MyersDiffTest {
|
||||
|
||||
public MyersDiffTest() {
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testDiffMyersExample1Forward() throws DiffException {
|
||||
final Patch<String> patch = new MyersDiff<String>().diff(
|
||||
Arrays.asList("A","B","C","A","B","B","A"),
|
||||
Arrays.asList("C","B","A","B","A","C"));
|
||||
assertNotNull(patch);
|
||||
assertEquals(4, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user