63 Commits

Author SHA1 Message Date
wumpz
4bab820483 [maven-release-plugin] prepare release java-diff-utils-4.0 2018-11-22 21:50:52 +01:00
wumpz
4fe80bdf1e changed readme to new home 2018-11-16 00:30:34 +01:00
wumpz
005ba349f8 2018-11-15 17:32:08 +01:00
wumpz
0fbbb53b77 2018-11-12 18:10:49 +01:00
wumpz
d5fbf5022e changed groupid, artifactid
moved to new organistion java-diff-utils
switched to version 4.0-SNAPSHOT
2018-11-04 22:56:17 +01:00
Tobias
2c85597238 Merge pull request #28 from koppor/fix-headers
Reformat Apache 2.0 headers (remove #%L things)
2018-10-28 18:09:06 +01:00
Tobias
f88ce15ff8 Merge pull request #27 from koppor/use-objects-hash
Use Objects.hash() instead of custom hashCode() method
2018-10-28 18:08:50 +01:00
Oliver Kopp
30a23c00d1 Reformat Apache 2.0 headers (remove #%L things) 2018-10-28 17:25:20 +01:00
Oliver Kopp
306f92684f Use Objects.hash() instead of custom hashCode() method 2018-10-28 17:13:03 +01:00
wumpz
d4f114226d fixes #26 2018-10-18 21:52:57 +02:00
wumpz
65183197c5 [maven-release-plugin] prepare for next development iteration 2018-10-18 21:39:22 +02:00
wumpz
5c33149e2a [maven-release-plugin] prepare release diffutils-3.0 2018-10-18 21:39:21 +02:00
Tobias
b273da278e Update README.md 2018-10-10 09:54:45 +02:00
wumpz
2671949b92 2018-09-13 15:32:14 +02:00
Tobias
5a32ede79f Merge pull request #25 from benelog/refactor-regex
Refactor to reuse java.util.regex.Pattern
2018-09-13 15:17:44 +02:00
Sanghyuk Jung
5dc489a4ef Refactor to reuse java.util.regex.Pattern 2018-09-13 17:31:05 +09:00
wumpz
f2ab70afc4 fixes #22 2018-08-03 10:55:07 +02:00
wumpz
c410422860 fixes #22 2018-08-03 10:51:56 +02:00
wumpz
1161243bc2 2018-08-03 09:23:04 +02:00
wumpz
f0fe7a2137 Merge origin/master 2018-08-02 11:46:07 +02:00
wumpz
d506d62a91 added a default method for computeDiff from arrays 2018-07-02 00:44:53 +02:00
wumpz
33f2d744ab brought back diffutils to life 2018-06-28 22:42:06 +02:00
wumpz
696d22bd94 Removed DiffAlgorithm.java and Delta.java due to licensing issues. The originals were Apache 1.1. Now we start a clean room implementation of those two files. 2018-06-28 21:46:18 +02:00
wumpz
42780b18a8 2018-06-27 22:31:42 +02:00
wumpz
13a1522d46 Merge origin/master
Conflicts:
	README.md
2018-06-17 23:34:02 +02:00
wumpz
d12b13da41 fixes #21 2018-06-17 23:32:43 +02:00
wumpz
c8f0624a7b jdk8 2018-06-13 23:19:43 +02:00
wumpz
54bf402a9a 2018-06-13 15:33:04 +02:00
Tobias
3a87d24632 Update README.md 2018-05-16 23:04:12 +02:00
Tobias
67b26e5cab Update README.md 2018-05-09 12:06:22 +02:00
Tobias
592ff058c1 Update README.md 2018-05-09 12:04:49 +02:00
wumpz
553ef27e0c Merge origin/master 2018-05-07 01:35:39 +02:00
wumpz
d1c22e7243 fixes #19 2018-05-07 01:34:22 +02:00
wumpz
0d15097947 some renaming 2018-04-10 07:32:44 +02:00
wumpz
dbfdffd626 Merge origin/master 2018-03-17 00:57:38 +01:00
wumpz
33a0b58299 introduces test for issue #15 2018-03-17 00:57:20 +01:00
Tobias
db114a2c2a Update README.md 2018-03-15 15:10:52 +01:00
Tobias
c001819855 Update README.md 2018-03-15 15:08:38 +01:00
Tobias
c6e4059de4 Update README.md 2018-03-05 10:01:59 +01:00
Tobias
653d1f9153 Update README.md 2018-03-05 09:45:57 +01:00
Tobias
1214f4cf23 Create ISSUE_TEMPLATE.md 2018-02-08 08:08:06 +01:00
Tobias
04832c7c9a Set theme jekyll-theme-minimal 2017-12-27 20:55:59 +01:00
Tobias
d498a41dd3 Delete _config.yml 2017-12-27 20:55:26 +01:00
Tobias
a998d8d98b Set theme jekyll-theme-minimal 2017-12-27 20:52:11 +01:00
Tobias
91ddcccd1e Set theme jekyll-theme-minimal 2017-12-22 10:25:53 +01:00
Tobias
005f95ab9d Delete _config.yml 2017-12-22 10:25:15 +01:00
Tobias
1914de7e5c Set theme jekyll-theme-minimal 2017-12-22 10:24:59 +01:00
Tobias
e630c7975a Set theme jekyll-theme-minimal 2017-12-22 10:22:13 +01:00
Tobias
10c17b4287 Set theme jekyll-theme-hacker 2017-12-22 10:20:58 +01:00
Tobias
08d4914a8b Delete docs.txt 2017-12-22 10:20:18 +01:00
Tobias
df3ec97df4 Delete _config.yml 2017-12-22 10:20:05 +01:00
Tobias
8c242a42ef Set theme jekyll-theme-cayman 2017-12-22 10:19:14 +01:00
wumpz
05de2df99d introduced docs folder 2017-12-22 10:11:35 +01:00
Tobias
0eb7b6c34f Set theme jekyll-theme-minimal 2017-12-22 09:04:38 +01:00
Tobias
5e0d398c53 Set theme jekyll-theme-hacker 2017-12-22 09:02:33 +01:00
Tobias
829567bace Create LICENSE 2017-12-22 08:24:51 +01:00
Tobias
02c97e4691 Update README.md 2017-12-01 09:12:42 +01:00
wumpz
4933ca5200 2017-11-09 23:02:00 +01:00
wumpz
a65ffd95a9 2017-11-09 22:59:29 +01:00
wumpz
dcf66dfadc [maven-release-plugin] prepare for next development iteration 2017-11-09 22:47:30 +01:00
wumpz
244e7e7fd8 [maven-release-plugin] prepare release diffutils-2.2 2017-11-09 22:47:30 +01:00
wumpz
424cfcefd7 2017-11-09 22:45:47 +01:00
wumpz
15af24ac02 [maven-release-plugin] prepare for next development iteration 2017-11-09 22:38:40 +01:00
37 changed files with 1568 additions and 1131 deletions

17
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,17 @@
### Expected Behavior
### Actual Behavior
### Steps to Reproduce the Problem
1.
1.
1.
### Specifications
- Version:
- Platform:
- Subsystem:

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,7 +1,9 @@
# java-diff-utils
## Status ##
[![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/wumpz/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=wumpz/java-diff-utils&utm_campaign=Badge_Grade)
[![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/java-diff-utils/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils/badge.svg)](http://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils)
## Intro ##
Diff Utils library is an OpenSource library for performing the comparison operations between texts: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
@@ -50,7 +52,19 @@ This is a test ~senctence~**for diffutils**.
But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future.
### Changelog ###
* Version 2.1-SNAPSHOT
* Version 4.0-SNAPSHOT
* moved to organisation **java-diff-utils**
* changed groupid to **io.github.java-diff-utils** and artifact id to **java-diff-utils**
* Version 3.0
* changed generation of inline diffes, if there are different linefeeds within one diff, then these are excluded
from the diff block.
* Due to licensing issues Delta.java and DiffAlgorithm.java were removed.
* Version 2.3-SNAPSHOT
* Introduced a process listener to diff algorithms. For long running
diffs one could implement some progress information.
* automatic module name for JDK 9 and higher usage
* Version 2.2
* released at maven central
* included checkstyle source code conventions
* groupid changed to **com.github.wumpz**, due to maven central releasing
* allow configurable splitting of lines to define the blocks to compare (words, characters, phrases).
@@ -72,7 +86,7 @@ But it can easily replaced by any other which is better for handing your texts.
## Source Code conventions
Recently a checkstyle process was integrated into the build process. JSqlParser follows the sun java format convention. There are no TABs allowed. Use spaces.
Recently a checkstyle process was integrated into the build process. java-diff-utils follows the sun java format convention. There are no TABs allowed. Use spaces.
```java
public static <T> Patch<T> diff(List<T> original, List<T> revised,
@@ -92,13 +106,27 @@ This is a valid piece of source code:
### To Install ###
**This jar is not yet to get at maven central.**
Just add the code below to your maven dependencies:
```
<dependency>
<groupId>com.github.wumpz</groupId>
<artifactId>diffutils</artifactId>
   <version>2.0-SNAPSHOT</version>
   <version>3.0</version>
</dependency>
```
Attention. We changed groupid and artifactid. Starting with version 4 you have to use:
```
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.0-SNAPSHOT</version>
</dependency>
```
or using gradle:
```
// https://mvnrepository.com/artifact/com.github.wumpz/diffutils
compile group: 'com.github.wumpz', name: 'diffutils', version: '2.2'
```

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-minimal

View File

@@ -1,22 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<netbeans.compile.on.save>none</netbeans.compile.on.save>
<com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable>
<com-junichi11-netbeans-changelf.use-project>true</com-junichi11-netbeans-changelf.use-project>
<com-junichi11-netbeans-changelf.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind>
<com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global>
</properties>
<netbeans.compile.on.save>none</netbeans.compile.on.save>
<com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable>
<com-junichi11-netbeans-changelf.use-project>true</com-junichi11-netbeans-changelf.use-project>
<com-junichi11-netbeans-changelf.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind>
<com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global>
<netbeans.hint.jdkPlatform>JDK_1.8</netbeans.hint.jdkPlatform>
</properties>
</project-shared-configuration>

521
pom.xml
View File

@@ -1,250 +1,255 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.wumpz</groupId>
<artifactId>diffutils</artifactId>
<packaging>jar</packaging>
<version>2.1</version>
<name>java-diff-utils</name>
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
<url>https://github.com/wumpz/java-diff-utils</url>
<inceptionYear>2009</inceptionYear>
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<packaging>jar</packaging>
<version>4.0</version>
<name>java-diff-utils</name>
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
<url>https://github.com/java-diff-utils/java-diff-utils</url>
<inceptionYear>2009</inceptionYear>
<distributionManagement>
<repository>
<id>sonatype-nexus-staging</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<distributionManagement>
<repository>
<id>sonatype-nexus-staging</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
</repository>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<scm>
<connection>scm:git:https://github.com/wumpz/java-diff-utils.git</connection>
<developerConnection>scm:git:ssh://git@github.com:wumpz/java-diff-utils.git</developerConnection>
<url>https://github.com/wumpz/java-diff-utils.git</url>
<tag>diffutils-2.1</tag>
</scm>
<scm>
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
<tag>java-diff-utils-4.0</tag>
</scm>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/wumpz/java-diff-utils/issues</url>
</issueManagement>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/java-diff-utils/java-diff-utils/issues</url>
</issueManagement>
<organization>
<name>java-diff-utils</name>
</organization>
<organization>
<name>java-diff-utils</name>
</organization>
<developers>
<developer>
<name>Tobias Warneke</name>
<email>t.warneke@gmx.net</email>
</developer>
<developer>
<name>Dmitry Naumenko</name>
<email>dm.naumenko@gmail.com</email>
</developer>
<developer>
<name>Juanco Anez</name>
<email>juanco@suigeneris.org</email>
</developer>
</developers>
<developers>
<developer>
<name>Tobias Warneke</name>
<email>t.warneke@gmx.net</email>
</developer>
<!--
<developer>
<name>Dmitry Naumenko</name>
<email>dm.naumenko@gmail.com</email>
</developer>
<developer>
<name>Juanco Anez</name>
<email>juanco@suigeneris.org</email>
</developer>
-->
</developers>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.4.1.201607150455-r</version>
<exclusions>
<exclusion>
<groupId>com.googlecode.javaewah</groupId>
<artifactId>JavaEWAH</artifactId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
<exclusion>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.4.1.201607150455-r</version>
<exclusions>
<exclusion>
<groupId>com.googlecode.javaewah</groupId>
<artifactId>JavaEWAH</artifactId>
</exclusion>
<exclusion>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
<exclusion>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- Make this JAR OSGi ready -->
<!-- We want to keep packaging type as jar. Therefore we need to customize the MANIFEST.MF.
See http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
-->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<configuration>
<additionalparam>${javadoc.opts}</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>**/LR*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<localCheckout>true</localCheckout>
<pushChanges>false</pushChanges>
<mavenExecutorId>forked-path</mavenExecutorId>
<goals>install</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>verify-style</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<logViolationsToConsole>true</logViolationsToConsole>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
<checkstyleRules>
<module name="Checker">
<module name="SuppressWarningsFilter" />
<module name="FileTabCharacter" />
<!-- git checkout may change linefeeds on the fly
<module name="RegexpMultiline">
<property name="format" value="(?s:(\r\n|\r).*)" />
<property name="message" value="CRLF and CR line endings are prohibited, but this file uses them." />
</module>
-->
<module name="TreeWalker">
<module name="AvoidNestedBlocks" />
<module name="ConstantName" />
<module name="EmptyCatchBlock" />
<module name="EmptyStatement" />
<module name="MissingOverride" />
<module name="MultipleVariableDeclarations" />
<module name="ParameterAssignment" />
<module name="StringLiteralEquality" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<!-- Make this JAR OSGi ready -->
<!-- We want to keep packaging type as jar. Therefore we need to customize the MANIFEST.MF.
See http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
-->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
<manifestEntries>
<!-- identical to OSGI name -->
<Automatic-Module-Name>com.github.wumpz.diffutils</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<configuration>
<additionalparam>${javadoc.opts}</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>**/LR*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<localCheckout>true</localCheckout>
<pushChanges>false</pushChanges>
<mavenExecutorId>forked-path</mavenExecutorId>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>verify-style</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<logViolationsToConsole>true</logViolationsToConsole>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<sourceDirectory>${project.build.sourceDirectory}</sourceDirectory>
<checkstyleRules>
<module name="Checker">
<module name="SuppressWarningsFilter" />
<module name="FileTabCharacter" />
<!-- git checkout may change linefeeds on the fly
<module name="RegexpMultiline">
<property name="format" value="(?s:(\r\n|\r).*)" />
<property name="message" value="CRLF and CR line endings are prohibited, but this file uses them." />
</module>
-->
<module name="TreeWalker">
<module name="AvoidNestedBlocks" />
<module name="ConstantName" />
<module name="EmptyCatchBlock" />
<module name="EmptyStatement" />
<module name="MissingOverride" />
<module name="MultipleVariableDeclarations" />
<module name="ParameterAssignment" />
<module name="StringLiteralEquality" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<module name="WhitespaceAfter" />
<module name="WhitespaceAfter" />
<module name="NeedBraces" />
<module name="UnnecessaryParentheses" />
<module name="LeftCurly" />
<module name="RightCurly" />
<module name="NeedBraces" />
<module name="UnnecessaryParentheses" />
<module name="LeftCurly" />
<module name="RightCurly" />
<module name="SuppressWarningsHolder" />
</module>
</module>
</checkstyleRules>
</configuration>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.19</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<profiles>
<module name="SuppressWarningsHolder" />
</module>
</module>
</checkstyleRules>
</configuration>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.19</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-release-artifacts</id>
<activation>
@@ -275,31 +280,31 @@
</plugins>
</build>
</profile>
<profile>
<id>doclint-java8-disable</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
<profile>
<id>long-running-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>xxx</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<profile>
<id>doclint-java8-disable</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<javadoc.opts>-Xdoclint:none</javadoc.opts>
</properties>
</profile>
<profile>
<id>long-running-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>xxx</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,28 +1,25 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib;
import com.github.difflib.algorithm.DiffAlgorithm;
import com.github.difflib.algorithm.DiffAlgorithmI;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.algorithm.myers.MyersDiff;
import com.github.difflib.patch.Delta;
import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import java.util.ArrayList;
@@ -37,7 +34,6 @@ import static java.util.stream.Collectors.joining;
* Implements the difference and patching engine
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @version 0.4.1
*/
public final class DiffUtils {
@@ -46,36 +42,45 @@ public final class DiffUtils {
*
* @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}.
* @param progress progress listener
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
* @throws com.github.difflib.algorithm.DiffException
*/
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) throws DiffException {
return DiffUtils.diff(original, revised, new MyersDiff<>(), progress);
}
public static <T> Patch<T> diff(List<T> original, List<T> revised) throws DiffException {
return DiffUtils.diff(original, revised, new MyersDiff<>());
return DiffUtils.diff(original, revised, new MyersDiff<>(), null);
}
/**
* Computes the difference between the original and revised text.
*/
public static Patch<String> diff(String originalText, String revisedText) throws DiffException {
return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n")));
public static Patch<String> diff(String sourceText, String targetText,
DiffAlgorithmListener progress) throws DiffException {
return DiffUtils.diff(
Arrays.asList(sourceText.split("\n")),
Arrays.asList(targetText.split("\n")), progress);
}
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}.
* @param source The original text. Must not be {@code null}.
* @param target The revised text. Must not be {@code null}.
*
* @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If {@code null}
* the default equalizer of the default algorithm is used..
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
*/
public static <T> Patch<T> diff(List<T> original, List<T> revised,
public static <T> Patch<T> diff(List<T> source, List<T> target,
BiPredicate<T, T> equalizer) throws DiffException {
if (equalizer != null) {
return DiffUtils.diff(original, revised,
return DiffUtils.diff(source, target,
new MyersDiff<>(equalizer));
}
return DiffUtils.diff(original, revised, new MyersDiff<>());
return DiffUtils.diff(source, target, new MyersDiff<>());
}
/**
@@ -84,16 +89,30 @@ public final class DiffUtils {
* @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}.
* @param algorithm The diff algorithm. Must not be {@code null}.
* @param progress The diff algorithm listener.
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
*/
public static <T> Patch<T> diff(List<T> original, List<T> revised,
DiffAlgorithm<T> algorithm) throws DiffException {
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) throws DiffException {
Objects.requireNonNull(original, "original must not be null");
Objects.requireNonNull(revised, "revised must not be null");
Objects.requireNonNull(algorithm, "algorithm must not be null");
return Patch.generate(original, revised, algorithm.diff(original, revised));
return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress));
}
/**
* Computes the difference between the original and revised list of elements with default diff algorithm
*
* @param original The original text. Must not be {@code null}.
* @param revised The revised text. Must not be {@code null}.
* @param algorithm The diff algorithm. Must not be {@code null}.
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
*/
public static <T> Patch<T> diff(List<T> original, List<T> revised,
DiffAlgorithmI<T> algorithm) throws DiffException {
return diff(original, revised, algorithm, null);
}
/**
* Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of
@@ -113,9 +132,9 @@ public final class DiffUtils {
revList.add(character.toString());
}
Patch<String> patch = DiffUtils.diff(origList, revList);
for (Delta<String> delta : patch.getDeltas()) {
delta.getOriginal().setLines(compressLines(delta.getOriginal().getLines(), ""));
delta.getRevised().setLines(compressLines(delta.getRevised().getLines(), ""));
for (AbstractDelta<String> delta : patch.getDeltas()) {
delta.getSource().setLines(compressLines(delta.getSource().getLines(), ""));
delta.getTarget().setLines(compressLines(delta.getTarget().getLines(), ""));
}
return patch;
}

View File

@@ -17,7 +17,7 @@ package com.github.difflib;
import com.github.difflib.patch.ChangeDelta;
import com.github.difflib.patch.Chunk;
import com.github.difflib.patch.Delta;
import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.Patch;
import java.util.ArrayList;
import java.util.List;
@@ -130,37 +130,37 @@ public final class UnifiedDiffUtils {
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing
* the Patch.
*
* @param original - Filename of the original (unrevised file)
* @param revised - Filename of the revised file
* @param originalFileName - Filename of the original (unrevised file)
* @param revisedFileName - Filename of the revised file
* @param originalLines - Lines of the original file
* @param patch - Patch created by the diff() function
* @param contextSize - number of lines of context output around each difference in the file.
* @return List of strings representing the Unified Diff representation of the Patch argument.
* @author Bill James (tankerbay@gmail.com)
*/
public static List<String> generateUnifiedDiff(String original,
String revised, List<String> originalLines, Patch<String> patch,
public static List<String> generateUnifiedDiff(String originalFileName,
String revisedFileName, List<String> originalLines, Patch<String> patch,
int contextSize) {
if (!patch.getDeltas().isEmpty()) {
List<String> ret = new ArrayList<>();
ret.add("--- " + original);
ret.add("+++ " + revised);
ret.add("--- " + originalFileName);
ret.add("+++ " + revisedFileName);
List<Delta<String>> patchDeltas = new ArrayList<>(
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
patch.getDeltas());
// code outside the if block also works for single-delta issues.
List<Delta<String>> deltas = new ArrayList<>(); // current
List<AbstractDelta<String>> deltas = new ArrayList<>(); // current
// list
// of
// Delta's to
// process
Delta<String> delta = patchDeltas.get(0);
AbstractDelta<String> delta = patchDeltas.get(0);
deltas.add(delta); // add the first Delta to the current set
// if there's more than 1 Delta, we may need to output them together
if (patchDeltas.size() > 1) {
for (int i = 1; i < patchDeltas.size(); i++) {
int position = delta.getOriginal().getPosition(); // store
int position = delta.getSource().getPosition(); // store
// the
// current
// position
@@ -170,9 +170,9 @@ public final class UnifiedDiffUtils {
// Check if the next Delta is too close to the current
// position.
// And if it is, add it to the current set
Delta<String> nextDelta = patchDeltas.get(i);
if ((position + delta.getOriginal().size() + contextSize) >= (nextDelta
.getOriginal().getPosition() - contextSize)) {
AbstractDelta<String> nextDelta = patchDeltas.get(i);
if ((position + delta.getSource().size() + contextSize) >= (nextDelta
.getSource().getPosition() - contextSize)) {
deltas.add(nextDelta);
} else {
// if it isn't, output the current set,
@@ -207,33 +207,33 @@ public final class UnifiedDiffUtils {
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> processDeltas(List<String> origLines,
List<Delta<String>> deltas, int contextSize) {
List<AbstractDelta<String>> deltas, int contextSize) {
List<String> buffer = new ArrayList<>();
int origTotal = 0; // counter for total lines output from Original
int revTotal = 0; // counter for total lines output from Original
int line;
Delta<String> curDelta = deltas.get(0);
AbstractDelta<String> curDelta = deltas.get(0);
// NOTE: +1 to overcome the 0-offset Position
int origStart = curDelta.getOriginal().getPosition() + 1 - contextSize;
int origStart = curDelta.getSource().getPosition() + 1 - contextSize;
if (origStart < 1) {
origStart = 1;
}
int revStart = curDelta.getRevised().getPosition() + 1 - contextSize;
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
if (revStart < 1) {
revStart = 1;
}
// find the start of the wrapper context code
int contextStart = curDelta.getOriginal().getPosition() - contextSize;
int contextStart = curDelta.getSource().getPosition() - contextSize;
if (contextStart < 0) {
contextStart = 0; // clamp to the start of the file
}
// output the context before the first Delta
for (line = contextStart; line < curDelta.getOriginal().getPosition(); line++) { //
for (line = contextStart; line < curDelta.getSource().getPosition(); line++) { //
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
@@ -241,15 +241,15 @@ public final class UnifiedDiffUtils {
// output the first Delta
buffer.addAll(getDeltaText(curDelta));
origTotal += curDelta.getOriginal().getLines().size();
revTotal += curDelta.getRevised().getLines().size();
origTotal += curDelta.getSource().getLines().size();
revTotal += curDelta.getTarget().getLines().size();
int deltaIndex = 1;
while (deltaIndex < deltas.size()) { // for each of the other Deltas
Delta<String> nextDelta = deltas.get(deltaIndex);
int intermediateStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
for (line = intermediateStart; line < nextDelta.getOriginal()
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
int intermediateStart = curDelta.getSource().getPosition()
+ curDelta.getSource().getLines().size();
for (line = intermediateStart; line < nextDelta.getSource()
.getPosition(); line++) {
// output the code between the last Delta and this one
buffer.add(" " + origLines.get(line));
@@ -257,15 +257,15 @@ public final class UnifiedDiffUtils {
revTotal++;
}
buffer.addAll(getDeltaText(nextDelta)); // output the Delta
origTotal += nextDelta.getOriginal().getLines().size();
revTotal += nextDelta.getRevised().getLines().size();
origTotal += nextDelta.getSource().getLines().size();
revTotal += nextDelta.getTarget().getLines().size();
curDelta = nextDelta;
deltaIndex++;
}
// Now output the post-Delta context code, clamping the end of the file
contextStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
contextStart = curDelta.getSource().getPosition()
+ curDelta.getSource().getLines().size();
for (line = contextStart; (line < (contextStart + contextSize))
&& (line < origLines.size()); line++) {
buffer.add(" " + origLines.get(line));
@@ -275,7 +275,7 @@ public final class UnifiedDiffUtils {
// Create and insert the block header, conforming to the Unified Diff
// standard
StringBuffer header = new StringBuffer();
StringBuilder header = new StringBuilder();
header.append("@@ -");
header.append(origStart);
header.append(",");
@@ -297,12 +297,12 @@ public final class UnifiedDiffUtils {
* @return list of String lines of code.
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> getDeltaText(Delta<String> delta) {
private static List<String> getDeltaText(AbstractDelta<String> delta) {
List<String> buffer = new ArrayList<>();
for (String line : delta.getOriginal().getLines()) {
for (String line : delta.getSource().getLines()) {
buffer.add("-" + line);
}
for (String line : delta.getRevised().getLines()) {
for (String line : delta.getTarget().getLines()) {
buffer.add("+" + line);
}
return buffer;

View File

@@ -19,7 +19,7 @@ import com.github.difflib.patch.DeltaType;
/**
*
* @author toben
* @author <a href="t.warneke@gmx.net">Tobias Warneke</a>
*/
public class Change {

View File

@@ -1,54 +0,0 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
*/
package com.github.difflib.algorithm;
import com.github.difflib.patch.Patch;
import java.util.*;
/**
* The general interface for computing diffs between two lists of elements of type T.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @param T The type of the compared elements in the 'lines'.
*/
public interface DiffAlgorithm<T> {
/**
* Computes the difference between the original sequence and the revised sequence and returns it as a {@link Patch}
* object.
*
* @param original The original sequence. Must not be {@code null}.
* @param revised The revised sequence. Must not be {@code null}.
* @return The patch representing the diff of the given sequences. Never {@code null}.
*/
public default List<Change> diff(T[] original, T[] revised) throws DiffException {
return diff(Arrays.asList(original), Arrays.asList(revised));
}
/**
* Computes the difference between the original sequence and the revised sequence and returns it as a {@link Patch}
* object.
*
* @param original The original sequence. Must not be {@code null}.
* @param revised The revised sequence. Must not be {@code null}.
* @return The patch representing the diff of the given sequences. Never {@code null}.
*/
public List<Change> diff(List<T> original, List<T> revised) throws DiffException;
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2018 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm;
import java.util.Arrays;
import java.util.List;
/**
* Interface of a diff algorithm.
*
* @author Tobias Warneke (t.warneke@gmx.net)
*/
public interface DiffAlgorithmI<T> {
/**
* Computes the changeset to patch the source list to the target list.
*
* @param source source data
* @param target target data
* @param progress progress listener
* @return
* @throws DiffException
*/
List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) throws DiffException;
/**
* Simple extension to compute a changeset using arrays.
*
* @param source
* @param target
* @param progress
* @return
* @throws com.github.difflib.algorithm.DiffException
*/
default List<Change> computeDiff(T[] source, T[] target, DiffAlgorithmListener progress) throws DiffException {
return computeDiff(Arrays.asList(source), Arrays.asList(target), progress);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2018 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm;
/**
*
* @author Tobias Warneke (t.warneke@gmx.net)
*/
public interface DiffAlgorithmListener {
void diffStart();
/**
* This is a step within the diff algorithm. Due to different implementations the value
* is not strict incrementing to the max and is not garantee to reach the max. It could
* stop before.
* @param value
* @param max
*/
void diffStep(int value, int max);
void diffEnd();
}

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm;

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm;

View File

@@ -16,7 +16,8 @@
package com.github.difflib.algorithm.jgit;
import com.github.difflib.algorithm.Change;
import com.github.difflib.algorithm.DiffAlgorithm;
import com.github.difflib.algorithm.DiffAlgorithmI;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.DeltaType;
import java.util.ArrayList;
@@ -28,18 +29,22 @@ import org.eclipse.jgit.diff.Sequence;
import org.eclipse.jgit.diff.SequenceComparator;
/**
* HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers implementation.
* HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers
* implementation.
*
* @author toben
*/
public class HistogramDiff<T> implements DiffAlgorithm<T> {
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
@Override
public List<Change> diff(List<T> original, List<T> revised) throws DiffException {
Objects.requireNonNull(original, "original list must not be null");
Objects.requireNonNull(revised, "revised list must not be null");
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) throws DiffException {
Objects.requireNonNull(source, "source list must not be null");
Objects.requireNonNull(target, "target list must not be null");
if (progress != null) {
progress.diffStart();
}
EditList diffList = new EditList();
diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(), new DataList<>(original), new DataList<>(revised)));
diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(progress), new DataList<>(source), new DataList<>(target)));
List<Change> patch = new ArrayList<>();
for (Edit edit : diffList) {
DeltaType type = DeltaType.EQUAL;
@@ -56,14 +61,26 @@ public class HistogramDiff<T> implements DiffAlgorithm<T> {
}
patch.add(new Change(type, edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
}
if (progress != null) {
progress.diffEnd();
}
return patch;
}
}
class DataListComparator<T> extends SequenceComparator<DataList<T>> {
private final DiffAlgorithmListener progress;
public DataListComparator(DiffAlgorithmListener progress) {
this.progress = progress;
}
@Override
public boolean equals(DataList<T> original, int orgIdx, DataList<T> revised, int revIdx) {
if (progress != null) {
progress.diffStep(orgIdx + revIdx, original.size() + revised.size());
}
return original.data.get(orgIdx).equals(revised.data.get(revIdx));
}

View File

@@ -1,26 +1,23 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm.myers;
import com.github.difflib.algorithm.Change;
import com.github.difflib.algorithm.DiffAlgorithm;
import com.github.difflib.algorithm.DiffAlgorithmI;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.algorithm.DifferentiationFailedException;
import com.github.difflib.patch.DeltaType;
@@ -33,7 +30,7 @@ import java.util.function.BiPredicate;
/**
* A clean-room implementation of Eugene Myers greedy differencing algorithm.
*/
public final class MyersDiff<T> implements DiffAlgorithm<T> {
public final class MyersDiff<T> implements DiffAlgorithmI<T> {
private final BiPredicate<T, T> DEFAULT_EQUALIZER = Object::equals;
private final BiPredicate<T, T> equalizer;
@@ -53,24 +50,31 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
* Return empty diff if get the error while procession the difference.
*/
@Override
public List<Change> diff(final List<T> original, final List<T> revised) throws DiffException {
Objects.requireNonNull(original, "original list must not be null");
Objects.requireNonNull(revised, "revised list must not be null");
public List<Change> computeDiff(final List<T> source, final List<T> target, DiffAlgorithmListener progress) throws DiffException {
Objects.requireNonNull(source, "source list must not be null");
Objects.requireNonNull(target, "target list must not be null");
PathNode path = buildPath(original, revised);
return buildRevision(path, original, revised);
if (progress != null) {
progress.diffStart();
}
PathNode path = buildPath(source, target, progress);
List<Change> result = buildRevision(path, source, target);
if (progress != null) {
progress.diffEnd();
}
return result;
}
/**
* Computes the minimum diffpath that expresses de differences between the original and revised sequences, according
* to Gene Myers differencing algorithm.
* Computes the minimum diffpath that expresses de differences between the original and revised
* sequences, according to Gene Myers differencing algorithm.
*
* @param orig The original sequence.
* @param rev The revised sequence.
* @return A minimum {@link PathNode Path} accross the differences graph.
* @throws DifferentiationFailedException if a diff path could not be found.
*/
private PathNode buildPath(final List<T> orig, final List<T> rev)
private PathNode buildPath(final List<T> orig, final List<T> rev, DiffAlgorithmListener progress)
throws DifferentiationFailedException {
Objects.requireNonNull(orig, "original sequence is null");
Objects.requireNonNull(rev, "revised sequence is null");
@@ -86,6 +90,9 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
diagonal[middle + 1] = new PathNode(0, -1, true, true, null);
for (int d = 0; d < MAX; d++) {
if (progress != null) {
progress.diffStep(d, MAX);
}
for (int k = -d; k <= d; k += 2) {
final int kmiddle = middle + k;
final int kplus = kmiddle + 1;
@@ -135,7 +142,8 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
* @param orig The original sequence.
* @param rev The revised sequence.
* @return A {@link Patch} script corresponding to the path.
* @throws DifferentiationFailedException if a {@link Patch} could not be built from the given path.
* @throws DifferentiationFailedException if a {@link Patch} could not be built from the given
* path.
*/
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
Objects.requireNonNull(actualPath, "path is null");
@@ -165,18 +173,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
} else {
changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j));
}
// Chunk<T> original = new Chunk<>(ianchor, copyOfRange(orig, ianchor, i));
// Chunk<T> revised = new Chunk<>(janchor, copyOfRange(rev, janchor, j));
// Delta<T> delta = null;
// if (original.size() == 0 && revised.size() != 0) {
// delta = new InsertDelta<>(original, revised);
// } else if (original.size() > 0 && revised.size() == 0) {
// delta = new DeleteDelta<>(original, revised);
// } else {
// delta = new ChangeDelta<>(original, revised);
// }
//
// patch.addDelta(delta);
if (path.isSnake()) {
path = path.prev;
}

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.algorithm.myers;

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2018 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;
import java.util.List;
import java.util.Objects;
/**
* Abstract delta between a source and a target.
* @author Tobias Warneke (t.warneke@gmx.net)
*/
public abstract class AbstractDelta<T> {
private final Chunk<T> source;
private final Chunk<T> target;
private final DeltaType type;
public AbstractDelta(DeltaType type, Chunk<T> source, Chunk<T> target) {
Objects.requireNonNull(source);
Objects.requireNonNull(target);
Objects.requireNonNull(type);
this.type = type;
this.source = source;
this.target = target;
}
public Chunk<T> getSource() {
return source;
}
public Chunk<T> getTarget() {
return target;
}
public DeltaType getType() {
return type;
}
/**
* Verify the chunk of this delta, to fit the target.
* @param target
* @throws PatchFailedException
*/
protected void verifyChunk(List<T> target) throws PatchFailedException {
getSource().verify(target);
}
public abstract void applyTo(List<T> target) throws PatchFailedException;
public abstract void restore(List<T> target);
@Override
public int hashCode() {
return Objects.hash(this.source, this.target, this.type);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final AbstractDelta<?> other = (AbstractDelta<?>) obj;
if (!Objects.equals(this.source, other.source)) {
return false;
}
if (!Objects.equals(this.target, other.target)) {
return false;
}
if (this.type != other.type) {
return false;
}
return true;
}
}

View File

@@ -1,54 +1,53 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;
import java.util.List;
import java.util.Objects;
/**
* Describes the change-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @param T The type of the compared elements in the 'lines'.
* @param T The type of the compared elements in the data 'lines'.
*/
public final class ChangeDelta<T> extends Delta<T> {
public final class ChangeDelta<T> extends AbstractDelta<T> {
/**
* Creates a change delta with the two given chunks.
*
* @param original The original chunk. Must not be {@code null}.
* @param revised The original chunk. Must not be {@code null}.
* @param source The source chunk. Must not be {@code null}.
* @param target The target chunk. Must not be {@code null}.
*/
public ChangeDelta(Chunk<T> original, Chunk<T> revised) {
super(DeltaType.CHANGE, original, revised);
public ChangeDelta(Chunk<T> source, Chunk<T> target) {
super(DeltaType.CHANGE, source, target);
Objects.requireNonNull(source, "source must not be null");
Objects.requireNonNull(target, "target must not be null");
}
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
verifyChunk(target);
int position = getSource().getPosition();
int size = getSource().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getRevised().getLines()) {
for (T line : getTarget().getLines()) {
target.add(position + i, line);
i++;
}
@@ -56,13 +55,13 @@ public final class ChangeDelta<T> extends Delta<T> {
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
int position = getTarget().getPosition();
int size = getTarget().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getOriginal().getLines()) {
for (T line : getSource().getLines()) {
target.add(position + i, line);
i++;
}
@@ -70,7 +69,7 @@ public final class ChangeDelta<T> extends Delta<T> {
@Override
public String toString() {
return "[ChangeDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + " to " + getRevised().getLines() + "]";
return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: "
+ getSource().getLines() + " to " + getTarget().getLines() + "]";
}
}

View File

@@ -1,26 +1,23 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Holds the information about the part of text involved in the diff process
@@ -65,6 +62,7 @@ public final class Chunk<T> {
* Verifies that this chunk's saved text matches the corresponding text in the given sequence.
*
* @param target the sequence to verify against.
* @throws com.github.difflib.patch.PatchFailedException
*/
public void verify(List<T> target) throws PatchFailedException {
if (position > target.size() || last() > target.size()) {
@@ -107,26 +105,11 @@ public final class Chunk<T> {
return getPosition() + size() - 1;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
result = prime * result + position;
result = prime * result + size();
return result;
return Objects.hash(lines, position, size());
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;
@@ -27,7 +23,7 @@ import java.util.List;
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @param T The type of the compared elements in the 'lines'.
*/
public final class DeleteDelta<T> extends Delta<T> {
public final class DeleteDelta<T> extends AbstractDelta<T> {
/**
* Creates a change delta with the two given chunks.
@@ -41,9 +37,9 @@ public final class DeleteDelta<T> extends Delta<T> {
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
verifyChunk(target);
int position = getSource().getPosition();
int size = getSource().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
@@ -51,8 +47,8 @@ public final class DeleteDelta<T> extends Delta<T> {
@Override
public void restore(List<T> target) {
int position = this.getRevised().getPosition();
List<T> lines = this.getOriginal().getLines();
int position = this.getTarget().getPosition();
List<T> lines = this.getSource().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
@@ -60,7 +56,7 @@ public final class DeleteDelta<T> extends Delta<T> {
@Override
public String toString() {
return "[DeleteDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + "]";
return "[DeleteDelta, position: " + getSource().getPosition() + ", lines: "
+ getSource().getLines() + "]";
}
}

View File

@@ -1,133 +0,0 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
*/
package com.github.difflib.patch;
import java.util.*;
/**
* Describes the delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @param T The type of the compared elements in the 'lines'.
*/
public abstract class Delta<T> {
private final DeltaType deltaType;
private final Chunk<T> original;
private final Chunk<T> revised;
/**
* Construct the delta for original and revised chunks
*
* @param original Chunk describing the original text. Must not be {@code null}.
* @param revised Chunk describing the revised text. Must not be {@code null}.
*/
public Delta(DeltaType deltaType, Chunk<T> original, Chunk<T> revised) {
Objects.requireNonNull(deltaType, "deltaType must not be null");
Objects.requireNonNull(original, "original must not be null");
Objects.requireNonNull(revised, "revised must not be null");
this.deltaType = deltaType;
this.original = original;
this.revised = revised;
}
/**
* Verifies that this delta can be used to patch the given text.
*
* @param target the text to patch.
* @throws PatchFailedException if the patch cannot be applied.
*/
public void verify(List<T> target) throws PatchFailedException {
getOriginal().verify(target);
}
/**
* Applies this delta as the patch for a given target
*
* @param target the given target
* @throws PatchFailedException
*/
public abstract void applyTo(List<T> target) throws PatchFailedException;
/**
* Cancel this delta for a given revised text. The action is opposite to patch.
*
* @param target the given revised text
*/
public abstract void restore(List<T> target);
public final DeltaType getType() {
return deltaType;
}
/**
* @return The Chunk describing the original text.
*/
public Chunk<T> getOriginal() {
return original;
}
/**
* @return The Chunk describing the revised text.
*/
public Chunk<T> getRevised() {
return revised;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((original == null) ? 0 : original.hashCode());
result = prime * result + ((revised == null) ? 0 : revised.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Delta<T> other = (Delta) obj;
if (original == null) {
if (other.original != null) {
return false;
}
} else if (!original.equals(other.original)) {
return false;
}
if (revised == null) {
if (other.revised != null) {
return false;
}
} else if (!revised.equals(other.revised)) {
return false;
}
return true;
}
}

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;
@@ -27,7 +23,7 @@ import java.util.List;
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @param T The type of the compared elements in the 'lines'.
*/
public final class InsertDelta<T> extends Delta<T> {
public final class InsertDelta<T> extends AbstractDelta<T> {
/**
* Creates an insert delta with the two given chunks.
@@ -41,9 +37,9 @@ public final class InsertDelta<T> extends Delta<T> {
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = this.getOriginal().getPosition();
List<T> lines = this.getRevised().getLines();
verifyChunk(target);
int position = this.getSource().getPosition();
List<T> lines = this.getTarget().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
@@ -51,8 +47,8 @@ public final class InsertDelta<T> extends Delta<T> {
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
int position = getTarget().getPosition();
int size = getTarget().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
@@ -60,7 +56,7 @@ public final class InsertDelta<T> extends Delta<T> {
@Override
public String toString() {
return "[InsertDelta, position: " + getOriginal().getPosition()
+ ", lines: " + getRevised().getLines() + "]";
return "[InsertDelta, position: " + getSource().getPosition()
+ ", lines: " + getTarget().getLines() + "]";
}
}

View File

@@ -36,7 +36,7 @@ import java.util.ListIterator;
*/
public final class Patch<T> {
private final List<Delta<T>> deltas;
private final List<AbstractDelta<T>> deltas;
public Patch() {
this(10);
@@ -54,9 +54,9 @@ public final class Patch<T> {
*/
public List<T> applyTo(List<T> target) throws PatchFailedException {
List<T> result = new ArrayList<>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
ListIterator<AbstractDelta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
AbstractDelta<T> delta = it.previous();
delta.applyTo(result);
}
return result;
@@ -70,9 +70,9 @@ public final class Patch<T> {
*/
public List<T> restore(List<T> target) {
List<T> result = new ArrayList<>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
ListIterator<AbstractDelta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
AbstractDelta<T> delta = it.previous();
delta.restore(result);
}
return result;
@@ -83,7 +83,7 @@ public final class Patch<T> {
*
* @param delta the given delta
*/
public void addDelta(Delta<T> delta) {
public void addDelta(AbstractDelta<T> delta) {
deltas.add(delta);
}
@@ -92,8 +92,8 @@ public final class Patch<T> {
*
* @return the deltas
*/
public List<Delta<T>> getDeltas() {
Collections.sort(deltas, comparing(d -> d.getOriginal().getPosition()));
public List<AbstractDelta<T>> getDeltas() {
Collections.sort(deltas, comparing(d -> d.getSource().getPosition()));
return deltas;
}

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.patch;

View File

@@ -1,25 +1,22 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.text;
import java.io.Serializable;
import java.util.Objects;
/**
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two texts
@@ -70,26 +67,11 @@ public final class DiffRow implements Serializable {
return newLine;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((newLine == null) ? 0 : newLine.hashCode());
result = prime * result + ((oldLine == null) ? 0 : oldLine.hashCode());
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
return result;
return Objects.hash(newLine, oldLine, tag);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {

View File

@@ -1,30 +1,26 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.text;
import com.github.difflib.DiffUtils;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.ChangeDelta;
import com.github.difflib.patch.Chunk;
import com.github.difflib.patch.DeleteDelta;
import com.github.difflib.patch.Delta;
import com.github.difflib.patch.InsertDelta;
import com.github.difflib.patch.Patch;
import com.github.difflib.text.DiffRow.Tag;
@@ -47,17 +43,11 @@ import java.util.regex.Pattern;
* </code>
*/
public class DiffRowGenerator {
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
-> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " "));
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
/**
* Splitting lines by word to achieve word by word diff checking.
*/
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
/**
* Splitting lines by character to achieve char by char diff checking.
@@ -69,17 +59,290 @@ public class DiffRowGenerator {
}
return list;
};
private final boolean showInlineDiffs;
private final boolean ignoreWhiteSpaces;
private final Function<Boolean, String> oldTag;
private final Function<Boolean, String> newTag;
private final Function<String, List<String>> inlineDiffSplitter;
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
/**
* Splitting lines by word to achieve word by word diff checking.
*/
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
public static Builder create() {
return new Builder();
}
private static String adjustWhitespace(String raw) {
return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" ");
}
protected final static List<String> splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) {
List<String> list = new ArrayList<>();
if (str != null) {
Matcher matcher = SPLIT_PATTERN.matcher(str);
int pos = 0;
while (matcher.find()) {
if (pos < matcher.start()) {
list.add(str.substring(pos, matcher.start()));
}
list.add(matcher.group());
pos = matcher.end();
}
if (pos < str.length()) {
list.add(str.substring(pos));
}
}
return list;
}
/**
* Wrap the elements in the sequence with the given tag
*
* @param startPosition the position from which tag should start. The counting start from a zero.
* @param endPosition the position before which tag should should be closed.
* @param tag the tag name without angle brackets, just a word
* @param cssClass the optional css class
*/
static void wrapInTag(List<String> sequence, int startPosition,
int endPosition, Function<Boolean, String> tagGenerator) {
int endPos = endPosition;
while (endPos >= startPosition) {
//search position for end tag
while (endPos > startPosition) {
if (!"\n".equals(sequence.get(endPos - 1))) {
break;
}
endPos--;
}
if (endPos == startPosition) {
break;
}
sequence.add(endPos, tagGenerator.apply(false));
endPos--;
//search position for end tag
while (endPos > startPosition) {
if ("\n".equals(sequence.get(endPos - 1))) {
break;
}
endPos--;
}
sequence.add(endPos, tagGenerator.apply(true));
endPos--;
}
// sequence.add(endPosition, tagGenerator.apply(false));
// sequence.add(startPosition, tagGenerator.apply(true));
}
private final int columnWidth;
private final BiPredicate<String, String> equalizer;
private final boolean ignoreWhiteSpaces;
private final Function<String, List<String>> inlineDiffSplitter;
private final boolean mergeOriginalRevised;
private final Function<Boolean, String> newTag;
private final Function<Boolean, String> oldTag;
private final boolean reportLinesUnchanged;
private final boolean showInlineDiffs;
private DiffRowGenerator(Builder builder) {
showInlineDiffs = builder.showInlineDiffs;
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
oldTag = builder.oldTag;
newTag = builder.newTag;
columnWidth = builder.columnWidth;
mergeOriginalRevised = builder.mergeOriginalRevised;
inlineDiffSplitter = builder.inlineDiffSplitter;
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
reportLinesUnchanged = builder.reportLinesUnchanged;
Objects.requireNonNull(inlineDiffSplitter);
}
/**
* Get the DiffRows describing the difference between original and revised texts using the given patch. Useful for
* displaying side-by-side diff.
*
* @param original the original text
* @param revised the revised text
* @return the DiffRows between original and revised texts
*/
public List<DiffRow> generateDiffRows(List<String> original, List<String> revised) throws DiffException {
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
}
/**
* Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful
* for displaying side-by-side diff.
*
* @param original the original text
* @param revised the revised text
* @param patch the given patch
* @return the DiffRows between original and revised texts
*/
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) throws DiffException {
List<DiffRow> diffRows = new ArrayList<>();
int endPos = 0;
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
for (int i = 0; i < deltaList.size(); i++) {
AbstractDelta<String> delta = deltaList.get(i);
Chunk<String> orig = delta.getSource();
Chunk<String> rev = delta.getTarget();
for (String line : original.subList(endPos, orig.getPosition())) {
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
}
// Inserted DiffRow
if (delta instanceof InsertDelta) {
endPos = orig.last() + 1;
for (String line : (List<String>) rev.getLines()) {
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
}
continue;
}
// Deleted DiffRow
if (delta instanceof DeleteDelta) {
endPos = orig.last() + 1;
for (String line : (List<String>) orig.getLines()) {
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
}
continue;
}
if (showInlineDiffs) {
diffRows.addAll(generateInlineDiffs(delta));
} else {
for (int j = 0; j < Math.max(orig.size(), rev.size()); j++) {
diffRows.add(buildDiffRow(Tag.CHANGE,
orig.getLines().size() > j ? orig.getLines().get(j) : "",
rev.getLines().size() > j ? rev.getLines().get(j) : ""));
}
}
endPos = orig.last() + 1;
}
// Copy the final matching chunk if any.
for (String line : original.subList(endPos, original.size())) {
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
}
return diffRows;
}
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
if (reportLinesUnchanged) {
return new DiffRow(type, orgline, newline);
} else {
String wrapOrg = preprocessLine(orgline);
if (Tag.DELETE == type) {
if (mergeOriginalRevised || showInlineDiffs) {
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false);
}
}
String wrapNew = preprocessLine(newline);
if (Tag.INSERT == type) {
if (mergeOriginalRevised) {
wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false);
} else if (showInlineDiffs) {
wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false);
}
}
return new DiffRow(type, wrapOrg, wrapNew);
}
}
private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) {
return new DiffRow(type,
StringUtils.wrapText(orgline, columnWidth),
StringUtils.wrapText(newline, columnWidth));
}
/**
* Add the inline diffs for given delta
*
* @param delta the given delta
*/
private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws DiffException {
List<String> orig = StringUtils.normalize(delta.getSource().getLines());
List<String> rev = StringUtils.normalize(delta.getTarget().getLines());
List<String> origList;
List<String> revList;
String joinedOrig = String.join("\n", orig);
String joinedRev = String.join("\n", rev);
origList = inlineDiffSplitter.apply(joinedOrig);
revList = inlineDiffSplitter.apply(joinedRev);
List<AbstractDelta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas();
Collections.reverse(inlineDeltas);
for (AbstractDelta<String> inlineDelta : inlineDeltas) {
Chunk<String> inlineOrig = inlineDelta.getSource();
Chunk<String> inlineRev = inlineDelta.getTarget();
if (inlineDelta instanceof DeleteDelta) {
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
.getPosition()
+ inlineOrig.size(), oldTag);
} else if (inlineDelta instanceof InsertDelta) {
if (mergeOriginalRevised) {
origList.addAll(inlineOrig.getPosition(),
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig.getPosition()
+ inlineRev.size(), newTag);
} else {
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size(), newTag);
}
} else if (inlineDelta instanceof ChangeDelta) {
if (mergeOriginalRevised) {
origList.addAll(inlineOrig.getPosition() + inlineOrig.size(),
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(), inlineOrig.getPosition() + inlineOrig.size()
+ inlineRev.size(), newTag);
} else {
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size(), newTag);
}
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
.getPosition()
+ inlineOrig.size(), oldTag);
}
}
StringBuilder origResult = new StringBuilder();
StringBuilder revResult = new StringBuilder();
for (String character : origList) {
origResult.append(character);
}
for (String character : revList) {
revResult.append(character);
}
List<String> original = Arrays.asList(origResult.toString().split("\n"));
List<String> revised = Arrays.asList(revResult.toString().split("\n"));
List<DiffRow> diffRows = new ArrayList<>();
for (int j = 0; j < Math.max(original.size(), revised.size()); j++) {
diffRows.
add(buildDiffRowWithoutNormalizing(Tag.CHANGE,
original.size() > j ? original.get(j) : "",
revised.size() > j ? revised.get(j) : ""));
}
return diffRows;
}
private String preprocessLine(String line) {
if (columnWidth == 0) {
return StringUtils.normalize(line);
} else {
return StringUtils.wrapText(StringUtils.normalize(line), columnWidth);
}
}
/**
* This class used for building the DiffRowGenerator.
*
@@ -195,246 +458,13 @@ public class DiffRowGenerator {
* deliver no in word changes.
*/
public Builder inlineDiffByWord(boolean inlineDiffByWord) {
inlineDiffSplitter = inlineDiffByWord?SPLITTER_BY_WORD:SPLITTER_BY_CHARACTER;
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
return this;
}
public Builder inlineDiffBySplitter(Function<String, List<String>> inlineDiffSplitter) {
this.inlineDiffSplitter = inlineDiffSplitter;
return this;
}
}
public static Builder create() {
return new Builder();
}
private DiffRowGenerator(Builder builder) {
showInlineDiffs = builder.showInlineDiffs;
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
oldTag = builder.oldTag;
newTag = builder.newTag;
columnWidth = builder.columnWidth;
mergeOriginalRevised = builder.mergeOriginalRevised;
inlineDiffSplitter = builder.inlineDiffSplitter;
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
reportLinesUnchanged = builder.reportLinesUnchanged;
Objects.requireNonNull(inlineDiffSplitter);
}
/**
* Get the DiffRows describing the difference between original and revised texts using the given patch. Useful for
* displaying side-by-side diff.
*
* @param original the original text
* @param revised the revised text
* @return the DiffRows between original and revised texts
*/
public List<DiffRow> generateDiffRows(List<String> original, List<String> revised) throws DiffException {
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
}
private String preprocessLine(String line) {
if (columnWidth == 0) {
return StringUtils.normalize(line);
} else {
return StringUtils.wrapText(StringUtils.normalize(line), columnWidth);
}
}
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
if (reportLinesUnchanged) {
return new DiffRow(type, orgline, newline);
} else {
String wrapOrg = preprocessLine(orgline);
if (Tag.DELETE == type) {
if (mergeOriginalRevised || showInlineDiffs) {
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false);
}
}
String wrapNew = preprocessLine(newline);
if (Tag.INSERT == type) {
if (mergeOriginalRevised) {
wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false);
} else if (showInlineDiffs) {
wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false);
}
}
return new DiffRow(type, wrapOrg, wrapNew);
}
}
private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) {
return new DiffRow(type,
StringUtils.wrapText(orgline, columnWidth),
StringUtils.wrapText(newline, columnWidth));
}
/**
* Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful
* for displaying side-by-side diff.
*
* @param original the original text
* @param revised the revised text
* @param patch the given patch
* @return the DiffRows between original and revised texts
*/
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) throws DiffException {
List<DiffRow> diffRows = new ArrayList<>();
int endPos = 0;
final List<Delta<String>> deltaList = patch.getDeltas();
for (int i = 0; i < deltaList.size(); i++) {
Delta<String> delta = deltaList.get(i);
Chunk<String> orig = delta.getOriginal();
Chunk<String> rev = delta.getRevised();
for (String line : original.subList(endPos, orig.getPosition())) {
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
}
// Inserted DiffRow
if (delta instanceof InsertDelta) {
endPos = orig.last() + 1;
for (String line : (List<String>) rev.getLines()) {
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
}
continue;
}
// Deleted DiffRow
if (delta instanceof DeleteDelta) {
endPos = orig.last() + 1;
for (String line : (List<String>) orig.getLines()) {
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
}
continue;
}
if (showInlineDiffs) {
diffRows.addAll(generateInlineDiffs(delta));
} else {
for (int j = 0; j < Math.max(orig.size(), rev.size()); j++) {
diffRows.add(buildDiffRow(Tag.CHANGE,
orig.getLines().size() > j ? orig.getLines().get(j) : "",
rev.getLines().size() > j ? rev.getLines().get(j) : ""));
}
}
endPos = orig.last() + 1;
}
// Copy the final matching chunk if any.
for (String line : original.subList(endPos, original.size())) {
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
}
return diffRows;
}
/**
* Add the inline diffs for given delta
*
* @param delta the given delta
*/
private List<DiffRow> generateInlineDiffs(Delta<String> delta) throws DiffException {
List<String> orig = StringUtils.normalize(delta.getOriginal().getLines());
List<String> rev = StringUtils.normalize(delta.getRevised().getLines());
List<String> origList;
List<String> revList;
String joinedOrig = String.join("\n", orig);
String joinedRev = String.join("\n", rev);
origList = inlineDiffSplitter.apply(joinedOrig);
revList = inlineDiffSplitter.apply(joinedRev);
List<Delta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas();
Collections.reverse(inlineDeltas);
for (Delta<String> inlineDelta : inlineDeltas) {
Chunk<String> inlineOrig = inlineDelta.getOriginal();
Chunk<String> inlineRev = inlineDelta.getRevised();
if (inlineDelta instanceof DeleteDelta) {
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
.getPosition()
+ inlineOrig.size() + 1, oldTag);
} else if (inlineDelta instanceof InsertDelta) {
if (mergeOriginalRevised) {
origList.addAll(inlineOrig.getPosition(),
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig.getPosition()
+ inlineRev.size() + 1, newTag);
} else {
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size() + 1, newTag);
}
} else if (inlineDelta instanceof ChangeDelta) {
if (mergeOriginalRevised) {
origList.addAll(inlineOrig.getPosition() + inlineOrig.size(),
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size()));
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(), inlineOrig.getPosition() + inlineOrig.size()
+ inlineRev.size() + 1, newTag);
} else {
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
+ inlineRev.size() + 1, newTag);
}
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
.getPosition()
+ inlineOrig.size() + 1, oldTag);
}
}
StringBuilder origResult = new StringBuilder();
StringBuilder revResult = new StringBuilder();
for (String character : origList) {
origResult.append(character);
}
for (String character : revList) {
revResult.append(character);
}
List<String> original = Arrays.asList(origResult.toString().split("\n"));
List<String> revised = Arrays.asList(revResult.toString().split("\n"));
List<DiffRow> diffRows = new ArrayList<>();
for (int j = 0; j < Math.max(original.size(), revised.size()); j++) {
diffRows.
add(buildDiffRowWithoutNormalizing(Tag.CHANGE,
original.size() > j ? original.get(j) : "",
revised.size() > j ? revised.get(j) : ""));
}
return diffRows;
}
/**
* Wrap the elements in the sequence with the given tag
*
* @param startPosition the position from which tag should start. The counting start from a zero.
* @param endPosition the position before which tag should should be closed.
* @param tag the tag name without angle brackets, just a word
* @param cssClass the optional css class
*/
public static void wrapInTag(List<String> sequence, int startPosition,
int endPosition, Function<Boolean, String> generator) {
sequence.add(startPosition, generator.apply(true));
sequence.add(endPosition, generator.apply(false));
}
protected final static List<String> splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) {
List<String> list = new ArrayList<>();
if (str != null) {
Matcher matcher = SPLIT_PATTERN.matcher(str);
int pos = 0;
while (matcher.find()) {
if (pos < matcher.start()) {
list.add(str.substring(pos, matcher.start()));
}
list.add(matcher.group());
pos = matcher.end();
}
if (pos < str.length()) {
list.add(str.substring(pos));
}
}
return list;
}
}

View File

@@ -1,21 +1,17 @@
/*-
* #%L
* java-diff-utils
* %%
* Copyright (C) 2009 - 2017 java-diff-utils
* %%
/*
* Copyright 2009-2017 java-diff-utils.
*
* Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
* #L%
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.difflib.text;

View File

@@ -4,7 +4,7 @@ import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.ChangeDelta;
import com.github.difflib.patch.Chunk;
import com.github.difflib.patch.DeleteDelta;
import com.github.difflib.patch.Delta;
import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.InsertDelta;
import com.github.difflib.patch.Patch;
import java.io.BufferedReader;
@@ -33,10 +33,10 @@ public class DiffUtilsTest {
asList("hhh", "jjj", "kkk"));
assertNotNull(patch);
assertEquals(1, patch.getDeltas().size());
final Delta<String> delta = patch.getDeltas().get(0);
final AbstractDelta<String> delta = patch.getDeltas().get(0);
assertTrue(delta instanceof InsertDelta);
assertEquals(new Chunk<>(1, Collections.<String>emptyList()), delta.getOriginal());
assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getRevised());
assertEquals(new Chunk<>(1, Collections.<String>emptyList()), delta.getSource());
assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getTarget());
}
@Test
@@ -45,10 +45,10 @@ public class DiffUtilsTest {
asList("ggg"));
assertNotNull(patch);
assertEquals(1, patch.getDeltas().size());
final Delta<String> delta = patch.getDeltas().get(0);
final AbstractDelta<String> delta = patch.getDeltas().get(0);
assertTrue(delta instanceof DeleteDelta);
assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getOriginal());
assertEquals(new Chunk<>(0, Collections.<String>emptyList()), delta.getRevised());
assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getSource());
assertEquals(new Chunk<>(0, Collections.<String>emptyList()), delta.getTarget());
}
@Test
@@ -59,10 +59,10 @@ public class DiffUtilsTest {
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
assertNotNull(patch);
assertEquals(1, patch.getDeltas().size());
final Delta<String> delta = patch.getDeltas().get(0);
final AbstractDelta<String> delta = patch.getDeltas().get(0);
assertTrue(delta instanceof ChangeDelta);
assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getOriginal());
assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getRevised());
assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getSource());
assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getTarget());
}
@Test
@@ -77,7 +77,7 @@ public class DiffUtilsTest {
final Patch<String> patch = DiffUtils.diff(new ArrayList<>(), Arrays.asList("aaa"));
assertNotNull(patch);
assertEquals(1, patch.getDeltas().size());
final Delta<String> delta = patch.getDeltas().get(0);
final AbstractDelta<String> delta = patch.getDeltas().get(0);
assertTrue(delta instanceof InsertDelta);
}
@@ -86,9 +86,9 @@ public class DiffUtilsTest {
final Patch<String> patch = DiffUtils.diffInline("", "test");
assertEquals(1, patch.getDeltas().size());
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition());
assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size());
assertEquals("test", patch.getDeltas().get(0).getRevised().getLines().get(0));
assertEquals(0, patch.getDeltas().get(0).getSource().getPosition());
assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size());
assertEquals("test", patch.getDeltas().get(0).getTarget().getLines().get(0));
}
@Test
@@ -96,12 +96,12 @@ public class DiffUtilsTest {
final Patch<String> patch = DiffUtils.diffInline("es", "fest");
assertEquals(2, patch.getDeltas().size());
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition());
assertEquals(2, patch.getDeltas().get(1).getOriginal().getPosition());
assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size());
assertEquals(0, patch.getDeltas().get(1).getOriginal().getLines().size());
assertEquals("f", patch.getDeltas().get(0).getRevised().getLines().get(0));
assertEquals("t", patch.getDeltas().get(1).getRevised().getLines().get(0));
assertEquals(0, patch.getDeltas().get(0).getSource().getPosition());
assertEquals(2, patch.getDeltas().get(1).getSource().getPosition());
assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size());
assertEquals(0, patch.getDeltas().get(1).getSource().getLines().size());
assertEquals("f", patch.getDeltas().get(0).getTarget().getLines().get(0));
assertEquals("t", patch.getDeltas().get(1).getTarget().getLines().get(0));
}
@Test
@@ -111,7 +111,7 @@ public class DiffUtilsTest {
final Patch<Integer> patch = DiffUtils.diff(original, revised);
for (Delta delta : patch.getDeltas()) {
for (AbstractDelta delta : patch.getDeltas()) {
System.out.println(delta);
}

View File

@@ -15,9 +15,11 @@
*/
package com.github.difflib.algorithm.jgit;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
@@ -59,7 +61,7 @@ public class HistogramDiffTest {
public void testDiff() throws DiffException, PatchFailedException {
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList));
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null));
System.out.println(patch);
assertNotNull(patch);
assertEquals(3, patch.getDeltas().size());
@@ -68,4 +70,38 @@ public class HistogramDiffTest {
List<String> patched = patch.applyTo(orgList);
assertEquals(revList, patched);
}
@Test
public void testDiffWithListener() throws DiffException, PatchFailedException {
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
List<String> logdata = new ArrayList<>();
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, new DiffAlgorithmListener() {
@Override
public void diffStart() {
logdata.add("start");
}
@Override
public void diffStep(int value, int max) {
logdata.add(value + " - " + max);
}
@Override
public void diffEnd() {
logdata.add("end");
}
}));
System.out.println(patch);
assertNotNull(patch);
assertEquals(3, patch.getDeltas().size());
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [DeleteDelta, position: 3, lines: [A, B]], [InsertDelta, position: 7, lines: [B, A, C]]]}", patch.toString());
List<String> patched = patch.applyTo(orgList);
assertEquals(revList, patched);
System.out.println(logdata);
assertEquals(17, logdata.size());
}
}

View File

@@ -17,10 +17,12 @@ package com.github.difflib.algorithm.jgit;
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
import com.github.difflib.TestConstants;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch;
import com.github.difflib.patch.PatchFailedException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;
import org.junit.After;
@@ -61,12 +63,30 @@ public class LRHistogramDiffTest {
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised));
List<String> logdata = new ArrayList<>();
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().computeDiff(original, revised, new DiffAlgorithmListener() {
@Override
public void diffStart() {
logdata.add("start");
}
@Override
public void diffStep(int value, int max) {
logdata.add(value + " - " + max);
}
@Override
public void diffEnd() {
logdata.add("end");
}
}));
assertEquals(34, patch.getDeltas().size());
List<String> created = patch.applyTo(original);
assertArrayEquals(revised.toArray(), created.toArray());
assertEquals(50, logdata.size());
}
}

View File

@@ -15,8 +15,10 @@
*/
package com.github.difflib.algorithm.myers;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Patch;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.*;
@@ -32,10 +34,40 @@ public class MyersDiffTest {
public void testDiffMyersExample1Forward() throws DiffException {
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
final Patch<String> patch = Patch.generate(original, revised, new MyersDiff<String>().diff(original, revised));
final Patch<String> patch = Patch.generate(original, revised, new MyersDiff<String>().computeDiff(original, revised, null));
assertNotNull(patch);
assertEquals(4, patch.getDeltas().size());
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
}
@Test
public void testDiffMyersExample1ForwardWithListener() throws DiffException {
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
List<String> logdata = new ArrayList<>();
final Patch<String> patch = Patch.generate(original, revised,
new MyersDiff<String>().computeDiff(original, revised, new DiffAlgorithmListener() {
@Override
public void diffStart() {
logdata.add("start");
}
@Override
public void diffStep(int value, int max) {
logdata.add(value + " - " + max);
}
@Override
public void diffEnd() {
logdata.add("end");
}
}));
assertNotNull(patch);
assertEquals(4, patch.getDeltas().size());
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
System.out.println(logdata);
assertEquals(8, logdata.size());
}
}

View File

@@ -3,7 +3,7 @@ package com.github.difflib.examples;
import com.github.difflib.DiffUtils;
import com.github.difflib.TestConstants;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.patch.Delta;
import com.github.difflib.patch.AbstractDelta;
import com.github.difflib.patch.Patch;
import java.io.File;
import java.io.IOException;
@@ -22,7 +22,7 @@ public class ComputeDifference {
// Compute diff. Get the Patch object. Patch is the container for computed deltas.
Patch<String> patch = DiffUtils.diff(original, revised);
for (Delta<String> delta : patch.getDeltas()) {
for (AbstractDelta<String> delta : patch.getDeltas()) {
System.out.println(delta);
}
}

View File

@@ -1,9 +1,13 @@
package com.github.difflib.text;
import com.github.difflib.algorithm.DiffException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
@@ -144,8 +148,8 @@ public class DiffRowGeneratorTest {
print(rows);
assertEquals(6, rows.size());
assertEquals("[CHANGE,<span class=\"editOldInline\">test,anything]", rows.get(0).toString());
assertEquals("[CHANGE,</span>anything<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
assertEquals("[CHANGE,<span class=\"editOldInline\">test</span>,anything]", rows.get(0).toString());
assertEquals("[CHANGE,anything<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(2).toString());
assertEquals("[EQUAL,other,other]", rows.get(3).toString());
assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString());
@@ -263,7 +267,7 @@ public class DiffRowGeneratorTest {
assertEquals("[CHANGE, ,]", rows.get(1).toString());
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
}
@Test
public void testGeneratorIssue14() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create()
@@ -282,4 +286,93 @@ public class DiffRowGeneratorTest {
assertEquals(1, rows.size());
assertEquals("~J. G. Feldstein~**T. P. Pastor**, Chair", rows.get(0).getOldLine());
}
@Test
public void testGeneratorIssue15() throws DiffException, IOException {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true) //show the ~ ~ and ** ** symbols on each difference
.inlineDiffByWord(true) //show the ~ ~ and ** ** around each different word instead of each letter
//.reportLinesUnchanged(true) //experiment
.oldTag(f -> "~")
.newTag(f -> "**")
.build();
List<String> listOne = Files.lines(new File("target/test-classes/mocks/issue15_1.txt").toPath())
.collect(toList());
List<String> listTwo = Files.lines(new File("target/test-classes/mocks/issue15_2.txt").toPath())
.collect(toList());
List<DiffRow> rows = generator.generateDiffRows(listOne, listTwo);
assertEquals(9, rows.size());
for (DiffRow row : rows) {
System.out.println("|" + row.getOldLine() + "| " + row.getNewLine() + " |");
if (!row.getOldLine().startsWith("TABLE_NAME")) {
assertTrue(row.getNewLine().startsWith("**ACTIONS_C16913**"));
assertTrue(row.getOldLine().startsWith("~ACTIONS_C1700"));
}
}
}
@Test
public void testGeneratorIssue22() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.inlineDiffByWord(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.build();
String aa = "This is a test senctence.";
String bb = "This is a test for diffutils.\nThis is the second line.";
List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList(aa.split("\n")),
Arrays.asList(bb.split("\n")));
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**]]",
rows.toString());
System.out.println("|original|new|");
System.out.println("|--------|---|");
for (DiffRow row : rows) {
System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
}
}
@Test
public void testGeneratorIssue22_2() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.inlineDiffByWord(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.build();
String aa = "This is a test for diffutils.\nThis is the second line.";
String bb = "This is a test senctence.";
List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList(aa.split("\n")),
Arrays.asList(bb.split("\n")));
assertEquals("[[CHANGE,This is a test ~for diffutils~.,This is a test **senctence**.], [CHANGE,~This is the second line.~,]]",
rows.toString());
}
@Test
public void testGeneratorIssue22_3() throws DiffException {
DiffRowGenerator generator = DiffRowGenerator.create()
.showInlineDiffs(true)
.inlineDiffByWord(true)
.oldTag(f -> "~")
.newTag(f -> "**")
.build();
String aa = "This is a test senctence.";
String bb = "This is a test for diffutils.\nThis is the second line.\nAnd one more.";
List<DiffRow> rows = generator.generateDiffRows(
Arrays.asList(aa.split("\n")),
Arrays.asList(bb.split("\n")));
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**], [CHANGE,,**And one more.**]]",
rows.toString());
}
}

View File

@@ -0,0 +1,9 @@
TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, NULLABLE,
ACTIONS_C17005, ID, NUMBER, 22, 19, N,
ACTIONS_C17005, ISSUEID, NUMBER, 22, 19, Y,
ACTIONS_C17005, MODIFIED, NUMBER, 22, 10, Y,
ACTIONS_C17005, TABLE, VARCHAR2, 1020, null, Y,
ACTIONS_C17005, S_NAME, CLOB, 4000, null, Y,
ACTIONS_C17008, ID, NUMBER, 22, 19, N,
ACTIONS_C17008, ISSUEID, NUMBER, 22, 19, Y,
ACTIONS_C17008, MODIFIED, NUMBER, 22, 10, Y,

View File

@@ -0,0 +1,9 @@
TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH, DATA_PRECISION, NULLABLE,
ACTIONS_C16913, ID, NUMBER, 22, 19, N,
ACTIONS_C16913, ISSUEID, NUMBER, 22, 19, Y,
ACTIONS_C16913, MODIFIED, NUMBER, 22, 10, Y,
ACTIONS_C16913, VRS, NUMBER, 22, 1, Y,
ACTIONS_C16913, ZTABS, VARCHAR2, 255, null, Y,
ACTIONS_C16913, ZTABS_S, VARCHAR2, 255, null, Y,
ACTIONS_C16913, TASK, VARCHAR2, 255, null, Y,
ACTIONS_C16913, HOURS_SPENT, VARCHAR2, 255, null, Y,