1 16 package org.outerj.daisy.diff; 17 18 import org.eclipse.compare.rangedifferencer.RangeDifference; 19 import org.eclipse.compare.rangedifferencer.RangeDifferencer; 20 21 public class Diff { 22 23 private Diff() { 24 } 25 26 33 public static void diff(String text1, String text2, DiffOutput output, int contextLineCount) throws Exception { 34 TextComparator leftComparator = new TextComparator(text1); 35 TextComparator rightComparator = new TextComparator(text2); 36 37 RangeDifference[] differences = RangeDifferencer.findDifferences(leftComparator, rightComparator); 38 39 int pos = 0; if (differences.length > 0) { 41 int diffIndex = 0; 42 43 int leftLineCount = leftComparator.getRangeCount(); 44 while (diffIndex < differences.length && pos < leftLineCount) { 45 RangeDifference diff = differences[diffIndex]; 46 47 if (diff.kind() == RangeDifference.CHANGE) { 48 int nextChangedLine = diff.leftStart(); 49 50 if (pos != 0) { int beginContextEndPos = pos + contextLineCount; 53 while ((pos < beginContextEndPos || contextLineCount == -1) && pos < nextChangedLine) { 54 output.startLine(DiffLineType.UNCHANGED); 55 output.addUnchangedText(leftComparator.getLine(pos)); 56 output.endLine(); 57 pos++; 58 } 59 } 60 61 if (contextLineCount >= 0) { 63 int endContextStartPos = nextChangedLine - contextLineCount; 64 if (endContextStartPos > pos + 1) { output.skippedLines(endContextStartPos - pos); 66 pos = endContextStartPos; 67 } 68 } 69 70 while (pos < nextChangedLine) { 72 output.startLine(DiffLineType.UNCHANGED); 73 output.addUnchangedText(leftComparator.getLine(pos)); 74 output.endLine(); 75 pos++; 76 } 77 78 StringBuffer leftBlock = null; 79 StringBuffer rightBlock = null; 80 if (diff.leftLength() > 0 && diff.rightLength() > 0) { 81 leftBlock = concatLines(leftComparator, diff.leftStart(), diff.leftLength()); 82 rightBlock = concatLines(rightComparator, diff.rightStart(), diff.rightLength()); 83 } 84 85 if (leftBlock == null) { 86 for (int i = 0; i < diff.leftLength(); i++) { 87 int currentLine = diff.leftStart() + i; 88 output.startLine(DiffLineType.REMOVED); 89 output.addUnchangedText(leftComparator.getLine(currentLine)); 90 output.endLine(); 91 } 92 } else { 93 diffBlock(leftBlock, rightBlock, output, DiffLineType.REMOVED); 94 } 95 96 if (leftBlock == null) { 97 for (int i = 0; i < diff.rightLength(); i++) { 98 int currentLine = diff.rightStart() + i; 99 output.startLine(DiffLineType.ADDED); 100 output.addUnchangedText(rightComparator.getLine(currentLine)); 101 output.endLine(); 102 } 103 } else { 104 diffBlock(rightBlock, leftBlock, output, DiffLineType.ADDED); 105 } 106 } 107 108 109 pos = differences[diffIndex].leftEnd(); 110 diffIndex++; 111 } 112 113 int endPos = pos; 115 while (pos < leftLineCount && (contextLineCount == -1 || pos < endPos + contextLineCount)) { 116 output.startLine(DiffLineType.UNCHANGED); 117 output.addUnchangedText(leftComparator.getLine(pos)); 118 output.endLine(); 119 pos++; 120 } 121 if (pos < leftLineCount) { 122 output.skippedLines(leftLineCount - pos); 123 } 124 } 125 } 126 127 private static StringBuffer concatLines(TextComparator comparator, int start, int count) { 128 int totalLinesLength = 0; 129 for (int i = 0; i < count; i++) 130 totalLinesLength += comparator.getLine(start + i).length() + 1; 131 132 StringBuffer result = new StringBuffer (totalLinesLength); 133 for (int i = 0; i < count; i++) { 134 if (i > 0) 135 result.append("\n"); 136 result.append(comparator.getLine(start + i)); 137 } 138 139 return result; 140 } 141 142 private static void diffBlock(StringBuffer block1, StringBuffer block2, DiffOutput output, DiffLineType diffLineType) throws Exception { 143 BlockComparator leftBlockComparator = new BlockComparator(block1); 144 BlockComparator rightBlockComparator = new BlockComparator(block2); 145 RangeDifference[] lineDiffs = RangeDifferencer.findDifferences(leftBlockComparator, rightBlockComparator); 146 147 int pos = 0; 148 RangeDifference diff = null; 149 output.startLine(diffLineType); 150 151 for (int i = 0; i < lineDiffs.length; i++) { 152 diff = lineDiffs[i]; 153 154 int left = diff.leftStart(); 155 if (pos < left) { 156 String [] strings = leftBlockComparator.substringSplitted(pos, left); 157 for (int d = 0; d < strings.length; d++) { 158 if (strings[d].equals("\n")) { 159 output.endLine(); 160 output.startLine(diffLineType); 161 } else { 162 output.addUnchangedText(strings[d]); 163 } 164 } 165 } 166 167 if (diff.leftLength() > 0) { 168 String [] strings = leftBlockComparator.substringSplitted(left, diff.leftEnd()); 169 for (int d = 0; d < strings.length; d++) { 170 if (strings[d].equals("\n")) { 171 output.endLine(); 172 output.startLine(diffLineType); 173 } else { 174 output.addChangedText(strings[d]); 175 } 176 } 177 } 178 179 pos = diff.leftEnd(); 180 } 181 182 if (diff == null || diff.leftEnd() < leftBlockComparator.getRangeCount()) { 183 int start = 0; 184 if (diff != null) 185 start = diff.leftEnd(); 186 String [] strings = leftBlockComparator.substringSplitted(start); 187 for (int d = 0; d < strings.length; d++) { 188 if (strings[d].equals("\n")) { 189 output.endLine(); 190 output.startLine(diffLineType); 191 } else { 192 output.addUnchangedText(strings[d]); 193 } 194 } 195 output.endLine(); 196 } else { 197 output.endLine(); 198 } 199 } 200 201 } 202 | Popular Tags |