1515 */
1616package difflib ;
1717
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 ;
2224
2325import javax .annotation .Nonnull ;
2426import javax .annotation .Nullable ;
2729import com .google .common .base .Joiner ;
2830import com .google .common .collect .Lists ;
2931
32+ import difflib .DiffRow .Tag ;
33+ import difflib .myers .Equalizer ;
34+
3035/**
3136 * This class for generating DiffRows for side-by-sidy view.
3237 * You can customize the way of generating. For example, show inline diffs on not, ignoring
4954 */
5055public class DiffRowGenerator {
5156 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+
5365 private final boolean showInlineDiffs ;
5466 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 ;
5975 private final int columnWidth ;
6076 @ Nullable
6177 private final String defaultString ;
@@ -69,11 +85,15 @@ public class DiffRowGenerator {
6985 public static class Builder {
7086 private boolean showInlineDiffs = false ;
7187 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 ;
7797 @ Nullable
7898 private String defaultString = "" ;
7999 private Equalizer <String > stringEqualizer = new Equalizer <String >() {
@@ -104,53 +124,96 @@ public Builder ignoreWhiteSpaces(boolean val) {
104124
105125 /**
106126 * 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)}
109130 */
131+ @ Deprecated
110132 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 ;
112144 return this ;
113145 }
114146
115147 /**
116148 * 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)}
119152 */
120153 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 ;
122165 return this ;
123166 }
124167
125168 /**
126169 * 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)}
129173 */
130174 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 ;
132186 return this ;
133187 }
134188
135189 /**
136190 * 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)}
139194 */
140195 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 ;
142207 return this ;
143208 }
144209
145210 /**
146211 * 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
149214 */
150215 public Builder columnWidth (int width ) {
151- if (width > 0 ) {
152- columnWidth = width ;
153- }
216+ columnWidth = width ;
154217 return this ;
155218 }
156219
@@ -182,12 +245,21 @@ public DiffRowGenerator build() {
182245
183246 private DiffRowGenerator (Builder builder ) {
184247 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 ;
191263 defaultString = builder .defaultString ;
192264 equalizer = builder .stringEqualizer ;
193265 }
@@ -233,9 +305,10 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
233305 revised = StringUtills .normalize (revised );
234306
235307 // 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+ }
239312 List <DiffRow > diffRows = new ArrayList <DiffRow >();
240313 int endPos = 0 ;
241314 final List <Delta <String >> deltaList = patch .getDeltas ();
@@ -245,12 +318,13 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
245318 Chunk <String > rev = delta .getRevised ();
246319
247320 // 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 ()));
253323
324+ if (columnWidth > 0 ) {
325+ orig .setLines (StringUtills .wrapText (orig .getLines (), this .columnWidth ));
326+ rev .setLines (StringUtills .wrapText (rev .getLines (), this .columnWidth ));
327+ }
254328 // catch the equal prefix for each chunk
255329 for (String line : original .subList (endPos , orig .getPosition ())) {
256330 diffRows .add (new DiffRow (Tag .EQUAL , line , line ));
@@ -259,7 +333,7 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
259333 // Inserted DiffRow
260334 if (delta .getClass ().equals (InsertDelta .class )) {
261335 endPos = orig .last () + 1 ;
262- for (String line : ( List < String >) rev .getLines ()) {
336+ for (String line : rev .getLines ()) {
263337 diffRows .add (new DiffRow (Tag .INSERT , defaultString , line ));
264338 }
265339 continue ;
@@ -268,7 +342,7 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
268342 // Deleted DiffRow
269343 if (delta .getClass ().equals (DeleteDelta .class )) {
270344 endPos = orig .last () + 1 ;
271- for (String line : ( List < String >) orig .getLines ()) {
345+ for (String line : orig .getLines ()) {
272346 diffRows .add (new DiffRow (Tag .DELETE , line , defaultString ));
273347 }
274348 continue ;
@@ -280,18 +354,18 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
280354 // the changed size is match
281355 if (orig .size () == rev .size ()) {
282356 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 )));
285359 }
286360 } else if (orig .size () > rev .size ()) {
287361 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
289363 .getLines ().size () > j ? (String ) rev .getLines ().get (j ) : defaultString ));
290364 }
291365 } else {
292366 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 )));
295369 }
296370 }
297371 endPos = orig .last () + 1 ;
@@ -309,8 +383,8 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
309383 * @param delta the given delta
310384 */
311385 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 ();
314388 LinkedList <String > origList = new LinkedList <String >();
315389 for (Character character : LF_JOINER .join (orig ).toCharArray ()) {
316390 origList .add (character .toString ());
@@ -320,24 +394,23 @@ private void addInlineDiffs(Delta<String> delta) {
320394 revList .add (character .toString ());
321395 }
322396 List <Delta <String >> inlineDeltas = DiffUtils .diff (origList , revList ).getDeltas ();
323- if (inlineDeltas .size () < 3 ) {
324397 Collections .reverse (inlineDeltas );
325398 for (Delta <String > inlineDelta : inlineDeltas ) {
326399 Chunk <String > inlineOrig = inlineDelta .getOriginal ();
327400 Chunk <String > inlineRev = inlineDelta .getRevised ();
328401 if (inlineDelta .getClass ().equals (DeleteDelta .class )) {
329402 origList = wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
330403 .getPosition ()
331- + inlineOrig .size () + 1 , this .InlineOldTag , this .InlineOldCssClass );
404+ + inlineOrig .size () + 1 , this .inlineOriginDeleteTag , this .inlineOriginDeleteCssClass );
332405 } else if (inlineDelta .getClass ().equals (InsertDelta .class )) {
333406 revList = wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
334- + inlineRev .size () + 1 , this .InlineNewTag , this .InlineNewCssClass );
407+ + inlineRev .size () + 1 , this .inlineRevisedInsertTag , this .inlineRevisedInsertCssClass );
335408 } else if (inlineDelta .getClass ().equals (ChangeDelta .class )) {
336409 origList = wrapInTag (origList , inlineOrig .getPosition (), inlineOrig
337410 .getPosition ()
338- + inlineOrig .size () + 1 , this .InlineOldTag , this .InlineOldCssClass );
411+ + inlineOrig .size () + 1 , this .inlineOriginChangeTag , this .inlineOriginChangeCssClass );
339412 revList = wrapInTag (revList , inlineRev .getPosition (), inlineRev .getPosition ()
340- + inlineRev .size () + 1 , this .InlineNewTag , this .InlineNewCssClass );
413+ + inlineRev .size () + 1 , this .inlineRevisedChangeTag , this .inlineRevisedChangeCssClass );
341414 }
342415 }
343416 StringBuilder origResult = new StringBuilder (), revResult = new StringBuilder ();
@@ -349,7 +422,6 @@ private void addInlineDiffs(Delta<String> delta) {
349422 }
350423 delta .getOriginal ().setLines (Arrays .asList (origResult .toString ().split ("\n " )));
351424 delta .getRevised ().setLines (Arrays .asList (revResult .toString ().split ("\n " )));
352- }
353425 }
354426
355427 /**
@@ -359,8 +431,8 @@ private void addInlineDiffs(Delta<String> delta) {
359431 * @param tag the tag name without angle brackets, just a word
360432 * @param cssClass the optional css class
361433 */
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 ) {
364436 LinkedList <String > result = (LinkedList <String >) sequence .clone ();
365437 StringBuilder tagBuilder = new StringBuilder ();
366438 tagBuilder .append ("<" );
0 commit comments