mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
cleanup and fixes: comparator in Patch was broken which caused incorrect delta sorting, Chunk does not store lines as a separate field, in fact it is an attribute of the Chunk.lines collection.Minor cleanup in tests, still more to be done in geenerated udiff tests
This commit is contained in:
@@ -40,7 +40,7 @@ public class ChangeDelta extends Delta {
|
||||
public void applyTo(List<Object> target) throws PatchFailedException {
|
||||
verify(target);
|
||||
int position = getOriginal().getPosition();
|
||||
int size = getOriginal().getSize();
|
||||
int size = getOriginal().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
target.remove(position);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public class ChangeDelta extends Delta {
|
||||
@Override
|
||||
public void restore(List<Object> target) {
|
||||
int position = getRevised().getPosition();
|
||||
int size = getRevised().getSize();
|
||||
int size = getRevised().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
target.remove(position);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package difflib;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Holds the information about the part of text involved in the diff process
|
||||
@@ -31,8 +32,8 @@ import java.util.*;
|
||||
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
||||
*/
|
||||
public class Chunk {
|
||||
private int position;
|
||||
private int size;
|
||||
|
||||
private final int position;
|
||||
private List<?> lines;
|
||||
|
||||
/**
|
||||
@@ -40,14 +41,11 @@ public class Chunk {
|
||||
*
|
||||
* @param position
|
||||
* the start position
|
||||
* @param size
|
||||
* the size of a Chunk
|
||||
* @param lines
|
||||
* the affected lines
|
||||
*/
|
||||
public Chunk(int position, int size, List<?> lines) {
|
||||
public Chunk(int position, List<?> lines) {
|
||||
this.position = position;
|
||||
this.size = size;
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@@ -56,14 +54,11 @@ public class Chunk {
|
||||
*
|
||||
* @param position
|
||||
* the start position
|
||||
* @param size
|
||||
* the size of a Chunk
|
||||
* @param lines
|
||||
* the affected lines
|
||||
*/
|
||||
public Chunk(int position, int size, Object[] lines) {
|
||||
public Chunk(int position, Object[] lines) {
|
||||
this.position = position;
|
||||
this.size = size;
|
||||
this.lines = Arrays.asList(lines);
|
||||
}
|
||||
|
||||
@@ -78,7 +73,7 @@ public class Chunk {
|
||||
if (last() > target.size()) {
|
||||
throw new PatchFailedException("Incorrect Chunk: the position of chunk > target size");
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (!target.get(position + i).equals(lines.get(i))) {
|
||||
throw new PatchFailedException(
|
||||
"Incorrect Chunk: the chunk content doesn't match the target");
|
||||
@@ -92,50 +87,27 @@ public class Chunk {
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position
|
||||
* the start position to set
|
||||
*/
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
|
||||
public void setLines(List<?> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size of Chunk (size of affected lines)
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size
|
||||
* the size of affected lines to set
|
||||
*/
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the affected lines
|
||||
*/
|
||||
public List<?> getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lines
|
||||
* the affected lines to set
|
||||
*/
|
||||
public void setLines(List<?> lines) {
|
||||
this.lines = lines;
|
||||
|
||||
public int size() {
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the last line of the chunk.
|
||||
*/
|
||||
public int last() {
|
||||
return getPosition() + getSize() - 1;
|
||||
return getPosition() + size() - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -149,7 +121,7 @@ public class Chunk {
|
||||
int result = 1;
|
||||
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
|
||||
result = prime * result + position;
|
||||
result = prime * result + size;
|
||||
result = prime * result + size();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -174,14 +146,12 @@ public class Chunk {
|
||||
return false;
|
||||
if (position != other.position)
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[position: " + position + ", size: " + size + ", lines: " + lines + "]";
|
||||
return "[position: " + position + ", size: " + size() + ", lines: " + lines + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class DeleteDelta extends Delta {
|
||||
public void applyTo(List<Object> target) throws PatchFailedException {
|
||||
verify(target);
|
||||
int position = getOriginal().getPosition();
|
||||
int size = getOriginal().getSize();
|
||||
int size = getOriginal().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
target.remove(position);
|
||||
}
|
||||
|
||||
19
src/difflib/DeltaComparator.java
Normal file
19
src/difflib/DeltaComparator.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package difflib;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author mksenzov
|
||||
*/
|
||||
public class DeltaComparator implements Comparator<Delta>, Serializable {
|
||||
|
||||
public static final Comparator<Delta> INSTANCE = new DeltaComparator();
|
||||
|
||||
private DeltaComparator() {
|
||||
}
|
||||
|
||||
public int compare(final Delta a, final Delta b) {
|
||||
return new Integer(a.getOriginal().getPosition()).compareTo(b.getOriginal().getPosition());
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,10 @@
|
||||
*/
|
||||
package difflib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import difflib.DiffRow.Tag;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class for generating DiffRows for side-by-sidy view.
|
||||
* You can customize the way of generating. For example, show inline diffs on not, ignoring
|
||||
@@ -195,17 +190,18 @@ public class DiffRowGenerator {
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<DiffRow> generateDiffRows(List<String> original, List<String> revised, Patch patch) {
|
||||
// normalize the lines (expand tabs, escape html entities)
|
||||
original = StringUtills.normalize((List<String>) original);
|
||||
revised = StringUtills.normalize((List<String>) revised);
|
||||
original = StringUtills.normalize(original);
|
||||
revised = StringUtills.normalize(revised);
|
||||
|
||||
// wrap to the column width
|
||||
original = StringUtills.wrapText((List<String>) original, this.columnWidth);
|
||||
revised = StringUtills.wrapText((List<String>) revised, this.columnWidth);
|
||||
original = StringUtills.wrapText(original, this.columnWidth);
|
||||
revised = StringUtills.wrapText(revised, this.columnWidth);
|
||||
|
||||
List<DiffRow> diffRows = new ArrayList<DiffRow>();
|
||||
int endPos = 0;
|
||||
for (int i = 0; i < patch.getDeltas().size(); i++) {
|
||||
Delta delta = patch.getDelta(i);
|
||||
final List<Delta> deltaList = patch.getDeltas();
|
||||
for (int i = 0; i < deltaList.size(); i++) {
|
||||
Delta delta = deltaList.get(i);
|
||||
Chunk orig = delta.getOriginal();
|
||||
Chunk rev = delta.getRevised();
|
||||
|
||||
@@ -243,18 +239,18 @@ public class DiffRowGenerator {
|
||||
addInlineDiffs(delta);
|
||||
}
|
||||
// the changed size is match
|
||||
if (orig.getSize() == rev.getSize()) {
|
||||
for (int j = 0; j < orig.getSize(); j++) {
|
||||
if (orig.size() == rev.size()) {
|
||||
for (int j = 0; j < orig.size(); j++) {
|
||||
diffRows.add(new DiffRow(Tag.CHANGE, (String) orig.getLines().get(j),
|
||||
(String) rev.getLines().get(j)));
|
||||
}
|
||||
} else if (orig.getSize() > rev.getSize()) {
|
||||
for (int j = 0; j < orig.getSize(); j++) {
|
||||
} else if (orig.size() > rev.size()) {
|
||||
for (int j = 0; j < orig.size(); j++) {
|
||||
diffRows.add(new DiffRow(Tag.CHANGE, (String) orig.getLines().get(j), rev
|
||||
.getLines().size() > j ? (String) rev.getLines().get(j) : ""));
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < rev.getSize(); j++) {
|
||||
for (int j = 0; j < rev.size(); j++) {
|
||||
diffRows.add(new DiffRow(Tag.CHANGE, orig.getLines().size() > j ? (String) orig
|
||||
.getLines().get(j) : "", (String) rev.getLines().get(j)));
|
||||
}
|
||||
@@ -294,16 +290,16 @@ public class DiffRowGenerator {
|
||||
if (inlineDelta.getClass().equals(DeleteDelta.class)) {
|
||||
origList = wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
||||
.getPosition()
|
||||
+ inlineOrig.getSize() + 1, this.InlineOldTag, this.InlineOldCssClass);
|
||||
+ inlineOrig.size() + 1, this.InlineOldTag, this.InlineOldCssClass);
|
||||
} else if (inlineDelta.getClass().equals(InsertDelta.class)) {
|
||||
revList = wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
||||
+ inlineRev.getSize() + 1, this.InlineNewTag, this.InlineNewCssClass);
|
||||
+ inlineRev.size() + 1, this.InlineNewTag, this.InlineNewCssClass);
|
||||
} else if (inlineDelta.getClass().equals(ChangeDelta.class)) {
|
||||
origList = wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
||||
.getPosition()
|
||||
+ inlineOrig.getSize() + 1, this.InlineOldTag, this.InlineOldCssClass);
|
||||
+ inlineOrig.size() + 1, this.InlineOldTag, this.InlineOldCssClass);
|
||||
revList = wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
||||
+ inlineRev.getSize() + 1, this.InlineNewTag, this.InlineNewCssClass);
|
||||
+ inlineRev.size() + 1, this.InlineNewTag, this.InlineNewCssClass);
|
||||
}
|
||||
}
|
||||
StringBuilder origResult = new StringBuilder(), revResult = new StringBuilder();
|
||||
|
||||
@@ -26,74 +26,75 @@ import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Implements the difference and patching engine
|
||||
*
|
||||
*
|
||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||
* @version 0.4.1
|
||||
*/
|
||||
public class DiffUtils {
|
||||
private static DiffAlgorithm defaultDiffAlgorithm = new MyersDiff();
|
||||
private static Pattern unifiedDiffChunkRe =
|
||||
Pattern.compile("@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||
|
||||
private static Pattern unifiedDiffChunkRe =
|
||||
Pattern.compile("@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with default diff algorithm
|
||||
*
|
||||
* Compute the difference between the original and revised texts with default diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
* @param revised the revised text
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised) {
|
||||
return DiffUtils.diff(original, revised, defaultDiffAlgorithm);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with given diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* Compute the difference between the original and revised texts with given diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @param algorithm the given algorithm
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised, DiffAlgorithm algorithm) {
|
||||
return algorithm.diff(original, revised);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Patch the original text with given patch
|
||||
*
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
* @param patch the given patch
|
||||
* @return the revised text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
public static List<?> patch(List<?> original, Patch patch) throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unpatch the revised text for a given patch
|
||||
*
|
||||
*
|
||||
* @param revised the revised text
|
||||
* @param patch the given patch
|
||||
* @param patch the given patch
|
||||
* @return the original text
|
||||
*/
|
||||
public static List<?> unpatch(List<?> revised, Patch patch) {
|
||||
return patch.restore(revised);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the given text in unified format and creates the list of deltas for it.
|
||||
*
|
||||
* @param diff the text in unified format
|
||||
*
|
||||
* @param diff the text in unified format
|
||||
* @return the patch with deltas.
|
||||
*/
|
||||
public static Patch parseUnifiedDiff(List<String> diff) {
|
||||
boolean inPrelude = true;
|
||||
List<Object[]> rawChunk = new ArrayList<Object[]>();
|
||||
Patch patch = new Patch();
|
||||
|
||||
int old_ln = 0, old_n = 0, new_ln = 0, new_n = 0;
|
||||
String tag = "", rest = "";
|
||||
|
||||
int old_ln = 0, new_ln = 0;
|
||||
String tag;
|
||||
String rest;
|
||||
for (String line : diff) {
|
||||
// Skip leading lines until after we've seen one starting with '+++'
|
||||
if (inPrelude) {
|
||||
@@ -108,7 +109,7 @@ public class DiffUtils {
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
|
||||
for (Object[] raw_line : rawChunk) {
|
||||
tag = (String) raw_line[0];
|
||||
rest = (String) raw_line[1];
|
||||
@@ -119,17 +120,14 @@ public class DiffUtils {
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines),
|
||||
new Chunk(new_ln - 1, new_n, newChunkLines)));
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, oldChunkLines),
|
||||
new Chunk(new_ln - 1, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
// Parse the @@ header
|
||||
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
|
||||
old_n = m.group(2) == null ? 1 : Integer.parseInt(m.group(2));
|
||||
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
||||
new_n = m.group(4) == null ? 1 : Integer.parseInt(m.group(4));
|
||||
old_ln = Integer.parseInt(m.group(1));
|
||||
|
||||
|
||||
if (old_ln == 0) {
|
||||
old_ln += 1;
|
||||
}
|
||||
@@ -141,19 +139,19 @@ public class DiffUtils {
|
||||
tag = line.substring(0, 1);
|
||||
rest = line.substring(1);
|
||||
if (tag.equals(" ") || tag.equals("+") || tag.equals("-")) {
|
||||
rawChunk.add(new Object[] { tag, rest });
|
||||
rawChunk.add(new Object[]{tag, rest});
|
||||
}
|
||||
} else {
|
||||
rawChunk.add(new Object[] {" ", ""});
|
||||
rawChunk.add(new Object[]{" ", ""});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Process the lines in the last chunk
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
|
||||
for (Object[] raw_line : rawChunk) {
|
||||
tag = (String) raw_line[0];
|
||||
rest = (String) raw_line[1];
|
||||
@@ -164,38 +162,38 @@ public class DiffUtils {
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines), new Chunk(
|
||||
new_ln - 1, new_n, newChunkLines)));
|
||||
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, oldChunkLines), new Chunk(
|
||||
new_ln - 1, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing the Patch.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
* @param original - Filename of the original (unrevised file)
|
||||
* @param revised - Filename of the revised file
|
||||
*
|
||||
* @param original - Filename of the original (unrevised file)
|
||||
* @param revised - Filename of the revised file
|
||||
* @param originalLines - Lines of the original file
|
||||
* @param patch - Patch created by the diff() function
|
||||
* @param contextSize - number of lines of context output around each difference in the file.
|
||||
* @param patch - Patch created by the diff() function
|
||||
* @param contextSize - number of lines of context output around each difference in the file.
|
||||
* @return List of strings representing the Unified Diff representation of the Patch argument.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*/
|
||||
public static List<String> generateUnifiedDiff(String original, String revised,
|
||||
List<String> originalLines, Patch patch, int contextSize) {
|
||||
List<String> originalLines, Patch patch, int contextSize) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ret.add("--- " + original);
|
||||
ret.add("+++ " + revised);
|
||||
|
||||
if (!patch.getDeltas().isEmpty()) {
|
||||
// Hmm, I thought the Deltas were sorted already... turns out they're not.
|
||||
List<Delta> patchDeltas = new ArrayList<Delta>( patch.getDeltas() );
|
||||
Collections.sort( patchDeltas, new Comparator<Delta>() {
|
||||
public int compare( Delta a, Delta b ) {
|
||||
return new Integer(a.getOriginal().getPosition()).compareTo( b.getOriginal().getPosition() );
|
||||
List<Delta> patchDeltas = new ArrayList<Delta>(patch.getDeltas());
|
||||
Collections.sort(patchDeltas, new Comparator<Delta>() {
|
||||
public int compare(Delta a, Delta b) {
|
||||
return new Integer(a.getOriginal().getPosition()).compareTo(b.getOriginal().getPosition());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -207,13 +205,13 @@ public class DiffUtils {
|
||||
if (patchDeltas.size() > 1) {
|
||||
for (int i = 1; i < patchDeltas.size(); i++) {
|
||||
int position = delta.getOriginal().getPosition(); // store the current position of
|
||||
// the first Delta
|
||||
// the first Delta
|
||||
|
||||
// Check if the next Delta is too close to the current position.
|
||||
// And if it is, add it to the current set
|
||||
Delta nextDelta = patchDeltas.get(i);
|
||||
if ((position + delta.getOriginal().getSize() + contextSize) >=
|
||||
(nextDelta.getOriginal().getPosition() - contextSize)) {
|
||||
if ((position + delta.getOriginal().size() + contextSize) >=
|
||||
(nextDelta.getOriginal().getPosition() - contextSize)) {
|
||||
deltas.add(nextDelta);
|
||||
} else {
|
||||
// if it isn't, output the current set,
|
||||
@@ -233,54 +231,54 @@ public class DiffUtils {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
|
||||
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
|
||||
*
|
||||
* @param origLines - the lines of the original file
|
||||
* @param deltas - the Deltas to be output as a single block
|
||||
* @param contextSize - the number of lines of context to place around block
|
||||
* @return
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
* @param origLines - the lines of the original file
|
||||
* @param deltas - the Deltas to be output as a single block
|
||||
* @param contextSize - the number of lines of context to place around block
|
||||
* @return
|
||||
*/
|
||||
*/
|
||||
private static List<String> processDeltas(List<String> origLines, List<Delta> deltas,
|
||||
int contextSize) {
|
||||
int contextSize) {
|
||||
List<String> buffer = new ArrayList<String>();
|
||||
int origTotal = 0; // counter for total lines output from Original
|
||||
int revTotal = 0; // counter for total lines output from Original
|
||||
int line;
|
||||
|
||||
|
||||
Delta curDelta = deltas.get(0);
|
||||
|
||||
|
||||
// NOTE: +1 to overcome the 0-offset Position
|
||||
int origStart = curDelta.getOriginal().getPosition() + 1 - contextSize;
|
||||
if (origStart < 1) {
|
||||
origStart = 1;
|
||||
}
|
||||
|
||||
|
||||
int revStart = curDelta.getRevised().getPosition() + 1 - contextSize;
|
||||
if (revStart < 1) {
|
||||
revStart = 1;
|
||||
}
|
||||
|
||||
|
||||
// find the start of the wrapper context code
|
||||
int contextStart = curDelta.getOriginal().getPosition() - contextSize;
|
||||
if (contextStart < 0) {
|
||||
contextStart = 0; // clamp to the start of the file
|
||||
}
|
||||
|
||||
|
||||
// output the context before the first Delta
|
||||
for (line = contextStart; line < curDelta.getOriginal().getPosition(); line++) { //
|
||||
buffer.add(" " + origLines.get(line));
|
||||
origTotal++;
|
||||
revTotal++;
|
||||
}
|
||||
|
||||
|
||||
// output the first Delta
|
||||
buffer.addAll(getDeltaText(curDelta));
|
||||
buffer.addAll(getDeltaText(curDelta));
|
||||
origTotal += curDelta.getOriginal().getLines().size();
|
||||
revTotal += curDelta.getRevised().getLines().size();
|
||||
|
||||
|
||||
int deltaIndex = 1;
|
||||
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
||||
Delta nextDelta = deltas.get(deltaIndex);
|
||||
@@ -298,7 +296,7 @@ public class DiffUtils {
|
||||
curDelta = nextDelta;
|
||||
deltaIndex++;
|
||||
}
|
||||
|
||||
|
||||
// Now output the post-Delta context code, clamping the end of the file
|
||||
contextStart = curDelta.getOriginal().getPosition()
|
||||
+ curDelta.getOriginal().getLines().size();
|
||||
@@ -308,7 +306,7 @@ public class DiffUtils {
|
||||
origTotal++;
|
||||
revTotal++;
|
||||
}
|
||||
|
||||
|
||||
// Create and insert the block header, conforming to the Unified Diff standard
|
||||
StringBuffer header = new StringBuffer();
|
||||
header.append("@@ -");
|
||||
@@ -321,16 +319,16 @@ public class DiffUtils {
|
||||
header.append(revTotal);
|
||||
header.append(" @@");
|
||||
buffer.add(0, header.toString());
|
||||
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
*
|
||||
* @param delta - the Delta to output
|
||||
* @return list of String lines of code.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*/
|
||||
private static List<String> getDeltaText(Delta delta) {
|
||||
List<String> buffer = new ArrayList<String>();
|
||||
@@ -342,5 +340,5 @@ public class DiffUtils {
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class InsertDelta extends Delta {
|
||||
@Override
|
||||
public void restore(List<Object> target) {
|
||||
int position = getRevised().getPosition();
|
||||
int size = getRevised().getSize();
|
||||
int size = getRevised().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
target.remove(position);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package difflib;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* Describes the patch holding all deltas between the original and revised texts.
|
||||
@@ -24,11 +27,9 @@ import java.util.*;
|
||||
*/
|
||||
public class Patch {
|
||||
private List<Delta> deltas = new LinkedList<Delta>();
|
||||
private boolean isSorted = false;
|
||||
|
||||
|
||||
/**
|
||||
* Apply this patch to the given target
|
||||
* @param target
|
||||
* @return the patched text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
@@ -63,45 +64,14 @@ public class Patch {
|
||||
*/
|
||||
public void addDelta(Delta delta) {
|
||||
deltas.add(delta);
|
||||
isSorted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deltas the deltas to set
|
||||
*/
|
||||
public void setDeltas(List<Delta> deltas) {
|
||||
this.deltas = deltas;
|
||||
isSorted = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of computed deltas
|
||||
* @return the deltas
|
||||
*/
|
||||
public List<Delta> getDeltas() {
|
||||
if (!this.isSorted) {
|
||||
Collections.sort(deltas, new Comparator<Delta>() {
|
||||
public int compare(Delta d1, Delta d2) {
|
||||
if (d1.getOriginal().getPosition() > d2.getOriginal().getPosition()) {
|
||||
return 1;
|
||||
} else if (d1.getOriginal().getPosition() > d2.getOriginal().getPosition()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
isSorted = true;
|
||||
}
|
||||
Collections.sort(deltas, DeltaComparator.INSTANCE);
|
||||
return deltas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific delta from patch deltas
|
||||
* @param index the index of delta
|
||||
* @return the needed delta
|
||||
*/
|
||||
public Delta getDelta(int index) {
|
||||
return deltas.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ package difflib.myers;
|
||||
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
|
||||
*
|
||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||
* @see Diff
|
||||
* @see DiffAlgorithm
|
||||
* @see MyersDiff
|
||||
* @see difflib.DiffAlgorithm
|
||||
*/
|
||||
public class DifferentiationFailedException extends DiffException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -57,17 +57,11 @@
|
||||
|
||||
package difflib.myers;
|
||||
|
||||
import difflib.*;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.List;
|
||||
|
||||
import difflib.ChangeDelta;
|
||||
import difflib.Chunk;
|
||||
import difflib.DeleteDelta;
|
||||
import difflib.Delta;
|
||||
import difflib.DiffAlgorithm;
|
||||
import difflib.InsertDelta;
|
||||
import difflib.Patch;
|
||||
|
||||
/**
|
||||
* A clean-room implementation of <a href="http://www.cs.arizona.edu/people/gene/">
|
||||
* Eugene Myers</a> differencing algorithm.
|
||||
@@ -182,13 +176,13 @@ public class MyersDiff implements DiffAlgorithm {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link Revision} from a difference path.
|
||||
* Constructs a {@link Patch} from a difference path.
|
||||
*
|
||||
* @param path The path.
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
* @return A {@link Revision} script corresponding to the path.
|
||||
* @throws DifferentiationFailedException if a {@link Revision} could
|
||||
* @return A {@link Patch} script corresponding to the path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could
|
||||
* not be built from the given path.
|
||||
*/
|
||||
public static Patch buildRevision(PathNode path, Object[] orig, Object[] rev) {
|
||||
@@ -212,12 +206,12 @@ public class MyersDiff implements DiffAlgorithm {
|
||||
int ianchor = path.i;
|
||||
int janchor = path.j;
|
||||
|
||||
Chunk original = new Chunk(ianchor, i - ianchor, copyOfRange(orig, ianchor, i));
|
||||
Chunk revised = new Chunk(janchor, j - janchor, copyOfRange(rev, janchor, j));
|
||||
Chunk original = new Chunk(ianchor, copyOfRange(orig, ianchor, i));
|
||||
Chunk revised = new Chunk(janchor, copyOfRange(rev, janchor, j));
|
||||
Delta delta = null;
|
||||
if (original.getSize() == 0 && revised.getSize() != 0) {
|
||||
if (original.size() == 0 && revised.size() != 0) {
|
||||
delta = new InsertDelta(original, revised);
|
||||
} else if (original.getSize() > 0 && revised.getSize() == 0) {
|
||||
} else if (original.size() > 0 && revised.size() == 0) {
|
||||
delta = new DeleteDelta(original, revised);
|
||||
} else {
|
||||
delta = new ChangeDelta(original, revised);
|
||||
|
||||
Reference in New Issue
Block a user