mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Compare commits
76 Commits
diffutils-
...
java-diff-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bab820483 | ||
|
|
4fe80bdf1e | ||
|
|
005ba349f8 | ||
|
|
0fbbb53b77 | ||
|
|
d5fbf5022e | ||
|
|
2c85597238 | ||
|
|
f88ce15ff8 | ||
|
|
30a23c00d1 | ||
|
|
306f92684f | ||
|
|
d4f114226d | ||
|
|
65183197c5 | ||
|
|
5c33149e2a | ||
|
|
b273da278e | ||
|
|
2671949b92 | ||
|
|
5a32ede79f | ||
|
|
5dc489a4ef | ||
|
|
f2ab70afc4 | ||
|
|
c410422860 | ||
|
|
1161243bc2 | ||
|
|
f0fe7a2137 | ||
|
|
d506d62a91 | ||
|
|
33f2d744ab | ||
|
|
696d22bd94 | ||
|
|
42780b18a8 | ||
|
|
13a1522d46 | ||
|
|
d12b13da41 | ||
|
|
c8f0624a7b | ||
|
|
54bf402a9a | ||
|
|
3a87d24632 | ||
|
|
67b26e5cab | ||
|
|
592ff058c1 | ||
|
|
553ef27e0c | ||
|
|
d1c22e7243 | ||
|
|
0d15097947 | ||
|
|
dbfdffd626 | ||
|
|
33a0b58299 | ||
|
|
db114a2c2a | ||
|
|
c001819855 | ||
|
|
c6e4059de4 | ||
|
|
653d1f9153 | ||
|
|
1214f4cf23 | ||
|
|
04832c7c9a | ||
|
|
d498a41dd3 | ||
|
|
a998d8d98b | ||
|
|
91ddcccd1e | ||
|
|
005f95ab9d | ||
|
|
1914de7e5c | ||
|
|
e630c7975a | ||
|
|
10c17b4287 | ||
|
|
08d4914a8b | ||
|
|
df3ec97df4 | ||
|
|
8c242a42ef | ||
|
|
05de2df99d | ||
|
|
0eb7b6c34f | ||
|
|
5e0d398c53 | ||
|
|
829567bace | ||
|
|
02c97e4691 | ||
|
|
4933ca5200 | ||
|
|
a65ffd95a9 | ||
|
|
dcf66dfadc | ||
|
|
244e7e7fd8 | ||
|
|
424cfcefd7 | ||
|
|
15af24ac02 | ||
|
|
0a2053f71a | ||
|
|
4f6b1839f8 | ||
|
|
5764356be2 | ||
|
|
4f6f8dbcf2 | ||
|
|
573460df9c | ||
|
|
d2a432059d | ||
|
|
90eaf2e134 | ||
|
|
e6fa5938a9 | ||
|
|
88146c6afb | ||
|
|
aed1d31c2b | ||
|
|
5d5218ba30 | ||
|
|
1107f43f36 | ||
|
|
6c91ef68df |
17
ISSUE_TEMPLATE.md
Normal file
17
ISSUE_TEMPLATE.md
Normal 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
201
LICENSE
Normal 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.
|
||||||
62
README.md
62
README.md
@@ -1,7 +1,9 @@
|
|||||||
# java-diff-utils
|
# java-diff-utils
|
||||||
|
|
||||||
## Status ##
|
## Status ##
|
||||||
[](https://travis-ci.org/wumpz/java-diff-utils) [](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)
|
[](https://travis-ci.org/java-diff-utils/java-diff-utils) [](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)
|
||||||
|
[](http://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils)
|
||||||
|
|
||||||
|
|
||||||
## Intro ##
|
## 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.
|
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,6 +52,22 @@ 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.
|
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 ###
|
### Changelog ###
|
||||||
|
* 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).
|
||||||
* Version 2.0
|
* Version 2.0
|
||||||
* switch to maven and removed other artifacts
|
* switch to maven and removed other artifacts
|
||||||
* changed groupid to **com.github.java-diff-utils** due to different forks at github
|
* changed groupid to **com.github.java-diff-utils** due to different forks at github
|
||||||
@@ -66,15 +84,49 @@ But it can easily replaced by any other which is better for handing your texts.
|
|||||||
* Ant build script
|
* Ant build script
|
||||||
* Generate output in unified diff format (thanks for Bill James)
|
* Generate output in unified diff format (thanks for Bill James)
|
||||||
|
|
||||||
### To Install ###
|
## Source Code conventions
|
||||||
|
|
||||||
**This jar is not yet to get at maven central.**
|
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,
|
||||||
|
BiPredicate<T, T> equalizer) throws DiffException {
|
||||||
|
if (equalizer != null) {
|
||||||
|
return DiffUtils.diff(original, revised,
|
||||||
|
new MyersDiff<>(equalizer));
|
||||||
|
}
|
||||||
|
return DiffUtils.diff(original, revised, new MyersDiff<>());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a valid piece of source code:
|
||||||
|
* blocks without braces are not allowed
|
||||||
|
* after control statements (if, while, for) a whitespace is expected
|
||||||
|
* the opening brace should be in the same line as the control statement
|
||||||
|
|
||||||
|
### To Install ###
|
||||||
|
|
||||||
Just add the code below to your maven dependencies:
|
Just add the code below to your maven dependencies:
|
||||||
```
|
```
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.java-diff-utils</groupId>
|
<groupId>com.github.wumpz</groupId>
|
||||||
<artifactId>diffutils</artifactId>
|
<artifactId>diffutils</artifactId>
|
||||||
<version>2.0-SNAPSHOT</version>
|
<version>3.0</version>
|
||||||
</dependency>
|
</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
1
_config.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
theme: jekyll-theme-minimal
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
|
||||||
<output url="file://$MODULE_DIR$/target/classes" />
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="module-library">
|
<orderEntry type="module-library">
|
||||||
<library>
|
<library>
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MODULE_DIR$/lib/junit.jar!/" />
|
<root url="jar://$MODULE_DIR$/lib/junit.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES />
|
<SOURCES />
|
||||||
</library>
|
</library>
|
||||||
</orderEntry>
|
</orderEntry>
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.8.1" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.8.1" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project-shared-configuration>
|
<project-shared-configuration>
|
||||||
<!--
|
<!--
|
||||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
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
|
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.
|
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.
|
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.
|
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.
|
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).
|
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.
|
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>
|
<netbeans.compile.on.save>none</netbeans.compile.on.save>
|
||||||
<com-junichi11-netbeans-changelf.enable>false</com-junichi11-netbeans-changelf.enable>
|
<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.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.lf-kind>LF</com-junichi11-netbeans-changelf.lf-kind>
|
||||||
<com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global>
|
<com-junichi11-netbeans-changelf.use-global>false</com-junichi11-netbeans-changelf.use-global>
|
||||||
|
<netbeans.hint.jdkPlatform>JDK_1.8</netbeans.hint.jdkPlatform>
|
||||||
</properties>
|
</properties>
|
||||||
</project-shared-configuration>
|
</project-shared-configuration>
|
||||||
|
|||||||
11
nbactions.xml
Normal file
11
nbactions.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<actions>
|
||||||
|
<action>
|
||||||
|
<actionName>CUSTOM-clean deploy</actionName>
|
||||||
|
<displayName>clean deploy</displayName>
|
||||||
|
<goals>
|
||||||
|
<goal>clean</goal>
|
||||||
|
<goal>deploy</goal>
|
||||||
|
</goals>
|
||||||
|
</action>
|
||||||
|
</actions>
|
||||||
153
pom.xml
153
pom.xml
@@ -1,32 +1,35 @@
|
|||||||
<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">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.github.java-diff-utils</groupId>
|
<groupId>io.github.java-diff-utils</groupId>
|
||||||
<artifactId>diffutils</artifactId>
|
<artifactId>java-diff-utils</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>2.0</version>
|
<version>4.0</version>
|
||||||
|
|
||||||
<name>java-diff-utils</name>
|
<name>java-diff-utils</name>
|
||||||
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
|
<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>
|
<url>https://github.com/java-diff-utils/java-diff-utils</url>
|
||||||
<inceptionYear>2009</inceptionYear>
|
<inceptionYear>2009</inceptionYear>
|
||||||
<!--
|
|
||||||
to make a local release
|
<distributionManagement>
|
||||||
<parent>
|
<repository>
|
||||||
<groupId>org.sonatype.oss</groupId>
|
<id>sonatype-nexus-staging</id>
|
||||||
<artifactId>oss-parent</artifactId>
|
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url>
|
||||||
<version>9</version>
|
</repository>
|
||||||
</parent>
|
<snapshotRepository>
|
||||||
-->
|
<id>sonatype-nexus-snapshots</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:git:https://github.com/wumpz/java-diff-utils.git</connection>
|
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
|
||||||
<developerConnection>scm:git:ssh://git@github.com:wumpz/java-diff-utils.git</developerConnection>
|
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
|
||||||
<url>https://github.com/wumpz/java-diff-utils.git</url>
|
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
|
||||||
<tag>diffutils-2.0</tag>
|
<tag>java-diff-utils-4.0</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
<system>GitHub Issues</system>
|
<system>GitHub Issues</system>
|
||||||
<url>https://github.com/wumpz/java-diff-utils/issues</url>
|
<url>https://github.com/java-diff-utils/java-diff-utils/issues</url>
|
||||||
</issueManagement>
|
</issueManagement>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
@@ -38,14 +41,16 @@
|
|||||||
<name>Tobias Warneke</name>
|
<name>Tobias Warneke</name>
|
||||||
<email>t.warneke@gmx.net</email>
|
<email>t.warneke@gmx.net</email>
|
||||||
</developer>
|
</developer>
|
||||||
<developer>
|
<!--
|
||||||
<name>Dmitry Naumenko</name>
|
<developer>
|
||||||
<email>dm.naumenko@gmail.com</email>
|
<name>Dmitry Naumenko</name>
|
||||||
</developer>
|
<email>dm.naumenko@gmail.com</email>
|
||||||
<developer>
|
</developer>
|
||||||
<name>Juanco Anez</name>
|
<developer>
|
||||||
<email>juanco@suigeneris.org</email>
|
<name>Juanco Anez</name>
|
||||||
</developer>
|
<email>juanco@suigeneris.org</email>
|
||||||
|
</developer>
|
||||||
|
-->
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@@ -126,6 +131,10 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
<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>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -177,12 +186,100 @@
|
|||||||
<localCheckout>true</localCheckout>
|
<localCheckout>true</localCheckout>
|
||||||
<pushChanges>false</pushChanges>
|
<pushChanges>false</pushChanges>
|
||||||
<mavenExecutorId>forked-path</mavenExecutorId>
|
<mavenExecutorId>forked-path</mavenExecutorId>
|
||||||
<goals>install</goals>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</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="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>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>sign-release-artifacts</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>performRelease</name>
|
||||||
|
<value>true</value>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<keyname>f22e0543</keyname>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>doclint-java8-disable</id>
|
<id>doclint-java8-disable</id>
|
||||||
<activation>
|
<activation>
|
||||||
|
|||||||
@@ -1,33 +1,30 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib;
|
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.DiffException;
|
||||||
import com.github.difflib.algorithm.myers.MyersDiff;
|
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.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
@@ -37,82 +34,97 @@ import static java.util.stream.Collectors.joining;
|
|||||||
* Implements the difference and patching engine
|
* Implements the difference and patching engine
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
* @version 0.4.1
|
|
||||||
*/
|
*/
|
||||||
public final class DiffUtils {
|
public final class DiffUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised list of elements with default diff
|
* Computes the difference between the original and revised list of elements with default diff algorithm
|
||||||
* algorithm
|
|
||||||
*
|
*
|
||||||
* @param original The original text. Must not be {@code null}.
|
* @param original The original text. Must not be {@code null}.
|
||||||
* @param revised The revised text. Must not be {@code null}.
|
* @param revised The revised text. Must not be {@code null}.
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never
|
* @param progress progress listener
|
||||||
* {@code null}.
|
* @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) throws DiffException {
|
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) throws DiffException {
|
||||||
return DiffUtils.diff(original, revised, new MyersDiff<>());
|
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<>(), null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised text.
|
* Computes the difference between the original and revised text.
|
||||||
*/
|
*/
|
||||||
public static Patch<String> diff(String originalText, String revisedText) throws DiffException {
|
public static Patch<String> diff(String sourceText, String targetText,
|
||||||
return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n")));
|
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
|
* Computes the difference between the original and revised list of elements with default diff algorithm
|
||||||
* algorithm
|
|
||||||
*
|
*
|
||||||
* @param original The original text. Must not be {@code null}.
|
* @param source The original text. Must not be {@code null}.
|
||||||
* @param revised The revised 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
|
* @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If {@code null}
|
||||||
* (Object.equals). If {@code null} the default equalizer of the default algorithm is used..
|
* the default equalizer of the default algorithm is used..
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never
|
* @return The patch describing the difference between the original and revised sequences. Never {@code null}.
|
||||||
* {@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 {
|
BiPredicate<T, T> equalizer) throws DiffException {
|
||||||
if (equalizer != null) {
|
if (equalizer != null) {
|
||||||
return DiffUtils.diff(original, revised,
|
return DiffUtils.diff(source, target,
|
||||||
new MyersDiff<>(equalizer));
|
new MyersDiff<>(equalizer));
|
||||||
}
|
}
|
||||||
return DiffUtils.diff(original, revised, new MyersDiff<>());
|
return DiffUtils.diff(source, target, new MyersDiff<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the difference between the original and revised list of elements with default diff
|
* Computes the difference between the original and revised list of elements with default diff algorithm
|
||||||
* algorithm
|
|
||||||
*
|
*
|
||||||
* @param original The original text. Must not be {@code null}.
|
* @param original The original text. Must not be {@code null}.
|
||||||
* @param revised The revised 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 algorithm The diff algorithm. Must not be {@code null}.
|
||||||
* @return The patch describing the difference between the original and revised sequences. Never
|
* @param progress The diff algorithm listener.
|
||||||
* {@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,
|
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(original, "original must not be null");
|
||||||
Objects.requireNonNull(revised,"revised must not be null");
|
Objects.requireNonNull(revised, "revised must not be null");
|
||||||
Objects.requireNonNull(algorithm,"algorithm 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
|
* Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of
|
||||||
* of texts lists of characters, like DiffRowGenerator does and merges those changes at the end
|
* characters, like DiffRowGenerator does and merges those changes at the end together again.
|
||||||
* together again.
|
|
||||||
*
|
*
|
||||||
* @param original
|
* @param original
|
||||||
* @param revised
|
* @param revised
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Patch<String> diffInline(String original, String revised) throws DiffException {
|
public static Patch<String> diffInline(String original, String revised) throws DiffException {
|
||||||
LinkedList<String> origList = new LinkedList<>();
|
List<String> origList = new ArrayList<>();
|
||||||
LinkedList<String> revList = new LinkedList<>();
|
List<String> revList = new ArrayList<>();
|
||||||
for (Character character : original.toCharArray()) {
|
for (Character character : original.toCharArray()) {
|
||||||
origList.add(character.toString());
|
origList.add(character.toString());
|
||||||
}
|
}
|
||||||
@@ -120,9 +132,9 @@ public final class DiffUtils {
|
|||||||
revList.add(character.toString());
|
revList.add(character.toString());
|
||||||
}
|
}
|
||||||
Patch<String> patch = DiffUtils.diff(origList, revList);
|
Patch<String> patch = DiffUtils.diff(origList, revList);
|
||||||
for (Delta<String> delta : patch.getDeltas()) {
|
for (AbstractDelta<String> delta : patch.getDeltas()) {
|
||||||
delta.getOriginal().setLines(compressLines(delta.getOriginal().getLines(), ""));
|
delta.getSource().setLines(compressLines(delta.getSource().getLines(), ""));
|
||||||
delta.getRevised().setLines(compressLines(delta.getRevised().getLines(), ""));
|
delta.getTarget().setLines(compressLines(delta.getTarget().getLines(), ""));
|
||||||
}
|
}
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ package com.github.difflib;
|
|||||||
|
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
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 com.github.difflib.patch.Patch;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -29,6 +29,7 @@ import java.util.regex.Pattern;
|
|||||||
* @author toben
|
* @author toben
|
||||||
*/
|
*/
|
||||||
public final class UnifiedDiffUtils {
|
public final class UnifiedDiffUtils {
|
||||||
|
|
||||||
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
|
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
|
||||||
.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
|
.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
|
||||||
|
|
||||||
@@ -124,42 +125,42 @@ public final class UnifiedDiffUtils {
|
|||||||
|
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format
|
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing
|
||||||
* text representing the Patch.
|
* the Patch.
|
||||||
*
|
*
|
||||||
* @param original - Filename of the original (unrevised file)
|
* @param originalFileName - Filename of the original (unrevised file)
|
||||||
* @param revised - Filename of the revised file
|
* @param revisedFileName - Filename of the revised file
|
||||||
* @param originalLines - Lines of the original file
|
* @param originalLines - Lines of the original file
|
||||||
* @param patch - Patch created by the diff() function
|
* @param patch - Patch created by the diff() function
|
||||||
* @param contextSize - number of lines of context output around each difference in the file.
|
* @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.
|
* @return List of strings representing the Unified Diff representation of the Patch argument.
|
||||||
* @author Bill James (tankerbay@gmail.com)
|
* @author Bill James (tankerbay@gmail.com)
|
||||||
*/
|
*/
|
||||||
public static List<String> generateUnifiedDiff(String original,
|
public static List<String> generateUnifiedDiff(String originalFileName,
|
||||||
String revised, List<String> originalLines, Patch<String> patch,
|
String revisedFileName, List<String> originalLines, Patch<String> patch,
|
||||||
int contextSize) {
|
int contextSize) {
|
||||||
if (!patch.getDeltas().isEmpty()) {
|
if (!patch.getDeltas().isEmpty()) {
|
||||||
List<String> ret = new ArrayList<>();
|
List<String> ret = new ArrayList<>();
|
||||||
ret.add("--- " + original);
|
ret.add("--- " + originalFileName);
|
||||||
ret.add("+++ " + revised);
|
ret.add("+++ " + revisedFileName);
|
||||||
|
|
||||||
List<Delta<String>> patchDeltas = new ArrayList<>(
|
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
||||||
patch.getDeltas());
|
patch.getDeltas());
|
||||||
|
|
||||||
// code outside the if block also works for single-delta issues.
|
// 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
|
// list
|
||||||
// of
|
// of
|
||||||
// Delta's to
|
// Delta's to
|
||||||
// process
|
// process
|
||||||
Delta<String> delta = patchDeltas.get(0);
|
AbstractDelta<String> delta = patchDeltas.get(0);
|
||||||
deltas.add(delta); // add the first Delta to the current set
|
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 there's more than 1 Delta, we may need to output them together
|
||||||
if (patchDeltas.size() > 1) {
|
if (patchDeltas.size() > 1) {
|
||||||
for (int i = 1; i < patchDeltas.size(); i++) {
|
for (int i = 1; i < patchDeltas.size(); i++) {
|
||||||
int position = delta.getOriginal().getPosition(); // store
|
int position = delta.getSource().getPosition(); // store
|
||||||
// the
|
// the
|
||||||
// current
|
// current
|
||||||
// position
|
// position
|
||||||
@@ -169,9 +170,9 @@ public final class UnifiedDiffUtils {
|
|||||||
// Check if the next Delta is too close to the current
|
// Check if the next Delta is too close to the current
|
||||||
// position.
|
// position.
|
||||||
// And if it is, add it to the current set
|
// And if it is, add it to the current set
|
||||||
Delta<String> nextDelta = patchDeltas.get(i);
|
AbstractDelta<String> nextDelta = patchDeltas.get(i);
|
||||||
if ((position + delta.getOriginal().size() + contextSize) >= (nextDelta
|
if ((position + delta.getSource().size() + contextSize) >= (nextDelta
|
||||||
.getOriginal().getPosition() - contextSize)) {
|
.getSource().getPosition() - contextSize)) {
|
||||||
deltas.add(nextDelta);
|
deltas.add(nextDelta);
|
||||||
} else {
|
} else {
|
||||||
// if it isn't, output the current set,
|
// if it isn't, output the current set,
|
||||||
@@ -195,10 +196,9 @@ public final class UnifiedDiffUtils {
|
|||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* processDeltas takes a list of Deltas and outputs them together in a single block of
|
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
|
||||||
* Unified-Diff-format text.
|
|
||||||
*
|
*
|
||||||
* @param origLines - the lines of the original file
|
* @param origLines - the lines of the original file
|
||||||
* @param deltas - the Deltas to be output as a single block
|
* @param deltas - the Deltas to be output as a single block
|
||||||
@@ -207,33 +207,33 @@ public final class UnifiedDiffUtils {
|
|||||||
* @author Bill James (tankerbay@gmail.com)
|
* @author Bill James (tankerbay@gmail.com)
|
||||||
*/
|
*/
|
||||||
private static List<String> processDeltas(List<String> origLines,
|
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<>();
|
List<String> buffer = new ArrayList<>();
|
||||||
int origTotal = 0; // counter for total lines output from Original
|
int origTotal = 0; // counter for total lines output from Original
|
||||||
int revTotal = 0; // counter for total lines output from Original
|
int revTotal = 0; // counter for total lines output from Original
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
Delta<String> curDelta = deltas.get(0);
|
AbstractDelta<String> curDelta = deltas.get(0);
|
||||||
|
|
||||||
// NOTE: +1 to overcome the 0-offset Position
|
// 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) {
|
if (origStart < 1) {
|
||||||
origStart = 1;
|
origStart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int revStart = curDelta.getRevised().getPosition() + 1 - contextSize;
|
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
||||||
if (revStart < 1) {
|
if (revStart < 1) {
|
||||||
revStart = 1;
|
revStart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the start of the wrapper context code
|
// find the start of the wrapper context code
|
||||||
int contextStart = curDelta.getOriginal().getPosition() - contextSize;
|
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
||||||
if (contextStart < 0) {
|
if (contextStart < 0) {
|
||||||
contextStart = 0; // clamp to the start of the file
|
contextStart = 0; // clamp to the start of the file
|
||||||
}
|
}
|
||||||
|
|
||||||
// output the context before the first Delta
|
// 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));
|
buffer.add(" " + origLines.get(line));
|
||||||
origTotal++;
|
origTotal++;
|
||||||
revTotal++;
|
revTotal++;
|
||||||
@@ -241,15 +241,15 @@ public final class UnifiedDiffUtils {
|
|||||||
|
|
||||||
// output the first Delta
|
// output the first Delta
|
||||||
buffer.addAll(getDeltaText(curDelta));
|
buffer.addAll(getDeltaText(curDelta));
|
||||||
origTotal += curDelta.getOriginal().getLines().size();
|
origTotal += curDelta.getSource().getLines().size();
|
||||||
revTotal += curDelta.getRevised().getLines().size();
|
revTotal += curDelta.getTarget().getLines().size();
|
||||||
|
|
||||||
int deltaIndex = 1;
|
int deltaIndex = 1;
|
||||||
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
||||||
Delta<String> nextDelta = deltas.get(deltaIndex);
|
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
||||||
int intermediateStart = curDelta.getOriginal().getPosition()
|
int intermediateStart = curDelta.getSource().getPosition()
|
||||||
+ curDelta.getOriginal().getLines().size();
|
+ curDelta.getSource().getLines().size();
|
||||||
for (line = intermediateStart; line < nextDelta.getOriginal()
|
for (line = intermediateStart; line < nextDelta.getSource()
|
||||||
.getPosition(); line++) {
|
.getPosition(); line++) {
|
||||||
// output the code between the last Delta and this one
|
// output the code between the last Delta and this one
|
||||||
buffer.add(" " + origLines.get(line));
|
buffer.add(" " + origLines.get(line));
|
||||||
@@ -257,15 +257,15 @@ public final class UnifiedDiffUtils {
|
|||||||
revTotal++;
|
revTotal++;
|
||||||
}
|
}
|
||||||
buffer.addAll(getDeltaText(nextDelta)); // output the Delta
|
buffer.addAll(getDeltaText(nextDelta)); // output the Delta
|
||||||
origTotal += nextDelta.getOriginal().getLines().size();
|
origTotal += nextDelta.getSource().getLines().size();
|
||||||
revTotal += nextDelta.getRevised().getLines().size();
|
revTotal += nextDelta.getTarget().getLines().size();
|
||||||
curDelta = nextDelta;
|
curDelta = nextDelta;
|
||||||
deltaIndex++;
|
deltaIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now output the post-Delta context code, clamping the end of the file
|
// Now output the post-Delta context code, clamping the end of the file
|
||||||
contextStart = curDelta.getOriginal().getPosition()
|
contextStart = curDelta.getSource().getPosition()
|
||||||
+ curDelta.getOriginal().getLines().size();
|
+ curDelta.getSource().getLines().size();
|
||||||
for (line = contextStart; (line < (contextStart + contextSize))
|
for (line = contextStart; (line < (contextStart + contextSize))
|
||||||
&& (line < origLines.size()); line++) {
|
&& (line < origLines.size()); line++) {
|
||||||
buffer.add(" " + origLines.get(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
|
// Create and insert the block header, conforming to the Unified Diff
|
||||||
// standard
|
// standard
|
||||||
StringBuffer header = new StringBuffer();
|
StringBuilder header = new StringBuilder();
|
||||||
header.append("@@ -");
|
header.append("@@ -");
|
||||||
header.append(origStart);
|
header.append(origStart);
|
||||||
header.append(",");
|
header.append(",");
|
||||||
@@ -289,7 +289,7 @@ public final class UnifiedDiffUtils {
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||||
*
|
*
|
||||||
@@ -297,17 +297,17 @@ public final class UnifiedDiffUtils {
|
|||||||
* @return list of String lines of code.
|
* @return list of String lines of code.
|
||||||
* @author Bill James (tankerbay@gmail.com)
|
* @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<>();
|
List<String> buffer = new ArrayList<>();
|
||||||
for (String line : delta.getOriginal().getLines()) {
|
for (String line : delta.getSource().getLines()) {
|
||||||
buffer.add("-" + line);
|
buffer.add("-" + line);
|
||||||
}
|
}
|
||||||
for (String line : delta.getRevised().getLines()) {
|
for (String line : delta.getTarget().getLines()) {
|
||||||
buffer.add("+" + line);
|
buffer.add("+" + line);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UnifiedDiffUtils() {
|
private UnifiedDiffUtils() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ import com.github.difflib.patch.DeltaType;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author toben
|
* @author <a href="t.warneke@gmx.net">Tobias Warneke</a>
|
||||||
*/
|
*/
|
||||||
public class Change {
|
public class Change {
|
||||||
|
|
||||||
public final DeltaType deltaType;
|
public final DeltaType deltaType;
|
||||||
public final int startOriginal;
|
public final int startOriginal;
|
||||||
public final int endOriginal;
|
public final int endOriginal;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,23 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm;
|
package com.github.difflib.algorithm;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown whenever the differencing engine cannot produce the differences between two revisions of
|
* Thrown whenever the differencing engine cannot produce the differences between two revisions of ta text.
|
||||||
* ta text.
|
*
|
||||||
|
|
||||||
* @see MyersDiff
|
* @see MyersDiff
|
||||||
* @see difflib.DiffAlgorithm
|
* @see difflib.DiffAlgorithm
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
package com.github.difflib.algorithm.jgit;
|
package com.github.difflib.algorithm.jgit;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.Change;
|
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.DiffException;
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -28,34 +29,40 @@ import org.eclipse.jgit.diff.Sequence;
|
|||||||
import org.eclipse.jgit.diff.SequenceComparator;
|
import org.eclipse.jgit.diff.SequenceComparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HistorgramDiff using JGit - Library. This one is much more performant than the
|
* HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers
|
||||||
* orginal Myers implementation.
|
* implementation.
|
||||||
*
|
*
|
||||||
* @author toben
|
* @author toben
|
||||||
*/
|
*/
|
||||||
public class HistogramDiff<T> implements DiffAlgorithm<T> {
|
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Change> diff(List<T> original, List<T> revised) throws DiffException {
|
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) throws DiffException {
|
||||||
Objects.requireNonNull(original, "original list must not be null");
|
Objects.requireNonNull(source, "source list must not be null");
|
||||||
Objects.requireNonNull(revised, "revised list must not be null");
|
Objects.requireNonNull(target, "target list must not be null");
|
||||||
|
if (progress != null) {
|
||||||
|
progress.diffStart();
|
||||||
|
}
|
||||||
EditList diffList = new EditList();
|
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<>();
|
List<Change> patch = new ArrayList<>();
|
||||||
for (Edit edit : diffList) {
|
for (Edit edit : diffList) {
|
||||||
DeltaType type = DeltaType.EQUAL;
|
DeltaType type = DeltaType.EQUAL;
|
||||||
switch (edit.getType()) {
|
switch (edit.getType()) {
|
||||||
case DELETE:
|
case DELETE:
|
||||||
type = DeltaType.DELETE;
|
type = DeltaType.DELETE;
|
||||||
break;
|
break;
|
||||||
case INSERT:
|
case INSERT:
|
||||||
type = DeltaType.INSERT;
|
type = DeltaType.INSERT;
|
||||||
break;
|
break;
|
||||||
case REPLACE:
|
case REPLACE:
|
||||||
type = DeltaType.CHANGE;
|
type = DeltaType.CHANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
patch.add(new Change(type,edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
|
patch.add(new Change(type, edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
|
||||||
|
}
|
||||||
|
if (progress != null) {
|
||||||
|
progress.diffEnd();
|
||||||
}
|
}
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
@@ -63,8 +70,17 @@ public class HistogramDiff<T> implements DiffAlgorithm<T> {
|
|||||||
|
|
||||||
class DataListComparator<T> extends SequenceComparator<DataList<T>> {
|
class DataListComparator<T> extends SequenceComparator<DataList<T>> {
|
||||||
|
|
||||||
|
private final DiffAlgorithmListener progress;
|
||||||
|
|
||||||
|
public DataListComparator(DiffAlgorithmListener progress) {
|
||||||
|
this.progress = progress;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(DataList<T> original, int orgIdx, DataList<T> revised, int revIdx) {
|
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));
|
return original.data.get(orgIdx).equals(revised.data.get(revIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.Change;
|
import com.github.difflib.algorithm.Change;
|
||||||
import com.github.difflib.algorithm.DifferentiationFailedException;
|
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithm;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
|
import com.github.difflib.algorithm.DifferentiationFailedException;
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -33,18 +30,16 @@ import java.util.function.BiPredicate;
|
|||||||
/**
|
/**
|
||||||
* A clean-room implementation of Eugene Myers greedy differencing algorithm.
|
* 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;
|
|
||||||
|
|
||||||
|
private final BiPredicate<T, T> DEFAULT_EQUALIZER = Object::equals;
|
||||||
|
private final BiPredicate<T, T> equalizer;
|
||||||
|
|
||||||
public MyersDiff() {
|
public MyersDiff() {
|
||||||
equalizer = DEFAULT_EQUALIZER;
|
equalizer = DEFAULT_EQUALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MyersDiff(final BiPredicate<T, T> equalizer) {
|
||||||
public MyersDiff(final BiPredicate<T,T> equalizer) {
|
|
||||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||||
this.equalizer = equalizer;
|
this.equalizer = equalizer;
|
||||||
}
|
}
|
||||||
@@ -55,25 +50,31 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
|||||||
* Return empty diff if get the error while procession the difference.
|
* Return empty diff if get the error while procession the difference.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Change> diff(final List<T> original, final List<T> revised) throws DiffException {
|
public List<Change> computeDiff(final List<T> source, final List<T> target, DiffAlgorithmListener progress) throws DiffException {
|
||||||
Objects.requireNonNull(original, "original list must not be null");
|
Objects.requireNonNull(source, "source list must not be null");
|
||||||
Objects.requireNonNull(revised, "revised list must not be null");
|
Objects.requireNonNull(target, "target list must not be null");
|
||||||
|
|
||||||
PathNode path = buildPath(original, revised);
|
if (progress != null) {
|
||||||
return buildRevision(path, original, revised);
|
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
|
* Computes the minimum diffpath that expresses de differences between the original and revised
|
||||||
* original and revised sequences, according to Gene Myers differencing
|
* sequences, according to Gene Myers differencing algorithm.
|
||||||
* algorithm.
|
|
||||||
*
|
*
|
||||||
* @param orig The original sequence.
|
* @param orig The original sequence.
|
||||||
* @param rev The revised sequence.
|
* @param rev The revised sequence.
|
||||||
* @return A minimum {@link PathNode Path} accross the differences graph.
|
* @return A minimum {@link PathNode Path} accross the differences graph.
|
||||||
* @throws DifferentiationFailedException if a diff path could not be found.
|
* @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 {
|
throws DifferentiationFailedException {
|
||||||
Objects.requireNonNull(orig, "original sequence is null");
|
Objects.requireNonNull(orig, "original sequence is null");
|
||||||
Objects.requireNonNull(rev, "revised sequence is null");
|
Objects.requireNonNull(rev, "revised sequence is null");
|
||||||
@@ -89,6 +90,9 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
|||||||
|
|
||||||
diagonal[middle + 1] = new PathNode(0, -1, true, true, null);
|
diagonal[middle + 1] = new PathNode(0, -1, true, true, null);
|
||||||
for (int d = 0; d < MAX; d++) {
|
for (int d = 0; d < MAX; d++) {
|
||||||
|
if (progress != null) {
|
||||||
|
progress.diffStep(d, MAX);
|
||||||
|
}
|
||||||
for (int k = -d; k <= d; k += 2) {
|
for (int k = -d; k <= d; k += 2) {
|
||||||
final int kmiddle = middle + k;
|
final int kmiddle = middle + k;
|
||||||
final int kplus = kmiddle + 1;
|
final int kplus = kmiddle + 1;
|
||||||
@@ -138,8 +142,8 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
|||||||
* @param orig The original sequence.
|
* @param orig The original sequence.
|
||||||
* @param rev The revised sequence.
|
* @param rev The revised sequence.
|
||||||
* @return A {@link Patch} script corresponding to the path.
|
* @return A {@link Patch} script corresponding to the path.
|
||||||
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
* @throws DifferentiationFailedException if a {@link Patch} could not be built from the given
|
||||||
* built from the given path.
|
* path.
|
||||||
*/
|
*/
|
||||||
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||||
Objects.requireNonNull(actualPath, "path is null");
|
Objects.requireNonNull(actualPath, "path is null");
|
||||||
@@ -169,18 +173,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
|||||||
} else {
|
} else {
|
||||||
changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j));
|
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()) {
|
if (path.isSnake()) {
|
||||||
path = path.prev;
|
path = path.prev;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
@@ -44,7 +40,7 @@ public final class PathNode {
|
|||||||
public final PathNode prev;
|
public final PathNode prev;
|
||||||
|
|
||||||
public final boolean snake;
|
public final boolean snake;
|
||||||
|
|
||||||
public final boolean bootstrap;
|
public final boolean bootstrap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,7 +57,7 @@ public final class PathNode {
|
|||||||
if (snake) {
|
if (snake) {
|
||||||
this.prev = prev;
|
this.prev = prev;
|
||||||
} else {
|
} else {
|
||||||
this.prev = (prev == null ? null : prev.previousSnake());
|
this.prev = prev == null ? null : prev.previousSnake();
|
||||||
}
|
}
|
||||||
this.snake = snake;
|
this.snake = snake;
|
||||||
}
|
}
|
||||||
@@ -82,11 +78,10 @@ public final class PathNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is
|
* Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is found, or the end of the
|
||||||
* found, or the end of the path is reached.
|
* path is reached.
|
||||||
*
|
*
|
||||||
* @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if
|
* @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if none found.
|
||||||
* none found.
|
|
||||||
*/
|
*/
|
||||||
public final PathNode previousSnake() {
|
public final PathNode previousSnake() {
|
||||||
if (isBootstrap()) {
|
if (isBootstrap()) {
|
||||||
|
|||||||
92
src/main/java/com/github/difflib/patch/AbstractDelta.java
Normal file
92
src/main/java/com/github/difflib/patch/AbstractDelta.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,54 +1,53 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the change-delta between original and revised texts.
|
* Describes the change-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @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.
|
* Creates a change delta with the two given chunks.
|
||||||
*
|
*
|
||||||
* @param original The original chunk. Must not be {@code null}.
|
* @param source The source chunk. Must not be {@code null}.
|
||||||
* @param revised The original chunk. Must not be {@code null}.
|
* @param target The target chunk. Must not be {@code null}.
|
||||||
*/
|
*/
|
||||||
public ChangeDelta(Chunk<T> original, Chunk<T> revised) {
|
public ChangeDelta(Chunk<T> source, Chunk<T> target) {
|
||||||
super(DeltaType.CHANGE, original, revised);
|
super(DeltaType.CHANGE, source, target);
|
||||||
|
Objects.requireNonNull(source, "source must not be null");
|
||||||
|
Objects.requireNonNull(target, "target must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyTo(List<T> target) throws PatchFailedException {
|
public void applyTo(List<T> target) throws PatchFailedException {
|
||||||
verify(target);
|
verifyChunk(target);
|
||||||
int position = getOriginal().getPosition();
|
int position = getSource().getPosition();
|
||||||
int size = getOriginal().size();
|
int size = getSource().size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (T line : getRevised().getLines()) {
|
for (T line : getTarget().getLines()) {
|
||||||
target.add(position + i, line);
|
target.add(position + i, line);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -56,13 +55,13 @@ public final class ChangeDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restore(List<T> target) {
|
public void restore(List<T> target) {
|
||||||
int position = getRevised().getPosition();
|
int position = getTarget().getPosition();
|
||||||
int size = getRevised().size();
|
int size = getTarget().size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (T line : getOriginal().getLines()) {
|
for (T line : getSource().getLines()) {
|
||||||
target.add(position + i, line);
|
target.add(position + i, line);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -70,7 +69,7 @@ public final class ChangeDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[ChangeDelta, position: " + getOriginal().getPosition() + ", lines: "
|
return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: "
|
||||||
+ getOriginal().getLines() + " to " + getRevised().getLines() + "]";
|
+ getSource().getLines() + " to " + getTarget().getLines() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,31 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the information about the part of text involved in the diff process
|
* Holds the information about the part of text involved in the diff process
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more
|
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more than plain ascci. In
|
||||||
* than plain ascci. In fact, arrays or lists of any type that implements
|
* fact, arrays or lists of any type that implements {@link java.lang.Object#hashCode hashCode()} and
|
||||||
* {@link java.lang.Object#hashCode hashCode()} and {@link java.lang.Object#equals equals()}
|
* {@link java.lang.Object#equals equals()} correctly can be subject to differencing using this library.
|
||||||
* correctly can be subject to differencing using this library.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
||||||
@@ -66,6 +62,7 @@ public final class Chunk<T> {
|
|||||||
* Verifies that this chunk's saved text matches the corresponding text in the given sequence.
|
* Verifies that this chunk's saved text matches the corresponding text in the given sequence.
|
||||||
*
|
*
|
||||||
* @param target the sequence to verify against.
|
* @param target the sequence to verify against.
|
||||||
|
* @throws com.github.difflib.patch.PatchFailedException
|
||||||
*/
|
*/
|
||||||
public void verify(List<T> target) throws PatchFailedException {
|
public void verify(List<T> target) throws PatchFailedException {
|
||||||
if (position > target.size() || last() > target.size()) {
|
if (position > target.size() || last() > target.size()) {
|
||||||
@@ -108,26 +105,11 @@ public final class Chunk<T> {
|
|||||||
return getPosition() + size() - 1;
|
return getPosition() + size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
return Objects.hash(lines, position, size());
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
|
|
||||||
result = prime * result + position;
|
|
||||||
result = prime * result + size();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
@@ -27,7 +23,7 @@ import java.util.List;
|
|||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @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 '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.
|
* Creates a change delta with the two given chunks.
|
||||||
@@ -41,18 +37,18 @@ public final class DeleteDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyTo(List<T> target) throws PatchFailedException {
|
public void applyTo(List<T> target) throws PatchFailedException {
|
||||||
verify(target);
|
verifyChunk(target);
|
||||||
int position = getOriginal().getPosition();
|
int position = getSource().getPosition();
|
||||||
int size = getOriginal().size();
|
int size = getSource().size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restore(List<T> target) {
|
public void restore(List<T> target) {
|
||||||
int position = this.getRevised().getPosition();
|
int position = this.getTarget().getPosition();
|
||||||
List<T> lines = this.getOriginal().getLines();
|
List<T> lines = this.getSource().getLines();
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
target.add(position + i, lines.get(i));
|
target.add(position + i, lines.get(i));
|
||||||
}
|
}
|
||||||
@@ -60,7 +56,7 @@ public final class DeleteDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[DeleteDelta, position: " + getOriginal().getPosition() + ", lines: "
|
return "[DeleteDelta, position: " + getSource().getPosition() + ", lines: "
|
||||||
+ getOriginal().getLines() + "]";
|
+ getSource().getLines() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -31,8 +31,7 @@ public enum DeltaType {
|
|||||||
/**
|
/**
|
||||||
* An insert into the original.
|
* An insert into the original.
|
||||||
*/
|
*/
|
||||||
INSERT,
|
INSERT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An do nothing.
|
* An do nothing.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
@@ -27,7 +23,7 @@ import java.util.List;
|
|||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @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 '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.
|
* Creates an insert delta with the two given chunks.
|
||||||
@@ -41,18 +37,18 @@ public final class InsertDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyTo(List<T> target) throws PatchFailedException {
|
public void applyTo(List<T> target) throws PatchFailedException {
|
||||||
verify(target);
|
verifyChunk(target);
|
||||||
int position = this.getOriginal().getPosition();
|
int position = this.getSource().getPosition();
|
||||||
List<T> lines = this.getRevised().getLines();
|
List<T> lines = this.getTarget().getLines();
|
||||||
for (int i = 0; i < lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
target.add(position + i, lines.get(i));
|
target.add(position + i, lines.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restore(List<T> target) {
|
public void restore(List<T> target) {
|
||||||
int position = getRevised().getPosition();
|
int position = getTarget().getPosition();
|
||||||
int size = getRevised().size();
|
int size = getTarget().size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
target.remove(position);
|
target.remove(position);
|
||||||
}
|
}
|
||||||
@@ -60,7 +56,7 @@ public final class InsertDelta<T> extends Delta<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[InsertDelta, position: " + getOriginal().getPosition()
|
return "[InsertDelta, position: " + getSource().getPosition()
|
||||||
+ ", lines: " + getRevised().getLines() + "]";
|
+ ", lines: " + getTarget().getLines() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import static com.github.difflib.patch.DeltaType.INSERT;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
@@ -37,7 +36,15 @@ import java.util.ListIterator;
|
|||||||
*/
|
*/
|
||||||
public final class Patch<T> {
|
public final class Patch<T> {
|
||||||
|
|
||||||
private final List<Delta<T>> deltas = new LinkedList<>();
|
private final List<AbstractDelta<T>> deltas;
|
||||||
|
|
||||||
|
public Patch() {
|
||||||
|
this(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Patch(int estimatedPatchSize) {
|
||||||
|
deltas = new ArrayList<>(estimatedPatchSize);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply this patch to the given target
|
* Apply this patch to the given target
|
||||||
@@ -46,10 +53,10 @@ public final class Patch<T> {
|
|||||||
* @throws PatchFailedException if can't apply patch
|
* @throws PatchFailedException if can't apply patch
|
||||||
*/
|
*/
|
||||||
public List<T> applyTo(List<T> target) throws PatchFailedException {
|
public List<T> applyTo(List<T> target) throws PatchFailedException {
|
||||||
List<T> result = new LinkedList<>(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()) {
|
while (it.hasPrevious()) {
|
||||||
Delta<T> delta = it.previous();
|
AbstractDelta<T> delta = it.previous();
|
||||||
delta.applyTo(result);
|
delta.applyTo(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -62,10 +69,10 @@ public final class Patch<T> {
|
|||||||
* @return the restored text
|
* @return the restored text
|
||||||
*/
|
*/
|
||||||
public List<T> restore(List<T> target) {
|
public List<T> restore(List<T> target) {
|
||||||
List<T> result = new LinkedList<>(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()) {
|
while (it.hasPrevious()) {
|
||||||
Delta<T> delta = it.previous();
|
AbstractDelta<T> delta = it.previous();
|
||||||
delta.restore(result);
|
delta.restore(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -76,17 +83,17 @@ public final class Patch<T> {
|
|||||||
*
|
*
|
||||||
* @param delta the given delta
|
* @param delta the given delta
|
||||||
*/
|
*/
|
||||||
public void addDelta(Delta<T> delta) {
|
public void addDelta(AbstractDelta<T> delta) {
|
||||||
deltas.add(delta);
|
deltas.add(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of computed deltas
|
* Get the list of computed deltas
|
||||||
*
|
*
|
||||||
* @return the deltas
|
* @return the deltas
|
||||||
*/
|
*/
|
||||||
public List<Delta<T>> getDeltas() {
|
public List<AbstractDelta<T>> getDeltas() {
|
||||||
Collections.sort(deltas, comparing(d -> d.getOriginal().getPosition()));
|
Collections.sort(deltas, comparing(d -> d.getSource().getPosition()));
|
||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +101,9 @@ public final class Patch<T> {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Patch{" + "deltas=" + deltas + '}';
|
return "Patch{" + "deltas=" + deltas + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
|
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
|
||||||
Patch<T> patch = new Patch<>();
|
Patch<T> patch = new Patch<>(changes.size());
|
||||||
for (Change change : changes) {
|
for (Change change : changes) {
|
||||||
Chunk<T> orgChunk = new Chunk<>(change.startOriginal, new ArrayList<>(original.subList(change.startOriginal, change.endOriginal)));
|
Chunk<T> orgChunk = new Chunk<>(change.startOriginal, new ArrayList<>(original.subList(change.startOriginal, change.endOriginal)));
|
||||||
Chunk<T> revChunk = new Chunk<>(change.startRevised, new ArrayList<>(revised.subList(change.startRevised, change.endRevised)));
|
Chunk<T> revChunk = new Chunk<>(change.startRevised, new ArrayList<>(revised.subList(change.startRevised, change.endRevised)));
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,25 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two
|
* Describes the diff row in form [tag, oldLine, newLine) for showing the difference between two texts
|
||||||
* texts
|
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
*/
|
*/
|
||||||
@@ -71,26 +67,11 @@ public final class DiffRow implements Serializable {
|
|||||||
return newLine;
|
return newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
return Objects.hash(newLine, oldLine, tag);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
|||||||
@@ -1,30 +1,26 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import com.github.difflib.DiffUtils;
|
import com.github.difflib.DiffUtils;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
import com.github.difflib.patch.Chunk;
|
||||||
import com.github.difflib.patch.DeleteDelta;
|
import com.github.difflib.patch.DeleteDelta;
|
||||||
import com.github.difflib.patch.Delta;
|
|
||||||
import com.github.difflib.patch.InsertDelta;
|
import com.github.difflib.patch.InsertDelta;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.text.DiffRow.Tag;
|
import com.github.difflib.text.DiffRow.Tag;
|
||||||
@@ -35,146 +31,123 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class for generating DiffRows for side-by-sidy view. You can customize the way of
|
* This class for generating DiffRows for side-by-sidy view. You can customize the way of generating. For example, show
|
||||||
* generating. For example, show inline diffs on not, ignoring white spaces or/and blank lines and
|
* inline diffs on not, ignoring white spaces or/and blank lines and so on. All parameters for generating are optional.
|
||||||
* so on. All parameters for generating are optional. If you do not specify them, the class will use
|
* If you do not specify them, the class will use the default values.
|
||||||
* the default values.
|
|
||||||
*
|
*
|
||||||
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ...
|
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ...
|
||||||
*
|
*
|
||||||
* For instantiating the DiffRowGenerator you should use the its builder. Like in example <code>
|
* For instantiating the DiffRowGenerator you should use the its builder. Like in example <code>
|
||||||
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
|
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
|
||||||
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
public class DiffRowGenerator {
|
public class DiffRowGenerator {
|
||||||
|
|
||||||
public static final BiPredicate<String,String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
|
||||||
-> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " "));
|
|
||||||
public static final BiPredicate<String,String> DEFAULT_EQUALIZER = Object::equals;
|
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
||||||
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
|
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
|
||||||
private final boolean showInlineDiffs;
|
|
||||||
private final boolean ignoreWhiteSpaces;
|
|
||||||
private final Function<Boolean, String> oldTag;
|
|
||||||
private final Function<Boolean, String> newTag;
|
|
||||||
private final boolean inlineDiffByWord;
|
|
||||||
private final int columnWidth;
|
|
||||||
private final BiPredicate<String, String> equalizer;
|
|
||||||
private final boolean mergeOriginalRevised;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class used for building the DiffRowGenerator.
|
* Splitting lines by character to achieve char by char diff checking.
|
||||||
*
|
|
||||||
* @author dmitry
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static final Function<String, List<String>> SPLITTER_BY_CHARACTER = line -> {
|
||||||
|
List<String> list = new ArrayList<>(line.length());
|
||||||
private boolean showInlineDiffs = false;
|
for (Character character : line.toCharArray()) {
|
||||||
private boolean ignoreWhiteSpaces = false;
|
list.add(character.toString());
|
||||||
|
|
||||||
private Function<Boolean, String> oldTag = f -> f ? "<span class=\"editOldInline\">" : "</span>";
|
|
||||||
private Function<Boolean, String> newTag = f -> f ? "<span class=\"editNewInline\">" : "</span>";
|
|
||||||
|
|
||||||
private int columnWidth = 80;
|
|
||||||
private boolean mergeOriginalRevised = false;
|
|
||||||
private boolean inlineDiffByWord = false;
|
|
||||||
|
|
||||||
private Builder() {
|
|
||||||
}
|
}
|
||||||
|
return list;
|
||||||
/**
|
};
|
||||||
* Show inline diffs in generating diff rows or not.
|
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
|
||||||
*
|
/**
|
||||||
* @param val the value to set. Default: false.
|
* Splitting lines by word to achieve word by word diff checking.
|
||||||
* @return builder with configured showInlineDiff parameter
|
*/
|
||||||
*/
|
public static final Function<String, List<String>> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN);
|
||||||
public Builder showInlineDiffs(boolean val) {
|
public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
|
||||||
showInlineDiffs = val;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ignore white spaces in generating diff rows or not.
|
|
||||||
*
|
|
||||||
* @param val the value to set. Default: true.
|
|
||||||
* @return builder with configured ignoreWhiteSpaces parameter
|
|
||||||
*/
|
|
||||||
public Builder ignoreWhiteSpaces(boolean val) {
|
|
||||||
ignoreWhiteSpaces = val;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generator for Old-Text-Tags.
|
|
||||||
*
|
|
||||||
* @param tag the tag to set. Without angle brackets. Default: span.
|
|
||||||
* @return builder with configured ignoreBlankLines parameter
|
|
||||||
*/
|
|
||||||
public Builder oldTag(Function<Boolean, String> generator) {
|
|
||||||
this.oldTag = generator;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generator for New-Text-Tags.
|
|
||||||
*
|
|
||||||
* @param generator
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Builder newTag(Function<Boolean, String> generator) {
|
|
||||||
this.newTag = generator;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the column with of generated lines of original and revised texts.
|
|
||||||
*
|
|
||||||
* @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return
|
|
||||||
* builder with config ured ignoreBlankLines parameter
|
|
||||||
*/
|
|
||||||
public Builder columnWidth(int width) {
|
|
||||||
if (width > 0) {
|
|
||||||
columnWidth = width;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build the DiffRowGenerator. If some parameters is not set, the default values are used.
|
|
||||||
*
|
|
||||||
* @return the customized DiffRowGenerator
|
|
||||||
*/
|
|
||||||
public DiffRowGenerator build() {
|
|
||||||
return new DiffRowGenerator(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge the complete result within the original text. This makes sense for one line
|
|
||||||
* display.
|
|
||||||
*
|
|
||||||
* @param mergeOriginalRevised
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Builder mergeOriginalRevised(boolean mergeOriginalRevised) {
|
|
||||||
this.mergeOriginalRevised = mergeOriginalRevised;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Per default each character is separatly processed. This variant introduces processing by
|
|
||||||
* word, which should deliver no in word changes.
|
|
||||||
*/
|
|
||||||
public Builder inlineDiffByWord(boolean inlineDiffByWord) {
|
|
||||||
this.inlineDiffByWord = inlineDiffByWord;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder create() {
|
public static Builder create() {
|
||||||
return new Builder();
|
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) {
|
private DiffRowGenerator(Builder builder) {
|
||||||
showInlineDiffs = builder.showInlineDiffs;
|
showInlineDiffs = builder.showInlineDiffs;
|
||||||
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
|
ignoreWhiteSpaces = builder.ignoreWhiteSpaces;
|
||||||
@@ -182,13 +155,16 @@ public class DiffRowGenerator {
|
|||||||
newTag = builder.newTag;
|
newTag = builder.newTag;
|
||||||
columnWidth = builder.columnWidth;
|
columnWidth = builder.columnWidth;
|
||||||
mergeOriginalRevised = builder.mergeOriginalRevised;
|
mergeOriginalRevised = builder.mergeOriginalRevised;
|
||||||
inlineDiffByWord = builder.inlineDiffByWord;
|
inlineDiffSplitter = builder.inlineDiffSplitter;
|
||||||
equalizer = ignoreWhiteSpaces?IGNORE_WHITESPACE_EQUALIZER:DEFAULT_EQUALIZER;
|
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
|
* Get the DiffRows describing the difference between original and revised texts using the given patch. Useful for
|
||||||
* patch. Useful for displaying side-by-side diff.
|
* displaying side-by-side diff.
|
||||||
*
|
*
|
||||||
* @param original the original text
|
* @param original the original text
|
||||||
* @param revised the revised text
|
* @param revised the revised text
|
||||||
@@ -198,33 +174,9 @@ public class DiffRowGenerator {
|
|||||||
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
|
return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer));
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
|
|
||||||
String wrapOrg = StringUtils.wrapText(StringUtils.normalize(orgline), columnWidth);
|
|
||||||
if (Tag.DELETE == type) {
|
|
||||||
if (mergeOriginalRevised || showInlineDiffs) {
|
|
||||||
wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String wrapNew = StringUtils.wrapText(StringUtils.normalize(newline), columnWidth);
|
|
||||||
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
|
* Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful
|
||||||
* given patch. Useful for displaying side-by-side diff.
|
* for displaying side-by-side diff.
|
||||||
*
|
*
|
||||||
* @param original the original text
|
* @param original the original text
|
||||||
* @param revised the revised text
|
* @param revised the revised text
|
||||||
@@ -234,11 +186,11 @@ public class DiffRowGenerator {
|
|||||||
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) throws DiffException {
|
public List<DiffRow> generateDiffRows(final List<String> original, Patch<String> patch) throws DiffException {
|
||||||
List<DiffRow> diffRows = new ArrayList<>();
|
List<DiffRow> diffRows = new ArrayList<>();
|
||||||
int endPos = 0;
|
int endPos = 0;
|
||||||
final List<Delta<String>> deltaList = patch.getDeltas();
|
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
||||||
for (int i = 0; i < deltaList.size(); i++) {
|
for (int i = 0; i < deltaList.size(); i++) {
|
||||||
Delta<String> delta = deltaList.get(i);
|
AbstractDelta<String> delta = deltaList.get(i);
|
||||||
Chunk<String> orig = delta.getOriginal();
|
Chunk<String> orig = delta.getSource();
|
||||||
Chunk<String> rev = delta.getRevised();
|
Chunk<String> rev = delta.getTarget();
|
||||||
|
|
||||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||||
@@ -281,51 +233,70 @@ public class DiffRowGenerator {
|
|||||||
return diffRows;
|
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
|
* Add the inline diffs for given delta
|
||||||
*
|
*
|
||||||
* @param delta the given delta
|
* @param delta the given delta
|
||||||
*/
|
*/
|
||||||
private List<DiffRow> generateInlineDiffs(Delta<String> delta) throws DiffException {
|
private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws DiffException {
|
||||||
List<String> orig = StringUtils.normalize(delta.getOriginal().getLines());
|
List<String> orig = StringUtils.normalize(delta.getSource().getLines());
|
||||||
List<String> rev = StringUtils.normalize(delta.getRevised().getLines());
|
List<String> rev = StringUtils.normalize(delta.getTarget().getLines());
|
||||||
List<String> origList;
|
List<String> origList;
|
||||||
List<String> revList;
|
List<String> revList;
|
||||||
|
String joinedOrig = String.join("\n", orig);
|
||||||
|
String joinedRev = String.join("\n", rev);
|
||||||
|
|
||||||
if (inlineDiffByWord) {
|
origList = inlineDiffSplitter.apply(joinedOrig);
|
||||||
origList = splitStringPreserveDelimiter(String.join("\n", orig));
|
revList = inlineDiffSplitter.apply(joinedRev);
|
||||||
revList = splitStringPreserveDelimiter(String.join("\n", rev));
|
|
||||||
} else {
|
|
||||||
origList = new LinkedList<>();
|
|
||||||
revList = new LinkedList<>();
|
|
||||||
for (Character character : String.join("\n", orig).toCharArray()) {
|
|
||||||
origList.add(character.toString());
|
|
||||||
}
|
|
||||||
for (Character character : String.join("\n", rev).toCharArray()) {
|
|
||||||
revList.add(character.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Delta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas();
|
List<AbstractDelta<String>> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas();
|
||||||
|
|
||||||
Collections.reverse(inlineDeltas);
|
Collections.reverse(inlineDeltas);
|
||||||
for (Delta<String> inlineDelta : inlineDeltas) {
|
for (AbstractDelta<String> inlineDelta : inlineDeltas) {
|
||||||
Chunk<String> inlineOrig = inlineDelta.getOriginal();
|
Chunk<String> inlineOrig = inlineDelta.getSource();
|
||||||
Chunk<String> inlineRev = inlineDelta.getRevised();
|
Chunk<String> inlineRev = inlineDelta.getTarget();
|
||||||
if (inlineDelta instanceof DeleteDelta) {
|
if (inlineDelta instanceof DeleteDelta) {
|
||||||
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
||||||
.getPosition()
|
.getPosition()
|
||||||
+ inlineOrig.size() + 1, oldTag);
|
+ inlineOrig.size(), oldTag);
|
||||||
} else if (inlineDelta instanceof InsertDelta) {
|
} else if (inlineDelta instanceof InsertDelta) {
|
||||||
if (mergeOriginalRevised) {
|
if (mergeOriginalRevised) {
|
||||||
origList.addAll(inlineOrig.getPosition(),
|
origList.addAll(inlineOrig.getPosition(),
|
||||||
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
|
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
|
||||||
+ inlineRev.size()));
|
+ inlineRev.size()));
|
||||||
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig.getPosition()
|
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig.getPosition()
|
||||||
+ inlineRev.size() + 1, newTag);
|
+ inlineRev.size(), newTag);
|
||||||
} else {
|
} else {
|
||||||
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
||||||
+ inlineRev.size() + 1, newTag);
|
+ inlineRev.size(), newTag);
|
||||||
}
|
}
|
||||||
} else if (inlineDelta instanceof ChangeDelta) {
|
} else if (inlineDelta instanceof ChangeDelta) {
|
||||||
if (mergeOriginalRevised) {
|
if (mergeOriginalRevised) {
|
||||||
@@ -333,14 +304,14 @@ public class DiffRowGenerator {
|
|||||||
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
|
revList.subList(inlineRev.getPosition(), inlineRev.getPosition()
|
||||||
+ inlineRev.size()));
|
+ inlineRev.size()));
|
||||||
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(), inlineOrig.getPosition() + inlineOrig.size()
|
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(), inlineOrig.getPosition() + inlineOrig.size()
|
||||||
+ inlineRev.size() + 1, newTag);
|
+ inlineRev.size(), newTag);
|
||||||
} else {
|
} else {
|
||||||
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition()
|
||||||
+ inlineRev.size() + 1, newTag);
|
+ inlineRev.size(), newTag);
|
||||||
}
|
}
|
||||||
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
||||||
.getPosition()
|
.getPosition()
|
||||||
+ inlineOrig.size() + 1, oldTag);
|
+ inlineOrig.size(), oldTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StringBuilder origResult = new StringBuilder();
|
StringBuilder origResult = new StringBuilder();
|
||||||
@@ -364,37 +335,136 @@ public class DiffRowGenerator {
|
|||||||
return diffRows;
|
return diffRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String preprocessLine(String line) {
|
||||||
* Wrap the elements in the sequence with the given tag
|
if (columnWidth == 0) {
|
||||||
*
|
return StringUtils.normalize(line);
|
||||||
* @param startPosition the position from which tag should start. The counting start from a
|
} else {
|
||||||
* zero.
|
return StringUtils.wrapText(StringUtils.normalize(line), columnWidth);
|
||||||
* @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) {
|
/**
|
||||||
List<String> list = new ArrayList<>();
|
* This class used for building the DiffRowGenerator.
|
||||||
if (str != null) {
|
*
|
||||||
Matcher matcher = SPLIT_PATTERN.matcher(str);
|
* @author dmitry
|
||||||
int pos = 0;
|
*
|
||||||
while (matcher.find()) {
|
*/
|
||||||
if (pos < matcher.start()) {
|
public static class Builder {
|
||||||
list.add(str.substring(pos, matcher.start()));
|
|
||||||
}
|
private boolean showInlineDiffs = false;
|
||||||
list.add(matcher.group());
|
private boolean ignoreWhiteSpaces = false;
|
||||||
pos = matcher.end();
|
|
||||||
}
|
private Function<Boolean, String> oldTag = f -> f ? "<span class=\"editOldInline\">" : "</span>";
|
||||||
if (pos < str.length()) {
|
private Function<Boolean, String> newTag = f -> f ? "<span class=\"editNewInline\">" : "</span>";
|
||||||
list.add(str.substring(pos));
|
|
||||||
}
|
private int columnWidth = 0;
|
||||||
|
private boolean mergeOriginalRevised = false;
|
||||||
|
private boolean reportLinesUnchanged = false;
|
||||||
|
private Function<String, List<String>> inlineDiffSplitter = SPLITTER_BY_CHARACTER;
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show inline diffs in generating diff rows or not.
|
||||||
|
*
|
||||||
|
* @param val the value to set. Default: false.
|
||||||
|
* @return builder with configured showInlineDiff parameter
|
||||||
|
*/
|
||||||
|
public Builder showInlineDiffs(boolean val) {
|
||||||
|
showInlineDiffs = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore white spaces in generating diff rows or not.
|
||||||
|
*
|
||||||
|
* @param val the value to set. Default: true.
|
||||||
|
* @return builder with configured ignoreWhiteSpaces parameter
|
||||||
|
*/
|
||||||
|
public Builder ignoreWhiteSpaces(boolean val) {
|
||||||
|
ignoreWhiteSpaces = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give the originial old and new text lines to Diffrow without any additional processing.
|
||||||
|
*
|
||||||
|
* @param val the value to set. Default: false.
|
||||||
|
* @return builder with configured reportLinesUnWrapped parameter
|
||||||
|
*/
|
||||||
|
public Builder reportLinesUnchanged(final boolean val) {
|
||||||
|
reportLinesUnchanged = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generator for Old-Text-Tags.
|
||||||
|
*
|
||||||
|
* @param tag the tag to set. Without angle brackets. Default: span.
|
||||||
|
* @return builder with configured ignoreBlankLines parameter
|
||||||
|
*/
|
||||||
|
public Builder oldTag(Function<Boolean, String> generator) {
|
||||||
|
this.oldTag = generator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generator for New-Text-Tags.
|
||||||
|
*
|
||||||
|
* @param generator
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder newTag(Function<Boolean, String> generator) {
|
||||||
|
this.newTag = generator;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the column with of generated lines of original and revised texts.
|
||||||
|
*
|
||||||
|
* @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return builder with config
|
||||||
|
* ured ignoreBlankLines parameter
|
||||||
|
*/
|
||||||
|
public Builder columnWidth(int width) {
|
||||||
|
if (width >= 0) {
|
||||||
|
columnWidth = width;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the DiffRowGenerator. If some parameters is not set, the default values are used.
|
||||||
|
*
|
||||||
|
* @return the customized DiffRowGenerator
|
||||||
|
*/
|
||||||
|
public DiffRowGenerator build() {
|
||||||
|
return new DiffRowGenerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge the complete result within the original text. This makes sense for one line display.
|
||||||
|
*
|
||||||
|
* @param mergeOriginalRevised
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder mergeOriginalRevised(boolean mergeOriginalRevised) {
|
||||||
|
this.mergeOriginalRevised = mergeOriginalRevised;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per default each character is separatly processed. This variant introduces processing by word, which should
|
||||||
|
* deliver no in word changes.
|
||||||
|
*/
|
||||||
|
public Builder inlineDiffByWord(boolean inlineDiffByWord) {
|
||||||
|
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder inlineDiffBySplitter(Function<String, List<String>> inlineDiffSplitter) {
|
||||||
|
this.inlineDiffSplitter = inlineDiffSplitter;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
/*-
|
/*
|
||||||
* #%L
|
* Copyright 2009-2017 java-diff-utils.
|
||||||
* java-diff-utils
|
*
|
||||||
* %%
|
|
||||||
* Copyright (C) 2009 - 2017 java-diff-utils
|
|
||||||
* %%
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
|
||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
@@ -58,8 +54,11 @@ final class StringUtils {
|
|||||||
* @return the wrapped text
|
* @return the wrapped text
|
||||||
*/
|
*/
|
||||||
public static String wrapText(String line, int columnWidth) {
|
public static String wrapText(String line, int columnWidth) {
|
||||||
if (columnWidth <= 0) {
|
if (columnWidth < 0) {
|
||||||
throw new IllegalArgumentException("columnWidth may not be less or equal 0");
|
throw new IllegalArgumentException("columnWidth may not be less 0");
|
||||||
|
}
|
||||||
|
if (columnWidth == 0) {
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
int length = line.length();
|
int length = line.length();
|
||||||
int delimiter = "<br/>".length();
|
int delimiter = "<br/>".length();
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.github.difflib;
|
package com.github.difflib;
|
||||||
|
|
||||||
import com.github.difflib.DiffUtils;
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import com.github.difflib.patch.ChangeDelta;
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
import com.github.difflib.patch.Chunk;
|
import com.github.difflib.patch.Chunk;
|
||||||
import com.github.difflib.patch.DeleteDelta;
|
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.InsertDelta;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -34,10 +33,10 @@ public class DiffUtilsTest {
|
|||||||
asList("hhh", "jjj", "kkk"));
|
asList("hhh", "jjj", "kkk"));
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(1, patch.getDeltas().size());
|
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);
|
assertTrue(delta instanceof InsertDelta);
|
||||||
assertEquals(new Chunk<>(1, Collections.<String>emptyList()), delta.getOriginal());
|
assertEquals(new Chunk<>(1, Collections.<String>emptyList()), delta.getSource());
|
||||||
assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getRevised());
|
assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -46,10 +45,10 @@ public class DiffUtilsTest {
|
|||||||
asList("ggg"));
|
asList("ggg"));
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(1, patch.getDeltas().size());
|
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);
|
assertTrue(delta instanceof DeleteDelta);
|
||||||
assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getOriginal());
|
assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getSource());
|
||||||
assertEquals(new Chunk<>(0, Collections.<String>emptyList()), delta.getRevised());
|
assertEquals(new Chunk<>(0, Collections.<String>emptyList()), delta.getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -60,10 +59,10 @@ public class DiffUtilsTest {
|
|||||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(1, patch.getDeltas().size());
|
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);
|
assertTrue(delta instanceof ChangeDelta);
|
||||||
assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getOriginal());
|
assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getSource());
|
||||||
assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getRevised());
|
assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -78,7 +77,7 @@ public class DiffUtilsTest {
|
|||||||
final Patch<String> patch = DiffUtils.diff(new ArrayList<>(), Arrays.asList("aaa"));
|
final Patch<String> patch = DiffUtils.diff(new ArrayList<>(), Arrays.asList("aaa"));
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(1, patch.getDeltas().size());
|
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);
|
assertTrue(delta instanceof InsertDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,9 +86,9 @@ public class DiffUtilsTest {
|
|||||||
final Patch<String> patch = DiffUtils.diffInline("", "test");
|
final Patch<String> patch = DiffUtils.diffInline("", "test");
|
||||||
assertEquals(1, patch.getDeltas().size());
|
assertEquals(1, patch.getDeltas().size());
|
||||||
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
|
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
|
||||||
assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition());
|
assertEquals(0, patch.getDeltas().get(0).getSource().getPosition());
|
||||||
assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size());
|
assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size());
|
||||||
assertEquals("test", patch.getDeltas().get(0).getRevised().getLines().get(0));
|
assertEquals("test", patch.getDeltas().get(0).getTarget().getLines().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -97,12 +96,12 @@ public class DiffUtilsTest {
|
|||||||
final Patch<String> patch = DiffUtils.diffInline("es", "fest");
|
final Patch<String> patch = DiffUtils.diffInline("es", "fest");
|
||||||
assertEquals(2, patch.getDeltas().size());
|
assertEquals(2, patch.getDeltas().size());
|
||||||
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
|
assertTrue(patch.getDeltas().get(0) instanceof InsertDelta);
|
||||||
assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition());
|
assertEquals(0, patch.getDeltas().get(0).getSource().getPosition());
|
||||||
assertEquals(2, patch.getDeltas().get(1).getOriginal().getPosition());
|
assertEquals(2, patch.getDeltas().get(1).getSource().getPosition());
|
||||||
assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size());
|
assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size());
|
||||||
assertEquals(0, patch.getDeltas().get(1).getOriginal().getLines().size());
|
assertEquals(0, patch.getDeltas().get(1).getSource().getLines().size());
|
||||||
assertEquals("f", patch.getDeltas().get(0).getRevised().getLines().get(0));
|
assertEquals("f", patch.getDeltas().get(0).getTarget().getLines().get(0));
|
||||||
assertEquals("t", patch.getDeltas().get(1).getRevised().getLines().get(0));
|
assertEquals("t", patch.getDeltas().get(1).getTarget().getLines().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -112,7 +111,7 @@ public class DiffUtilsTest {
|
|||||||
|
|
||||||
final Patch<Integer> patch = DiffUtils.diff(original, revised);
|
final Patch<Integer> patch = DiffUtils.diff(original, revised);
|
||||||
|
|
||||||
for (Delta delta : patch.getDeltas()) {
|
for (AbstractDelta delta : patch.getDeltas()) {
|
||||||
System.out.println(delta);
|
System.out.println(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,25 +137,25 @@ public class DiffUtilsTest {
|
|||||||
@Ignore
|
@Ignore
|
||||||
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException {
|
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException {
|
||||||
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
|
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
|
||||||
|
|
||||||
Patch<String> patch = DiffUtils.diff(
|
Patch<String> patch = DiffUtils.diff(
|
||||||
readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))),
|
readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))),
|
||||||
readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))));
|
readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))));
|
||||||
|
|
||||||
assertEquals(1, patch.getDeltas().size());
|
assertEquals(1, patch.getDeltas().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> readStringListFromInputStream(InputStream is) throws IOException {
|
public static List<String> readStringListFromInputStream(InputStream is) throws IOException {
|
||||||
try (BufferedReader reader = new BufferedReader(
|
try (BufferedReader reader = new BufferedReader(
|
||||||
new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) {
|
new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) {
|
||||||
|
|
||||||
return reader.lines().collect(toList());
|
return reader.lines().collect(toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDiffMyersExample1() throws DiffException {
|
public void testDiffMyersExample1() throws DiffException {
|
||||||
final Patch<String> patch = DiffUtils.diff(Arrays.asList("A","B","C","A","B","B","A"), Arrays.asList("C","B","A","B","A","C"));
|
final Patch<String> patch = DiffUtils.diff(Arrays.asList("A", "B", "C", "A", "B", "B", "A"), Arrays.asList("C", "B", "A", "B", "A", "C"));
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(4, patch.getDeltas().size());
|
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());
|
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());
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.github.difflib;
|
package com.github.difflib;
|
||||||
|
|
||||||
import com.github.difflib.DiffUtils;
|
|
||||||
import com.github.difflib.UnifiedDiffUtils;
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package com.github.difflib;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class TestConstants {
|
public final class TestConstants {
|
||||||
|
|
||||||
public static final String BASE_FOLDER_RESOURCES = "target/test-classes/";
|
public static final String BASE_FOLDER_RESOURCES = "target/test-classes/";
|
||||||
/**
|
/**
|
||||||
* The base folder containing the test files. Ends with {@link #FS}.
|
* The base folder containing the test files. Ends with {@link #FS}.
|
||||||
|
|||||||
@@ -15,44 +15,41 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.jgit;
|
package com.github.difflib.algorithm.jgit;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.jgit.HistogramDiff;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
|
|
||||||
import com.github.difflib.TestConstants;
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
import java.io.IOException;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipFile;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author toben
|
* @author toben
|
||||||
*/
|
*/
|
||||||
public class HistogramDiffTest {
|
public class HistogramDiffTest {
|
||||||
|
|
||||||
public HistogramDiffTest() {
|
public HistogramDiffTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() {
|
public static void setUpClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDownClass() {
|
public static void tearDownClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
@@ -62,15 +59,49 @@ public class HistogramDiffTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDiff() throws DiffException, PatchFailedException {
|
public void testDiff() throws DiffException, PatchFailedException {
|
||||||
List<String> orgList = Arrays.asList("A","B","C","A","B","B","A");
|
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> 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);
|
System.out.println(patch);
|
||||||
assertNotNull(patch);
|
assertNotNull(patch);
|
||||||
assertEquals(3, patch.getDeltas().size());
|
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());
|
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);
|
List<String> patched = patch.applyTo(orgList);
|
||||||
assertEquals(revList, patched);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,61 +15,78 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.jgit;
|
package com.github.difflib.algorithm.jgit;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.jgit.HistogramDiff;
|
|
||||||
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
|
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
|
||||||
import com.github.difflib.TestConstants;
|
import com.github.difflib.TestConstants;
|
||||||
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author toben
|
* @author toben
|
||||||
*/
|
*/
|
||||||
public class LRHistogramDiffTest {
|
public class LRHistogramDiffTest {
|
||||||
|
|
||||||
public LRHistogramDiffTest() {
|
public LRHistogramDiffTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() {
|
public static void setUpClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDownClass() {
|
public static void tearDownClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException, PatchFailedException {
|
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException, PatchFailedException {
|
||||||
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
|
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
|
||||||
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
||||||
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
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());
|
assertEquals(34, patch.getDeltas().size());
|
||||||
|
|
||||||
List<String> created = patch.applyTo(original);
|
List<String> created = patch.applyTo(original);
|
||||||
assertArrayEquals(revised.toArray(), created.toArray());
|
assertArrayEquals(revised.toArray(), created.toArray());
|
||||||
|
|
||||||
|
assertEquals(50, logdata.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,18 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.myers;
|
package com.github.difflib.algorithm.myers;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.myers.MyersDiff;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.DiffUtils;
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.AfterClass;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -38,10 +34,40 @@ public class MyersDiffTest {
|
|||||||
public void testDiffMyersExample1Forward() throws DiffException {
|
public void testDiffMyersExample1Forward() throws DiffException {
|
||||||
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
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> 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);
|
assertNotNull(patch);
|
||||||
assertEquals(4, patch.getDeltas().size());
|
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());
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.github.difflib.examples;
|
|||||||
import com.github.difflib.DiffUtils;
|
import com.github.difflib.DiffUtils;
|
||||||
import com.github.difflib.TestConstants;
|
import com.github.difflib.TestConstants;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
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 com.github.difflib.patch.Patch;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -22,7 +22,7 @@ public class ComputeDifference {
|
|||||||
// Compute diff. Get the Patch object. Patch is the container for computed deltas.
|
// Compute diff. Get the Patch object. Patch is the container for computed deltas.
|
||||||
Patch<String> patch = DiffUtils.diff(original, revised);
|
Patch<String> patch = DiffUtils.diff(original, revised);
|
||||||
|
|
||||||
for (Delta<String> delta : patch.getDeltas()) {
|
for (AbstractDelta<String> delta : patch.getDeltas()) {
|
||||||
System.out.println(delta);
|
System.out.println(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import com.github.difflib.patch.Patch;
|
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
|
||||||
import com.github.difflib.DiffUtils;
|
import com.github.difflib.DiffUtils;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
import com.github.difflib.algorithm.DiffException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import com.github.difflib.text.DiffRow;
|
|
||||||
import com.github.difflib.text.DiffRowGenerator;
|
|
||||||
import com.github.difflib.algorithm.DiffException;
|
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.Arrays;
|
||||||
import java.util.List;
|
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.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -25,6 +28,20 @@ public class DiffRowGeneratorTest {
|
|||||||
assertEquals(3, rows.size());
|
assertEquals(3, rows.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerator_Default2() throws DiffException {
|
||||||
|
String first = "anything \n \nother";
|
||||||
|
String second = "anything\n\nother";
|
||||||
|
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.columnWidth(0) // do not wrap
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
|
||||||
|
print(rows);
|
||||||
|
|
||||||
|
assertEquals(3, rows.size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerator_InlineDiff() throws DiffException {
|
public void testGenerator_InlineDiff() throws DiffException {
|
||||||
String first = "anything \n \nother";
|
String first = "anything \n \nother";
|
||||||
@@ -69,14 +86,14 @@ public class DiffRowGeneratorTest {
|
|||||||
System.out.println(row);
|
System.out.println(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithWordWrap() throws DiffException {
|
public void testGeneratorWithWordWrap() throws DiffException {
|
||||||
String first = "anything \n \nother";
|
String first = "anything \n \nother";
|
||||||
String second = "anything\n\nother";
|
String second = "anything\n\nother";
|
||||||
|
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
.columnWidth(5)
|
.columnWidth(5)
|
||||||
.build();
|
.build();
|
||||||
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
|
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
|
||||||
print(rows);
|
print(rows);
|
||||||
@@ -86,7 +103,7 @@ public class DiffRowGeneratorTest {
|
|||||||
assertEquals("[CHANGE, ,]", rows.get(1).toString());
|
assertEquals("[CHANGE, ,]", rows.get(1).toString());
|
||||||
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
|
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithMerge() throws DiffException {
|
public void testGeneratorWithMerge() throws DiffException {
|
||||||
String first = "anything \n \nother";
|
String first = "anything \n \nother";
|
||||||
@@ -104,20 +121,20 @@ public class DiffRowGeneratorTest {
|
|||||||
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
|
||||||
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
|
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithMerge2() throws DiffException {
|
public void testGeneratorWithMerge2() throws DiffException {
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
.showInlineDiffs(true)
|
.showInlineDiffs(true)
|
||||||
.mergeOriginalRevised(true)
|
.mergeOriginalRevised(true)
|
||||||
.build();
|
.build();
|
||||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"),Arrays.asList("ester"));
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"), Arrays.asList("ester"));
|
||||||
print(rows);
|
print(rows);
|
||||||
|
|
||||||
assertEquals(1, rows.size());
|
assertEquals(1, rows.size());
|
||||||
assertEquals("[CHANGE,<span class=\"editOldInline\">T</span>est<span class=\"editNewInline\">er</span>,ester]", rows.get(0).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\">T</span>est<span class=\"editNewInline\">er</span>,ester]", rows.get(0).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithMerge3() throws DiffException {
|
public void testGeneratorWithMerge3() throws DiffException {
|
||||||
String first = "test\nanything \n \nother";
|
String first = "test\nanything \n \nother";
|
||||||
@@ -131,14 +148,14 @@ public class DiffRowGeneratorTest {
|
|||||||
print(rows);
|
print(rows);
|
||||||
|
|
||||||
assertEquals(6, rows.size());
|
assertEquals(6, rows.size());
|
||||||
assertEquals("[CHANGE,<span class=\"editOldInline\">test,anything]", rows.get(0).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\">test</span>,anything]", rows.get(0).toString());
|
||||||
assertEquals("[CHANGE,</span>anything<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
|
assertEquals("[CHANGE,anything<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
|
||||||
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(2).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(2).toString());
|
||||||
assertEquals("[EQUAL,other,other]", rows.get(3).toString());
|
assertEquals("[EQUAL,other,other]", rows.get(3).toString());
|
||||||
assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString());
|
assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString());
|
||||||
assertEquals("[INSERT,<span class=\"editNewInline\">test2</span>,test2]", rows.get(5).toString());
|
assertEquals("[INSERT,<span class=\"editNewInline\">test2</span>,test2]", rows.get(5).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithMergeByWord4() throws DiffException {
|
public void testGeneratorWithMergeByWord4() throws DiffException {
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
@@ -146,51 +163,51 @@ public class DiffRowGeneratorTest {
|
|||||||
.mergeOriginalRevised(true)
|
.mergeOriginalRevised(true)
|
||||||
.inlineDiffByWord(true)
|
.inlineDiffByWord(true)
|
||||||
.build();
|
.build();
|
||||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"),Arrays.asList("ester"));
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test"), Arrays.asList("ester"));
|
||||||
print(rows);
|
print(rows);
|
||||||
|
|
||||||
assertEquals(1, rows.size());
|
assertEquals(1, rows.size());
|
||||||
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span>,ester]", rows.get(0).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span>,ester]", rows.get(0).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorWithMergeByWord5() throws DiffException {
|
public void testGeneratorWithMergeByWord5() throws DiffException {
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
.showInlineDiffs(true)
|
.showInlineDiffs(true)
|
||||||
.mergeOriginalRevised(true)
|
.mergeOriginalRevised(true)
|
||||||
.inlineDiffByWord(true)
|
.inlineDiffByWord(true)
|
||||||
|
.columnWidth(80)
|
||||||
.build();
|
.build();
|
||||||
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test feature"),Arrays.asList("ester feature best"));
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("Test feature"), Arrays.asList("ester feature best"));
|
||||||
print(rows);
|
print(rows);
|
||||||
|
|
||||||
assertEquals(1, rows.size());
|
assertEquals(1, rows.size());
|
||||||
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span> <br/>feature<span class=\"editNewInline\"> best</span>,ester feature best]", rows.get(0).toString());
|
assertEquals("[CHANGE,<span class=\"editOldInline\">Test</span><span class=\"editNewInline\">ester</span> <br/>feature<span class=\"editNewInline\"> best</span>,ester feature best]", rows.get(0).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSplitString() {
|
public void testSplitString() {
|
||||||
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2");
|
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
|
||||||
assertEquals(3, list.size());
|
assertEquals(3, list.size());
|
||||||
assertEquals("[test, ,, test2]", list.toString());
|
assertEquals("[test, ,, test2]", list.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSplitString2() {
|
public void testSplitString2() {
|
||||||
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test , test2");
|
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test , test2", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
|
||||||
System.out.println(list);
|
System.out.println(list);
|
||||||
assertEquals(5, list.size());
|
assertEquals(5, list.size());
|
||||||
assertEquals("[test, , ,, , test2]", list.toString());
|
assertEquals("[test, , ,, , test2]", list.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSplitString3() {
|
public void testSplitString3() {
|
||||||
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2,");
|
List<String> list = DiffRowGenerator.splitStringPreserveDelimiter("test,test2,", DiffRowGenerator.SPLIT_BY_WORD_PATTERN);
|
||||||
System.out.println(list);
|
System.out.println(list);
|
||||||
assertEquals(4, list.size());
|
assertEquals(4, list.size());
|
||||||
assertEquals("[test, ,, test2, ,]", list.toString());
|
assertEquals("[test, ,, test2, ,]", list.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorExample1() throws DiffException {
|
public void testGeneratorExample1() throws DiffException {
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
@@ -203,13 +220,13 @@ public class DiffRowGeneratorTest {
|
|||||||
List<DiffRow> rows = generator.generateDiffRows(
|
List<DiffRow> rows = generator.generateDiffRows(
|
||||||
Arrays.asList("This is a test senctence."),
|
Arrays.asList("This is a test senctence."),
|
||||||
Arrays.asList("This is a test for diffutils."));
|
Arrays.asList("This is a test for diffutils."));
|
||||||
|
|
||||||
System.out.println(rows.get(0).getOldLine());
|
System.out.println(rows.get(0).getOldLine());
|
||||||
|
|
||||||
assertEquals(1, rows.size());
|
assertEquals(1, rows.size());
|
||||||
assertEquals("This is a test ~senctence~**for diffutils**.", rows.get(0).getOldLine());
|
assertEquals("This is a test ~senctence~**for diffutils**.", rows.get(0).getOldLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGeneratorExample2() throws DiffException {
|
public void testGeneratorExample2() throws DiffException {
|
||||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
@@ -221,15 +238,141 @@ public class DiffRowGeneratorTest {
|
|||||||
List<DiffRow> rows = generator.generateDiffRows(
|
List<DiffRow> rows = generator.generateDiffRows(
|
||||||
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
|
Arrays.asList("This is a test senctence.", "This is the second line.", "And here is the finish."),
|
||||||
Arrays.asList("This is a test for diffutils.", "This is the second line."));
|
Arrays.asList("This is a test for diffutils.", "This is the second line."));
|
||||||
|
|
||||||
System.out.println("|original|new|");
|
System.out.println("|original|new|");
|
||||||
System.out.println("|--------|---|");
|
System.out.println("|--------|---|");
|
||||||
for (DiffRow row : rows) {
|
for (DiffRow row : rows) {
|
||||||
System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
|
System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(3, rows.size());
|
assertEquals(3, rows.size());
|
||||||
assertEquals("This is a test ~senctence~.", rows.get(0).getOldLine());
|
assertEquals("This is a test ~senctence~.", rows.get(0).getOldLine());
|
||||||
assertEquals("This is a test **for diffutils**.", rows.get(0).getNewLine());
|
assertEquals("This is a test **for diffutils**.", rows.get(0).getNewLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGeneratorUnchanged() throws DiffException {
|
||||||
|
String first = "anything \n \nother";
|
||||||
|
String second = "anything\n\nother";
|
||||||
|
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.columnWidth(5)
|
||||||
|
.reportLinesUnchanged(true)
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(split(first), split(second));
|
||||||
|
print(rows);
|
||||||
|
|
||||||
|
assertEquals(3, rows.size());
|
||||||
|
assertEquals("[CHANGE,anything ,anything]", rows.get(0).toString());
|
||||||
|
assertEquals("[CHANGE, ,]", rows.get(1).toString());
|
||||||
|
assertEquals("[EQUAL,other,other]", rows.get(2).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGeneratorIssue14() throws DiffException {
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.showInlineDiffs(true)
|
||||||
|
.mergeOriginalRevised(true)
|
||||||
|
.inlineDiffBySplitter(line -> DiffRowGenerator.splitStringPreserveDelimiter(line, Pattern.compile(",")))
|
||||||
|
.oldTag(f -> "~")
|
||||||
|
.newTag(f -> "**")
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(
|
||||||
|
Arrays.asList("J. G. Feldstein, Chair"),
|
||||||
|
Arrays.asList("T. P. Pastor, Chair"));
|
||||||
|
|
||||||
|
System.out.println(rows.get(0).getOldLine());
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import com.github.difflib.text.StringUtils;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import org.junit.Test;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -39,7 +38,7 @@ public class StringUtilsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNormalize_String() {
|
public void testNormalize_String() {
|
||||||
assertEquals(" test",StringUtils.normalize("\ttest"));
|
assertEquals(" test", StringUtils.normalize("\ttest"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +46,7 @@ public class StringUtilsTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testNormalize_List() {
|
public void testNormalize_List() {
|
||||||
assertEquals(Collections.singletonList(" test"),StringUtils.normalize(Collections.singletonList("\ttest")));
|
assertEquals(Collections.singletonList(" test"), StringUtils.normalize(Collections.singletonList("\ttest")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,10 +58,10 @@ public class StringUtilsTest {
|
|||||||
assertEquals("tes<br/>t", StringUtils.wrapText("test", 3));
|
assertEquals("tes<br/>t", StringUtils.wrapText("test", 3));
|
||||||
assertEquals("test", StringUtils.wrapText("test", 10));
|
assertEquals("test", StringUtils.wrapText("test", 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testWrapText_String_int_zero() {
|
public void testWrapText_String_int_zero() {
|
||||||
assertEquals("test", StringUtils.wrapText("test", 0));
|
assertEquals("test", StringUtils.wrapText("test", -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
src/test/resources/mocks/issue15_1.txt
Normal file
9
src/test/resources/mocks/issue15_1.txt
Normal 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,
|
||||||
9
src/test/resources/mocks/issue15_2.txt
Normal file
9
src/test/resources/mocks/issue15_2.txt
Normal 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,
|
||||||
Reference in New Issue
Block a user