From dcf66dfadcef086c5ce78aace39c003d4211c0d6 Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 9 Nov 2017 22:47:30 +0100 Subject: [PATCH 01/44] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 87d136e0..282a95e9 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.github.wumpz diffutils jar - 2.2 + 2.3-SNAPSHOT java-diff-utils The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java. https://github.com/wumpz/java-diff-utils @@ -24,7 +24,7 @@ scm:git:https://github.com/wumpz/java-diff-utils.git scm:git:ssh://git@github.com:wumpz/java-diff-utils.git https://github.com/wumpz/java-diff-utils.git - diffutils-2.2 + HEAD From a65ffd95a9250835a29e143b0e8cd49395b6b6cb Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 9 Nov 2017 22:59:29 +0100 Subject: [PATCH 02/44] --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index be31df25..72ccf3f5 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,9 @@ This is a test ~senctence~**for diffutils**. But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future. ### Changelog ### - * Version 2.1-SNAPSHOT + * Version 2.3-SNAPSHOT + * 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). From 4933ca520068a4d9b5203b70ff5bd3d84f22de50 Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 9 Nov 2017 23:02:00 +0100 Subject: [PATCH 03/44] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 72ccf3f5..fff2cfa5 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,6 @@ Just add the code below to your maven dependencies: com.github.wumpz diffutils -    2.0-SNAPSHOT +    2.2 ``` From 02c97e4691f657c164a31f44ec28dfafa6d150ae Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 1 Dec 2017 09:12:42 +0100 Subject: [PATCH 04/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fff2cfa5..f4b55e38 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ But it can easily replaced by any other which is better for handing your texts. ## Source Code conventions -Recently a checkstyle process was integrated into the build process. JSqlParser follows the sun java format convention. There are no TABs allowed. Use spaces. +Recently a checkstyle process was integrated into the build process. java-diff-utils follows the sun java format convention. There are no TABs allowed. Use spaces. ```java public static Patch diff(List original, List revised, From 829567bace962e832e04fa74c0ca617742f40788 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 08:24:51 +0100 Subject: [PATCH 05/44] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -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. From 5e0d398c535a52bd93fc4bc8edce0c30d011b602 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 09:02:33 +0100 Subject: [PATCH 06/44] Set theme jekyll-theme-hacker --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..fc24e7a6 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-hacker \ No newline at end of file From 0eb7b6c34f13d8784ce3c2b60a9d4f6dc2cd9df0 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 09:04:38 +0100 Subject: [PATCH 07/44] Set theme jekyll-theme-minimal --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index fc24e7a6..2f7efbea 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-minimal \ No newline at end of file From 05de2df99d9e9461f6bb26a27dd66fc8fb41db5a Mon Sep 17 00:00:00 2001 From: wumpz Date: Fri, 22 Dec 2017 10:11:35 +0100 Subject: [PATCH 08/44] introduced docs folder --- docs/docs.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/docs.txt diff --git a/docs/docs.txt b/docs/docs.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/docs/docs.txt @@ -0,0 +1 @@ + From 8c242a42eff698bb883c058c460a68802627cf80 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:19:14 +0100 Subject: [PATCH 09/44] Set theme jekyll-theme-cayman --- docs/_config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/_config.yml diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..c4192631 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file From df3ec97df4077d09139213b4f667fd5e9870ae7c Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:20:05 +0100 Subject: [PATCH 10/44] Delete _config.yml --- _config.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 _config.yml diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 2f7efbea..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file From 08d4914a8bf7138d8f06c5c7ed7ecc3af054054b Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:20:18 +0100 Subject: [PATCH 11/44] Delete docs.txt --- docs/docs.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/docs.txt diff --git a/docs/docs.txt b/docs/docs.txt deleted file mode 100644 index 8b137891..00000000 --- a/docs/docs.txt +++ /dev/null @@ -1 +0,0 @@ - From 10c17b42872c8b04752e724d83c7bd2b62727841 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:20:58 +0100 Subject: [PATCH 12/44] Set theme jekyll-theme-hacker --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index c4192631..fc24e7a6 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-cayman \ No newline at end of file +theme: jekyll-theme-hacker \ No newline at end of file From e630c7975a210a0102cabfd06af4fbc1047e189c Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:22:13 +0100 Subject: [PATCH 13/44] Set theme jekyll-theme-minimal --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index fc24e7a6..2f7efbea 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-minimal \ No newline at end of file From 1914de7e5ca49cf0b95045b72b71af10b3abf688 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:24:59 +0100 Subject: [PATCH 14/44] Set theme jekyll-theme-minimal --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..2f7efbea --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-minimal \ No newline at end of file From 005f95ab9d0a0083617390d06df5230ea99f36a3 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:25:15 +0100 Subject: [PATCH 15/44] Delete _config.yml --- _config.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 _config.yml diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 2f7efbea..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file From 91ddcccd1e1aeb612c31f07ce0c9f1e42d2bafa9 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 22 Dec 2017 10:25:53 +0100 Subject: [PATCH 16/44] Set theme jekyll-theme-minimal From a998d8d98bd5a931cd2af6b9998699c669847ff0 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 27 Dec 2017 20:52:11 +0100 Subject: [PATCH 17/44] Set theme jekyll-theme-minimal From d498a41dd38909bc5541dabb057e050ace5b4167 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 27 Dec 2017 20:55:26 +0100 Subject: [PATCH 18/44] Delete _config.yml --- docs/_config.yml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/_config.yml diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 2f7efbea..00000000 --- a/docs/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-minimal \ No newline at end of file From 04832c7c9a39c71ee7535041e7de0f7300c08221 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 27 Dec 2017 20:55:59 +0100 Subject: [PATCH 19/44] Set theme jekyll-theme-minimal --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..2f7efbea --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-minimal \ No newline at end of file From 1214f4cf23b39f8412e4b2a23582bbf82621a791 Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 8 Feb 2018 08:08:06 +0100 Subject: [PATCH 20/44] Create ISSUE_TEMPLATE.md --- ISSUE_TEMPLATE.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..057f67a4 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,17 @@ +### Expected Behavior + + +### Actual Behavior + + +### Steps to Reproduce the Problem + + 1. + 1. + 1. + +### Specifications + + - Version: + - Platform: + - Subsystem: From 653d1f9153e3a031c84bf70a478d0810dd68617d Mon Sep 17 00:00:00 2001 From: Tobias Date: Mon, 5 Mar 2018 09:45:57 +0100 Subject: [PATCH 21/44] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f4b55e38..b544b3da 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ ## Status ## [![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/wumpz/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=wumpz/java-diff-utils&utm_campaign=Badge_Grade) +After a while using it, at least for me, this one seems to be feature complete. If someone finds bugs or has improvement ideas, please file an issue. I wonder why that this project is a zero issue project. + + ## 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. From c6e4059de43dccb7efa942a946c7bdd10751aeca Mon Sep 17 00:00:00 2001 From: Tobias Date: Mon, 5 Mar 2018 10:01:59 +0100 Subject: [PATCH 22/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b544b3da..2948c1c4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Status ## [![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/wumpz/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=wumpz/java-diff-utils&utm_campaign=Badge_Grade) -After a while using it, at least for me, this one seems to be feature complete. If someone finds bugs or has improvement ideas, please file an issue. I wonder why that this project is a zero issue project. +**After a while using it, at least for me, this one seems to be feature complete. If someone finds bugs or has improvement ideas, please file an issue. I wonder why that this project is a zero issue project.** ## Intro ## From c001819855c7ca8e4c51e41d103384d73f03b1c9 Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 15 Mar 2018 15:08:38 +0100 Subject: [PATCH 23/44] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 2948c1c4..851402f7 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,6 @@ This is a valid piece of source code: ### To Install ### -**This jar is not yet to get at maven central.** - Just add the code below to your maven dependencies: ``` From db114a2c2a687832c600ba46496ba33ec5119bf7 Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 15 Mar 2018 15:10:52 +0100 Subject: [PATCH 24/44] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 851402f7..bc5e0f03 100644 --- a/README.md +++ b/README.md @@ -105,3 +105,8 @@ Just add the code below to your maven dependencies:    2.2 ``` +or using gradle: +``` +// https://mvnrepository.com/artifact/com.github.wumpz/diffutils +compile group: 'com.github.wumpz', name: 'diffutils', version: '2.2' +``` From 33a0b58299a2b18d949feaa179445925e88dc15d Mon Sep 17 00:00:00 2001 From: wumpz Date: Sat, 17 Mar 2018 00:57:20 +0100 Subject: [PATCH 25/44] introduces test for issue #15 --- .../difflib/text/DiffRowGeneratorTest.java | 35 ++++++++++++++++++- src/test/resources/mocks/issue15_1.txt | 9 +++++ src/test/resources/mocks/issue15_2.txt | 9 +++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/mocks/issue15_1.txt create mode 100644 src/test/resources/mocks/issue15_2.txt diff --git a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java index 19748282..f80cefb3 100644 --- a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java +++ b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java @@ -1,9 +1,13 @@ package com.github.difflib.text; import com.github.difflib.algorithm.DiffException; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -263,7 +267,7 @@ public void testGeneratorUnchanged() throws DiffException { assertEquals("[CHANGE, ,]", rows.get(1).toString()); assertEquals("[EQUAL,other,other]", rows.get(2).toString()); } - + @Test public void testGeneratorIssue14() throws DiffException { DiffRowGenerator generator = DiffRowGenerator.create() @@ -282,4 +286,33 @@ public void testGeneratorIssue14() throws DiffException { 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 listOne = Files.lines(new File("target/test-classes/mocks/issue15_1.txt").toPath()) + .collect(toList()); + + List listTwo = Files.lines(new File("target/test-classes/mocks/issue15_2.txt").toPath()) + .collect(toList()); + + List 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")); + } + } + } } diff --git a/src/test/resources/mocks/issue15_1.txt b/src/test/resources/mocks/issue15_1.txt new file mode 100644 index 00000000..fb40d61f --- /dev/null +++ b/src/test/resources/mocks/issue15_1.txt @@ -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, \ No newline at end of file diff --git a/src/test/resources/mocks/issue15_2.txt b/src/test/resources/mocks/issue15_2.txt new file mode 100644 index 00000000..8b622651 --- /dev/null +++ b/src/test/resources/mocks/issue15_2.txt @@ -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, \ No newline at end of file From 0d15097947ef7cdfc2795c9caace8356f48d698d Mon Sep 17 00:00:00 2001 From: wumpz Date: Tue, 10 Apr 2018 07:32:44 +0200 Subject: [PATCH 26/44] some renaming --- .../java/com/github/difflib/UnifiedDiffUtils.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/difflib/UnifiedDiffUtils.java b/src/main/java/com/github/difflib/UnifiedDiffUtils.java index 1395c795..c7b83560 100644 --- a/src/main/java/com/github/difflib/UnifiedDiffUtils.java +++ b/src/main/java/com/github/difflib/UnifiedDiffUtils.java @@ -130,21 +130,21 @@ public static Patch parseUnifiedDiff(List diff) { * generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing * the Patch. * - * @param original - Filename of the original (unrevised file) - * @param revised - Filename of the revised file + * @param originalFileName - Filename of the original (unrevised file) + * @param revisedFileName - Filename of the revised file * @param originalLines - Lines of the original file * @param patch - Patch created by the diff() function * @param contextSize - number of lines of context output around each difference in the file. * @return List of strings representing the Unified Diff representation of the Patch argument. * @author Bill James (tankerbay@gmail.com) */ - public static List generateUnifiedDiff(String original, - String revised, List originalLines, Patch patch, + public static List generateUnifiedDiff(String originalFileName, + String revisedFileName, List originalLines, Patch patch, int contextSize) { if (!patch.getDeltas().isEmpty()) { List ret = new ArrayList<>(); - ret.add("--- " + original); - ret.add("+++ " + revised); + ret.add("--- " + originalFileName); + ret.add("+++ " + revisedFileName); List> patchDeltas = new ArrayList<>( patch.getDeltas()); From d1c22e724383b586a21159209da4920d4d1d939c Mon Sep 17 00:00:00 2001 From: wumpz Date: Mon, 7 May 2018 01:34:22 +0200 Subject: [PATCH 27/44] fixes #19 --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 282a95e9..54da0ae2 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,10 @@ ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + + com.github.wumpz.diffutils + From 592ff058c15863fae910b7f1379700305cf0dd67 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 9 May 2018 12:04:49 +0200 Subject: [PATCH 28/44] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bc5e0f03..2ac59b6a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ But it can easily replaced by any other which is better for handing your texts. ### Changelog ### * Version 2.3-SNAPSHOT + * automatic module name for JDK 9 and hight usage * Version 2.2 * released at maven central * included checkstyle source code conventions From 67b26e5cabfa152bdf3105c45531a5e74cd3abb7 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 9 May 2018 12:06:22 +0200 Subject: [PATCH 29/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2ac59b6a..cd4d0b02 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ But it can easily replaced by any other which is better for handing your texts. ### Changelog ### * Version 2.3-SNAPSHOT - * automatic module name for JDK 9 and hight usage + * automatic module name for JDK 9 and higher usage * Version 2.2 * released at maven central * included checkstyle source code conventions From 3a87d246324adf9bf0fb7400fe6d4ae712ebddfc Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 16 May 2018 23:04:12 +0200 Subject: [PATCH 30/44] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cd4d0b02..95657fcb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ## Status ## [![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/wumpz/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=wumpz/java-diff-utils&utm_campaign=Badge_Grade) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils/badge.svg)](http://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils) **After a while using it, at least for me, this one seems to be feature complete. If someone finds bugs or has improvement ideas, please file an issue. I wonder why that this project is a zero issue project.** From 54bf402a9a18f31f826bfde8a37419a1236163bd Mon Sep 17 00:00:00 2001 From: wumpz Date: Wed, 13 Jun 2018 15:33:04 +0200 Subject: [PATCH 31/44] --- nb-configuration.xml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nb-configuration.xml b/nb-configuration.xml index f5e3165a..03683cb3 100644 --- a/nb-configuration.xml +++ b/nb-configuration.xml @@ -1,22 +1,23 @@ - - - - none - false - true - LF - false - + none + false + true + LF + false + JDK_1.8 + From c8f0624a7bcf3e1d686108e9fe786f531d97203a Mon Sep 17 00:00:00 2001 From: wumpz Date: Wed, 13 Jun 2018 23:19:43 +0200 Subject: [PATCH 32/44] jdk8 --- nb-configuration.xml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nb-configuration.xml b/nb-configuration.xml index f5e3165a..03683cb3 100644 --- a/nb-configuration.xml +++ b/nb-configuration.xml @@ -1,22 +1,23 @@ - - - - none - false - true - LF - false - + none + false + true + LF + false + JDK_1.8 + From d12b13da41cfeb39da4d13987f486cf59efecd6e Mon Sep 17 00:00:00 2001 From: wumpz Date: Sun, 17 Jun 2018 23:32:43 +0200 Subject: [PATCH 33/44] fixes #21 --- README.md | 4 +- .../java/com/github/difflib/DiffUtils.java | 32 +++++++++++++--- .../difflib/algorithm/DiffAlgorithm.java | 6 +-- .../algorithm/DiffAlgorithmListener.java | 34 +++++++++++++++++ .../difflib/algorithm/jgit/HistogramDiff.java | 23 +++++++++-- .../difflib/algorithm/myers/MyersDiff.java | 26 +++++++++---- .../algorithm/jgit/HistogramDiffTest.java | 38 ++++++++++++++++++- .../algorithm/jgit/LRHistogramDiffTest.java | 22 ++++++++++- .../algorithm/myers/MyersDiffTest.java | 34 ++++++++++++++++- 9 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/github/difflib/algorithm/DiffAlgorithmListener.java diff --git a/README.md b/README.md index bc5e0f03..89456613 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ ## Status ## [![Build Status](https://travis-ci.org/wumpz/java-diff-utils.svg?branch=master)](https://travis-ci.org/wumpz/java-diff-utils) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7eba77f10bed4c2a8d08ac8dc8da4a86)](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=wumpz/java-diff-utils&utm_campaign=Badge_Grade) -**After a while using it, at least for me, this one seems to be feature complete. If someone finds bugs or has improvement ideas, please file an issue. I wonder why that this project is a zero issue project.** - ## 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. @@ -54,6 +52,8 @@ But it can easily replaced by any other which is better for handing your texts. ### Changelog ### * Version 2.3-SNAPSHOT + * Introduced a process listener to diff algorithms. For long running + diffs one could implement some progress information. * Version 2.2 * released at maven central * included checkstyle source code conventions diff --git a/src/main/java/com/github/difflib/DiffUtils.java b/src/main/java/com/github/difflib/DiffUtils.java index 807d7b4a..86861be8 100644 --- a/src/main/java/com/github/difflib/DiffUtils.java +++ b/src/main/java/com/github/difflib/DiffUtils.java @@ -20,6 +20,7 @@ package com.github.difflib; import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.myers.MyersDiff; import com.github.difflib.patch.Delta; @@ -37,7 +38,6 @@ * Implements the difference and patching engine * * @author Dmitry Naumenko - * @version 0.4.1 */ public final class DiffUtils { @@ -46,17 +46,23 @@ public final class DiffUtils { * * @param original The original text. Must not be {@code null}. * @param revised The revised text. Must not be {@code null}. + * @param progress progress listener * @return The patch describing the difference between the original and revised sequences. Never {@code null}. + * @throws com.github.difflib.algorithm.DiffException */ + public static Patch diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException { + return DiffUtils.diff(original, revised, new MyersDiff<>(), progress); + } + public static Patch diff(List original, List revised) throws DiffException { - return DiffUtils.diff(original, revised, new MyersDiff<>()); + return DiffUtils.diff(original, revised, new MyersDiff<>(), null); } /** * Computes the difference between the original and revised text. */ - public static Patch diff(String originalText, String revisedText) throws DiffException { - return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n"))); + public static Patch diff(String originalText, String revisedText, DiffAlgorithmListener progress) throws DiffException { + return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n")), progress); } /** @@ -84,16 +90,30 @@ public static Patch diff(List original, List revised, * @param original The original text. Must not be {@code null}. * @param revised The revised text. Must not be {@code null}. * @param algorithm The diff algorithm. Must not be {@code null}. + * @param progress The diff algorithm listener. * @return The patch describing the difference between the original and revised sequences. Never {@code null}. */ public static Patch diff(List original, List revised, - DiffAlgorithm algorithm) throws DiffException { + DiffAlgorithm algorithm, DiffAlgorithmListener progress) throws DiffException { Objects.requireNonNull(original, "original must not be null"); Objects.requireNonNull(revised, "revised must not be null"); Objects.requireNonNull(algorithm, "algorithm must not be null"); - return Patch.generate(original, revised, algorithm.diff(original, revised)); + return Patch.generate(original, revised, algorithm.diff(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 Patch diff(List original, List revised, + DiffAlgorithm algorithm) throws DiffException { + return diff(original, revised, algorithm, null); + } /** * Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java index b97a15a4..c6f26986 100644 --- a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java +++ b/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java @@ -38,8 +38,8 @@ public interface DiffAlgorithm { * @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 diff(T[] original, T[] revised) throws DiffException { - return diff(Arrays.asList(original), Arrays.asList(revised)); + default List diff(T[] original, T[] revised, DiffAlgorithmListener progress) throws DiffException { + return diff(Arrays.asList(original), Arrays.asList(revised), progress); } /** @@ -50,5 +50,5 @@ public default List diff(T[] original, T[] revised) throws DiffException * @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 diff(List original, List revised) throws DiffException; + List diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException; } diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithmListener.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmListener.java new file mode 100644 index 00000000..37d51813 --- /dev/null +++ b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmListener.java @@ -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(); +} diff --git a/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java b/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java index 6ca80103..3029f6c8 100644 --- a/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java +++ b/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java @@ -17,6 +17,7 @@ import com.github.difflib.algorithm.Change; import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.patch.DeltaType; import java.util.ArrayList; @@ -28,18 +29,22 @@ import org.eclipse.jgit.diff.SequenceComparator; /** - * HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers implementation. + * HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers + * implementation. * * @author toben */ public class HistogramDiff implements DiffAlgorithm { @Override - public List diff(List original, List revised) throws DiffException { + public List diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException { Objects.requireNonNull(original, "original list must not be null"); Objects.requireNonNull(revised, "revised list must not be null"); + if (progress != null) { + progress.diffStart(); + } EditList diffList = new EditList(); - diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(), new DataList<>(original), new DataList<>(revised))); + diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(progress), new DataList<>(original), new DataList<>(revised))); List patch = new ArrayList<>(); for (Edit edit : diffList) { DeltaType type = DeltaType.EQUAL; @@ -56,14 +61,26 @@ public List diff(List original, List revised) throws DiffException } patch.add(new Change(type, edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB())); } + if (progress != null) { + progress.diffEnd(); + } return patch; } } class DataListComparator extends SequenceComparator> { + private final DiffAlgorithmListener progress; + + public DataListComparator(DiffAlgorithmListener progress) { + this.progress = progress; + } + @Override public boolean equals(DataList original, int orgIdx, DataList revised, int revIdx) { + if (progress != null) { + progress.diffStep(orgIdx + revIdx, original.size() + revised.size()); + } return original.data.get(orgIdx).equals(revised.data.get(revIdx)); } diff --git a/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java b/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java index ec76ec3f..e3a3d69a 100644 --- a/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java +++ b/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java @@ -21,6 +21,7 @@ import com.github.difflib.algorithm.Change; import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DifferentiationFailedException; import com.github.difflib.patch.DeltaType; @@ -53,24 +54,31 @@ public MyersDiff(final BiPredicate equalizer) { * Return empty diff if get the error while procession the difference. */ @Override - public List diff(final List original, final List revised) throws DiffException { + public List diff(final List original, final List revised, DiffAlgorithmListener progress) throws DiffException { Objects.requireNonNull(original, "original list must not be null"); Objects.requireNonNull(revised, "revised list must not be null"); - PathNode path = buildPath(original, revised); - return buildRevision(path, original, revised); + if (progress != null) { + progress.diffStart(); + } + PathNode path = buildPath(original, revised, progress); + List result = buildRevision(path, original, revised); + if (progress != null) { + progress.diffEnd(); + } + return result; } /** - * Computes the minimum diffpath that expresses de differences between the original and revised sequences, according - * to Gene Myers differencing algorithm. + * Computes the minimum diffpath that expresses de differences between the original and revised + * sequences, according to Gene Myers differencing algorithm. * * @param orig The original sequence. * @param rev The revised sequence. * @return A minimum {@link PathNode Path} accross the differences graph. * @throws DifferentiationFailedException if a diff path could not be found. */ - private PathNode buildPath(final List orig, final List rev) + private PathNode buildPath(final List orig, final List rev, DiffAlgorithmListener progress) throws DifferentiationFailedException { Objects.requireNonNull(orig, "original sequence is null"); Objects.requireNonNull(rev, "revised sequence is null"); @@ -86,6 +94,9 @@ private PathNode buildPath(final List orig, final List rev) diagonal[middle + 1] = new PathNode(0, -1, true, true, null); for (int d = 0; d < MAX; d++) { + if (progress != null) { + progress.diffStep(d, MAX); + } for (int k = -d; k <= d; k += 2) { final int kmiddle = middle + k; final int kplus = kmiddle + 1; @@ -135,7 +146,8 @@ private PathNode buildPath(final List orig, final List rev) * @param orig The original sequence. * @param rev The revised sequence. * @return A {@link Patch} script corresponding to the path. - * @throws DifferentiationFailedException if a {@link Patch} could not be built from the given path. + * @throws DifferentiationFailedException if a {@link Patch} could not be built from the given + * path. */ private List buildRevision(PathNode actualPath, List orig, List rev) { Objects.requireNonNull(actualPath, "path is null"); diff --git a/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java b/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java index ec44adea..0d6a3e4e 100644 --- a/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java @@ -15,9 +15,11 @@ */ package com.github.difflib.algorithm.jgit; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.patch.Patch; import com.github.difflib.patch.PatchFailedException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.After; @@ -59,7 +61,7 @@ public void tearDown() { public void testDiff() throws DiffException, PatchFailedException { List orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); List revList = Arrays.asList("C", "B", "A", "B", "A", "C"); - final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList)); + final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList, null)); System.out.println(patch); assertNotNull(patch); assertEquals(3, patch.getDeltas().size()); @@ -68,4 +70,38 @@ public void testDiff() throws DiffException, PatchFailedException { List patched = patch.applyTo(orgList); assertEquals(revList, patched); } + + @Test + public void testDiffWithListener() throws DiffException, PatchFailedException { + List orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); + List revList = Arrays.asList("C", "B", "A", "B", "A", "C"); + + List logdata = new ArrayList<>(); + final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().diff(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 patched = patch.applyTo(orgList); + assertEquals(revList, patched); + + System.out.println(logdata); + assertEquals(17, logdata.size()); + } } diff --git a/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java b/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java index 93e2950e..54311be9 100644 --- a/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java @@ -17,10 +17,12 @@ import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream; import com.github.difflib.TestConstants; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.patch.Patch; import com.github.difflib.patch.PatchFailedException; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.zip.ZipFile; import org.junit.After; @@ -61,12 +63,30 @@ public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOExcept List original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta"))); List revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))); - Patch patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised)); + List logdata = new ArrayList<>(); + Patch patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised, new DiffAlgorithmListener() { + @Override + public void diffStart() { + logdata.add("start"); + } + + @Override + public void diffStep(int value, int max) { + logdata.add(value + " - " + max); + } + + @Override + public void diffEnd() { + logdata.add("end"); + } + })); assertEquals(34, patch.getDeltas().size()); List created = patch.applyTo(original); assertArrayEquals(revised.toArray(), created.toArray()); + + assertEquals(50, logdata.size()); } } diff --git a/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java b/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java index 9b911ff1..b9d12cef 100644 --- a/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java @@ -15,8 +15,10 @@ */ package com.github.difflib.algorithm.myers; +import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.patch.Patch; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.junit.Assert.*; @@ -32,10 +34,40 @@ public class MyersDiffTest { public void testDiffMyersExample1Forward() throws DiffException { List original = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); List revised = Arrays.asList("C", "B", "A", "B", "A", "C"); - final Patch patch = Patch.generate(original, revised, new MyersDiff().diff(original, revised)); + final Patch patch = Patch.generate(original, revised, new MyersDiff().diff(original, revised, null)); assertNotNull(patch); assertEquals(4, patch.getDeltas().size()); assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString()); } + + @Test + public void testDiffMyersExample1ForwardWithListener() throws DiffException { + List original = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); + List revised = Arrays.asList("C", "B", "A", "B", "A", "C"); + + List logdata = new ArrayList<>(); + final Patch patch = Patch.generate(original, revised, + new MyersDiff().diff(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()); + } } From 42780b18a88b6f74c30c5fd1f4ec0db540d0ba00 Mon Sep 17 00:00:00 2001 From: wumpz Date: Wed, 27 Jun 2018 22:31:42 +0200 Subject: [PATCH 34/44] --- src/main/java/com/github/difflib/algorithm/Change.java | 2 +- src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java | 1 + src/main/java/com/github/difflib/patch/Delta.java | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/difflib/algorithm/Change.java b/src/main/java/com/github/difflib/algorithm/Change.java index b90e2022..57fbb788 100644 --- a/src/main/java/com/github/difflib/algorithm/Change.java +++ b/src/main/java/com/github/difflib/algorithm/Change.java @@ -19,7 +19,7 @@ /** * - * @author toben + * @author Tobias Warneke */ public class Change { diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java index c6f26986..463863c1 100644 --- a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java +++ b/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java @@ -26,6 +26,7 @@ * The general interface for computing diffs between two lists of elements of type T. * * @author Dmitry Naumenko + * @author Tobias Warneke * @param T The type of the compared elements in the 'lines'. */ public interface DiffAlgorithm { diff --git a/src/main/java/com/github/difflib/patch/Delta.java b/src/main/java/com/github/difflib/patch/Delta.java index 657a8f4f..03bc6a6a 100644 --- a/src/main/java/com/github/difflib/patch/Delta.java +++ b/src/main/java/com/github/difflib/patch/Delta.java @@ -25,6 +25,7 @@ * Describes the delta between original and revised texts. * * @author Dmitry Naumenko + * @author Tobias Warneke * @param T The type of the compared elements in the 'lines'. */ public abstract class Delta { From 696d22bd94561bd39c36cfd1498373b85a4cc634 Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 28 Jun 2018 21:46:18 +0200 Subject: [PATCH 35/44] Removed DiffAlgorithm.java and Delta.java due to licensing issues. The originals were Apache 1.1. Now we start a clean room implementation of those two files. --- .../difflib/algorithm/DiffAlgorithm.java | 55 ------- .../java/com/github/difflib/patch/Delta.java | 134 ------------------ 2 files changed, 189 deletions(-) delete mode 100644 src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java delete mode 100644 src/main/java/com/github/difflib/patch/Delta.java diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java deleted file mode 100644 index 463863c1..00000000 --- a/src/main/java/com/github/difflib/algorithm/DiffAlgorithm.java +++ /dev/null @@ -1,55 +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 Dmitry Naumenko - * @author Tobias Warneke - * @param T The type of the compared elements in the 'lines'. - */ -public interface DiffAlgorithm { - - /** - * 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}. - */ - default List diff(T[] original, T[] revised, DiffAlgorithmListener progress) throws DiffException { - return diff(Arrays.asList(original), Arrays.asList(revised), progress); - } - - /** - * 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}. - */ - List diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException; -} diff --git a/src/main/java/com/github/difflib/patch/Delta.java b/src/main/java/com/github/difflib/patch/Delta.java deleted file mode 100644 index 03bc6a6a..00000000 --- a/src/main/java/com/github/difflib/patch/Delta.java +++ /dev/null @@ -1,134 +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 Dmitry Naumenko - * @author Tobias Warneke - * @param T The type of the compared elements in the 'lines'. - */ -public abstract class Delta { - - private final DeltaType deltaType; - private final Chunk original; - private final Chunk 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 original, Chunk 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 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 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 target); - - public final DeltaType getType() { - return deltaType; - } - - /** - * @return The Chunk describing the original text. - */ - public Chunk getOriginal() { - return original; - } - - /** - * @return The Chunk describing the revised text. - */ - public Chunk 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 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; - } - -} From 33f2d744abcb1898ba3b0538cbb5e499fbb0a236 Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 28 Jun 2018 22:42:06 +0200 Subject: [PATCH 36/44] brought back diffutils to life --- README.md | 2 + pom.xml | 2 +- .../java/com/github/difflib/DiffUtils.java | 33 ++++--- .../com/github/difflib/UnifiedDiffUtils.java | 56 +++++------ .../difflib/algorithm/DiffAlgorithmI.java | 37 +++++++ .../difflib/algorithm/jgit/HistogramDiff.java | 12 +-- .../difflib/algorithm/myers/MyersDiff.java | 27 ++---- .../github/difflib/patch/AbstractDelta.java | 96 +++++++++++++++++++ .../com/github/difflib/patch/ChangeDelta.java | 33 ++++--- .../java/com/github/difflib/patch/Chunk.java | 1 + .../com/github/difflib/patch/DeleteDelta.java | 16 ++-- .../com/github/difflib/patch/InsertDelta.java | 16 ++-- .../java/com/github/difflib/patch/Patch.java | 16 ++-- .../github/difflib/text/DiffRowGenerator.java | 24 ++--- .../com/github/difflib/DiffUtilsTest.java | 42 ++++---- .../algorithm/jgit/HistogramDiffTest.java | 4 +- .../algorithm/jgit/LRHistogramDiffTest.java | 2 +- .../algorithm/myers/MyersDiffTest.java | 4 +- .../difflib/examples/ComputeDifference.java | 4 +- 19 files changed, 279 insertions(+), 148 deletions(-) create mode 100644 src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java create mode 100644 src/main/java/com/github/difflib/patch/AbstractDelta.java diff --git a/README.md b/README.md index 2557c3c0..08334bf5 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ This is a test ~senctence~**for diffutils**. But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future. ### Changelog ### + * Version 3.0-SNAPSHOT + * 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. diff --git a/pom.xml b/pom.xml index 54da0ae2..2b45fa26 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.github.wumpz diffutils jar - 2.3-SNAPSHOT + 3.0-SNAPSHOT java-diff-utils The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java. https://github.com/wumpz/java-diff-utils diff --git a/src/main/java/com/github/difflib/DiffUtils.java b/src/main/java/com/github/difflib/DiffUtils.java index 86861be8..f2c8eb19 100644 --- a/src/main/java/com/github/difflib/DiffUtils.java +++ b/src/main/java/com/github/difflib/DiffUtils.java @@ -19,11 +19,11 @@ */ package com.github.difflib; -import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmI; import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.myers.MyersDiff; -import com.github.difflib.patch.Delta; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.Patch; import com.github.difflib.patch.PatchFailedException; import java.util.ArrayList; @@ -61,27 +61,30 @@ public static Patch diff(List original, List revised) throws DiffEx /** * Computes the difference between the original and revised text. */ - public static Patch diff(String originalText, String revisedText, DiffAlgorithmListener progress) throws DiffException { - return DiffUtils.diff(Arrays.asList(originalText.split("\n")), Arrays.asList(revisedText.split("\n")), progress); + public static Patch diff(String sourceText, String targetText, + DiffAlgorithmListener progress) throws DiffException { + return DiffUtils.diff( + Arrays.asList(sourceText.split("\n")), + Arrays.asList(targetText.split("\n")), progress); } /** * Computes the difference between the original and revised list of elements with default diff algorithm * - * @param original The original text. Must not be {@code null}. - * @param revised The revised text. Must not be {@code null}. + * @param source The original text. Must not be {@code null}. + * @param target The revised text. Must not be {@code null}. * * @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If {@code null} * the default equalizer of the default algorithm is used.. * @return The patch describing the difference between the original and revised sequences. Never {@code null}. */ - public static Patch diff(List original, List revised, + public static Patch diff(List source, List target, BiPredicate equalizer) throws DiffException { if (equalizer != null) { - return DiffUtils.diff(original, revised, + return DiffUtils.diff(source, target, new MyersDiff<>(equalizer)); } - return DiffUtils.diff(original, revised, new MyersDiff<>()); + return DiffUtils.diff(source, target, new MyersDiff<>()); } /** @@ -94,12 +97,12 @@ public static Patch diff(List original, List revised, * @return The patch describing the difference between the original and revised sequences. Never {@code null}. */ public static Patch diff(List original, List revised, - DiffAlgorithm algorithm, DiffAlgorithmListener progress) throws DiffException { + DiffAlgorithmI algorithm, DiffAlgorithmListener progress) throws DiffException { Objects.requireNonNull(original, "original must not be null"); Objects.requireNonNull(revised, "revised must not be null"); Objects.requireNonNull(algorithm, "algorithm must not be null"); - return Patch.generate(original, revised, algorithm.diff(original, revised, progress)); + return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress)); } /** @@ -111,7 +114,7 @@ public static Patch diff(List original, List revised, * @return The patch describing the difference between the original and revised sequences. Never {@code null}. */ public static Patch diff(List original, List revised, - DiffAlgorithm algorithm) throws DiffException { + DiffAlgorithmI algorithm) throws DiffException { return diff(original, revised, algorithm, null); } @@ -133,9 +136,9 @@ public static Patch diffInline(String original, String revised) throws D revList.add(character.toString()); } Patch patch = DiffUtils.diff(origList, revList); - for (Delta delta : patch.getDeltas()) { - delta.getOriginal().setLines(compressLines(delta.getOriginal().getLines(), "")); - delta.getRevised().setLines(compressLines(delta.getRevised().getLines(), "")); + for (AbstractDelta delta : patch.getDeltas()) { + delta.getSource().setLines(compressLines(delta.getSource().getLines(), "")); + delta.getTarget().setLines(compressLines(delta.getTarget().getLines(), "")); } return patch; } diff --git a/src/main/java/com/github/difflib/UnifiedDiffUtils.java b/src/main/java/com/github/difflib/UnifiedDiffUtils.java index c7b83560..fe5b6f69 100644 --- a/src/main/java/com/github/difflib/UnifiedDiffUtils.java +++ b/src/main/java/com/github/difflib/UnifiedDiffUtils.java @@ -17,7 +17,7 @@ import com.github.difflib.patch.ChangeDelta; import com.github.difflib.patch.Chunk; -import com.github.difflib.patch.Delta; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.Patch; import java.util.ArrayList; import java.util.List; @@ -146,21 +146,21 @@ public static List generateUnifiedDiff(String originalFileName, ret.add("--- " + originalFileName); ret.add("+++ " + revisedFileName); - List> patchDeltas = new ArrayList<>( + List> patchDeltas = new ArrayList<>( patch.getDeltas()); // code outside the if block also works for single-delta issues. - List> deltas = new ArrayList<>(); // current + List> deltas = new ArrayList<>(); // current // list // of // Delta's to // process - Delta delta = patchDeltas.get(0); + AbstractDelta delta = patchDeltas.get(0); deltas.add(delta); // add the first Delta to the current set // if there's more than 1 Delta, we may need to output them together if (patchDeltas.size() > 1) { for (int i = 1; i < patchDeltas.size(); i++) { - int position = delta.getOriginal().getPosition(); // store + int position = delta.getSource().getPosition(); // store // the // current // position @@ -170,9 +170,9 @@ public static List generateUnifiedDiff(String originalFileName, // Check if the next Delta is too close to the current // position. // And if it is, add it to the current set - Delta nextDelta = patchDeltas.get(i); - if ((position + delta.getOriginal().size() + contextSize) >= (nextDelta - .getOriginal().getPosition() - contextSize)) { + AbstractDelta nextDelta = patchDeltas.get(i); + if ((position + delta.getSource().size() + contextSize) >= (nextDelta + .getSource().getPosition() - contextSize)) { deltas.add(nextDelta); } else { // if it isn't, output the current set, @@ -207,33 +207,33 @@ public static List generateUnifiedDiff(String originalFileName, * @author Bill James (tankerbay@gmail.com) */ private static List processDeltas(List origLines, - List> deltas, int contextSize) { + List> deltas, int contextSize) { List buffer = new ArrayList<>(); int origTotal = 0; // counter for total lines output from Original int revTotal = 0; // counter for total lines output from Original int line; - Delta curDelta = deltas.get(0); + AbstractDelta curDelta = deltas.get(0); // NOTE: +1 to overcome the 0-offset Position - int origStart = curDelta.getOriginal().getPosition() + 1 - contextSize; + int origStart = curDelta.getSource().getPosition() + 1 - contextSize; if (origStart < 1) { origStart = 1; } - int revStart = curDelta.getRevised().getPosition() + 1 - contextSize; + int revStart = curDelta.getTarget().getPosition() + 1 - contextSize; if (revStart < 1) { revStart = 1; } // find the start of the wrapper context code - int contextStart = curDelta.getOriginal().getPosition() - contextSize; + int contextStart = curDelta.getSource().getPosition() - contextSize; if (contextStart < 0) { contextStart = 0; // clamp to the start of the file } // output the context before the first Delta - for (line = contextStart; line < curDelta.getOriginal().getPosition(); line++) { // + for (line = contextStart; line < curDelta.getSource().getPosition(); line++) { // buffer.add(" " + origLines.get(line)); origTotal++; revTotal++; @@ -241,15 +241,15 @@ private static List processDeltas(List origLines, // output the first Delta buffer.addAll(getDeltaText(curDelta)); - origTotal += curDelta.getOriginal().getLines().size(); - revTotal += curDelta.getRevised().getLines().size(); + origTotal += curDelta.getSource().getLines().size(); + revTotal += curDelta.getTarget().getLines().size(); int deltaIndex = 1; while (deltaIndex < deltas.size()) { // for each of the other Deltas - Delta nextDelta = deltas.get(deltaIndex); - int intermediateStart = curDelta.getOriginal().getPosition() - + curDelta.getOriginal().getLines().size(); - for (line = intermediateStart; line < nextDelta.getOriginal() + AbstractDelta nextDelta = deltas.get(deltaIndex); + int intermediateStart = curDelta.getSource().getPosition() + + curDelta.getSource().getLines().size(); + for (line = intermediateStart; line < nextDelta.getSource() .getPosition(); line++) { // output the code between the last Delta and this one buffer.add(" " + origLines.get(line)); @@ -257,15 +257,15 @@ private static List processDeltas(List origLines, revTotal++; } buffer.addAll(getDeltaText(nextDelta)); // output the Delta - origTotal += nextDelta.getOriginal().getLines().size(); - revTotal += nextDelta.getRevised().getLines().size(); + origTotal += nextDelta.getSource().getLines().size(); + revTotal += nextDelta.getTarget().getLines().size(); curDelta = nextDelta; deltaIndex++; } // Now output the post-Delta context code, clamping the end of the file - contextStart = curDelta.getOriginal().getPosition() - + curDelta.getOriginal().getLines().size(); + contextStart = curDelta.getSource().getPosition() + + curDelta.getSource().getLines().size(); for (line = contextStart; (line < (contextStart + contextSize)) && (line < origLines.size()); line++) { buffer.add(" " + origLines.get(line)); @@ -275,7 +275,7 @@ private static List processDeltas(List origLines, // Create and insert the block header, conforming to the Unified Diff // standard - StringBuffer header = new StringBuffer(); + StringBuilder header = new StringBuilder(); header.append("@@ -"); header.append(origStart); header.append(","); @@ -297,12 +297,12 @@ private static List processDeltas(List origLines, * @return list of String lines of code. * @author Bill James (tankerbay@gmail.com) */ - private static List getDeltaText(Delta delta) { + private static List getDeltaText(AbstractDelta delta) { List buffer = new ArrayList<>(); - for (String line : delta.getOriginal().getLines()) { + for (String line : delta.getSource().getLines()) { buffer.add("-" + line); } - for (String line : delta.getRevised().getLines()) { + for (String line : delta.getTarget().getLines()) { buffer.add("+" + line); } return buffer; diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java new file mode 100644 index 00000000..17587b60 --- /dev/null +++ b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java @@ -0,0 +1,37 @@ +/* + * 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.List; + +/** + * Interface of a diff algorithm. + * + * @author Tobias Warneke (t.warneke@gmx.net) + */ +public interface DiffAlgorithmI { + + /** + * 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 computeDiff(List source, List target, DiffAlgorithmListener progress) throws DiffException; +} diff --git a/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java b/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java index 3029f6c8..c2e941f2 100644 --- a/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java +++ b/src/main/java/com/github/difflib/algorithm/jgit/HistogramDiff.java @@ -16,7 +16,7 @@ package com.github.difflib.algorithm.jgit; import com.github.difflib.algorithm.Change; -import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmI; import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.patch.DeltaType; @@ -34,17 +34,17 @@ * * @author toben */ -public class HistogramDiff implements DiffAlgorithm { +public class HistogramDiff implements DiffAlgorithmI { @Override - public List diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException { - Objects.requireNonNull(original, "original list must not be null"); - Objects.requireNonNull(revised, "revised list must not be null"); + public List computeDiff(List source, List target, DiffAlgorithmListener progress) throws DiffException { + Objects.requireNonNull(source, "source list must not be null"); + Objects.requireNonNull(target, "target list must not be null"); if (progress != null) { progress.diffStart(); } EditList diffList = new EditList(); - diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(progress), 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 patch = new ArrayList<>(); for (Edit edit : diffList) { DeltaType type = DeltaType.EQUAL; diff --git a/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java b/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java index e3a3d69a..00d22359 100644 --- a/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java +++ b/src/main/java/com/github/difflib/algorithm/myers/MyersDiff.java @@ -20,7 +20,7 @@ package com.github.difflib.algorithm.myers; import com.github.difflib.algorithm.Change; -import com.github.difflib.algorithm.DiffAlgorithm; +import com.github.difflib.algorithm.DiffAlgorithmI; import com.github.difflib.algorithm.DiffAlgorithmListener; import com.github.difflib.algorithm.DiffException; import com.github.difflib.algorithm.DifferentiationFailedException; @@ -34,7 +34,7 @@ /** * A clean-room implementation of Eugene Myers greedy differencing algorithm. */ -public final class MyersDiff implements DiffAlgorithm { +public final class MyersDiff implements DiffAlgorithmI { private final BiPredicate DEFAULT_EQUALIZER = Object::equals; private final BiPredicate equalizer; @@ -54,15 +54,15 @@ public MyersDiff(final BiPredicate equalizer) { * Return empty diff if get the error while procession the difference. */ @Override - public List diff(final List original, final List revised, DiffAlgorithmListener progress) throws DiffException { - Objects.requireNonNull(original, "original list must not be null"); - Objects.requireNonNull(revised, "revised list must not be null"); + public List computeDiff(final List source, final List target, DiffAlgorithmListener progress) throws DiffException { + Objects.requireNonNull(source, "source list must not be null"); + Objects.requireNonNull(target, "target list must not be null"); if (progress != null) { progress.diffStart(); } - PathNode path = buildPath(original, revised, progress); - List result = buildRevision(path, original, revised); + PathNode path = buildPath(source, target, progress); + List result = buildRevision(path, source, target); if (progress != null) { progress.diffEnd(); } @@ -177,18 +177,7 @@ private List buildRevision(PathNode actualPath, List orig, List re } else { changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j)); } -// Chunk original = new Chunk<>(ianchor, copyOfRange(orig, ianchor, i)); -// Chunk revised = new Chunk<>(janchor, copyOfRange(rev, janchor, j)); -// Delta delta = null; -// if (original.size() == 0 && revised.size() != 0) { -// delta = new InsertDelta<>(original, revised); -// } else if (original.size() > 0 && revised.size() == 0) { -// delta = new DeleteDelta<>(original, revised); -// } else { -// delta = new ChangeDelta<>(original, revised); -// } -// -// patch.addDelta(delta); + if (path.isSnake()) { path = path.prev; } diff --git a/src/main/java/com/github/difflib/patch/AbstractDelta.java b/src/main/java/com/github/difflib/patch/AbstractDelta.java new file mode 100644 index 00000000..30de287c --- /dev/null +++ b/src/main/java/com/github/difflib/patch/AbstractDelta.java @@ -0,0 +1,96 @@ +/* + * 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 { + private final Chunk source; + private final Chunk target; + private final DeltaType type; + + public AbstractDelta(DeltaType type, Chunk source, Chunk target) { + Objects.requireNonNull(source); + Objects.requireNonNull(target); + Objects.requireNonNull(type); + this.type = type; + this.source = source; + this.target = target; + } + + public Chunk getSource() { + return source; + } + + public Chunk 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 target) throws PatchFailedException { + getSource().verify(target); + } + + public abstract void applyTo(List target) throws PatchFailedException; + + public abstract void restore(List target); + + @Override + public int hashCode() { + int hash = 3; + hash = 61 * hash + Objects.hashCode(this.source); + hash = 61 * hash + Objects.hashCode(this.target); + hash = 61 * hash + Objects.hashCode(this.type); + return hash; + } + + @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; + } +} diff --git a/src/main/java/com/github/difflib/patch/ChangeDelta.java b/src/main/java/com/github/difflib/patch/ChangeDelta.java index 34a8bd6b..eb67606b 100644 --- a/src/main/java/com/github/difflib/patch/ChangeDelta.java +++ b/src/main/java/com/github/difflib/patch/ChangeDelta.java @@ -20,35 +20,38 @@ package com.github.difflib.patch; import java.util.List; +import java.util.Objects; /** * Describes the change-delta between original and revised texts. * * @author Dmitry Naumenko - * @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 extends Delta { +public final class ChangeDelta extends AbstractDelta { /** * Creates a change delta with the two given chunks. * - * @param original The original chunk. Must not be {@code null}. - * @param revised The original chunk. Must not be {@code null}. + * @param source The source chunk. Must not be {@code null}. + * @param target The target chunk. Must not be {@code null}. */ - public ChangeDelta(Chunk original, Chunk revised) { - super(DeltaType.CHANGE, original, revised); + public ChangeDelta(Chunk source, Chunk target) { + super(DeltaType.CHANGE, source, target); + Objects.requireNonNull(source, "source must not be null"); + Objects.requireNonNull(target, "target must not be null"); } @Override public void applyTo(List target) throws PatchFailedException { - verify(target); - int position = getOriginal().getPosition(); - int size = getOriginal().size(); + verifyChunk(target); + int position = getSource().getPosition(); + int size = getSource().size(); for (int i = 0; i < size; i++) { target.remove(position); } int i = 0; - for (T line : getRevised().getLines()) { + for (T line : getTarget().getLines()) { target.add(position + i, line); i++; } @@ -56,13 +59,13 @@ public void applyTo(List target) throws PatchFailedException { @Override public void restore(List target) { - int position = getRevised().getPosition(); - int size = getRevised().size(); + int position = getTarget().getPosition(); + int size = getTarget().size(); for (int i = 0; i < size; i++) { target.remove(position); } int i = 0; - for (T line : getOriginal().getLines()) { + for (T line : getSource().getLines()) { target.add(position + i, line); i++; } @@ -70,7 +73,7 @@ public void restore(List target) { @Override public String toString() { - return "[ChangeDelta, position: " + getOriginal().getPosition() + ", lines: " - + getOriginal().getLines() + " to " + getRevised().getLines() + "]"; + return "[ChangeDelta, position: " + getSource().getPosition() + ", lines: " + + getSource().getLines() + " to " + getTarget().getLines() + "]"; } } diff --git a/src/main/java/com/github/difflib/patch/Chunk.java b/src/main/java/com/github/difflib/patch/Chunk.java index 5855c3f1..3812be09 100644 --- a/src/main/java/com/github/difflib/patch/Chunk.java +++ b/src/main/java/com/github/difflib/patch/Chunk.java @@ -65,6 +65,7 @@ public Chunk(int position, T[] lines) { * Verifies that this chunk's saved text matches the corresponding text in the given sequence. * * @param target the sequence to verify against. + * @throws com.github.difflib.patch.PatchFailedException */ public void verify(List target) throws PatchFailedException { if (position > target.size() || last() > target.size()) { diff --git a/src/main/java/com/github/difflib/patch/DeleteDelta.java b/src/main/java/com/github/difflib/patch/DeleteDelta.java index 0ef14e91..d7417246 100644 --- a/src/main/java/com/github/difflib/patch/DeleteDelta.java +++ b/src/main/java/com/github/difflib/patch/DeleteDelta.java @@ -27,7 +27,7 @@ * @author Dmitry Naumenko * @param T The type of the compared elements in the 'lines'. */ -public final class DeleteDelta extends Delta { +public final class DeleteDelta extends AbstractDelta { /** * Creates a change delta with the two given chunks. @@ -41,9 +41,9 @@ public DeleteDelta(Chunk original, Chunk revised) { @Override public void applyTo(List target) throws PatchFailedException { - verify(target); - int position = getOriginal().getPosition(); - int size = getOriginal().size(); + verifyChunk(target); + int position = getSource().getPosition(); + int size = getSource().size(); for (int i = 0; i < size; i++) { target.remove(position); } @@ -51,8 +51,8 @@ public void applyTo(List target) throws PatchFailedException { @Override public void restore(List target) { - int position = this.getRevised().getPosition(); - List lines = this.getOriginal().getLines(); + int position = this.getTarget().getPosition(); + List lines = this.getSource().getLines(); for (int i = 0; i < lines.size(); i++) { target.add(position + i, lines.get(i)); } @@ -60,7 +60,7 @@ public void restore(List target) { @Override public String toString() { - return "[DeleteDelta, position: " + getOriginal().getPosition() + ", lines: " - + getOriginal().getLines() + "]"; + return "[DeleteDelta, position: " + getSource().getPosition() + ", lines: " + + getSource().getLines() + "]"; } } diff --git a/src/main/java/com/github/difflib/patch/InsertDelta.java b/src/main/java/com/github/difflib/patch/InsertDelta.java index d6656e02..3cb40dde 100644 --- a/src/main/java/com/github/difflib/patch/InsertDelta.java +++ b/src/main/java/com/github/difflib/patch/InsertDelta.java @@ -27,7 +27,7 @@ * @author Dmitry Naumenko * @param T The type of the compared elements in the 'lines'. */ -public final class InsertDelta extends Delta { +public final class InsertDelta extends AbstractDelta { /** * Creates an insert delta with the two given chunks. @@ -41,9 +41,9 @@ public InsertDelta(Chunk original, Chunk revised) { @Override public void applyTo(List target) throws PatchFailedException { - verify(target); - int position = this.getOriginal().getPosition(); - List lines = this.getRevised().getLines(); + verifyChunk(target); + int position = this.getSource().getPosition(); + List lines = this.getTarget().getLines(); for (int i = 0; i < lines.size(); i++) { target.add(position + i, lines.get(i)); } @@ -51,8 +51,8 @@ public void applyTo(List target) throws PatchFailedException { @Override public void restore(List target) { - int position = getRevised().getPosition(); - int size = getRevised().size(); + int position = getTarget().getPosition(); + int size = getTarget().size(); for (int i = 0; i < size; i++) { target.remove(position); } @@ -60,7 +60,7 @@ public void restore(List target) { @Override public String toString() { - return "[InsertDelta, position: " + getOriginal().getPosition() - + ", lines: " + getRevised().getLines() + "]"; + return "[InsertDelta, position: " + getSource().getPosition() + + ", lines: " + getTarget().getLines() + "]"; } } diff --git a/src/main/java/com/github/difflib/patch/Patch.java b/src/main/java/com/github/difflib/patch/Patch.java index ec7c357b..9bbb30dc 100644 --- a/src/main/java/com/github/difflib/patch/Patch.java +++ b/src/main/java/com/github/difflib/patch/Patch.java @@ -36,7 +36,7 @@ */ public final class Patch { - private final List> deltas; + private final List> deltas; public Patch() { this(10); @@ -54,9 +54,9 @@ public Patch(int estimatedPatchSize) { */ public List applyTo(List target) throws PatchFailedException { List result = new ArrayList<>(target); - ListIterator> it = getDeltas().listIterator(deltas.size()); + ListIterator> it = getDeltas().listIterator(deltas.size()); while (it.hasPrevious()) { - Delta delta = it.previous(); + AbstractDelta delta = it.previous(); delta.applyTo(result); } return result; @@ -70,9 +70,9 @@ public List applyTo(List target) throws PatchFailedException { */ public List restore(List target) { List result = new ArrayList<>(target); - ListIterator> it = getDeltas().listIterator(deltas.size()); + ListIterator> it = getDeltas().listIterator(deltas.size()); while (it.hasPrevious()) { - Delta delta = it.previous(); + AbstractDelta delta = it.previous(); delta.restore(result); } return result; @@ -83,7 +83,7 @@ public List restore(List target) { * * @param delta the given delta */ - public void addDelta(Delta delta) { + public void addDelta(AbstractDelta delta) { deltas.add(delta); } @@ -92,8 +92,8 @@ public void addDelta(Delta delta) { * * @return the deltas */ - public List> getDeltas() { - Collections.sort(deltas, comparing(d -> d.getOriginal().getPosition())); + public List> getDeltas() { + Collections.sort(deltas, comparing(d -> d.getSource().getPosition())); return deltas; } diff --git a/src/main/java/com/github/difflib/text/DiffRowGenerator.java b/src/main/java/com/github/difflib/text/DiffRowGenerator.java index 9df68481..447f2faf 100644 --- a/src/main/java/com/github/difflib/text/DiffRowGenerator.java +++ b/src/main/java/com/github/difflib/text/DiffRowGenerator.java @@ -24,7 +24,7 @@ import com.github.difflib.patch.ChangeDelta; import com.github.difflib.patch.Chunk; import com.github.difflib.patch.DeleteDelta; -import com.github.difflib.patch.Delta; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.InsertDelta; import com.github.difflib.patch.Patch; import com.github.difflib.text.DiffRow.Tag; @@ -284,11 +284,11 @@ private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String public List generateDiffRows(final List original, Patch patch) throws DiffException { List diffRows = new ArrayList<>(); int endPos = 0; - final List> deltaList = patch.getDeltas(); + final List> deltaList = patch.getDeltas(); for (int i = 0; i < deltaList.size(); i++) { - Delta delta = deltaList.get(i); - Chunk orig = delta.getOriginal(); - Chunk rev = delta.getRevised(); + AbstractDelta delta = deltaList.get(i); + Chunk orig = delta.getSource(); + Chunk rev = delta.getTarget(); for (String line : original.subList(endPos, orig.getPosition())) { diffRows.add(buildDiffRow(Tag.EQUAL, line, line)); @@ -336,9 +336,9 @@ public List generateDiffRows(final List original, Patch * * @param delta the given delta */ - private List generateInlineDiffs(Delta delta) throws DiffException { - List orig = StringUtils.normalize(delta.getOriginal().getLines()); - List rev = StringUtils.normalize(delta.getRevised().getLines()); + private List generateInlineDiffs(AbstractDelta delta) throws DiffException { + List orig = StringUtils.normalize(delta.getSource().getLines()); + List rev = StringUtils.normalize(delta.getTarget().getLines()); List origList; List revList; String joinedOrig = String.join("\n", orig); @@ -347,12 +347,12 @@ private List generateInlineDiffs(Delta delta) throws DiffExcept origList = inlineDiffSplitter.apply(joinedOrig); revList = inlineDiffSplitter.apply(joinedRev); - List> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas(); + List> inlineDeltas = DiffUtils.diff(origList, revList).getDeltas(); Collections.reverse(inlineDeltas); - for (Delta inlineDelta : inlineDeltas) { - Chunk inlineOrig = inlineDelta.getOriginal(); - Chunk inlineRev = inlineDelta.getRevised(); + for (AbstractDelta inlineDelta : inlineDeltas) { + Chunk inlineOrig = inlineDelta.getSource(); + Chunk inlineRev = inlineDelta.getTarget(); if (inlineDelta instanceof DeleteDelta) { wrapInTag(origList, inlineOrig.getPosition(), inlineOrig .getPosition() diff --git a/src/test/java/com/github/difflib/DiffUtilsTest.java b/src/test/java/com/github/difflib/DiffUtilsTest.java index d815401b..28a37219 100644 --- a/src/test/java/com/github/difflib/DiffUtilsTest.java +++ b/src/test/java/com/github/difflib/DiffUtilsTest.java @@ -4,7 +4,7 @@ import com.github.difflib.patch.ChangeDelta; import com.github.difflib.patch.Chunk; import com.github.difflib.patch.DeleteDelta; -import com.github.difflib.patch.Delta; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.InsertDelta; import com.github.difflib.patch.Patch; import java.io.BufferedReader; @@ -33,10 +33,10 @@ public void testDiff_Insert() throws DiffException { asList("hhh", "jjj", "kkk")); assertNotNull(patch); assertEquals(1, patch.getDeltas().size()); - final Delta delta = patch.getDeltas().get(0); + final AbstractDelta delta = patch.getDeltas().get(0); assertTrue(delta instanceof InsertDelta); - assertEquals(new Chunk<>(1, Collections.emptyList()), delta.getOriginal()); - assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getRevised()); + assertEquals(new Chunk<>(1, Collections.emptyList()), delta.getSource()); + assertEquals(new Chunk<>(1, Arrays.asList("jjj", "kkk")), delta.getTarget()); } @Test @@ -45,10 +45,10 @@ public void testDiff_Delete() throws DiffException { asList("ggg")); assertNotNull(patch); assertEquals(1, patch.getDeltas().size()); - final Delta delta = patch.getDeltas().get(0); + final AbstractDelta delta = patch.getDeltas().get(0); assertTrue(delta instanceof DeleteDelta); - assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getOriginal()); - assertEquals(new Chunk<>(0, Collections.emptyList()), delta.getRevised()); + assertEquals(new Chunk<>(0, Arrays.asList("ddd", "fff")), delta.getSource()); + assertEquals(new Chunk<>(0, Collections.emptyList()), delta.getTarget()); } @Test @@ -59,10 +59,10 @@ public void testDiff_Change() throws DiffException { final Patch patch = DiffUtils.diff(changeTest_from, changeTest_to); assertNotNull(patch); assertEquals(1, patch.getDeltas().size()); - final Delta delta = patch.getDeltas().get(0); + final AbstractDelta delta = patch.getDeltas().get(0); assertTrue(delta instanceof ChangeDelta); - assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getOriginal()); - assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getRevised()); + assertEquals(new Chunk<>(1, Arrays.asList("bbb")), delta.getSource()); + assertEquals(new Chunk<>(1, Arrays.asList("zzz")), delta.getTarget()); } @Test @@ -77,7 +77,7 @@ public void testDiff_EmptyListWithNonEmpty() throws DiffException { final Patch patch = DiffUtils.diff(new ArrayList<>(), Arrays.asList("aaa")); assertNotNull(patch); assertEquals(1, patch.getDeltas().size()); - final Delta delta = patch.getDeltas().get(0); + final AbstractDelta delta = patch.getDeltas().get(0); assertTrue(delta instanceof InsertDelta); } @@ -86,9 +86,9 @@ public void testDiffInline() throws DiffException { final Patch patch = DiffUtils.diffInline("", "test"); assertEquals(1, patch.getDeltas().size()); assertTrue(patch.getDeltas().get(0) instanceof InsertDelta); - assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition()); - assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size()); - assertEquals("test", patch.getDeltas().get(0).getRevised().getLines().get(0)); + assertEquals(0, patch.getDeltas().get(0).getSource().getPosition()); + assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size()); + assertEquals("test", patch.getDeltas().get(0).getTarget().getLines().get(0)); } @Test @@ -96,12 +96,12 @@ public void testDiffInline2() throws DiffException { final Patch patch = DiffUtils.diffInline("es", "fest"); assertEquals(2, patch.getDeltas().size()); assertTrue(patch.getDeltas().get(0) instanceof InsertDelta); - assertEquals(0, patch.getDeltas().get(0).getOriginal().getPosition()); - assertEquals(2, patch.getDeltas().get(1).getOriginal().getPosition()); - assertEquals(0, patch.getDeltas().get(0).getOriginal().getLines().size()); - assertEquals(0, patch.getDeltas().get(1).getOriginal().getLines().size()); - assertEquals("f", patch.getDeltas().get(0).getRevised().getLines().get(0)); - assertEquals("t", patch.getDeltas().get(1).getRevised().getLines().get(0)); + assertEquals(0, patch.getDeltas().get(0).getSource().getPosition()); + assertEquals(2, patch.getDeltas().get(1).getSource().getPosition()); + assertEquals(0, patch.getDeltas().get(0).getSource().getLines().size()); + assertEquals(0, patch.getDeltas().get(1).getSource().getLines().size()); + assertEquals("f", patch.getDeltas().get(0).getTarget().getLines().get(0)); + assertEquals("t", patch.getDeltas().get(1).getTarget().getLines().get(0)); } @Test @@ -111,7 +111,7 @@ public void testDiffIntegerList() throws DiffException { final Patch patch = DiffUtils.diff(original, revised); - for (Delta delta : patch.getDeltas()) { + for (AbstractDelta delta : patch.getDeltas()) { System.out.println(delta); } diff --git a/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java b/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java index 0d6a3e4e..0009f18b 100644 --- a/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/jgit/HistogramDiffTest.java @@ -61,7 +61,7 @@ public void tearDown() { public void testDiff() throws DiffException, PatchFailedException { List orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); List revList = Arrays.asList("C", "B", "A", "B", "A", "C"); - final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList, null)); + final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null)); System.out.println(patch); assertNotNull(patch); assertEquals(3, patch.getDeltas().size()); @@ -77,7 +77,7 @@ public void testDiffWithListener() throws DiffException, PatchFailedException { List revList = Arrays.asList("C", "B", "A", "B", "A", "C"); List logdata = new ArrayList<>(); - final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().diff(orgList, revList, new DiffAlgorithmListener() { + final Patch patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, new DiffAlgorithmListener() { @Override public void diffStart() { logdata.add("start"); diff --git a/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java b/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java index 54311be9..5f93570d 100644 --- a/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/jgit/LRHistogramDiffTest.java @@ -64,7 +64,7 @@ public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOExcept List revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb"))); List logdata = new ArrayList<>(); - Patch patch = Patch.generate(original, revised, new HistogramDiff().diff(original, revised, new DiffAlgorithmListener() { + Patch patch = Patch.generate(original, revised, new HistogramDiff().computeDiff(original, revised, new DiffAlgorithmListener() { @Override public void diffStart() { logdata.add("start"); diff --git a/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java b/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java index b9d12cef..ea9b0dcc 100644 --- a/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java +++ b/src/test/java/com/github/difflib/algorithm/myers/MyersDiffTest.java @@ -34,7 +34,7 @@ public class MyersDiffTest { public void testDiffMyersExample1Forward() throws DiffException { List original = Arrays.asList("A", "B", "C", "A", "B", "B", "A"); List revised = Arrays.asList("C", "B", "A", "B", "A", "C"); - final Patch patch = Patch.generate(original, revised, new MyersDiff().diff(original, revised, null)); + final Patch patch = Patch.generate(original, revised, new MyersDiff().computeDiff(original, revised, null)); assertNotNull(patch); assertEquals(4, patch.getDeltas().size()); assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString()); @@ -47,7 +47,7 @@ public void testDiffMyersExample1ForwardWithListener() throws DiffException { List logdata = new ArrayList<>(); final Patch patch = Patch.generate(original, revised, - new MyersDiff().diff(original, revised, new DiffAlgorithmListener() { + new MyersDiff().computeDiff(original, revised, new DiffAlgorithmListener() { @Override public void diffStart() { logdata.add("start"); diff --git a/src/test/java/com/github/difflib/examples/ComputeDifference.java b/src/test/java/com/github/difflib/examples/ComputeDifference.java index 82ff0190..bd6af94f 100644 --- a/src/test/java/com/github/difflib/examples/ComputeDifference.java +++ b/src/test/java/com/github/difflib/examples/ComputeDifference.java @@ -3,7 +3,7 @@ import com.github.difflib.DiffUtils; import com.github.difflib.TestConstants; import com.github.difflib.algorithm.DiffException; -import com.github.difflib.patch.Delta; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.Patch; import java.io.File; import java.io.IOException; @@ -22,7 +22,7 @@ public static void main(String[] args) throws DiffException, IOException { // Compute diff. Get the Patch object. Patch is the container for computed deltas. Patch patch = DiffUtils.diff(original, revised); - for (Delta delta : patch.getDeltas()) { + for (AbstractDelta delta : patch.getDeltas()) { System.out.println(delta); } } From d506d62a9104a080c004f4436b76d552ecddee7c Mon Sep 17 00:00:00 2001 From: wumpz Date: Mon, 2 Jul 2018 00:44:53 +0200 Subject: [PATCH 37/44] added a default method for computeDiff from arrays --- .../difflib/algorithm/DiffAlgorithmI.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java index 17587b60..d9236290 100644 --- a/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java +++ b/src/main/java/com/github/difflib/algorithm/DiffAlgorithmI.java @@ -15,15 +15,16 @@ */ 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 { - + /** * Computes the changeset to patch the source list to the target list. * @@ -34,4 +35,17 @@ public interface DiffAlgorithmI { * @throws DiffException */ List computeDiff(List source, List 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 computeDiff(T[] source, T[] target, DiffAlgorithmListener progress) throws DiffException { + return computeDiff(Arrays.asList(source), Arrays.asList(target), progress); + } } From 1161243bc2cbf558fb49a887f8181cc88483cf38 Mon Sep 17 00:00:00 2001 From: wumpz Date: Fri, 3 Aug 2018 09:23:04 +0200 Subject: [PATCH 38/44] --- .../github/difflib/text/DiffRowGenerator.java | 2 +- .../difflib/text/DiffRowGeneratorTest.java | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/difflib/text/DiffRowGenerator.java b/src/main/java/com/github/difflib/text/DiffRowGenerator.java index 447f2faf..5465c9aa 100644 --- a/src/main/java/com/github/difflib/text/DiffRowGenerator.java +++ b/src/main/java/com/github/difflib/text/DiffRowGenerator.java @@ -413,7 +413,7 @@ private List generateInlineDiffs(AbstractDelta delta) throws Di * @param tag the tag name without angle brackets, just a word * @param cssClass the optional css class */ - public static void wrapInTag(List sequence, int startPosition, + private static void wrapInTag(List sequence, int startPosition, int endPosition, Function generator) { sequence.add(startPosition, generator.apply(true)); sequence.add(endPosition, generator.apply(false)); diff --git a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java index f80cefb3..be945f48 100644 --- a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java +++ b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java @@ -315,4 +315,55 @@ public void testGeneratorIssue15() throws DiffException, IOException { } } } + + @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 rows = generator.generateDiffRows( + Arrays.asList(aa.split("\n")), + Arrays.asList(bb.split("\n"))); + + System.out.println(rows); + } + + @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 rows = generator.generateDiffRows( + Arrays.asList(aa.split("\n")), + Arrays.asList(bb.split("\n"))); + + System.out.println(rows); + } + + @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 rows = generator.generateDiffRows( + Arrays.asList(aa.split("\n")), + Arrays.asList(bb.split("\n"))); + + System.out.println(rows); + } } From c410422860a8d227b79f4b6cac037b65b86a5d7e Mon Sep 17 00:00:00 2001 From: wumpz Date: Fri, 3 Aug 2018 10:51:56 +0200 Subject: [PATCH 39/44] fixes #22 --- .../github/difflib/text/DiffRowGenerator.java | 67 ++++++++++++++----- .../difflib/text/DiffRowGeneratorTest.java | 23 +++++-- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/github/difflib/text/DiffRowGenerator.java b/src/main/java/com/github/difflib/text/DiffRowGenerator.java index 5465c9aa..30e16944 100644 --- a/src/main/java/com/github/difflib/text/DiffRowGenerator.java +++ b/src/main/java/com/github/difflib/text/DiffRowGenerator.java @@ -47,13 +47,14 @@ * */ public class DiffRowGenerator { + public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]"); - + public static final BiPredicate IGNORE_WHITESPACE_EQUALIZER = (original, revised) -> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " ")); - + public static final BiPredicate DEFAULT_EQUALIZER = Object::equals; - + /** * Splitting lines by word to achieve word by word diff checking. */ @@ -69,7 +70,7 @@ public class DiffRowGenerator { } return list; }; - + private final boolean showInlineDiffs; private final boolean ignoreWhiteSpaces; private final Function oldTag; @@ -195,11 +196,10 @@ public Builder mergeOriginalRevised(boolean mergeOriginalRevised) { * deliver no in word changes. */ public Builder inlineDiffByWord(boolean inlineDiffByWord) { - inlineDiffSplitter = inlineDiffByWord?SPLITTER_BY_WORD:SPLITTER_BY_CHARACTER; + inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER; return this; } - - + public Builder inlineDiffBySplitter(Function> inlineDiffSplitter) { this.inlineDiffSplitter = inlineDiffSplitter; return this; @@ -220,7 +220,7 @@ private DiffRowGenerator(Builder builder) { inlineDiffSplitter = builder.inlineDiffSplitter; equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER; reportLinesUnchanged = builder.reportLinesUnchanged; - + Objects.requireNonNull(inlineDiffSplitter); } @@ -356,17 +356,17 @@ private List generateInlineDiffs(AbstractDelta delta) throws Di if (inlineDelta instanceof DeleteDelta) { wrapInTag(origList, inlineOrig.getPosition(), inlineOrig .getPosition() - + inlineOrig.size() + 1, oldTag); + + inlineOrig.size(), oldTag); } else if (inlineDelta instanceof InsertDelta) { if (mergeOriginalRevised) { origList.addAll(inlineOrig.getPosition(), revList.subList(inlineRev.getPosition(), inlineRev.getPosition() + inlineRev.size())); wrapInTag(origList, inlineOrig.getPosition(), inlineOrig.getPosition() - + inlineRev.size() + 1, newTag); + + inlineRev.size(), newTag); } else { wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition() - + inlineRev.size() + 1, newTag); + + inlineRev.size(), newTag); } } else if (inlineDelta instanceof ChangeDelta) { if (mergeOriginalRevised) { @@ -374,14 +374,14 @@ private List generateInlineDiffs(AbstractDelta delta) throws Di revList.subList(inlineRev.getPosition(), inlineRev.getPosition() + inlineRev.size())); wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(), inlineOrig.getPosition() + inlineOrig.size() - + inlineRev.size() + 1, newTag); + + inlineRev.size(), newTag); } else { wrapInTag(revList, inlineRev.getPosition(), inlineRev.getPosition() - + inlineRev.size() + 1, newTag); + + inlineRev.size(), newTag); } wrapInTag(origList, inlineOrig.getPosition(), inlineOrig .getPosition() - + inlineOrig.size() + 1, oldTag); + + inlineOrig.size(), oldTag); } } StringBuilder origResult = new StringBuilder(); @@ -413,10 +413,41 @@ private List generateInlineDiffs(AbstractDelta delta) throws Di * @param tag the tag name without angle brackets, just a word * @param cssClass the optional css class */ - private static void wrapInTag(List sequence, int startPosition, - int endPosition, Function generator) { - sequence.add(startPosition, generator.apply(true)); - sequence.add(endPosition, generator.apply(false)); + static void wrapInTag(List sequence, int startPosition, + int endPosition, Function 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)); } protected final static List splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) { diff --git a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java index be945f48..f9e5c710 100644 --- a/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java +++ b/src/test/java/com/github/difflib/text/DiffRowGeneratorTest.java @@ -148,8 +148,8 @@ public void testGeneratorWithMerge3() throws DiffException { print(rows); assertEquals(6, rows.size()); - assertEquals("[CHANGE,test,anything]", rows.get(0).toString()); - assertEquals("[CHANGE,anything ,]", rows.get(1).toString()); + assertEquals("[CHANGE,test,anything]", rows.get(0).toString()); + assertEquals("[CHANGE,anything ,]", rows.get(1).toString()); assertEquals("[CHANGE, ,]", rows.get(2).toString()); assertEquals("[EQUAL,other,other]", rows.get(3).toString()); assertEquals("[INSERT,test,test]", rows.get(4).toString()); @@ -330,9 +330,16 @@ public void testGeneratorIssue22() throws DiffException { Arrays.asList(aa.split("\n")), Arrays.asList(bb.split("\n"))); - System.out.println(rows); + 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() @@ -347,9 +354,10 @@ public void testGeneratorIssue22_2() throws DiffException { Arrays.asList(aa.split("\n")), Arrays.asList(bb.split("\n"))); - System.out.println(rows); + 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() @@ -364,6 +372,7 @@ public void testGeneratorIssue22_3() throws DiffException { Arrays.asList(aa.split("\n")), Arrays.asList(bb.split("\n"))); - System.out.println(rows); + 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()); } } From f2ab70afc484f2ece9603ae3f3bdad147e50a29f Mon Sep 17 00:00:00 2001 From: wumpz Date: Fri, 3 Aug 2018 10:55:07 +0200 Subject: [PATCH 40/44] fixes #22 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 08334bf5..67679eb2 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ But it can easily replaced by any other which is better for handing your texts. ### Changelog ### * Version 3.0-SNAPSHOT + * changed generation of inline diffes, if there area different linefeeds within one diff to exclude linefeeds + 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 From 5dc489a4eff57adf111111efad49a54a261571af Mon Sep 17 00:00:00 2001 From: Sanghyuk Jung Date: Thu, 13 Sep 2018 17:31:05 +0900 Subject: [PATCH 41/44] Refactor to reuse java.util.regex.Pattern --- .../java/com/github/difflib/text/DiffRowGenerator.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/difflib/text/DiffRowGenerator.java b/src/main/java/com/github/difflib/text/DiffRowGenerator.java index 30e16944..6dd056ec 100644 --- a/src/main/java/com/github/difflib/text/DiffRowGenerator.java +++ b/src/main/java/com/github/difflib/text/DiffRowGenerator.java @@ -49,9 +49,10 @@ public class DiffRowGenerator { public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]"); + public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); public static final BiPredicate IGNORE_WHITESPACE_EQUALIZER = (original, revised) - -> original.trim().replaceAll("\\s+", " ").equals(revised.trim().replaceAll("\\s+", " ")); + -> adjustWhitespace(original).equals(adjustWhitespace(revised)); public static final BiPredicate DEFAULT_EQUALIZER = Object::equals; @@ -468,4 +469,8 @@ protected final static List splitStringPreserveDelimiter(String str, Pat } return list; } + + private static String adjustWhitespace(String raw) { + return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" "); + } } From 2671949b92a22f05c175c84bf6a46f20af18270d Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 13 Sep 2018 15:32:14 +0200 Subject: [PATCH 42/44] --- .../github/difflib/text/DiffRowGenerator.java | 434 +++++++++--------- 1 file changed, 216 insertions(+), 218 deletions(-) diff --git a/src/main/java/com/github/difflib/text/DiffRowGenerator.java b/src/main/java/com/github/difflib/text/DiffRowGenerator.java index 6dd056ec..8ded4253 100644 --- a/src/main/java/com/github/difflib/text/DiffRowGenerator.java +++ b/src/main/java/com/github/difflib/text/DiffRowGenerator.java @@ -21,10 +21,10 @@ import com.github.difflib.DiffUtils; import com.github.difflib.algorithm.DiffException; +import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.ChangeDelta; import com.github.difflib.patch.Chunk; import com.github.difflib.patch.DeleteDelta; -import com.github.difflib.patch.AbstractDelta; import com.github.difflib.patch.InsertDelta; import com.github.difflib.patch.Patch; import com.github.difflib.text.DiffRow.Tag; @@ -48,19 +48,11 @@ */ public class DiffRowGenerator { - public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]"); - public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); + public static final BiPredicate DEFAULT_EQUALIZER = Object::equals; public static final BiPredicate IGNORE_WHITESPACE_EQUALIZER = (original, revised) -> adjustWhitespace(original).equals(adjustWhitespace(revised)); - public static final BiPredicate DEFAULT_EQUALIZER = Object::equals; - - /** - * Splitting lines by word to achieve word by word diff checking. - */ - public static final Function> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN); - /** * Splitting lines by character to achieve char by char diff checking. */ @@ -71,145 +63,94 @@ public class DiffRowGenerator { } return list; }; - - private final boolean showInlineDiffs; - private final boolean ignoreWhiteSpaces; - private final Function oldTag; - private final Function newTag; - private final Function> inlineDiffSplitter; - private final int columnWidth; - private final BiPredicate equalizer; - private final boolean mergeOriginalRevised; - private final boolean reportLinesUnchanged; - + public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]"); /** - * This class used for building the DiffRowGenerator. - * - * @author dmitry - * + * Splitting lines by word to achieve word by word diff checking. */ - public static class Builder { - - private boolean showInlineDiffs = false; - private boolean ignoreWhiteSpaces = false; - - private Function oldTag = f -> f ? "" : ""; - private Function newTag = f -> f ? "" : ""; - - private int columnWidth = 0; - private boolean mergeOriginalRevised = false; - private boolean reportLinesUnchanged = false; - private Function> inlineDiffSplitter = SPLITTER_BY_CHARACTER; + public static final Function> SPLITTER_BY_WORD = line -> splitStringPreserveDelimiter(line, SPLIT_BY_WORD_PATTERN); + public static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); - private Builder() { - } + public static Builder create() { + return new 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; - } + private static String adjustWhitespace(String raw) { + return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" "); + } - /** - * 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; + protected final static List splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) { + List 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; + } - /** - * 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; - } + /** + * 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 sequence, int startPosition, + int endPosition, Function tagGenerator) { + int endPos = endPosition; - /** - * 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 generator) { - this.oldTag = generator; - return this; - } + while (endPos >= startPosition) { - /** - * Generator for New-Text-Tags. - * - * @param generator - * @return - */ - public Builder newTag(Function generator) { - this.newTag = generator; - return this; - } + //search position for end tag + while (endPos > startPosition) { + if (!"\n".equals(sequence.get(endPos - 1))) { + break; + } + endPos--; + } - /** - * 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; + if (endPos == startPosition) { + break; } - 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); - } + sequence.add(endPos, tagGenerator.apply(false)); + endPos--; - /** - * 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; - } + //search position for end tag + while (endPos > startPosition) { + if ("\n".equals(sequence.get(endPos - 1))) { + break; + } + endPos--; + } - /** - * 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; + sequence.add(endPos, tagGenerator.apply(true)); + endPos--; } - public Builder inlineDiffBySplitter(Function> inlineDiffSplitter) { - this.inlineDiffSplitter = inlineDiffSplitter; - return this; - } +// sequence.add(endPosition, tagGenerator.apply(false)); +// sequence.add(startPosition, tagGenerator.apply(true)); } + private final int columnWidth; + private final BiPredicate equalizer; + private final boolean ignoreWhiteSpaces; + private final Function> inlineDiffSplitter; + private final boolean mergeOriginalRevised; + private final Function newTag; + private final Function oldTag; + private final boolean reportLinesUnchanged; - public static Builder create() { - return new Builder(); - } + private final boolean showInlineDiffs; private DiffRowGenerator(Builder builder) { showInlineDiffs = builder.showInlineDiffs; @@ -237,42 +178,6 @@ public List generateDiffRows(List original, List revise return generateDiffRows(original, DiffUtils.diff(original, revised, equalizer)); } - private String preprocessLine(String line) { - if (columnWidth == 0) { - return StringUtils.normalize(line); - } else { - return StringUtils.wrapText(StringUtils.normalize(line), columnWidth); - } - } - - private DiffRow buildDiffRow(Tag type, String orgline, String newline) { - if (reportLinesUnchanged) { - return new DiffRow(type, orgline, newline); - } else { - String wrapOrg = preprocessLine(orgline); - if (Tag.DELETE == type) { - if (mergeOriginalRevised || showInlineDiffs) { - wrapOrg = oldTag.apply(true) + wrapOrg + oldTag.apply(false); - } - } - String wrapNew = preprocessLine(newline); - if (Tag.INSERT == type) { - if (mergeOriginalRevised) { - wrapOrg = newTag.apply(true) + wrapNew + newTag.apply(false); - } else if (showInlineDiffs) { - wrapNew = newTag.apply(true) + wrapNew + newTag.apply(false); - } - } - return new DiffRow(type, wrapOrg, wrapNew); - } - } - - private DiffRow buildDiffRowWithoutNormalizing(Tag type, String orgline, String newline) { - return new DiffRow(type, - StringUtils.wrapText(orgline, columnWidth), - StringUtils.wrapText(newline, columnWidth)); - } - /** * Generates the DiffRows describing the difference between original and revised texts using the given patch. Useful * for displaying side-by-side diff. @@ -332,6 +237,34 @@ public List generateDiffRows(final List original, Patch 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 * @@ -406,71 +339,136 @@ private List generateInlineDiffs(AbstractDelta delta) throws Di return diffRows; } + private String preprocessLine(String line) { + if (columnWidth == 0) { + return StringUtils.normalize(line); + } else { + return StringUtils.wrapText(StringUtils.normalize(line), columnWidth); + } + } + /** - * Wrap the elements in the sequence with the given tag + * This class used for building the DiffRowGenerator. + * + * @author dmitry * - * @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 sequence, int startPosition, - int endPosition, Function tagGenerator) { - int endPos = endPosition; + public static class Builder { - while (endPos >= startPosition) { + private boolean showInlineDiffs = false; + private boolean ignoreWhiteSpaces = false; - //search position for end tag - while (endPos > startPosition) { - if (!"\n".equals(sequence.get(endPos - 1))) { - break; - } - endPos--; - } + private Function oldTag = f -> f ? "" : ""; + private Function newTag = f -> f ? "" : ""; - if (endPos == startPosition) { - break; - } + private int columnWidth = 0; + private boolean mergeOriginalRevised = false; + private boolean reportLinesUnchanged = false; + private Function> inlineDiffSplitter = SPLITTER_BY_CHARACTER; - sequence.add(endPos, tagGenerator.apply(false)); - endPos--; + private Builder() { + } - //search position for end tag - while (endPos > startPosition) { - if ("\n".equals(sequence.get(endPos - 1))) { - break; - } - endPos--; - } + /** + * 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; + } - sequence.add(endPos, tagGenerator.apply(true)); - endPos--; + /** + * 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; } -// sequence.add(endPosition, tagGenerator.apply(false)); -// sequence.add(startPosition, tagGenerator.apply(true)); - } + /** + * 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; + } - protected final static List splitStringPreserveDelimiter(String str, Pattern SPLIT_PATTERN) { - List 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)); + /** + * 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 generator) { + this.oldTag = generator; + return this; + } + + /** + * Generator for New-Text-Tags. + * + * @param generator + * @return + */ + public Builder newTag(Function 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; } - return list; - } - private static String adjustWhitespace(String raw) { - return WHITESPACE_PATTERN.matcher(raw.trim()).replaceAll(" "); + /** + * 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> inlineDiffSplitter) { + this.inlineDiffSplitter = inlineDiffSplitter; + return this; + } } } From b273da278e76ae0e5b4117699b6eae68455d1686 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 10 Oct 2018 09:54:45 +0200 Subject: [PATCH 43/44] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 67679eb2..df31d84b 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ But it can easily replaced by any other which is better for handing your texts. ### Changelog ### * Version 3.0-SNAPSHOT - * changed generation of inline diffes, if there area different linefeeds within one diff to exclude linefeeds + * 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 From 5c33149e2a87d020263533271a9ed2086d1c2712 Mon Sep 17 00:00:00 2001 From: wumpz Date: Thu, 18 Oct 2018 21:39:21 +0200 Subject: [PATCH 44/44] [maven-release-plugin] prepare release diffutils-3.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2b45fa26..081b7949 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ com.github.wumpz diffutils jar - 3.0-SNAPSHOT + 3.0 java-diff-utils The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java. https://github.com/wumpz/java-diff-utils @@ -24,7 +24,7 @@ scm:git:https://github.com/wumpz/java-diff-utils.git scm:git:ssh://git@github.com:wumpz/java-diff-utils.git https://github.com/wumpz/java-diff-utils.git - HEAD + diffutils-3.0