KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > diff > Diff


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

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     /**
27      * Diffs two texts, outputting the result to the specified DiffOutput instance.
28      *
29      * @param contextLineCount specify -1 to include complete text
30      * @throws Exception the differencing itself should normally not throw exceptions, but the
31      * methods on DiffOutput can.
32      */

33     public static void diff(String JavaDoc text1, String JavaDoc text2, DiffOutput output, int contextLineCount) throws Exception JavaDoc {
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; // the position (line) in the left input
40
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                     // output contextLineCount number of lines (if available) or all lines if contextLineCount == -1
51
if (pos != 0) { // at start of file, skip immediately to first changes
52
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                     // skip a number of lines
62
if (contextLineCount >= 0) {
63                         int endContextStartPos = nextChangedLine - contextLineCount;
64                         if (endContextStartPos > pos + 1) { // the +1 is to avoid skipping just one line
65
output.skippedLines(endContextStartPos - pos);
66                             pos = endContextStartPos;
67                         }
68                     }
69
70                     // output contextLineCount number of lines
71
while (pos < nextChangedLine) {
72                         output.startLine(DiffLineType.UNCHANGED);
73                         output.addUnchangedText(leftComparator.getLine(pos));
74                         output.endLine();
75                         pos++;
76                     }
77
78                     StringBuffer JavaDoc leftBlock = null;
79                     StringBuffer JavaDoc 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             // output any remaining lines
114
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 JavaDoc 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 JavaDoc result = new StringBuffer JavaDoc(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 JavaDoc block1, StringBuffer JavaDoc block2, DiffOutput output, DiffLineType diffLineType) throws Exception JavaDoc {
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 JavaDoc[] 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 JavaDoc[] 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 JavaDoc[] 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