15
15
*/
16
16
package difflib ;
17
17
18
- import difflib .DiffRow .Tag ;
19
- import difflib .myers .Equalizer ;
20
-
21
- import java .util .*;
18
+ import java .util .ArrayList ;
19
+ import java .util .Arrays ;
20
+ import java .util .Collections ;
21
+ import java .util .LinkedList ;
22
+ import java .util .List ;
23
+ import java .util .Objects ;
22
24
23
25
import javax .annotation .Nonnull ;
24
26
import javax .annotation .Nullable ;
27
29
import com .google .common .base .Joiner ;
28
30
import com .google .common .collect .Lists ;
29
31
32
+ import difflib .DiffRow .Tag ;
33
+ import difflib .myers .Equalizer ;
34
+
30
35
/**
31
36
* This class for generating DiffRows for side-by-sidy view.
32
37
* You can customize the way of generating. For example, show inline diffs on not, ignoring
49
54
*/
50
55
public class DiffRowGenerator {
51
56
private static final Joiner LF_JOINER = Joiner .on ("\n " );
52
-
57
+
58
+ private static final String DEFAULT_TAG_DELETE = "del" ;
59
+ private static final String DEFAULT_TAG_INSERT = "ins" ;
60
+ private static final String DEFAULT_TAG_CHANGE = "span" ;
61
+ private static final String DEFAULT_CSSCLASS_DELETE = null ;
62
+ private static final String DEFAULT_CSSCLASS_INSERT = null ;
63
+ private static final String DEFAULT_CSSCLASS_CHANGE = "change" ;
64
+
53
65
private final boolean showInlineDiffs ;
54
66
private final boolean ignoreWhiteSpaces ;
55
- private final String InlineOldTag ;
56
- private final String InlineNewTag ;
57
- private final String InlineOldCssClass ;
58
- private final String InlineNewCssClass ;
67
+ private final String inlineOriginDeleteTag ;
68
+ private final String inlineRevisedInsertTag ;
69
+ private final String inlineOriginChangeTag ;
70
+ private final String inlineRevisedChangeTag ;
71
+ private final String inlineOriginDeleteCssClass ;
72
+ private final String inlineRevisedInsertCssClass ;
73
+ private final String inlineOriginChangeCssClass ;
74
+ private final String inlineRevisedChangeCssClass ;
59
75
private final int columnWidth ;
60
76
@ Nullable
61
77
private final String defaultString ;
@@ -69,11 +85,15 @@ public class DiffRowGenerator {
69
85
public static class Builder {
70
86
private boolean showInlineDiffs = false ;
71
87
private boolean ignoreWhiteSpaces = false ;
72
- private String InlineOldTag = "span" ;
73
- private String InlineNewTag = "span" ;
74
- private String InlineOldCssClass = "editOldInline" ;
75
- private String InlineNewCssClass = "editNewInline" ;
76
- private int columnWidth = 80 ;
88
+ private String inlineOriginDeleteTag = DEFAULT_TAG_DELETE ;
89
+ private String inlineOriginChangeTag = DEFAULT_TAG_CHANGE ;
90
+ private String inlineRevisedInsertTag = DEFAULT_TAG_INSERT ;
91
+ private String inlineRevisedChangeTag = DEFAULT_TAG_CHANGE ;
92
+ private String inlineOriginDeleteCssClass = DEFAULT_CSSCLASS_DELETE ;
93
+ private String inlineRevisedInsertCssClass = DEFAULT_CSSCLASS_INSERT ;
94
+ private String inlineOriginChangeCssClass = DEFAULT_CSSCLASS_CHANGE ;
95
+ private String inlineRevisedChangeCssClass = DEFAULT_CSSCLASS_CHANGE ;
96
+ private int columnWidth = -1 ;
77
97
@ Nullable
78
98
private String defaultString = "" ;
79
99
private Equalizer <String > stringEqualizer = new Equalizer <String >() {
@@ -104,53 +124,96 @@ public Builder ignoreWhiteSpaces(boolean val) {
104
124
105
125
/**
106
126
* Set the tag used for displaying changes in the original text.
107
- * @param tag the tag to set. Without angle brackets. Default: span.
108
- * @return builder with configured ignoreBlankLines parameter
127
+ * @param tag the tag to set. Without angle brackets. Default: {@value #DEFAULT_TAG_DELETE}.
128
+ * @return builder with configured inlineOriginDeleteTag parameter
129
+ * @deprecated Use {@link #inlineOriginDeleteTag(String)}
109
130
*/
131
+ @ Deprecated
110
132
public Builder InlineOldTag (String tag ) {
111
- InlineOldTag = tag ;
133
+ inlineOriginDeleteTag = tag ;
134
+ return this ;
135
+ }
136
+
137
+ /**
138
+ * Set the tag used for displaying delete data in the original text.
139
+ * @param tag the tag to set. Without angle brackets. Default: {@value #DEFAULT_TAG_DELETE}.
140
+ * @return builder with configured inlineOriginDeleteTag parameter
141
+ */
142
+ public Builder inlineOriginDeleteTag (String tag ) {
143
+ inlineOriginDeleteTag = tag ;
112
144
return this ;
113
145
}
114
146
115
147
/**
116
148
* Set the tag used for displaying changes in the revised text.
117
- * @param tag the tag to set. Without angle brackets. Default: span.
118
- * @return builder with configured ignoreBlankLines parameter
149
+ * @param tag the tag to set. Without angle brackets. Default: {@value #DEFAULT_TAG_INSERT}.
150
+ * @return builder with configured inlineRevisedInsertTag parameter
151
+ * @deprecated Use {@link #inlineRevisedInsertTag(String)}
119
152
*/
120
153
public Builder InlineNewTag (String tag ) {
121
- InlineNewTag = tag ;
154
+ inlineRevisedInsertTag = tag ;
155
+ return this ;
156
+ }
157
+
158
+ /**
159
+ * Set the tag used for displaying changes in the revised text.
160
+ * @param tag the tag to set. Without angle brackets. Default: {@value #DEFAULT_TAG_INSERT}.
161
+ * @return builder with configured inlineRevisedInsertTag parameter
162
+ */
163
+ public Builder inlineRevisedInsertTag (String tag ) {
164
+ inlineRevisedInsertTag = tag ;
122
165
return this ;
123
166
}
124
167
125
168
/**
126
169
* Set the css class used for displaying changes in the original text.
127
- * @param cssClass the tag to set. Without any quotes, just word. Default: editOldInline.
128
- * @return builder with configured ignoreBlankLines parameter
170
+ * @param cssClass the tag to set. Without any quotes, just word. Default: {@value #DEFAULT_CSSCLASS_DELETE}.
171
+ * @return builder with configured inlineOriginDeleteCssClass parameter
172
+ * @deprecated Use {@link #inlineOriginDeleteCssClass(String)}
129
173
*/
130
174
public Builder InlineOldCssClass (String cssClass ) {
131
- InlineOldCssClass = cssClass ;
175
+ inlineOriginDeleteCssClass = cssClass ;
176
+ return this ;
177
+ }
178
+
179
+ /**
180
+ * Set the css class used for displaying delete data in the original text.
181
+ * @param cssClass the tag to set. Without any quotes, just word. Default: {@value #DEFAULT_CSSCLASS_DELETE}.
182
+ * @return builder with configured inlineOriginDeleteCssClass parameter
183
+ */
184
+ public Builder inlineOriginDeleteCssClass (String cssClass ) {
185
+ inlineOriginDeleteCssClass = cssClass ;
132
186
return this ;
133
187
}
134
188
135
189
/**
136
190
* Set the css class used for displaying changes in the revised text.
137
- * @param cssClass the tag to set. Without any quotes, just word. Default: editNewInline.
138
- * @return builder with configured ignoreBlankLines parameter
191
+ * @param cssClass the tag to set. Without any quotes, just word. Default: {@value #DEFAULT_CSSCLASS_INSERT}.
192
+ * @return builder with configured inlineRevisedInsertCssClass parameter
193
+ * @deprecated Use {@link #inlineRevisedInsertCssClass(String)}
139
194
*/
140
195
public Builder InlineNewCssClass (String cssClass ) {
141
- InlineNewCssClass = cssClass ;
196
+ inlineRevisedInsertCssClass = cssClass ;
197
+ return this ;
198
+ }
199
+
200
+ /**
201
+ * Set the css class used for displaying insert data in the revised text.
202
+ * @param cssClass the tag to set. Without any quotes, just word. Default: {@value #DEFAULT_CSSCLASS_INSERT}.
203
+ * @return builder with configured inlineRevisedInsertCssClass parameter
204
+ */
205
+ public Builder inlineRevisedInsertCssClass (String cssClass ) {
206
+ inlineRevisedInsertCssClass = cssClass ;
142
207
return this ;
143
208
}
144
209
145
210
/**
146
211
* Set the column with of generated lines of original and revised texts.
147
- * @param width the width to set. Making it < 0 doesn't have any sense. Default 80 .
148
- * @return builder with configured ignoreBlankLines parameter
212
+ * @param width the width to set. Making it < 0 disable line breaking .
213
+ * @return builder with configured columnWidth parameter
149
214
*/
150
215
public Builder columnWidth (int width ) {
151
- if (width > 0 ) {
152
- columnWidth = width ;
153
- }
216
+ columnWidth = width ;
154
217
return this ;
155
218
}
156
219
@@ -182,12 +245,21 @@ public DiffRowGenerator build() {
182
245
183
246
private DiffRowGenerator (Builder builder ) {
184
247
showInlineDiffs = builder .showInlineDiffs ;
185
- ignoreWhiteSpaces = builder .ignoreWhiteSpaces ; //
186
- InlineOldTag = builder .InlineOldTag ;
187
- InlineNewTag = builder .InlineNewTag ;
188
- InlineOldCssClass = builder .InlineOldCssClass ;
189
- InlineNewCssClass = builder .InlineNewCssClass ;
190
- columnWidth = builder .columnWidth ; //
248
+ ignoreWhiteSpaces = builder .ignoreWhiteSpaces ;
249
+
250
+ inlineOriginDeleteTag = builder .inlineOriginDeleteTag ;
251
+ inlineOriginDeleteCssClass = builder .inlineOriginDeleteCssClass ;
252
+
253
+ inlineOriginChangeTag = builder .inlineOriginChangeTag ;
254
+ inlineOriginChangeCssClass = builder .inlineOriginChangeCssClass ;
255
+
256
+ inlineRevisedInsertTag = builder .inlineRevisedInsertTag ;
257
+ inlineRevisedInsertCssClass = builder .inlineRevisedInsertCssClass ;
258
+
259
+ inlineRevisedChangeTag = builder .inlineRevisedChangeTag ;
260
+ inlineRevisedChangeCssClass = builder .inlineRevisedChangeCssClass ;
261
+
262
+ columnWidth = builder .columnWidth ;
191
263
defaultString = builder .defaultString ;
192
264
equalizer = builder .stringEqualizer ;
193
265
}
@@ -233,9 +305,10 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
233
305
revised = StringUtills .normalize (revised );
234
306
235
307
// wrap to the column width
236
- original = StringUtills .wrapText (original , this .columnWidth );
237
- revised = StringUtills .wrapText (revised , this .columnWidth );
238
-
308
+ if (columnWidth > 0 ) {
309
+ original = StringUtills .wrapText (original , this .columnWidth );
310
+ revised = StringUtills .wrapText (revised , this .columnWidth );
311
+ }
239
312
List <DiffRow > diffRows = new ArrayList <DiffRow >();
240
313
int endPos = 0 ;
241
314
final List <Delta <String >> deltaList = patch .getDeltas ();
@@ -245,12 +318,13 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
245
318
Chunk <String > rev = delta .getRevised ();
246
319
247
320
// We should normalize and wrap lines in deltas too.
248
- orig .setLines (StringUtills .normalize ((List <String >) orig .getLines ()));
249
- rev .setLines (StringUtills .normalize ((List <String >) rev .getLines ()));
250
-
251
- orig .setLines (StringUtills .wrapText ((List <String >) orig .getLines (), this .columnWidth ));
252
- rev .setLines (StringUtills .wrapText ((List <String >) rev .getLines (), this .columnWidth ));
321
+ orig .setLines (StringUtills .normalize (orig .getLines ()));
322
+ rev .setLines (StringUtills .normalize (rev .getLines ()));
253
323
324
+ if (columnWidth > 0 ) {
325
+ orig .setLines (StringUtills .wrapText (orig .getLines (), this .columnWidth ));
326
+ rev .setLines (StringUtills .wrapText (rev .getLines (), this .columnWidth ));
327
+ }
254
328
// catch the equal prefix for each chunk
255
329
for (String line : original .subList (endPos , orig .getPosition ())) {
256
330
diffRows .add (new DiffRow (Tag .EQUAL , line , line ));
@@ -259,7 +333,7 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
259
333
// Inserted DiffRow
260
334
if (delta .getClass ().equals (InsertDelta .class )) {
261
335
endPos = orig .last () + 1 ;
262
- for (String line : ( List < String >) rev .getLines ()) {
336
+ for (String line : rev .getLines ()) {
263
337
diffRows .add (new DiffRow (Tag .INSERT , defaultString , line ));
264
338
}
265
339
continue ;
@@ -268,7 +342,7 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
268
342
// Deleted DiffRow
269
343
if (delta .getClass ().equals (DeleteDelta .class )) {
270
344
endPos = orig .last () + 1 ;
271
- for (String line : ( List < String >) orig .getLines ()) {
345
+ for (String line : orig .getLines ()) {
272
346
diffRows .add (new DiffRow (Tag .DELETE , line , defaultString ));
273
347
}
274
348
continue ;
@@ -280,18 +354,18 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
280
354
// the changed size is match
281
355
if (orig .size () == rev .size ()) {
282
356
for (int j = 0 ; j < orig .size (); j ++) {
283
- diffRows .add (new DiffRow (Tag .CHANGE , ( String ) orig .getLines ().get (j ),
284
- ( String ) rev .getLines ().get (j )));
357
+ diffRows .add (new DiffRow (Tag .CHANGE , orig .getLines ().get (j ),
358
+ rev .getLines ().get (j )));
285
359
}
286
360
} else if (orig .size () > rev .size ()) {
287
361
for (int j = 0 ; j < orig .size (); j ++) {
288
- diffRows .add (new DiffRow (Tag .CHANGE , ( String ) orig .getLines ().get (j ), rev
362
+ diffRows .add (new DiffRow (Tag .CHANGE , orig .getLines ().get (j ), rev
289
363
.getLines ().size () > j ? (String ) rev .getLines ().get (j ) : defaultString ));
290
364
}
291
365
} else {
292
366
for (int j = 0 ; j < rev .size (); j ++) {
293
- diffRows .add (new DiffRow (Tag .CHANGE , orig .getLines ().size () > j ? ( String ) orig
294
- .getLines ().get (j ) : defaultString , ( String ) rev .getLines ().get (j )));
367
+ diffRows .add (new DiffRow (Tag .CHANGE , orig .getLines ().size () > j ? orig
368
+ .getLines ().get (j ) : defaultString , rev .getLines ().get (j )));
295
369
}
296
370
}
297
371
endPos = orig .last () + 1 ;
@@ -309,8 +383,8 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
309
383
* @param delta the given delta
310
384
*/
311
385
private void addInlineDiffs (Delta <String > delta ) {
312
- List <String > orig = ( List < String >) delta .getOriginal ().getLines ();
313
- List <String > rev = ( List < String >) delta .getRevised ().getLines ();
386
+ List <String > orig = delta .getOriginal ().getLines ();
387
+ List <String > rev = delta .getRevised ().getLines ();
314
388
LinkedList <String > origList = new LinkedList <String >();
315
389
for (Character character : LF_JOINER .join (orig ).toCharArray ()) {
316
390
origList .add (character .toString ());
@@ -320,24 +394,23 @@ private void addInlineDiffs(Delta<String> delta) {
320
394
revList .add (character .toString ());
321
395
}
322
396
List <Delta <String >> inlineDeltas = DiffUtils .diff (origList , revList ).getDeltas ();
323
- if (inlineDeltas .size () < 3 ) {
324
397
Collections .reverse (inlineDeltas );
325
398
for (Delta <String > inlineDelta : inlineDeltas ) {
326
399
Chunk <String > inlineOrig = inlineDelta .getOriginal ();
327
400
Chunk <String > inlineRev = inlineDelta .getRevised ();
328
401
if (inlineDelta .getClass ().equals (DeleteDelta .class )) {
329
402
origList = wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
330
403
.getPosition ()
331
- + inlineOrig .size () + 1 , this .InlineOldTag , this .InlineOldCssClass );
404
+ + inlineOrig .size () + 1 , this .inlineOriginDeleteTag , this .inlineOriginDeleteCssClass );
332
405
} else if (inlineDelta .getClass ().equals (InsertDelta .class )) {
333
406
revList = wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
334
- + inlineRev .size () + 1 , this .InlineNewTag , this .InlineNewCssClass );
407
+ + inlineRev .size () + 1 , this .inlineRevisedInsertTag , this .inlineRevisedInsertCssClass );
335
408
} else if (inlineDelta .getClass ().equals (ChangeDelta .class )) {
336
409
origList = wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
337
410
.getPosition ()
338
- + inlineOrig .size () + 1 , this .InlineOldTag , this .InlineOldCssClass );
411
+ + inlineOrig .size () + 1 , this .inlineOriginChangeTag , this .inlineOriginChangeCssClass );
339
412
revList = wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
340
- + inlineRev .size () + 1 , this .InlineNewTag , this .InlineNewCssClass );
413
+ + inlineRev .size () + 1 , this .inlineRevisedChangeTag , this .inlineRevisedChangeCssClass );
341
414
}
342
415
}
343
416
StringBuilder origResult = new StringBuilder (), revResult = new StringBuilder ();
@@ -349,7 +422,6 @@ private void addInlineDiffs(Delta<String> delta) {
349
422
}
350
423
delta .getOriginal ().setLines (Arrays .asList (origResult .toString ().split ("\n " )));
351
424
delta .getRevised ().setLines (Arrays .asList (revResult .toString ().split ("\n " )));
352
- }
353
425
}
354
426
355
427
/**
@@ -359,8 +431,8 @@ private void addInlineDiffs(Delta<String> delta) {
359
431
* @param tag the tag name without angle brackets, just a word
360
432
* @param cssClass the optional css class
361
433
*/
362
- public static LinkedList <String > wrapInTag (LinkedList <String > sequence , int startPosition ,
363
- int endPosition , String tag , String cssClass ) {
434
+ public static LinkedList <String > wrapInTag (LinkedList <String > sequence , int startPosition , int endPosition ,
435
+ String tag , String cssClass ) {
364
436
LinkedList <String > result = (LinkedList <String >) sequence .clone ();
365
437
StringBuilder tagBuilder = new StringBuilder ();
366
438
tagBuilder .append ("<" );
0 commit comments