3535import java .util .regex .Pattern ;
3636
3737/**
38- * This class for generating DiffRows for side-by-sidy view. You can customize the way of
39- * generating. For example, show inline diffs on not, ignoring white spaces or/and blank lines and
40- * so on. All parameters for generating are optional. If you do not specify them, the class will use
41- * the default values.
38+ * This class for generating DiffRows for side-by-sidy view. You can customize the way of generating. For example, show
39+ * inline diffs on not, ignoring white spaces or/and blank lines and so on. All parameters for generating are optional.
40+ * If you do not specify them, the class will use the default values.
4241 *
4342 * These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ...
4443 *
4948 */
5049public class DiffRowGenerator {
5150
52- public static final BiPredicate <String ,String >IGNORE_WHITESPACE_EQUALIZER = (original ,revised )
51+ public static final BiPredicate <String ,String >IGNORE_WHITESPACE_EQUALIZER = (original ,revised )
5352 ->original .trim ().replaceAll ("\\ s+" ," " ).equals (revised .trim ().replaceAll ("\\ s+" ," " ));
54- public static final BiPredicate <String ,String >DEFAULT_EQUALIZER =Object ::equals ;
53+ public static final BiPredicate <String ,String >DEFAULT_EQUALIZER =Object ::equals ;
5554private static final Pattern SPLIT_PATTERN =Pattern .compile ("\\ s+|[,.\\ [\\ ](){}/\\ \\ *+\\ -#]" );
5655private final boolean showInlineDiffs ;
5756private final boolean ignoreWhiteSpaces ;
@@ -61,6 +60,7 @@ public class DiffRowGenerator {
6160private final int columnWidth ;
6261private final BiPredicate <String ,String >equalizer ;
6362private final boolean mergeOriginalRevised ;
63+ private final boolean reportLinesUnchanged ;
6464
6565/**
6666 * This class used for building the DiffRowGenerator.
@@ -79,6 +79,7 @@ public static class Builder {
7979private int columnWidth =80 ;
8080private boolean mergeOriginalRevised =false ;
8181private boolean inlineDiffByWord =false ;
82+ private boolean reportLinesUnchanged =false ;
8283
8384private Builder () {
8485 }
@@ -105,6 +106,17 @@ public Builder ignoreWhiteSpaces(boolean val) {
105106return this ;
106107 }
107108
109+ /**
110+ * Give the originial old and new text lines to Diffrow without any additional processing.
111+ *
112+ * @param val the value to set. Default: false.
113+ * @return builder with configured reportLinesUnWrapped parameter
114+ */
115+ public Builder reportLinesUnchanged (final boolean val ) {
116+ reportLinesUnchanged =val ;
117+ return this ;
118+ }
119+
108120/**
109121 * Generator for Old-Text-Tags.
110122 *
@@ -130,8 +142,8 @@ public Builder newTag(Function<Boolean, String> generator) {
130142/**
131143 * Set the column with of generated lines of original and revised texts.
132144 *
133- * @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return
134- *builder with config ured ignoreBlankLines parameter
145+ * @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return builder with config
146+ * ured ignoreBlankLines parameter
135147 */
136148public Builder columnWidth (int width ) {
137149if (width >0 ) {
@@ -150,8 +162,7 @@ public DiffRowGenerator build() {
150162 }
151163
152164/**
153- * Merge the complete result within the original text. This makes sense for one line
154- * display.
165+ * Merge the complete result within the original text. This makes sense for one line display.
155166 *
156167 * @param mergeOriginalRevised
157168 * @return
@@ -162,8 +173,8 @@ public Builder mergeOriginalRevised(boolean mergeOriginalRevised) {
162173 }
163174
164175/**
165- * Per default each character is separatly processed. This variant introduces processing by
166- *word, which should deliver no in word changes.
176+ * Per default each character is separatly processed. This variant introduces processing by word, which should
177+ * deliver no in word changes.
167178 */
168179public Builder inlineDiffByWord (boolean inlineDiffByWord ) {
169180this .inlineDiffByWord =inlineDiffByWord ;
@@ -174,7 +185,7 @@ public Builder inlineDiffByWord(boolean inlineDiffByWord) {
174185public static Builder create () {
175186return new Builder ();
176187 }
177-
188+
178189private DiffRowGenerator (Builder builder ) {
179190showInlineDiffs =builder .showInlineDiffs ;
180191ignoreWhiteSpaces =builder .ignoreWhiteSpaces ;
@@ -183,12 +194,13 @@ private DiffRowGenerator(Builder builder) {
183194columnWidth =builder .columnWidth ;
184195mergeOriginalRevised =builder .mergeOriginalRevised ;
185196inlineDiffByWord =builder .inlineDiffByWord ;
186- equalizer =ignoreWhiteSpaces ?IGNORE_WHITESPACE_EQUALIZER :DEFAULT_EQUALIZER ;
197+ equalizer =ignoreWhiteSpaces ?IGNORE_WHITESPACE_EQUALIZER :DEFAULT_EQUALIZER ;
198+ reportLinesUnchanged =builder .reportLinesUnchanged ;
187199 }
188200
189201/**
190- * Get the DiffRows describing the difference between original and revised texts using the given
191- *patch. Useful for displaying side-by-side diff.
202+ * Get the DiffRows describing the difference between original and revised texts using the given patch. Useful for
203+ * displaying side-by-side diff.
192204 *
193205 * @param original the original text
194206 * @param revised the revised text
@@ -198,22 +210,34 @@ public List<DiffRow> generateDiffRows(List<String> original, List<String> revise
198210return generateDiffRows (original ,DiffUtils .diff (original ,revised ,equalizer ));
199211 }
200212
213+ private String preprocessLine (String line ) {
214+ if (columnWidth ==0 ) {
215+ return StringUtils .normalize (line );
216+ }else {
217+ return StringUtils .wrapText (StringUtils .normalize (line ),columnWidth );
218+ }
219+ }
220+
201221private DiffRow buildDiffRow (Tag type ,String orgline ,String newline ) {
202- String wrapOrg =StringUtils .wrapText (StringUtils .normalize (orgline ),columnWidth );
203- if (Tag .DELETE ==type ) {
204- if (mergeOriginalRevised ||showInlineDiffs ) {
205- wrapOrg =oldTag .apply (true ) +wrapOrg +oldTag .apply (false );
222+ if (reportLinesUnchanged ) {
223+ return new DiffRow (type ,orgline ,newline );
224+ }else {
225+ String wrapOrg =preprocessLine (orgline );
226+ if (Tag .DELETE ==type ) {
227+ if (mergeOriginalRevised ||showInlineDiffs ) {
228+ wrapOrg =oldTag .apply (true ) +wrapOrg +oldTag .apply (false );
229+ }
206230 }
207- }
208- String wrapNew = StringUtils . wrapText ( StringUtils . normalize ( newline ), columnWidth );
209- if ( Tag . INSERT == type ) {
210- if ( mergeOriginalRevised ) {
211- wrapOrg = newTag . apply ( true ) + wrapNew + newTag . apply ( false );
212- } else if ( showInlineDiffs ) {
213- wrapNew = newTag . apply ( true ) + wrapNew + newTag . apply ( false );
231+ String wrapNew = preprocessLine ( newline );
232+ if ( Tag . INSERT == type ) {
233+ if ( mergeOriginalRevised ) {
234+ wrapOrg = newTag . apply ( true ) + wrapNew + newTag . apply ( false );
235+ } else if ( showInlineDiffs ) {
236+ wrapNew = newTag . apply ( true ) + wrapNew + newTag . apply ( false );
237+ }
214238 }
239+ return new DiffRow (type ,wrapOrg ,wrapNew );
215240 }
216- return new DiffRow (type ,wrapOrg ,wrapNew );
217241 }
218242
219243private DiffRow buildDiffRowWithoutNormalizing (Tag type ,String orgline ,String newline ) {
@@ -223,8 +247,8 @@ private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String
223247 }
224248
225249/**
226- * Generates the DiffRows describing the difference between original and revised texts using the
227- *given patch. Useful for displaying side-by-side diff.
250+ * Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful
251+ * for displaying side-by-side diff.
228252 *
229253 * @param original the original text
230254 * @param revised the revised text
@@ -367,8 +391,7 @@ private List<DiffRow> generateInlineDiffs(Delta<String> delta) throws DiffExcept
367391/**
368392 * Wrap the elements in the sequence with the given tag
369393 *
370- * @param startPosition the position from which tag should start. The counting start from a
371- * zero.
394+ * @param startPosition the position from which tag should start. The counting start from a zero.
372395 * @param endPosition the position before which tag should should be closed.
373396 * @param tag the tag name without angle brackets, just a word
374397 * @param cssClass the optional css class