mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Compare commits
91 Commits
java-diff-
...
java-diff-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab1e38c57b | ||
|
|
286e807232 | ||
|
|
c85296b63d | ||
|
|
4c457b39dc | ||
|
|
7dea4e2298 | ||
|
|
2b02951e89 | ||
|
|
894b8ba300 | ||
|
|
2294c5be7b | ||
|
|
7203d4890f | ||
|
|
e413d79ecd | ||
|
|
c765616957 | ||
|
|
24c3df1f39 | ||
|
|
9765052226 | ||
|
|
8bb4a9a8b1 | ||
|
|
89ce301123 | ||
|
|
3d5343c283 | ||
|
|
d384ab6178 | ||
|
|
f03df6cf38 | ||
|
|
5a11752126 | ||
|
|
94674a0ad7 | ||
|
|
91a42b2793 | ||
|
|
bf4ec94cc9 | ||
|
|
df27b689f3 | ||
|
|
2a1239b3a2 | ||
|
|
8d38e1012e | ||
|
|
8880ec545b | ||
|
|
ce05cbf9c9 | ||
|
|
f71275de08 | ||
|
|
307574225a | ||
|
|
b9fea86e43 | ||
|
|
b17bbb12c3 | ||
|
|
0905d0e5f7 | ||
|
|
57df629662 | ||
|
|
73ec9e9320 | ||
|
|
507ced4493 | ||
|
|
7e8d2867ad | ||
|
|
ffd14fb67d | ||
|
|
04b5c7e167 | ||
|
|
a9b5e5fa88 | ||
|
|
4061ab6c57 | ||
|
|
7da297322b | ||
|
|
fb0837fd73 | ||
|
|
642dc659f1 | ||
|
|
e59e9e8379 | ||
|
|
6748451e94 | ||
|
|
445381b277 | ||
|
|
ab76d7229a | ||
|
|
7647c0a39e | ||
|
|
759a2ba67a | ||
|
|
270754fb8c | ||
|
|
06f1e0593e | ||
|
|
26be87091b | ||
|
|
b927e6f477 | ||
|
|
ba3c313440 | ||
|
|
d62e9a9fb6 | ||
|
|
d7a5247b1d | ||
|
|
b8aef6a3da | ||
|
|
7d8b87a0ec | ||
|
|
1fdea352ad | ||
|
|
c6d3f73d22 | ||
|
|
5338313a54 | ||
|
|
55d71fea71 | ||
|
|
e4ab41bf04 | ||
|
|
1ec708fe30 | ||
|
|
fcf83e918f | ||
|
|
4ee56d2554 | ||
|
|
21f9e9d415 | ||
|
|
76ae5f3b6f | ||
|
|
7d88486bdc | ||
|
|
694e93143d | ||
|
|
dac751bf73 | ||
|
|
f76abb58f6 | ||
|
|
de04bd688a | ||
|
|
e38cd3a99f | ||
|
|
96f7fbdebd | ||
|
|
d3524314eb | ||
|
|
85c3199570 | ||
|
|
dbe601c2fc | ||
|
|
fc7c714264 | ||
|
|
dcc29eee7e | ||
|
|
f0f5d241c7 | ||
|
|
e11c1599ee | ||
|
|
73c4c307a9 | ||
|
|
8006986dd8 | ||
|
|
f292c97dae | ||
|
|
7620f919c2 | ||
|
|
a8e4ce2eff | ||
|
|
9bd7aaa0f2 | ||
|
|
80c17a30d9 | ||
|
|
b5569703c8 | ||
|
|
47fe8e0ea6 |
10
.github/ISSUE_TEMPLATE/simple.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/simple.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Simple
|
||||
about: just a simple issue
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
26
.github/workflows/maven.yml
vendored
Normal file
26
.github/workflows/maven.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [8, 11]
|
||||
name: Java ${{ matrix.java }} building ...
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Java ${{ matrix.java }}
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
19
.github/workflows/stale.yml
vendored
Normal file
19
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'Stale issue message'
|
||||
stale-pr-message: 'Stale pull request message'
|
||||
stale-issue-label: 'no-issue-activity'
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
||||
build/
|
||||
nbproject/
|
||||
target/
|
||||
|
||||
*.iml
|
||||
|
||||
43
CHANGELOG.md
43
CHANGELOG.md
@@ -5,7 +5,48 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
This project uses a custom versioning scheme (and not [Semantic Versioning](https://semver.org/spec/v2.0.0.html)).
|
||||
|
||||
## [Unreleased]
|
||||
## [unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
## [4.11]
|
||||
|
||||
### Changed
|
||||
|
||||
* bugfixing new UnifiedDiff reader
|
||||
* header for each file
|
||||
* skip empty lines
|
||||
* introduction of Meyers Diff Algorithm with Linear Space improvment (until matured this will not be the default diff algorithm)
|
||||
* introduction of DiffAlgorithmFactory to set the default diff algorithm DiffUtils use (`DiffUtils.withDefaultDiffAlgorithmFactory(MeyersDiffWithLinearSpace.factory());`)
|
||||
|
||||
## [4.10]
|
||||
|
||||
### Changed
|
||||
|
||||
* bugfixing on new UnifiedDiff reader / writer for multifile usage
|
||||
* bugfix for wrong DiffRow type while transforming from a patch that removed a line in one changeset
|
||||
* introduced change position into UnifiedDiff reader
|
||||
* introduced first version of conflict output possibility (like GIT merge conflict)
|
||||
* moved verification to `AbstractDelta`
|
||||
* introduced `ConflictOutput` to `Patch` to add optional behaviour to patch conflicts
|
||||
|
||||
## [4.9]
|
||||
|
||||
### Changed
|
||||
|
||||
* make patch serializable
|
||||
|
||||
## [4.8]
|
||||
|
||||
### Changed
|
||||
|
||||
* some bugfixes regarding unified diff writer
|
||||
* UnifiedDiffReader improved for **deleted file mode** and better timestamp recognition
|
||||
* UnifiedDiffReader improved for **new file mode** and better timestamp recognition
|
||||
|
||||
## [4.7]
|
||||
|
||||
### Changed
|
||||
|
||||
* minor bug fixes
|
||||
* optional include equal parts of original and revised data
|
||||
|
||||
19
README.md
19
README.md
@@ -3,7 +3,11 @@
|
||||
## Status
|
||||
|
||||
[](https://travis-ci.org/java-diff-utils/java-diff-utils)
|
||||
[](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
|
||||
|
||||
[](https://github.com/java-diff-utils/java-diff-utils/actions?query=workflow%3A%22Java+CI+with+Maven%22)
|
||||
|
||||
[](https://www.codacy.com/gh/java-diff-utils/java-diff-utils/dashboard?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
|
||||
|
||||
[](http://maven-badges.herokuapp.com/maven-central/io.github.java-diff-utils/java-diff-utils)
|
||||
|
||||
## Intro
|
||||
@@ -14,9 +18,13 @@ Main reason to build this library was the lack of easy-to-use libraries with all
|
||||
|
||||
**This is originally a fork of java-diff-utils from Google Code Archive.**
|
||||
|
||||
## API
|
||||
|
||||
Javadocs of the actual release version: [JavaDocs java-diff-utils](https://java-diff-utils.github.io/java-diff-utils/4.7/docs/api/)
|
||||
|
||||
## Examples
|
||||
|
||||
Look [here](https://github.com/wumpz/java-diff-utils/wiki) to find more helpful informations and examples.
|
||||
Look [here](https://github.com/java-diff-utils/java-diff-utils/wiki) to find more helpful informations and examples.
|
||||
|
||||
These two outputs are generated using this java-diff-utils. The source code can also be found at the *Examples* page:
|
||||
|
||||
@@ -41,12 +49,13 @@ This is a test ~senctence~**for diffutils**.
|
||||
* producing human-readable differences
|
||||
* inline difference construction
|
||||
* Algorithms:
|
||||
* Myer
|
||||
* Meyers Standard Algorithm
|
||||
* Meyers with linear space improvement
|
||||
* HistogramDiff using JGit Library
|
||||
|
||||
### Algorithms
|
||||
|
||||
* Myer's diff
|
||||
* Meyer's diff
|
||||
* HistogramDiff
|
||||
|
||||
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.
|
||||
@@ -80,7 +89,7 @@ Just add the code below to your maven dependencies:
|
||||
<dependency>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils</artifactId>
|
||||
<version>4.5</version>
|
||||
<version>4.9</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
theme: jekyll-theme-minimal
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.7</version>
|
||||
<version>4.11</version>
|
||||
</parent>
|
||||
<artifactId>java-diff-utils-jgit</artifactId>
|
||||
<name>java-diff-utils-jgit</name>
|
||||
@@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>4.4.1.201607150455-r</version>
|
||||
<version>5.8.1.202007141445-r</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.googlecode.javaewah</groupId>
|
||||
|
||||
@@ -41,7 +41,7 @@ public class HistogramDiffTest {
|
||||
public void testDiff() throws PatchFailedException {
|
||||
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null));
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff<String>().computeDiff(orgList, revList, null));
|
||||
System.out.println(patch);
|
||||
assertNotNull(patch);
|
||||
assertEquals(3, patch.getDeltas().size());
|
||||
@@ -57,7 +57,7 @@ public class HistogramDiffTest {
|
||||
List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, new DiffAlgorithmListener() {
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff<String>().computeDiff(orgList, revList, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
@@ -82,6 +82,6 @@ public class HistogramDiffTest {
|
||||
assertEquals(revList, patched);
|
||||
|
||||
System.out.println(logdata);
|
||||
assertEquals(17, logdata.size());
|
||||
assertEquals(19, logdata.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class LRHistogramDiffTest {
|
||||
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff<String>().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.7</version>
|
||||
<version>4.11</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@@ -51,6 +51,16 @@
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>target/test-classes/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
*/
|
||||
package com.github.difflib;
|
||||
|
||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.algorithm.myers.MyersDiff;
|
||||
import com.github.difflib.algorithm.myers.MeyersDiff;
|
||||
import com.github.difflib.patch.AbstractDelta;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
@@ -34,26 +35,35 @@ import java.util.function.BiPredicate;
|
||||
public final class DiffUtils {
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
* This factory generates the DEFAULT_DIFF algorithm for all these routines.
|
||||
*/
|
||||
static DiffAlgorithmFactory DEFAULT_DIFF = MeyersDiff.factory();
|
||||
|
||||
public static void withDefaultDiffAlgorithmFactory(DiffAlgorithmFactory factory) {
|
||||
DEFAULT_DIFF = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements
|
||||
* with default diff algorithm
|
||||
*
|
||||
* @param <T> types to be diffed
|
||||
* @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}.
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), progress);
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), progress);
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null);
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null);
|
||||
}
|
||||
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null, includeEqualParts);
|
||||
return DiffUtils.diff(original, revised, DEFAULT_DIFF.create(), null, includeEqualParts);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,45 +77,46 @@ public final class DiffUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
* Computes the difference between the original and revised list of elements
|
||||
* with default diff algorithm
|
||||
*
|
||||
* @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}.
|
||||
* @param equalizer the equalizer object to replace the default compare
|
||||
* algorithm (Object.equals). If {@code null} the default equalizer of the
|
||||
* default algorithm is used..
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> source, List<T> target,
|
||||
BiPredicate<T, T> equalizer) {
|
||||
if (equalizer != null) {
|
||||
return DiffUtils.diff(source, target,
|
||||
new MyersDiff<>(equalizer));
|
||||
DEFAULT_DIFF.create(equalizer));
|
||||
}
|
||||
return DiffUtils.diff(source, target, new MyersDiff<>());
|
||||
return DiffUtils.diff(source, target, new MeyersDiff<>());
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
||||
return diff(original, revised, algorithm, progress, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
* 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}.
|
||||
* @param progress The diff algorithm listener.
|
||||
* @param includeEqualParts Include equal data parts into the patch.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress,
|
||||
boolean includeEqualParts) {
|
||||
Objects.requireNonNull(original, "original must not be null");
|
||||
Objects.requireNonNull(revised, "revised must not be null");
|
||||
@@ -115,23 +126,23 @@ public final class DiffUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
* 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}.
|
||||
* @return The patch describing the difference between the original and
|
||||
* revised sequences. Never {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
||||
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 characters, like DiffRowGenerator does and merges those changes at the end
|
||||
* together again.
|
||||
* Computes the difference between the given texts inline. This one uses the
|
||||
* "trick" to make out of texts lists of characters, like DiffRowGenerator
|
||||
* does and merges those changes at the end together again.
|
||||
*
|
||||
* @param original
|
||||
* @param revised
|
||||
|
||||
@@ -33,6 +33,7 @@ public final class UnifiedDiffUtils {
|
||||
|
||||
private static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern
|
||||
.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
|
||||
private static final String NULL_FILE_INDICATOR = "/dev/null";
|
||||
|
||||
/**
|
||||
* Parse the given text in unified format and creates the list of deltas for it.
|
||||
@@ -97,26 +98,38 @@ public final class UnifiedDiffUtils {
|
||||
List<String> oldChunkLines = new ArrayList<>();
|
||||
List<String> newChunkLines = new ArrayList<>();
|
||||
|
||||
List<Integer> removePosition = new ArrayList<>();
|
||||
List<Integer> addPosition = new ArrayList<>();
|
||||
int removeNum = 0;
|
||||
int addNum = 0;
|
||||
for (String[] raw_line : rawChunk) {
|
||||
tag = raw_line[0];
|
||||
rest = raw_line[1];
|
||||
if (" ".equals(tag) || "-".equals(tag)) {
|
||||
removeNum++;
|
||||
oldChunkLines.add(rest);
|
||||
if ("-".equals(tag)) {
|
||||
removePosition.add(old_ln - 1 + removeNum);
|
||||
}
|
||||
}
|
||||
if (" ".equals(tag) || "+".equals(tag)) {
|
||||
addNum++;
|
||||
newChunkLines.add(rest);
|
||||
if ("+".equals(tag)) {
|
||||
addPosition.add(new_ln - 1 + addNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
patch.addDelta(new ChangeDelta<>(new Chunk<>(
|
||||
old_ln - 1, oldChunkLines), new Chunk<>(
|
||||
new_ln - 1, newChunkLines)));
|
||||
old_ln - 1, oldChunkLines, removePosition), new Chunk<>(
|
||||
new_ln - 1, newChunkLines, addPosition)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format
|
||||
* text representing the Patch.
|
||||
* text representing the Patch. Author: Bill James (tankerbay@gmail.com).
|
||||
*
|
||||
* @param originalFileName - Filename of the original (unrevised file)
|
||||
* @param revisedFileName - Filename of the revised file
|
||||
@@ -124,15 +137,14 @@ public final class UnifiedDiffUtils {
|
||||
* @param patch - Patch created by the diff() function
|
||||
* @param contextSize - number of lines of context output around each difference in the file.
|
||||
* @return List of strings representing the Unified Diff representation of the Patch argument.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*/
|
||||
public static List<String> generateUnifiedDiff(String originalFileName,
|
||||
String revisedFileName, List<String> originalLines, Patch<String> patch,
|
||||
int contextSize) {
|
||||
if (!patch.getDeltas().isEmpty()) {
|
||||
List<String> ret = new ArrayList<>();
|
||||
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(""));
|
||||
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(""));
|
||||
ret.add("--- " + Optional.ofNullable(originalFileName).orElse(NULL_FILE_INDICATOR));
|
||||
ret.add("+++ " + Optional.ofNullable(revisedFileName).orElse(NULL_FILE_INDICATOR));
|
||||
|
||||
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
||||
patch.getDeltas());
|
||||
@@ -187,13 +199,12 @@ public final class UnifiedDiffUtils {
|
||||
|
||||
/**
|
||||
* processDeltas takes a list of Deltas and outputs them together in a single block of
|
||||
* Unified-Diff-format text.
|
||||
* Unified-Diff-format text. Author: Bill James (tankerbay@gmail.com).
|
||||
*
|
||||
* @param origLines - the lines of the original file
|
||||
* @param deltas - the Deltas to be output as a single block
|
||||
* @param contextSize - the number of lines of context to place around block
|
||||
* @return
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*/
|
||||
private static List<String> processDeltas(List<String> origLines,
|
||||
List<AbstractDelta<String>> deltas, int contextSize, boolean newFile) {
|
||||
@@ -284,11 +295,10 @@ public final class UnifiedDiffUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter. Author: Bill James (tankerbay@gmail.com).
|
||||
*
|
||||
* @param delta - the Delta to output
|
||||
* @return list of String lines of code.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*/
|
||||
private static List<String> getDeltaText(AbstractDelta<String> delta) {
|
||||
List<String> buffer = new ArrayList<>();
|
||||
|
||||
@@ -36,4 +36,12 @@ public class Change {
|
||||
this.startRevised = startRevised;
|
||||
this.endRevised = endRevised;
|
||||
}
|
||||
|
||||
public Change withEndOriginal(int endOriginal) {
|
||||
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
||||
}
|
||||
|
||||
public Change withEndRevised(int endRevised) {
|
||||
return new Change(deltaType, startOriginal, endOriginal, startRevised, endRevised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2021 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.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* Tool to create new instances of a diff algorithm. This one is only needed at the moment to
|
||||
* set DiffUtils default diff algorithm.
|
||||
* @author tw
|
||||
*/
|
||||
public interface DiffAlgorithmFactory {
|
||||
<T> DiffAlgorithmI<T> create();
|
||||
|
||||
<T> DiffAlgorithmI<T> create(BiPredicate<T, T> equalizer);
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.github.difflib.algorithm.myers;
|
||||
|
||||
import com.github.difflib.algorithm.Change;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.DeltaType;
|
||||
@@ -26,18 +27,17 @@ import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* A clean-room implementation of Eugene Myers greedy differencing algorithm.
|
||||
* A clean-room implementation of Eugene Meyers greedy differencing algorithm.
|
||||
*/
|
||||
public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
public final class MeyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
private final BiPredicate<T, T> DEFAULT_EQUALIZER = Object::equals;
|
||||
private final BiPredicate<T, T> equalizer;
|
||||
|
||||
public MyersDiff() {
|
||||
equalizer = DEFAULT_EQUALIZER;
|
||||
public MeyersDiff() {
|
||||
equalizer = Object::equals;
|
||||
}
|
||||
|
||||
public MyersDiff(final BiPredicate<T, T> equalizer) {
|
||||
public MeyersDiff(final BiPredicate<T, T> equalizer) {
|
||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||
this.equalizer = equalizer;
|
||||
}
|
||||
@@ -64,8 +64,9 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -139,8 +140,8 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
* @return A {@link Patch} script corresponding to the path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could not be built from the given
|
||||
* path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
||||
* built from the given path.
|
||||
*/
|
||||
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||
Objects.requireNonNull(actualPath, "path is null");
|
||||
@@ -177,4 +178,23 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create instances of this specific diff algorithm.
|
||||
*/
|
||||
public static DiffAlgorithmFactory factory() {
|
||||
return new DiffAlgorithmFactory() {
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T>
|
||||
create() {
|
||||
return new MeyersDiff<T>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T>
|
||||
create(BiPredicate < T, T > equalizer) {
|
||||
return new MeyersDiff<T>(equalizer);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright 2021 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.myers;
|
||||
|
||||
import com.github.difflib.algorithm.Change;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.DeltaType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public class MeyersDiffWithLinearSpace<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
private final BiPredicate<T, T> equalizer;
|
||||
|
||||
public MeyersDiffWithLinearSpace() {
|
||||
equalizer = Object::equals;
|
||||
}
|
||||
|
||||
public MeyersDiffWithLinearSpace(final BiPredicate<T, T> equalizer) {
|
||||
Objects.requireNonNull(equalizer, "equalizer must not be null");
|
||||
this.equalizer = equalizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(source, "source list must not be null");
|
||||
Objects.requireNonNull(target, "target list must not be null");
|
||||
|
||||
if (progress != null) {
|
||||
progress.diffStart();
|
||||
}
|
||||
|
||||
DiffData data = new DiffData(source, target);
|
||||
|
||||
int maxIdx = source.size() + target.size();
|
||||
|
||||
buildScript(data, 0, source.size(), 0, target.size(), idx -> {
|
||||
if (progress != null) {
|
||||
progress.diffStep(idx, maxIdx);
|
||||
}
|
||||
});
|
||||
|
||||
if (progress != null) {
|
||||
progress.diffEnd();
|
||||
}
|
||||
return data.script;
|
||||
}
|
||||
|
||||
private void buildScript(DiffData data, int start1, int end1, int start2, int end2, Consumer<Integer> progress) {
|
||||
if (progress != null) {
|
||||
progress.accept((end1 - start1) / 2 + (end2 - start2) / 2);
|
||||
}
|
||||
final Snake middle = getMiddleSnake(data, start1, end1, start2, end2);
|
||||
if (middle == null
|
||||
|| middle.start == end1 && middle.diag == end1 - end2
|
||||
|| middle.end == start1 && middle.diag == start1 - start2) {
|
||||
int i = start1;
|
||||
int j = start2;
|
||||
while (i < end1 || j < end2) {
|
||||
if (i < end1 && j < end2 && equalizer.test(data.source.get(i), data.target.get(j))) {
|
||||
//script.append(new KeepCommand<>(left.charAt(i)));
|
||||
++i;
|
||||
++j;
|
||||
} else {
|
||||
//TODO: compress these commands.
|
||||
if (end1 - start1 > end2 - start2) {
|
||||
//script.append(new DeleteCommand<>(left.charAt(i)));
|
||||
if (data.script.isEmpty()
|
||||
|| data.script.get(data.script.size() - 1).endOriginal != i
|
||||
|| data.script.get(data.script.size() - 1).deltaType != DeltaType.DELETE) {
|
||||
data.script.add(new Change(DeltaType.DELETE, i, i + 1, j, j));
|
||||
} else {
|
||||
data.script.set(data.script.size() - 1, data.script.get(data.script.size() - 1).withEndOriginal(i + 1));
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
if (data.script.isEmpty()
|
||||
|| data.script.get(data.script.size() - 1).endRevised != j
|
||||
|| data.script.get(data.script.size() - 1).deltaType != DeltaType.INSERT) {
|
||||
data.script.add(new Change(DeltaType.INSERT, i, i, j, j + 1));
|
||||
} else {
|
||||
data.script.set(data.script.size() - 1, data.script.get(data.script.size() - 1).withEndRevised(j + 1));
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buildScript(data, start1, middle.start, start2, middle.start - middle.diag, progress);
|
||||
buildScript(data, middle.end, end1, middle.end - middle.diag, end2, progress);
|
||||
}
|
||||
}
|
||||
|
||||
private Snake getMiddleSnake(DiffData data, int start1, int end1, int start2, int end2) {
|
||||
final int m = end1 - start1;
|
||||
final int n = end2 - start2;
|
||||
if (m == 0 || n == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int delta = m - n;
|
||||
final int sum = n + m;
|
||||
final int offset = (sum % 2 == 0 ? sum : sum + 1) / 2;
|
||||
data.vDown[1 + offset] = start1;
|
||||
data.vUp[1 + offset] = end1 + 1;
|
||||
|
||||
for (int d = 0; d <= offset; ++d) {
|
||||
// Down
|
||||
for (int k = -d; k <= d; k += 2) {
|
||||
// First step
|
||||
|
||||
final int i = k + offset;
|
||||
if (k == -d || k != d && data.vDown[i - 1] < data.vDown[i + 1]) {
|
||||
data.vDown[i] = data.vDown[i + 1];
|
||||
} else {
|
||||
data.vDown[i] = data.vDown[i - 1] + 1;
|
||||
}
|
||||
|
||||
int x = data.vDown[i];
|
||||
int y = x - start1 + start2 - k;
|
||||
|
||||
while (x < end1 && y < end2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
||||
data.vDown[i] = ++x;
|
||||
++y;
|
||||
}
|
||||
// Second step
|
||||
if (delta % 2 != 0 && delta - d <= k && k <= delta + d) {
|
||||
if (data.vUp[i - delta] <= data.vDown[i]) {
|
||||
return buildSnake(data, data.vUp[i - delta], k + start1 - start2, end1, end2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Up
|
||||
for (int k = delta - d; k <= delta + d; k += 2) {
|
||||
// First step
|
||||
final int i = k + offset - delta;
|
||||
if (k == delta - d
|
||||
|| k != delta + d && data.vUp[i + 1] <= data.vUp[i - 1]) {
|
||||
data.vUp[i] = data.vUp[i + 1] - 1;
|
||||
} else {
|
||||
data.vUp[i] = data.vUp[i - 1];
|
||||
}
|
||||
|
||||
int x = data.vUp[i] - 1;
|
||||
int y = x - start1 + start2 - k;
|
||||
while (x >= start1 && y >= start2 && equalizer.test(data.source.get(x), data.target.get(y))) {
|
||||
data.vUp[i] = x--;
|
||||
y--;
|
||||
}
|
||||
// Second step
|
||||
if (delta % 2 == 0 && -d <= k && k <= d) {
|
||||
if (data.vUp[i] <= data.vDown[i + delta]) {
|
||||
return buildSnake(data, data.vUp[i], k + start1 - start2, end1, end2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// According to Myers, this cannot happen
|
||||
throw new IllegalStateException("could not find a diff path");
|
||||
}
|
||||
|
||||
private Snake buildSnake(DiffData data, final int start, final int diag, final int end1, final int end2) {
|
||||
int end = start;
|
||||
while (end - diag < end2 && end < end1 && equalizer.test(data.source.get(end), data.target.get(end - diag))) {
|
||||
++end;
|
||||
}
|
||||
return new Snake(start, end, diag);
|
||||
}
|
||||
|
||||
private class DiffData {
|
||||
|
||||
final int size;
|
||||
final int[] vDown;
|
||||
final int[] vUp;
|
||||
final List<Change> script;
|
||||
final List<T> source;
|
||||
final List<T> target;
|
||||
|
||||
public DiffData(List<T> source, List<T> target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
size = source.size() + target.size() + 2;
|
||||
vDown = new int[size];
|
||||
vUp = new int[size];
|
||||
script = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
private class Snake {
|
||||
|
||||
final int start;
|
||||
final int end;
|
||||
final int diag;
|
||||
|
||||
public Snake(final int start, final int end, final int diag) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.diag = diag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to create instances of this specific diff algorithm.
|
||||
*/
|
||||
public static DiffAlgorithmFactory factory() {
|
||||
return new DiffAlgorithmFactory() {
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T>
|
||||
create() {
|
||||
return new MeyersDiffWithLinearSpace<T>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DiffAlgorithmI<T>
|
||||
create(BiPredicate < T, T > equalizer) {
|
||||
return new MeyersDiffWithLinearSpace<T>(equalizer);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.github.difflib.patch;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -22,7 +23,7 @@ import java.util.Objects;
|
||||
* Abstract delta between a source and a target.
|
||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||
*/
|
||||
public abstract class AbstractDelta<T> {
|
||||
public abstract class AbstractDelta<T> implements Serializable {
|
||||
private final Chunk<T> source;
|
||||
private final Chunk<T> target;
|
||||
private final DeltaType type;
|
||||
@@ -53,13 +54,21 @@ public abstract class AbstractDelta<T> {
|
||||
* @param target
|
||||
* @throws PatchFailedException
|
||||
*/
|
||||
protected void verifyChunk(List<T> target) throws PatchFailedException {
|
||||
getSource().verify(target);
|
||||
protected VerifyChunk verifyChunkToFitTarget(List<T> target) throws PatchFailedException {
|
||||
return getSource().verifyChunk(target);
|
||||
}
|
||||
|
||||
protected VerifyChunk verifyAntApplyTo(List<T> target) throws PatchFailedException {
|
||||
final VerifyChunk verify = verifyChunkToFitTarget(target);
|
||||
if (verify == VerifyChunk.OK) {
|
||||
applyTo(target);
|
||||
}
|
||||
return verify;
|
||||
}
|
||||
|
||||
public abstract void applyTo(List<T> target) throws PatchFailedException;
|
||||
protected abstract void applyTo(List<T> target) throws PatchFailedException;
|
||||
|
||||
public abstract void restore(List<T> target);
|
||||
protected abstract void restore(List<T> target);
|
||||
|
||||
/**
|
||||
* Create a new delta of the actual instance with customized chunk data.
|
||||
@@ -89,9 +98,6 @@ public abstract class AbstractDelta<T> {
|
||||
if (!Objects.equals(this.target, other.target)) {
|
||||
return false;
|
||||
}
|
||||
if (this.type != other.type) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return this.type == other.type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(List<T> target) throws PatchFailedException {
|
||||
verifyChunk(target);
|
||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||
int position = getSource().getPosition();
|
||||
int size = getSource().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -54,7 +53,7 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(List<T> target) {
|
||||
protected void restore(List<T> target) {
|
||||
int position = getTarget().getPosition();
|
||||
int size = getTarget().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -75,6 +74,6 @@ public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||
|
||||
@Override
|
||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||
return new ChangeDelta(original, revised);
|
||||
return new ChangeDelta<T>(original, revised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.github.difflib.patch;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -24,19 +25,34 @@ import java.util.Objects;
|
||||
* Holds the information about the part of text involved in the diff process
|
||||
*
|
||||
* <p>
|
||||
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more
|
||||
* than plain ascci. In fact, arrays or lists of any type that implements
|
||||
* {@link java.lang.Object#hashCode hashCode()} and {@link java.lang.Object#equals equals()}
|
||||
* correctly can be subject to differencing using this library.
|
||||
* Text is represented as <code>Object[]</code> because the diff engine is
|
||||
* capable of handling more than plain ascci. In fact, arrays or lists of any
|
||||
* type that implements {@link java.lang.Object#hashCode hashCode()} and
|
||||
* {@link java.lang.Object#equals equals()} correctly can be subject to
|
||||
* differencing using this library.
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
||||
* @param <T> The type of the compared elements in the 'lines'.
|
||||
*/
|
||||
public final class Chunk<T> {
|
||||
public final class Chunk<T> implements Serializable {
|
||||
|
||||
private final int position;
|
||||
private List<T> lines;
|
||||
private final List<Integer> changePosition;
|
||||
|
||||
/**
|
||||
* Creates a chunk and saves a copy of affected lines
|
||||
*
|
||||
* @param position the start position
|
||||
* @param lines the affected lines
|
||||
* @param changePosition the positions of changed lines
|
||||
*/
|
||||
public Chunk(int position, List<T> lines, List<Integer> changePosition) {
|
||||
this.position = position;
|
||||
this.lines = new ArrayList<>(lines);
|
||||
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a chunk and saves a copy of affected lines
|
||||
@@ -45,8 +61,20 @@ public final class Chunk<T> {
|
||||
* @param lines the affected lines
|
||||
*/
|
||||
public Chunk(int position, List<T> lines) {
|
||||
this(position, lines, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a chunk and saves a copy of affected lines
|
||||
*
|
||||
* @param position the start position
|
||||
* @param lines the affected lines
|
||||
* @param changePosition the positions of changed lines
|
||||
*/
|
||||
public Chunk(int position, T[] lines, List<Integer> changePosition) {
|
||||
this.position = position;
|
||||
this.lines = new ArrayList<>(lines);
|
||||
this.lines = Arrays.asList(lines);
|
||||
this.changePosition = changePosition != null ? new ArrayList<>(changePosition) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,26 +84,26 @@ public final class Chunk<T> {
|
||||
* @param lines the affected lines
|
||||
*/
|
||||
public Chunk(int position, T[] lines) {
|
||||
this.position = position;
|
||||
this.lines = Arrays.asList(lines);
|
||||
this(position, lines, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that this chunk's saved text matches the corresponding text in the given sequence.
|
||||
* Verifies that this chunk's saved text matches the corresponding text in
|
||||
* the given sequence.
|
||||
*
|
||||
* @param target the sequence to verify against.
|
||||
* @throws com.github.difflib.patch.PatchFailedException
|
||||
*/
|
||||
public void verify(List<T> target) throws PatchFailedException {
|
||||
public VerifyChunk verifyChunk(List<T> target) throws PatchFailedException {
|
||||
if (position > target.size() || last() > target.size()) {
|
||||
throw new PatchFailedException("Incorrect Chunk: the position of chunk > target size");
|
||||
return VerifyChunk.POSITION_OUT_OF_TARGET;
|
||||
}
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (!target.get(position + i).equals(lines.get(i))) {
|
||||
throw new PatchFailedException(
|
||||
"Incorrect Chunk: the chunk content doesn't match the target");
|
||||
return VerifyChunk.CONTENT_DOES_NOT_MATCH_TARGET;
|
||||
}
|
||||
}
|
||||
return VerifyChunk.OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,6 +124,13 @@ public final class Chunk<T> {
|
||||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the positions of changed lines of chunk in the text
|
||||
*/
|
||||
public List<Integer> getChangePosition() {
|
||||
return changePosition;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return lines.size();
|
||||
}
|
||||
@@ -123,7 +158,7 @@ public final class Chunk<T> {
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Chunk<T> other = (Chunk) obj;
|
||||
Chunk<?> other = (Chunk<?>) obj;
|
||||
if (lines == null) {
|
||||
if (other.lines != null) {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*-
|
||||
* #%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.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConflictOutput<T> extends Serializable {
|
||||
|
||||
public void processConflict(VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) throws PatchFailedException;
|
||||
}
|
||||
@@ -36,8 +36,7 @@ public final class DeleteDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(List<T> target) throws PatchFailedException {
|
||||
verifyChunk(target);
|
||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||
int position = getSource().getPosition();
|
||||
int size = getSource().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -46,7 +45,7 @@ public final class DeleteDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(List<T> target) {
|
||||
protected void restore(List<T> target) {
|
||||
int position = this.getTarget().getPosition();
|
||||
List<T> lines = this.getSource().getLines();
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
@@ -62,6 +61,6 @@ public final class DeleteDelta<T> extends AbstractDelta<T> {
|
||||
|
||||
@Override
|
||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||
return new DeleteDelta(original, revised);
|
||||
return new DeleteDelta<T>(original, revised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,18 @@
|
||||
package com.github.difflib.patch;
|
||||
|
||||
/**
|
||||
* Specifies the type of the delta.
|
||||
* Specifies the type of the delta. There are three types of modifications from
|
||||
* the original to get the revised text.
|
||||
*
|
||||
* CHANGE: a block of data of the original is replaced by another block of data.
|
||||
* DELETE: a block of data of the original is removed
|
||||
* INSERT: at a position of the original a block of data is inserted
|
||||
*
|
||||
* to be complete there is also
|
||||
*
|
||||
* EQUAL: a block of data of original and the revised text is equal
|
||||
*
|
||||
* which is no change at all.
|
||||
*
|
||||
*/
|
||||
public enum DeltaType {
|
||||
|
||||
@@ -28,12 +28,11 @@ public class EqualDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(List<T> target) throws PatchFailedException {
|
||||
verifyChunk(target);
|
||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(List<T> target) {
|
||||
protected void restore(List<T> target) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,6 +43,6 @@ public class EqualDelta<T> extends AbstractDelta<T> {
|
||||
|
||||
@Override
|
||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||
return new EqualDelta(original, revised);
|
||||
return new EqualDelta<T>(original, revised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ public final class InsertDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(List<T> target) throws PatchFailedException {
|
||||
verifyChunk(target);
|
||||
protected void applyTo(List<T> target) throws PatchFailedException {
|
||||
int position = this.getSource().getPosition();
|
||||
List<T> lines = this.getTarget().getLines();
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
@@ -46,7 +45,7 @@ public final class InsertDelta<T> extends AbstractDelta<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(List<T> target) {
|
||||
protected void restore(List<T> target) {
|
||||
int position = getTarget().getPosition();
|
||||
int size = getTarget().size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
@@ -62,6 +61,6 @@ public final class InsertDelta<T> extends AbstractDelta<T> {
|
||||
|
||||
@Override
|
||||
public AbstractDelta<T> withChunks(Chunk<T> original, Chunk<T> revised) {
|
||||
return new InsertDelta(original, revised);
|
||||
return new InsertDelta<T>(original, revised);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,18 +21,21 @@ package com.github.difflib.patch;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import com.github.difflib.algorithm.Change;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* Describes the patch holding all deltas between the original and revised texts.
|
||||
* Describes the patch holding all deltas between the original and revised
|
||||
* texts.
|
||||
*
|
||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||
* @param <T> The type of the compared elements in the 'lines'.
|
||||
*/
|
||||
public final class Patch<T> {
|
||||
public final class Patch<T> implements Serializable {
|
||||
|
||||
private final List<AbstractDelta<T>> deltas;
|
||||
|
||||
@@ -55,11 +58,56 @@ public final class Patch<T> {
|
||||
ListIterator<AbstractDelta<T>> it = getDeltas().listIterator(deltas.size());
|
||||
while (it.hasPrevious()) {
|
||||
AbstractDelta<T> delta = it.previous();
|
||||
delta.applyTo(result);
|
||||
VerifyChunk valid = delta.verifyAntApplyTo(result);
|
||||
if (valid != VerifyChunk.OK) {
|
||||
conflictOutput.processConflict(valid, delta, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Patch behaviour to throw an exception for pathching conflicts.
|
||||
*/
|
||||
public final ConflictOutput<T> CONFLICT_PRODUCES_EXCEPTION = (VerifyChunk verifyChunk, AbstractDelta<T> delta, List<T> result) -> {
|
||||
throw new PatchFailedException("could not apply patch due to " + verifyChunk.toString());
|
||||
};
|
||||
|
||||
/**
|
||||
* Git like merge conflict output.
|
||||
*/
|
||||
public static final ConflictOutput<String> CONFLICT_PRODUCES_MERGE_CONFLICT = (VerifyChunk verifyChunk, AbstractDelta<String> delta, List<String> result) -> {
|
||||
if (result.size() > delta.getSource().getPosition()) {
|
||||
List<String> orgData = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < delta.getSource().size(); i++) {
|
||||
orgData.add(result.get(delta.getSource().getPosition()));
|
||||
result.remove(delta.getSource().getPosition());
|
||||
}
|
||||
|
||||
orgData.add(0, "<<<<<< HEAD");
|
||||
orgData.add("======");
|
||||
orgData.addAll(delta.getSource().getLines());
|
||||
orgData.add(">>>>>>> PATCH");
|
||||
|
||||
result.addAll(delta.getSource().getPosition(), orgData);
|
||||
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
};
|
||||
|
||||
private ConflictOutput<T> conflictOutput = CONFLICT_PRODUCES_EXCEPTION;
|
||||
|
||||
/**
|
||||
* Alter normal conflict output behaviour to e.g. inclide some conflict
|
||||
* statements in the result, like git does it.
|
||||
*/
|
||||
public Patch withConflictOutput(ConflictOutput<T> conflictOutput) {
|
||||
this.conflictOutput = conflictOutput;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the text to original. Opposite to applyTo() method.
|
||||
*
|
||||
@@ -112,18 +160,18 @@ public final class Patch<T> {
|
||||
Patch<T> patch = new Patch<>(_changes.size());
|
||||
int startOriginal = 0;
|
||||
int startRevised = 0;
|
||||
|
||||
|
||||
List<Change> changes = _changes;
|
||||
|
||||
|
||||
if (includeEquals) {
|
||||
changes = new ArrayList<Change>(_changes);
|
||||
Collections.sort(changes, comparing(d -> d.startOriginal));
|
||||
}
|
||||
|
||||
|
||||
for (Change change : changes) {
|
||||
|
||||
if (includeEquals && startOriginal < change.startOriginal) {
|
||||
patch.addDelta(new EqualDelta(
|
||||
patch.addDelta(new EqualDelta<T>(
|
||||
buildChunk(startOriginal, change.startOriginal, original),
|
||||
buildChunk(startRevised, change.startRevised, revised)));
|
||||
}
|
||||
@@ -140,6 +188,7 @@ public final class Patch<T> {
|
||||
case CHANGE:
|
||||
patch.addDelta(new ChangeDelta<>(orgChunk, revChunk));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
startOriginal = change.endOriginal;
|
||||
@@ -147,7 +196,7 @@ public final class Patch<T> {
|
||||
}
|
||||
|
||||
if (includeEquals && startOriginal < original.size()) {
|
||||
patch.addDelta(new EqualDelta(
|
||||
patch.addDelta(new EqualDelta<T>(
|
||||
buildChunk(startOriginal, original.size(), original),
|
||||
buildChunk(startRevised, revised.size(), revised)));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2021 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public enum VerifyChunk {
|
||||
OK,
|
||||
POSITION_OUT_OF_TARGET,
|
||||
CONTENT_DOES_NOT_MATCH_TARGET
|
||||
}
|
||||
@@ -17,8 +17,11 @@ package com.github.difflib.text;
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
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.DeltaType;
|
||||
import com.github.difflib.patch.InsertDelta;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.text.DiffRow.Tag;
|
||||
import java.util.*;
|
||||
@@ -30,14 +33,16 @@ import java.util.regex.Pattern;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
/**
|
||||
* This class for generating DiffRows for side-by-sidy view. You can customize the way of
|
||||
* generating. For example, show inline diffs on not, ignoring white spaces or/and blank lines and
|
||||
* so on. All parameters for generating are optional. If you do not specify them, the class will use
|
||||
* the default values.
|
||||
* This class for generating DiffRows for side-by-sidy view. You can customize
|
||||
* the way of generating. For example, show inline diffs on not, ignoring white
|
||||
* spaces or/and blank lines and so on. All parameters for generating are
|
||||
* optional. If you do not specify them, the class will use the default values.
|
||||
*
|
||||
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true; ignoreBlankLines = true; ...
|
||||
* These values are: showInlineDiffs = false; ignoreWhiteSpaces = true;
|
||||
* ignoreBlankLines = true; ...
|
||||
*
|
||||
* For instantiating the DiffRowGenerator you should use the its builder. Like in example <code>
|
||||
* For instantiating the DiffRowGenerator you should use the its builder. Like
|
||||
* in example <code>
|
||||
* DiffRowGenerator generator = new DiffRowGenerator.Builder().showInlineDiffs(true).
|
||||
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
||||
* </code>
|
||||
@@ -61,6 +66,7 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
|
||||
|
||||
/**
|
||||
@@ -99,14 +105,14 @@ public final class DiffRowGenerator {
|
||||
/**
|
||||
* 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 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 tagGenerator the tag generator
|
||||
*/
|
||||
static void wrapInTag(List<String> sequence, int startPosition,
|
||||
int endPosition, Tag tag, BiFunction<Tag, Boolean, String> tagGenerator,
|
||||
Function<String, String> processDiffs) {
|
||||
Function<String, String> processDiffs, boolean replaceLinefeedWithSpace) {
|
||||
int endPos = endPosition;
|
||||
|
||||
while (endPos >= startPosition) {
|
||||
@@ -115,6 +121,9 @@ public final class DiffRowGenerator {
|
||||
while (endPos > startPosition) {
|
||||
if (!"\n".equals(sequence.get(endPos - 1))) {
|
||||
break;
|
||||
} else if (replaceLinefeedWithSpace) {
|
||||
sequence.set(endPos - 1, " ");
|
||||
break;
|
||||
}
|
||||
endPos--;
|
||||
}
|
||||
@@ -133,7 +142,11 @@ public final class DiffRowGenerator {
|
||||
//search position for end tag
|
||||
while (endPos > startPosition) {
|
||||
if ("\n".equals(sequence.get(endPos - 1))) {
|
||||
break;
|
||||
if (replaceLinefeedWithSpace) {
|
||||
sequence.set(endPos - 1, " ");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (processDiffs != null) {
|
||||
sequence.set(endPos - 1,
|
||||
@@ -159,6 +172,7 @@ public final class DiffRowGenerator {
|
||||
private final Function<String, String> processDiffs;
|
||||
|
||||
private final boolean showInlineDiffs;
|
||||
private final boolean replaceOriginalLinefeedInChangesWithSpaces;
|
||||
|
||||
private DiffRowGenerator(Builder builder) {
|
||||
showInlineDiffs = builder.showInlineDiffs;
|
||||
@@ -179,13 +193,15 @@ public final class DiffRowGenerator {
|
||||
lineNormalizer = builder.lineNormalizer;
|
||||
processDiffs = builder.processDiffs;
|
||||
|
||||
replaceOriginalLinefeedInChangesWithSpaces = builder.replaceOriginalLinefeedInChangesWithSpaces;
|
||||
|
||||
Objects.requireNonNull(inlineDiffSplitter);
|
||||
Objects.requireNonNull(lineNormalizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DiffRows describing the difference between original and revised texts using the given
|
||||
* patch. Useful for displaying side-by-side diff.
|
||||
* Get the DiffRows describing the difference between original and revised
|
||||
* texts using the given patch. Useful for displaying side-by-side diff.
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
@@ -196,8 +212,9 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the DiffRows describing the difference between original and revised texts using the
|
||||
* given patch. Useful for displaying side-by-side diff.
|
||||
* Generates the DiffRows describing the difference between original and
|
||||
* revised texts using the given patch. Useful for displaying side-by-side
|
||||
* diff.
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
@@ -207,42 +224,11 @@ public final class DiffRowGenerator {
|
||||
List<DiffRow> diffRows = new ArrayList<>();
|
||||
int endPos = 0;
|
||||
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
||||
for (AbstractDelta<String> delta : deltaList) {
|
||||
Chunk<String> orig = delta.getSource();
|
||||
Chunk<String> rev = delta.getTarget();
|
||||
|
||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
for (AbstractDelta<String> originalDelta : deltaList) {
|
||||
for (AbstractDelta<String> delta : decompressDeltas(originalDelta)) {
|
||||
endPos = transformDeltaIntoDiffRow(original, endPos, diffRows, delta);
|
||||
}
|
||||
|
||||
// Inserted DiffRow
|
||||
if (delta.getType() == DeltaType.INSERT) {
|
||||
endPos = orig.last() + 1;
|
||||
for (String line : rev.getLines()) {
|
||||
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Deleted DiffRow
|
||||
if (delta.getType() == DeltaType.DELETE) {
|
||||
endPos = orig.last() + 1;
|
||||
for (String line : orig.getLines()) {
|
||||
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (showInlineDiffs) {
|
||||
diffRows.addAll(generateInlineDiffs(delta));
|
||||
} else {
|
||||
for (int j = 0; j < Math.max(orig.size(), rev.size()); j++) {
|
||||
diffRows.add(buildDiffRow(Tag.CHANGE,
|
||||
orig.getLines().size() > j ? orig.getLines().get(j) : "",
|
||||
rev.getLines().size() > j ? rev.getLines().get(j) : ""));
|
||||
}
|
||||
}
|
||||
endPos = orig.last() + 1;
|
||||
}
|
||||
|
||||
// Copy the final matching chunk if any.
|
||||
@@ -252,6 +238,78 @@ public final class DiffRowGenerator {
|
||||
return diffRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms one patch delta into a DiffRow object.
|
||||
*/
|
||||
private int transformDeltaIntoDiffRow(final List<String> original, int endPos, List<DiffRow> diffRows, AbstractDelta<String> delta) {
|
||||
Chunk<String> orig = delta.getSource();
|
||||
Chunk<String> rev = delta.getTarget();
|
||||
|
||||
for (String line : original.subList(endPos, orig.getPosition())) {
|
||||
diffRows.add(buildDiffRow(Tag.EQUAL, line, line));
|
||||
}
|
||||
|
||||
switch (delta.getType()) {
|
||||
case INSERT:
|
||||
for (String line : rev.getLines()) {
|
||||
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
|
||||
}
|
||||
break;
|
||||
case DELETE:
|
||||
for (String line : orig.getLines()) {
|
||||
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (showInlineDiffs) {
|
||||
diffRows.addAll(generateInlineDiffs(delta));
|
||||
} else {
|
||||
for (int j = 0; j < Math.max(orig.size(), rev.size()); j++) {
|
||||
diffRows.add(buildDiffRow(Tag.CHANGE,
|
||||
orig.getLines().size() > j ? orig.getLines().get(j) : "",
|
||||
rev.getLines().size() > j ? rev.getLines().get(j) : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return orig.last() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompresses ChangeDeltas with different source and target size to a
|
||||
* ChangeDelta with same size and a following InsertDelta or DeleteDelta.
|
||||
* With this problems of building DiffRows getting smaller.
|
||||
*
|
||||
* @param deltaList
|
||||
*/
|
||||
private List<AbstractDelta<String>> decompressDeltas(AbstractDelta<String> delta) {
|
||||
if (delta.getType() == DeltaType.CHANGE && delta.getSource().size() != delta.getTarget().size()) {
|
||||
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
||||
//System.out.println("decompress this " + delta);
|
||||
|
||||
int minSize = Math.min(delta.getSource().size(), delta.getTarget().size());
|
||||
Chunk<String> orig = delta.getSource();
|
||||
Chunk<String> rev = delta.getTarget();
|
||||
|
||||
deltas.add(new ChangeDelta<String>(
|
||||
new Chunk<>(orig.getPosition(), orig.getLines().subList(0, minSize)),
|
||||
new Chunk<>(rev.getPosition(), rev.getLines().subList(0, minSize))));
|
||||
|
||||
if (orig.getLines().size() < rev.getLines().size()) {
|
||||
deltas.add(new InsertDelta<String>(
|
||||
new Chunk<>(orig.getPosition() + minSize, Collections.emptyList()),
|
||||
new Chunk<>(rev.getPosition() + minSize, rev.getLines().subList(minSize, rev.getLines().size()))));
|
||||
} else {
|
||||
deltas.add(new DeleteDelta<String>(
|
||||
new Chunk<>(orig.getPosition() + minSize, orig.getLines().subList(minSize, orig.getLines().size())),
|
||||
new Chunk<>(rev.getPosition() + minSize, Collections.emptyList())));
|
||||
}
|
||||
return deltas;
|
||||
}
|
||||
|
||||
return Collections.singletonList(delta);
|
||||
}
|
||||
|
||||
private DiffRow buildDiffRow(Tag type, String orgline, String newline) {
|
||||
if (reportLinesUnchanged) {
|
||||
return new DiffRow(type, orgline, newline);
|
||||
@@ -313,7 +371,7 @@ public final class DiffRowGenerator {
|
||||
if (inlineDelta.getType() == DeltaType.DELETE) {
|
||||
wrapInTag(origList, inlineOrig.getPosition(), inlineOrig
|
||||
.getPosition()
|
||||
+ inlineOrig.size(), Tag.DELETE, oldTag, processDiffs);
|
||||
+ inlineOrig.size(), Tag.DELETE, oldTag, processDiffs, replaceOriginalLinefeedInChangesWithSpaces && mergeOriginalRevised);
|
||||
} else if (inlineDelta.getType() == DeltaType.INSERT) {
|
||||
if (mergeOriginalRevised) {
|
||||
origList.addAll(inlineOrig.getPosition(),
|
||||
@@ -321,11 +379,11 @@ public final class DiffRowGenerator {
|
||||
inlineRev.getPosition() + inlineRev.size()));
|
||||
wrapInTag(origList, inlineOrig.getPosition(),
|
||||
inlineOrig.getPosition() + inlineRev.size(),
|
||||
Tag.INSERT, newTag, processDiffs);
|
||||
Tag.INSERT, newTag, processDiffs, false);
|
||||
} else {
|
||||
wrapInTag(revList, inlineRev.getPosition(),
|
||||
inlineRev.getPosition() + inlineRev.size(),
|
||||
Tag.INSERT, newTag, processDiffs);
|
||||
Tag.INSERT, newTag, processDiffs, false);
|
||||
}
|
||||
} else if (inlineDelta.getType() == DeltaType.CHANGE) {
|
||||
if (mergeOriginalRevised) {
|
||||
@@ -334,15 +392,15 @@ public final class DiffRowGenerator {
|
||||
inlineRev.getPosition() + inlineRev.size()));
|
||||
wrapInTag(origList, inlineOrig.getPosition() + inlineOrig.size(),
|
||||
inlineOrig.getPosition() + inlineOrig.size() + inlineRev.size(),
|
||||
Tag.CHANGE, newTag, processDiffs);
|
||||
Tag.CHANGE, newTag, processDiffs, false);
|
||||
} else {
|
||||
wrapInTag(revList, inlineRev.getPosition(),
|
||||
inlineRev.getPosition() + inlineRev.size(),
|
||||
Tag.CHANGE, newTag, processDiffs);
|
||||
Tag.CHANGE, newTag, processDiffs, false);
|
||||
}
|
||||
wrapInTag(origList, inlineOrig.getPosition(),
|
||||
inlineOrig.getPosition() + inlineOrig.size(),
|
||||
Tag.CHANGE, oldTag, processDiffs);
|
||||
Tag.CHANGE, oldTag, processDiffs, replaceOriginalLinefeedInChangesWithSpaces && mergeOriginalRevised);
|
||||
}
|
||||
}
|
||||
StringBuilder origResult = new StringBuilder();
|
||||
@@ -385,10 +443,10 @@ public final class DiffRowGenerator {
|
||||
private boolean showInlineDiffs = false;
|
||||
private boolean ignoreWhiteSpaces = false;
|
||||
|
||||
private BiFunction<Tag, Boolean, String> oldTag =
|
||||
(tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
|
||||
private BiFunction<Tag, Boolean, String> newTag =
|
||||
(tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
|
||||
private BiFunction<Tag, Boolean, String> oldTag
|
||||
= (tag, f) -> f ? "<span class=\"editOldInline\">" : "</span>";
|
||||
private BiFunction<Tag, Boolean, String> newTag
|
||||
= (tag, f) -> f ? "<span class=\"editNewInline\">" : "</span>";
|
||||
|
||||
private int columnWidth = 0;
|
||||
private boolean mergeOriginalRevised = false;
|
||||
@@ -397,6 +455,7 @@ public final class DiffRowGenerator {
|
||||
private Function<String, String> lineNormalizer = LINE_NORMALIZER_FOR_HTML;
|
||||
private Function<String, String> processDiffs = null;
|
||||
private BiPredicate<String, String> equalizer = null;
|
||||
private boolean replaceOriginalLinefeedInChangesWithSpaces = false;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
@@ -424,8 +483,8 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Give the originial old and new text lines to Diffrow without any additional processing
|
||||
* and without any tags to highlight the change.
|
||||
* Give the originial old and new text lines to Diffrow without any
|
||||
* additional processing and without any tags to highlight the change.
|
||||
*
|
||||
* @param val the value to set. Default: false.
|
||||
* @return builder with configured reportLinesUnWrapped parameter
|
||||
@@ -445,7 +504,7 @@ public final class DiffRowGenerator {
|
||||
this.oldTag = generator;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generator for Old-Text-Tags.
|
||||
*
|
||||
@@ -467,7 +526,7 @@ public final class DiffRowGenerator {
|
||||
this.newTag = generator;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generator for New-Text-Tags.
|
||||
*
|
||||
@@ -480,8 +539,8 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Processor for diffed text parts. Here e.g. whitecharacters could be replaced by something
|
||||
* visible.
|
||||
* Processor for diffed text parts. Here e.g. whitecharacters could be
|
||||
* replaced by something visible.
|
||||
*
|
||||
* @param processDiffs
|
||||
* @return
|
||||
@@ -492,10 +551,11 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the column width of generated lines of original and revised texts.
|
||||
* Set the column width 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
|
||||
* @param width the width to set. Making it < 0 doesn't make any sense. Default 80.
|
||||
* @return builder with config of column width
|
||||
*/
|
||||
public Builder columnWidth(int width) {
|
||||
if (width >= 0) {
|
||||
@@ -505,7 +565,8 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the DiffRowGenerator. If some parameters is not set, the default values are used.
|
||||
* Build the DiffRowGenerator. If some parameters is not set, the
|
||||
* default values are used.
|
||||
*
|
||||
* @return the customized DiffRowGenerator
|
||||
*/
|
||||
@@ -514,8 +575,8 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the complete result within the original text. This makes sense for one line
|
||||
* display.
|
||||
* Merge the complete result within the original text. This makes sense
|
||||
* for one line display.
|
||||
*
|
||||
* @param mergeOriginalRevised
|
||||
* @return
|
||||
@@ -526,9 +587,9 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Per default each character is separatly processed. This variant introduces processing by
|
||||
* word, which does not deliver in word changes. Therefore the whole word will be tagged as
|
||||
* changed:
|
||||
* Per default each character is separatly processed. This variant
|
||||
* introduces processing by word, which does not deliver in word
|
||||
* changes. Therefore the whole word will be tagged as changed:
|
||||
*
|
||||
* <pre>
|
||||
* false: (aBa : aba) -- changed: a(B)a : a(b)a
|
||||
@@ -541,8 +602,9 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* To provide some customized splitting a splitter can be provided. Here someone could think
|
||||
* about sentence splitter, comma splitter or stuff like that.
|
||||
* To provide some customized splitting a splitter can be provided. Here
|
||||
* someone could think about sentence splitter, comma splitter or stuff
|
||||
* like that.
|
||||
*
|
||||
* @param inlineDiffSplitter
|
||||
* @return
|
||||
@@ -553,9 +615,10 @@ public final class DiffRowGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* By default DiffRowGenerator preprocesses lines for HTML output. Tabs and special HTML
|
||||
* characters like "<" are replaced with its encoded value. To change this you can
|
||||
* provide a customized line normalizer here.
|
||||
* By default DiffRowGenerator preprocesses lines for HTML output. Tabs
|
||||
* and special HTML characters like "<" are replaced with its encoded
|
||||
* value. To change this you can provide a customized line normalizer
|
||||
* here.
|
||||
*
|
||||
* @param lineNormalizer
|
||||
* @return
|
||||
@@ -575,5 +638,18 @@ public final class DiffRowGenerator {
|
||||
this.equalizer = equalizer;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes it happens that a change contains multiple lines. If there
|
||||
* is no correspondence in old and new. To keep the merged line more
|
||||
* readable the linefeeds could be replaced by spaces.
|
||||
*
|
||||
* @param replace
|
||||
* @return
|
||||
*/
|
||||
public Builder replaceOriginalLinefeedInChangesWithSpaces(boolean replace) {
|
||||
this.replaceOriginalLinefeedInChangesWithSpaces = replace;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ import static java.util.stream.Collectors.toList;
|
||||
final class StringUtils {
|
||||
|
||||
/**
|
||||
* Replaces all opening an closing tags with <code><</code> or <code>></code>.
|
||||
* Replaces all opening and closing tags with <code><</code> or <code>></code>.
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
* @return str with some HTML meta characters escaped.
|
||||
*/
|
||||
public static String htmlEntites(String str) {
|
||||
return str.replace("<", "<").replace(">", ">");
|
||||
@@ -61,7 +61,17 @@ final class StringUtils {
|
||||
StringBuilder b = new StringBuilder(line);
|
||||
|
||||
for (int count = 0; length > widthIndex; count++) {
|
||||
b.insert(widthIndex + delimiter * count, "<br/>");
|
||||
int breakPoint = widthIndex + delimiter * count;
|
||||
if (Character.isHighSurrogate(b.charAt(breakPoint - 1)) &&
|
||||
Character.isLowSurrogate(b.charAt(breakPoint))) {
|
||||
// Shift a breakpoint that would split a supplemental code-point.
|
||||
breakPoint += 1;
|
||||
if (breakPoint == b.length()) {
|
||||
// Break before instead of after if this is the last code-point.
|
||||
breakPoint -= 2;
|
||||
}
|
||||
}
|
||||
b.insert(breakPoint, "<br/>");
|
||||
widthIndex += columnWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public final class UnifiedDiff {
|
||||
return tail;
|
||||
}
|
||||
|
||||
public List<String> spplyPatchTo(Predicate<String> findFile, List<String> originalLines) throws PatchFailedException {
|
||||
public List<String> applyPatchTo(Predicate<String> findFile, List<String> originalLines) throws PatchFailedException {
|
||||
UnifiedDiffFile file = files.stream()
|
||||
.filter(diff -> findFile.test(diff.getFromFile()))
|
||||
.findFirst().orElse(null);
|
||||
|
||||
@@ -18,7 +18,8 @@ package com.github.difflib.unifieddiff;
|
||||
import com.github.difflib.patch.Patch;
|
||||
|
||||
/**
|
||||
*
|
||||
* Data structure for one patched file from a unified diff file.
|
||||
*
|
||||
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||
*/
|
||||
public final class UnifiedDiffFile {
|
||||
@@ -27,9 +28,15 @@ public final class UnifiedDiffFile {
|
||||
private String fromFile;
|
||||
private String fromTimestamp;
|
||||
private String toFile;
|
||||
private String renameFrom;
|
||||
private String renameTo;
|
||||
private String toTimestamp;
|
||||
private String index;
|
||||
private String newFileMode;
|
||||
private String deletedFileMode;
|
||||
private Patch<String> patch = new Patch<>();
|
||||
private boolean noNewLineAtTheEndOfTheFile = false;
|
||||
private Integer similarityIndex;
|
||||
|
||||
public String getDiffCommand() {
|
||||
return diffCommand;
|
||||
@@ -82,8 +89,30 @@ public final class UnifiedDiffFile {
|
||||
public void setToTimestamp(String toTimestamp) {
|
||||
this.toTimestamp = toTimestamp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Integer getSimilarityIndex() {
|
||||
return similarityIndex;
|
||||
}
|
||||
|
||||
public void setSimilarityIndex(Integer similarityIndex) {
|
||||
this.similarityIndex = similarityIndex;
|
||||
}
|
||||
|
||||
public String getRenameFrom() {
|
||||
return renameFrom;
|
||||
}
|
||||
|
||||
public void setRenameFrom(String renameFrom) {
|
||||
this.renameFrom = renameFrom;
|
||||
}
|
||||
|
||||
public String getRenameTo() {
|
||||
return renameTo;
|
||||
}
|
||||
|
||||
public void setRenameTo(String renameTo) {
|
||||
this.renameTo = renameTo;
|
||||
}
|
||||
|
||||
public static UnifiedDiffFile from(String fromFile, String toFile, Patch<String> patch) {
|
||||
UnifiedDiffFile file = new UnifiedDiffFile();
|
||||
@@ -92,4 +121,28 @@ public final class UnifiedDiffFile {
|
||||
file.patch = patch;
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setNewFileMode(String newFileMode) {
|
||||
this.newFileMode = newFileMode;
|
||||
}
|
||||
|
||||
public String getNewFileMode() {
|
||||
return newFileMode;
|
||||
}
|
||||
|
||||
public String getDeletedFileMode() {
|
||||
return deletedFileMode;
|
||||
}
|
||||
|
||||
public void setDeletedFileMode(String deletedFileMode) {
|
||||
this.deletedFileMode = deletedFileMode;
|
||||
}
|
||||
|
||||
public boolean isNoNewLineAtTheEndOfTheFile() {
|
||||
return noNewLineAtTheEndOfTheFile;
|
||||
}
|
||||
|
||||
public void setNoNewLineAtTheEndOfTheFile(boolean noNewLineAtTheEndOfTheFile) {
|
||||
this.noNewLineAtTheEndOfTheFile = noNewLineAtTheEndOfTheFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,15 +39,22 @@ import java.util.regex.Pattern;
|
||||
public final class UnifiedDiffReader {
|
||||
|
||||
static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})");
|
||||
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})(?: [+-]\\d+)?");
|
||||
|
||||
private final InternalUnifiedDiffReader READER;
|
||||
private final UnifiedDiff data = new UnifiedDiff();
|
||||
|
||||
private final UnifiedDiffLine DIFF_COMMAND = new UnifiedDiffLine(true, "^diff\\s", this::processDiff);
|
||||
private final UnifiedDiffLine SIMILARITY_INDEX = new UnifiedDiffLine(true, "^similarity index (\\d+)%$", this::processSimilarityIndex);
|
||||
private final UnifiedDiffLine INDEX = new UnifiedDiffLine(true, "^index\\s[\\da-zA-Z]+\\.\\.[\\da-zA-Z]+(\\s(\\d+))?$", this::processIndex);
|
||||
private final UnifiedDiffLine FROM_FILE = new UnifiedDiffLine(true, "^---\\s", this::processFromFile);
|
||||
private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine(true, "^\\+\\+\\+\\s", this::processToFile);
|
||||
private final UnifiedDiffLine RENAME_FROM = new UnifiedDiffLine(true, "^rename\\sfrom\\s(.+)$", this::processRenameFrom);
|
||||
private final UnifiedDiffLine RENAME_TO = new UnifiedDiffLine(true, "^rename\\sto\\s(.+)$", this::processRenameTo);
|
||||
|
||||
private final UnifiedDiffLine NEW_FILE_MODE = new UnifiedDiffLine(true, "^new\\sfile\\smode\\s(\\d+)", this::processNewFileMode);
|
||||
|
||||
private final UnifiedDiffLine DELETED_FILE_MODE = new UnifiedDiffLine(true, "^deleted\\sfile\\smode\\s(\\d+)", this::processDeletedFileMode);
|
||||
|
||||
private final UnifiedDiffLine CHUNK = new UnifiedDiffLine(false, UNIFIED_DIFF_CHUNK_REGEXP, this::processChunk);
|
||||
private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine("^\\s", this::processNormalLine);
|
||||
@@ -65,47 +72,76 @@ public final class UnifiedDiffReader {
|
||||
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
|
||||
// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
|
||||
private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
|
||||
String headerTxt = "";
|
||||
LOG.log(Level.INFO, "header parsing");
|
||||
String line = null;
|
||||
while (READER.ready()) {
|
||||
line = READER.readLine();
|
||||
LOG.log(Level.INFO, "parsing line {0}", line);
|
||||
if (DIFF_COMMAND.validLine(line) || INDEX.validLine(line)
|
||||
|| FROM_FILE.validLine(line) || TO_FILE.validLine(line)) {
|
||||
break;
|
||||
} else {
|
||||
headerTxt += line + "\n";
|
||||
}
|
||||
}
|
||||
if (!"".equals(headerTxt)) {
|
||||
data.setHeader(headerTxt);
|
||||
}
|
||||
// String headerTxt = "";
|
||||
// LOG.log(Level.FINE, "header parsing");
|
||||
// String line = null;
|
||||
// while (READER.ready()) {
|
||||
// line = READER.readLine();
|
||||
// LOG.log(Level.FINE, "parsing line {0}", line);
|
||||
// if (DIFF_COMMAND.validLine(line) || INDEX.validLine(line)
|
||||
// || FROM_FILE.validLine(line) || TO_FILE.validLine(line)
|
||||
// || NEW_FILE_MODE.validLine(line)) {
|
||||
// break;
|
||||
// } else {
|
||||
// headerTxt += line + "\n";
|
||||
// }
|
||||
// }
|
||||
// if (!"".equals(headerTxt)) {
|
||||
// data.setHeader(headerTxt);
|
||||
// }
|
||||
|
||||
String line = READER.readLine();
|
||||
while (line != null) {
|
||||
if (!CHUNK.validLine(line)) {
|
||||
String headerTxt = "";
|
||||
LOG.log(Level.FINE, "header parsing");
|
||||
while (line != null) {
|
||||
LOG.log(Level.FINE, "parsing line {0}", line);
|
||||
if (validLine(line, DIFF_COMMAND, SIMILARITY_INDEX, INDEX,
|
||||
FROM_FILE, TO_FILE,
|
||||
RENAME_FROM, RENAME_TO,
|
||||
NEW_FILE_MODE, DELETED_FILE_MODE,
|
||||
CHUNK)) {
|
||||
break;
|
||||
} else {
|
||||
headerTxt += line + "\n";
|
||||
}
|
||||
line = READER.readLine();
|
||||
}
|
||||
if (!"".equals(headerTxt)) {
|
||||
data.setHeader(headerTxt);
|
||||
}
|
||||
if (line != null && !CHUNK.validLine(line)) {
|
||||
initFileIfNecessary();
|
||||
while (!CHUNK.validLine(line)) {
|
||||
if (processLine(line, DIFF_COMMAND, INDEX, FROM_FILE, TO_FILE) == false) {
|
||||
while (line != null && !CHUNK.validLine(line)) {
|
||||
if (!processLine(line, DIFF_COMMAND, SIMILARITY_INDEX, INDEX,
|
||||
FROM_FILE, TO_FILE,
|
||||
RENAME_FROM, RENAME_TO,
|
||||
NEW_FILE_MODE, DELETED_FILE_MODE)) {
|
||||
throw new UnifiedDiffParserException("expected file start line not found");
|
||||
}
|
||||
line = READER.readLine();
|
||||
}
|
||||
}
|
||||
processLine(line, CHUNK);
|
||||
while ((line = READER.readLine()) != null) {
|
||||
if (processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL) == false) {
|
||||
throw new UnifiedDiffParserException("expected data line not found");
|
||||
}
|
||||
if ((originalTxt.size() == old_size && revisedTxt.size() == new_size)
|
||||
|| (old_size==0 && new_size==0 && originalTxt.size() == this.old_ln
|
||||
if (line != null) {
|
||||
processLine(line, CHUNK);
|
||||
while ((line = READER.readLine()) != null) {
|
||||
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
||||
|
||||
if (!processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL)) {
|
||||
throw new UnifiedDiffParserException("expected data line not found");
|
||||
}
|
||||
if ((originalTxt.size() == old_size && revisedTxt.size() == new_size)
|
||||
|| (old_size == 0 && new_size == 0 && originalTxt.size() == this.old_ln
|
||||
&& revisedTxt.size() == this.new_ln)) {
|
||||
finalizeChunk();
|
||||
break;
|
||||
finalizeChunk();
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = READER.readLine();
|
||||
|
||||
line = checkForNoNewLineAtTheEndOfTheFile(line);
|
||||
}
|
||||
line = READER.readLine();
|
||||
if (line == null || line.startsWith("--")) {
|
||||
if (line == null || (line.startsWith("--") && !line.startsWith("---"))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -113,7 +149,10 @@ public final class UnifiedDiffReader {
|
||||
if (READER.ready()) {
|
||||
String tailTxt = "";
|
||||
while (READER.ready()) {
|
||||
tailTxt += READER.readLine() + "\n";
|
||||
if (tailTxt.length() > 0) {
|
||||
tailTxt += "\n";
|
||||
}
|
||||
tailTxt += READER.readLine();
|
||||
}
|
||||
data.setTailTxt(tailTxt);
|
||||
}
|
||||
@@ -121,6 +160,14 @@ public final class UnifiedDiffReader {
|
||||
return data;
|
||||
}
|
||||
|
||||
private String checkForNoNewLineAtTheEndOfTheFile(String line) throws IOException {
|
||||
if ("\\ No newline at end of file".equals(line)) {
|
||||
actualFile.setNoNewLineAtTheEndOfTheFile(true);
|
||||
return READER.readLine();
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
static String[] parseFileNames(String line) {
|
||||
String[] split = line.split(" ");
|
||||
return new String[]{
|
||||
@@ -131,22 +178,46 @@ public final class UnifiedDiffReader {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(UnifiedDiffReader.class.getName());
|
||||
|
||||
/**
|
||||
* To parse a diff file use this method.
|
||||
*
|
||||
* @param stream This is the diff file data.
|
||||
* @return In a UnifiedDiff structure this diff file data is returned.
|
||||
* @throws IOException
|
||||
* @throws UnifiedDiffParserException
|
||||
*/
|
||||
public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOException, UnifiedDiffParserException {
|
||||
UnifiedDiffReader parser = new UnifiedDiffReader(new BufferedReader(new InputStreamReader(stream)));
|
||||
return parser.parse();
|
||||
}
|
||||
|
||||
private boolean processLine(String line, UnifiedDiffLine... rules) throws UnifiedDiffParserException {
|
||||
if (line == null) {
|
||||
return false;
|
||||
}
|
||||
for (UnifiedDiffLine rule : rules) {
|
||||
if (rule.processLine(line)) {
|
||||
LOG.info(" >>> processed rule " + rule.toString());
|
||||
LOG.fine(" >>> processed rule " + rule.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
LOG.info(" >>> no rule matched " + line);
|
||||
LOG.warning(" >>> no rule matched " + line);
|
||||
return false;
|
||||
//throw new UnifiedDiffParserException("parsing error at line " + line);
|
||||
}
|
||||
|
||||
private boolean validLine(String line, UnifiedDiffLine ... rules) {
|
||||
if (line == null) {
|
||||
return false;
|
||||
}
|
||||
for (UnifiedDiffLine rule : rules) {
|
||||
if (rule.validLine(line)) {
|
||||
LOG.fine(" >>> accepted rule " + rule.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initFileIfNecessary() {
|
||||
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||
@@ -161,29 +232,41 @@ public final class UnifiedDiffReader {
|
||||
|
||||
private void processDiff(MatchResult match, String line) {
|
||||
//initFileIfNecessary();
|
||||
LOG.log(Level.INFO, "start {0}", line);
|
||||
LOG.log(Level.FINE, "start {0}", line);
|
||||
String[] fromTo = parseFileNames(READER.lastLine());
|
||||
actualFile.setFromFile(fromTo[0]);
|
||||
actualFile.setToFile(fromTo[1]);
|
||||
actualFile.setDiffCommand(line);
|
||||
}
|
||||
|
||||
private void processSimilarityIndex(MatchResult match, String line) {
|
||||
actualFile.setSimilarityIndex(Integer.valueOf(match.group(1)));
|
||||
}
|
||||
|
||||
private List<String> originalTxt = new ArrayList<>();
|
||||
private List<String> revisedTxt = new ArrayList<>();
|
||||
private List<Integer> addLineIdxList = new ArrayList<>();
|
||||
private List<Integer> delLineIdxList = new ArrayList<>();
|
||||
private int old_ln;
|
||||
private int old_size;
|
||||
private int new_ln;
|
||||
private int new_size;
|
||||
private int delLineIdx = 0;
|
||||
private int addLineIdx = 0;
|
||||
|
||||
private void finalizeChunk() {
|
||||
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||
actualFile.getPatch().addDelta(new ChangeDelta<>(new Chunk<>(
|
||||
old_ln - 1, originalTxt), new Chunk<>(
|
||||
new_ln - 1, revisedTxt)));
|
||||
old_ln - 1, originalTxt, delLineIdxList), new Chunk<>(
|
||||
new_ln - 1, revisedTxt, addLineIdxList)));
|
||||
old_ln = 0;
|
||||
new_ln = 0;
|
||||
originalTxt.clear();
|
||||
revisedTxt.clear();
|
||||
addLineIdxList.clear();
|
||||
delLineIdxList.clear();
|
||||
delLineIdx = 0;
|
||||
addLineIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,24 +274,30 @@ public final class UnifiedDiffReader {
|
||||
String cline = line.substring(1);
|
||||
originalTxt.add(cline);
|
||||
revisedTxt.add(cline);
|
||||
delLineIdx++;
|
||||
addLineIdx++;
|
||||
}
|
||||
|
||||
private void processAddLine(MatchResult match, String line) {
|
||||
String cline = line.substring(1);
|
||||
revisedTxt.add(cline);
|
||||
addLineIdx++;
|
||||
addLineIdxList.add(new_ln - 1 + addLineIdx);
|
||||
}
|
||||
|
||||
private void processDelLine(MatchResult match, String line) {
|
||||
String cline = line.substring(1);
|
||||
originalTxt.add(cline);
|
||||
delLineIdx++;
|
||||
delLineIdxList.add(old_ln - 1 + delLineIdx);
|
||||
}
|
||||
|
||||
private void processChunk(MatchResult match, String chunkStart) {
|
||||
// finalizeChunk();
|
||||
old_ln = toInteger(match, 1, 1);
|
||||
old_size = toInteger(match, 2, 0);
|
||||
old_size = toInteger(match, 2, 1);
|
||||
new_ln = toInteger(match, 3, 1);
|
||||
new_size = toInteger(match, 4, 0);
|
||||
new_size = toInteger(match, 4, 1);
|
||||
if (old_ln == 0) {
|
||||
old_ln = 1;
|
||||
}
|
||||
@@ -223,7 +312,7 @@ public final class UnifiedDiffReader {
|
||||
|
||||
private void processIndex(MatchResult match, String line) {
|
||||
//initFileIfNecessary();
|
||||
LOG.log(Level.INFO, "index {0}", line);
|
||||
LOG.log(Level.FINE, "index {0}", line);
|
||||
actualFile.setIndex(line.substring(6));
|
||||
}
|
||||
|
||||
@@ -239,14 +328,33 @@ public final class UnifiedDiffReader {
|
||||
actualFile.setToTimestamp(extractTimestamp(line));
|
||||
}
|
||||
|
||||
private void processRenameFrom(MatchResult match, String line) {
|
||||
actualFile.setRenameFrom(match.group(1));
|
||||
}
|
||||
|
||||
private void processRenameTo(MatchResult match, String line) {
|
||||
actualFile.setRenameTo(match.group(1));
|
||||
}
|
||||
|
||||
private void processNewFileMode(MatchResult match, String line) {
|
||||
//initFileIfNecessary();
|
||||
actualFile.setNewFileMode(match.group(1));
|
||||
}
|
||||
|
||||
private void processDeletedFileMode(MatchResult match, String line) {
|
||||
//initFileIfNecessary();
|
||||
actualFile.setDeletedFileMode(match.group(1));
|
||||
}
|
||||
|
||||
private String extractFileName(String _line) {
|
||||
Matcher matcher = TIMESTAMP_REGEXP.matcher(_line);
|
||||
String line = _line;
|
||||
if (matcher.find()) {
|
||||
line = line.substring(0, matcher.start());
|
||||
}
|
||||
line = line.split("\t")[0];
|
||||
return line.substring(4).replaceFirst("^(a|b|old|new)(\\/)?", "")
|
||||
.replace(TIMESTAMP_REGEXP.toString(), "").trim();
|
||||
.trim();
|
||||
}
|
||||
|
||||
private String extractTimestamp(String line) {
|
||||
|
||||
@@ -59,7 +59,7 @@ public class UnifiedDiffWriter {
|
||||
writer.accept("index " + file.getIndex());
|
||||
}
|
||||
|
||||
writer.accept("--- " + file.getFromFile());
|
||||
writer.accept("--- " + (file.getFromFile() == null ? "/dev/null" : file.getFromFile()));
|
||||
|
||||
if (file.getToFile() != null) {
|
||||
writer.accept("+++ " + file.getToFile());
|
||||
@@ -96,7 +96,7 @@ public class UnifiedDiffWriter {
|
||||
|
||||
}
|
||||
// don't forget to process the last set of Deltas
|
||||
processDeltas(writer, originalLines, deltas, contextSize,
|
||||
processDeltas(writer, originalLines, deltas, contextSize,
|
||||
patchDeltas.size() == 1 && file.getFromFile() == null);
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ public class UnifiedDiffWriter {
|
||||
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
||||
int intermediateStart = curDelta.getSource().getPosition()
|
||||
+ curDelta.getSource().getLines().size();
|
||||
for (line = intermediateStart; line < nextDelta.getSource().getPosition()
|
||||
for (line = intermediateStart; line < nextDelta.getSource().getPosition()
|
||||
&& line < origLines.size(); line++) {
|
||||
// output the code between the last Delta and this one
|
||||
buffer.add(" " + origLines.get(line));
|
||||
@@ -189,11 +189,10 @@ public class UnifiedDiffWriter {
|
||||
}
|
||||
|
||||
/**
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter.
|
||||
*
|
||||
* @param delta - the Delta to output
|
||||
* @return list of String lines of code.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
* @param writer consumer for the list of String lines of code
|
||||
* @param delta the Delta to output
|
||||
*/
|
||||
private static void getDeltaText(Consumer<String> writer, AbstractDelta<String> delta) {
|
||||
for (String line : delta.getSource().getLines()) {
|
||||
|
||||
@@ -14,7 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* This is the first test version of a multifile diff parser. The Api is still subject
|
||||
* of change.
|
||||
* This is the new implementation of UnifiedDiff Tools. This version is multi file aware.
|
||||
* <p/>
|
||||
* To read a unified diff file you should use {@link UnifiedDiffReader#parseUnifiedDiff}.
|
||||
* You will get a {@link UnifiedDiff} that holds all informations about the
|
||||
* diffs and the files.
|
||||
* <p/>
|
||||
* To process the UnifiedDiff use {@link UnifiedDiffWriter#write}.
|
||||
*/
|
||||
package com.github.difflib.unifieddiff;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class DiffUtilsTest {
|
||||
|
||||
final Patch<Integer> patch = DiffUtils.diff(original, revised);
|
||||
|
||||
for (AbstractDelta delta : patch.getDeltas()) {
|
||||
for (AbstractDelta<Integer> delta : patch.getDeltas()) {
|
||||
System.out.println(delta);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.difflib;
|
||||
|
||||
import com.github.difflib.patch.Chunk;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
import java.io.BufferedReader;
|
||||
@@ -8,9 +9,13 @@ import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -119,13 +124,51 @@ public class GenerateUnifiedDiffTest {
|
||||
List<String> udiff = UnifiedDiffUtils.generateUnifiedDiff(null, "revised",
|
||||
original, patch, 10);
|
||||
|
||||
assertEquals("--- ", udiff.get(0));
|
||||
assertEquals("--- /dev/null", udiff.get(0));
|
||||
assertEquals("+++ revised", udiff.get(1));
|
||||
assertEquals("@@ -0,0 +1,2 @@", udiff.get(2));
|
||||
|
||||
UnifiedDiffUtils.parseUnifiedDiff(udiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue 89
|
||||
*/
|
||||
@Test
|
||||
public void testChangePosition() throws IOException {
|
||||
final List<String> patchLines = fileToLines(TestConstants.MOCK_FOLDER + "issue89_patch.txt");
|
||||
final Patch<String> patch = UnifiedDiffUtils.parseUnifiedDiff(patchLines);
|
||||
List<Integer> realRemoveListOne = Collections.singletonList(3);
|
||||
List<Integer> realAddListOne = Arrays.asList(3, 7, 8, 9, 10, 11, 12, 13, 14);
|
||||
validateChangePosition(patch, 0, realRemoveListOne, realAddListOne);
|
||||
List<Integer> realRemoveListTwo = new ArrayList<>();
|
||||
List<Integer> realAddListTwo = Arrays.asList(27, 28);
|
||||
validateChangePosition(patch, 1, realRemoveListTwo, realAddListTwo);
|
||||
|
||||
}
|
||||
|
||||
private void validateChangePosition(Patch<String> patch, int index, List<Integer> realRemoveList,
|
||||
List<Integer> realAddList ) {
|
||||
final Chunk<String> originChunk = patch.getDeltas().get(index).getSource();
|
||||
List<Integer> removeList = originChunk.getChangePosition();
|
||||
assertEquals(realRemoveList.size(), removeList.size());
|
||||
for (Integer ele: realRemoveList) {
|
||||
assertTrue(realRemoveList.contains(ele));
|
||||
}
|
||||
for (Integer ele: removeList) {
|
||||
assertTrue(realAddList.contains(ele));
|
||||
}
|
||||
final Chunk<String> targetChunk = patch.getDeltas().get(index).getTarget();
|
||||
List<Integer> addList = targetChunk.getChangePosition();
|
||||
assertEquals(realAddList.size(), addList.size());
|
||||
for (Integer ele: realAddList) {
|
||||
assertTrue(addList.contains(ele));
|
||||
}
|
||||
for (Integer ele: addList) {
|
||||
assertTrue(realAddList.contains(ele));
|
||||
}
|
||||
}
|
||||
|
||||
private void verify(List<String> origLines, List<String> revLines,
|
||||
String originalFile, String revisedFile) {
|
||||
Patch<String> patch = DiffUtils.diff(origLines, revLines);
|
||||
@@ -150,4 +193,31 @@ public class GenerateUnifiedDiffTest {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFailingPatchByException() throws IOException {
|
||||
final List<String> baseLines = fileToLines(TestConstants.MOCK_FOLDER + "issue10_base.txt");
|
||||
final List<String> patchLines = fileToLines(TestConstants.MOCK_FOLDER + "issue10_patch.txt");
|
||||
final Patch<String> p = UnifiedDiffUtils.parseUnifiedDiff(patchLines);
|
||||
|
||||
//make original not fitting
|
||||
baseLines.set(40, baseLines.get(40) + " corrupted ");
|
||||
|
||||
assertThrows(PatchFailedException.class, () -> DiffUtils.patch(baseLines, p));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongContextLength() throws IOException {
|
||||
List<String> original = fileToLines(TestConstants.BASE_FOLDER_RESOURCES + "com/github/difflib/text/issue_119_original.txt");
|
||||
List<String> revised = fileToLines(TestConstants.BASE_FOLDER_RESOURCES + "com/github/difflib/text/issue_119_revised.txt");
|
||||
|
||||
Patch<String> patch = DiffUtils.diff(original, revised);
|
||||
List<String> udiff = UnifiedDiffUtils.generateUnifiedDiff("a/$filename", "b/$filename",
|
||||
original, patch, 3);
|
||||
|
||||
//System.out.println(udiff.stream().collect(joining("\n")));
|
||||
|
||||
assertThat(udiff).contains("@@ -1,4 +1,4 @@");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2021 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.myers;
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import java.util.stream.IntStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public class MeyersDiffWithLinearSpaceTest {
|
||||
|
||||
@Test
|
||||
public void testDiffMyersExample1Forward() {
|
||||
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
final Patch<String> patch = Patch.generate(original, revised, new MeyersDiffWithLinearSpace<String>().computeDiff(original, revised, null));
|
||||
assertNotNull(patch);
|
||||
System.out.println(patch);
|
||||
assertEquals(5, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[InsertDelta, position: 0, lines: [C]], [DeleteDelta, position: 0, lines: [A]], [DeleteDelta, position: 2, lines: [C]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiffMyersExample1ForwardWithListener() {
|
||||
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
final Patch<String> patch = Patch.generate(original, revised,
|
||||
new MeyersDiffWithLinearSpace<String>().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffStep(int value, int max) {
|
||||
logdata.add(value + " - " + max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffEnd() {
|
||||
logdata.add("end");
|
||||
}
|
||||
}));
|
||||
assertNotNull(patch);
|
||||
System.out.println(patch);
|
||||
assertEquals(5, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[InsertDelta, position: 0, lines: [C]], [DeleteDelta, position: 0, lines: [A]], [DeleteDelta, position: 2, lines: [C]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
System.out.println(logdata);
|
||||
assertEquals(11, logdata.size());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPerformanceProblemsIssue124() {
|
||||
List<String> old = Arrays.asList("abcd");
|
||||
List<String> newl = IntStream.range(0, 90000)
|
||||
.boxed()
|
||||
.map(i -> i.toString())
|
||||
.collect(toList());
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Patch<String> diff = DiffUtils.diff(old, newl, new MeyersDiffWithLinearSpace<String>());
|
||||
long end = System.currentTimeMillis();
|
||||
System.out.println("Finished in " + (end - start) + "ms and resulted " + diff.getDeltas().size() + " deltas");
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class MyersDiffTest {
|
||||
public void testDiffMyersExample1Forward() {
|
||||
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
final Patch<String> patch = Patch.generate(original, revised, new MyersDiff<String>().computeDiff(original, revised, null));
|
||||
final Patch<String> patch = Patch.generate(original, revised, new MeyersDiff<String>().computeDiff(original, revised, null));
|
||||
assertNotNull(patch);
|
||||
assertEquals(4, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
@@ -47,7 +47,7 @@ public class MyersDiffTest {
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
final Patch<String> patch = Patch.generate(original, revised,
|
||||
new MyersDiff<String>().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
new MeyersDiff<String>().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
@@ -69,5 +69,4 @@ public class MyersDiffTest {
|
||||
System.out.println(logdata);
|
||||
assertEquals(8, logdata.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.github.difflib.algorithm.myers;
|
||||
|
||||
import com.github.difflib.patch.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
|
||||
public class WithMeyersDiffWithLinearSpacePatchTest {
|
||||
|
||||
@Test
|
||||
public void testPatch_Insert() {
|
||||
final List<String> insertTest_from = Arrays.asList("hhh");
|
||||
final List<String> insertTest_to = Arrays.asList("hhh", "jjj", "kkk", "lll");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(insertTest_from, insertTest_to, new MeyersDiffWithLinearSpace<String>());
|
||||
try {
|
||||
assertEquals(insertTest_to, DiffUtils.patch(insertTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Delete() {
|
||||
final List<String> deleteTest_from = Arrays.asList("ddd", "fff", "ggg", "hhh");
|
||||
final List<String> deleteTest_to = Arrays.asList("ggg");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(deleteTest_from, deleteTest_to, new MeyersDiffWithLinearSpace<String>());
|
||||
try {
|
||||
assertEquals(deleteTest_to, DiffUtils.patch(deleteTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Change() {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to, new MeyersDiffWithLinearSpace<String>());
|
||||
try {
|
||||
assertEquals(changeTest_to, DiffUtils.patch(changeTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Serializable() throws IOException, ClassNotFoundException {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to, new MeyersDiffWithLinearSpace<String>());
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(baos);
|
||||
out.writeObject(patch);
|
||||
out.close();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream in = new ObjectInputStream(bais);
|
||||
Patch<String> result = (Patch<String>) in.readObject();
|
||||
in.close();
|
||||
|
||||
try {
|
||||
assertEquals(changeTest_to, DiffUtils.patch(changeTest_from, result));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Change_withExceptionProcessor() {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to, new MeyersDiffWithLinearSpace<String>());
|
||||
|
||||
changeTest_from.set(2, "CDC");
|
||||
|
||||
patch.withConflictOutput(Patch.CONFLICT_PRODUCES_MERGE_CONFLICT);
|
||||
|
||||
try {
|
||||
List<String> data = DiffUtils.patch(changeTest_from, patch);
|
||||
assertEquals(11, data.size());
|
||||
|
||||
assertEquals(Arrays.asList("aaa", "bxb", "cxc", "<<<<<< HEAD", "bbb", "CDC", "======", "bbb", "ccc", ">>>>>>> PATCH", "ddd"), data);
|
||||
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.github.difflib.patch;
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PatchTest {
|
||||
|
||||
@Test
|
||||
public void testPatch_Insert() {
|
||||
final List<String> insertTest_from = Arrays.asList("hhh");
|
||||
final List<String> insertTest_to = Arrays.asList("hhh", "jjj", "kkk", "lll");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(insertTest_from, insertTest_to);
|
||||
try {
|
||||
assertEquals(insertTest_to, DiffUtils.patch(insertTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Delete() {
|
||||
final List<String> deleteTest_from = Arrays.asList("ddd", "fff", "ggg", "hhh");
|
||||
final List<String> deleteTest_to = Arrays.asList("ggg");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(deleteTest_from, deleteTest_to);
|
||||
try {
|
||||
assertEquals(deleteTest_to, DiffUtils.patch(deleteTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Change() {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||
try {
|
||||
assertEquals(changeTest_to, DiffUtils.patch(changeTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.github.difflib.patch;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmFactory;
|
||||
import com.github.difflib.algorithm.myers.MeyersDiff;
|
||||
import com.github.difflib.algorithm.myers.MeyersDiffWithLinearSpace;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
public class PatchWithAllDiffAlgorithmsTest {
|
||||
|
||||
private static Stream<Arguments> provideAlgorithms() {
|
||||
return Stream.of(
|
||||
Arguments.of(MeyersDiff.factory()),
|
||||
Arguments.of(MeyersDiffWithLinearSpace.factory()));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterAll() {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(MeyersDiff.factory());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideAlgorithms")
|
||||
public void testPatch_Insert(DiffAlgorithmFactory factory) {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(factory);
|
||||
|
||||
final List<String> insertTest_from = Arrays.asList("hhh");
|
||||
final List<String> insertTest_to = Arrays.asList("hhh", "jjj", "kkk", "lll");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(insertTest_from, insertTest_to);
|
||||
try {
|
||||
assertEquals(insertTest_to, DiffUtils.patch(insertTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideAlgorithms")
|
||||
public void testPatch_Delete(DiffAlgorithmFactory factory) {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(factory);
|
||||
|
||||
final List<String> deleteTest_from = Arrays.asList("ddd", "fff", "ggg", "hhh");
|
||||
final List<String> deleteTest_to = Arrays.asList("ggg");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(deleteTest_from, deleteTest_to);
|
||||
try {
|
||||
assertEquals(deleteTest_to, DiffUtils.patch(deleteTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideAlgorithms")
|
||||
public void testPatch_Change(DiffAlgorithmFactory factory) {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(factory);
|
||||
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||
try {
|
||||
assertEquals(changeTest_to, DiffUtils.patch(changeTest_from, patch));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideAlgorithms")
|
||||
public void testPatch_Serializable(DiffAlgorithmFactory factory) throws IOException, ClassNotFoundException {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(factory);
|
||||
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(baos);
|
||||
out.writeObject(patch);
|
||||
out.close();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream in = new ObjectInputStream(bais);
|
||||
Patch<String> result = (Patch<String>) in.readObject();
|
||||
in.close();
|
||||
|
||||
try {
|
||||
assertEquals(changeTest_to, DiffUtils.patch(changeTest_from, result));
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2021 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 com.github.difflib.DiffUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public class PatchWithMeyerDiffTest {
|
||||
@Test
|
||||
public void testPatch_Change_withExceptionProcessor() {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||
|
||||
changeTest_from.set(2, "CDC");
|
||||
|
||||
patch.withConflictOutput(Patch.CONFLICT_PRODUCES_MERGE_CONFLICT);
|
||||
|
||||
try {
|
||||
List<String> data = DiffUtils.patch(changeTest_from, patch);
|
||||
assertEquals(9, data.size());
|
||||
|
||||
assertEquals(Arrays.asList("aaa", "<<<<<< HEAD", "bbb", "CDC", "======", "bbb", "ccc", ">>>>>>> PATCH", "ddd"), data);
|
||||
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2021 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 com.github.difflib.DiffUtils;
|
||||
import com.github.difflib.algorithm.myers.MeyersDiff;
|
||||
import com.github.difflib.algorithm.myers.MeyersDiffWithLinearSpace;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tw
|
||||
*/
|
||||
public class PatchWithMeyerDiffWithLinearSpaceTest {
|
||||
|
||||
@BeforeAll
|
||||
public static void setupClass() {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(MeyersDiffWithLinearSpace.factory());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void resetClass() {
|
||||
DiffUtils.withDefaultDiffAlgorithmFactory(MeyersDiff.factory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatch_Change_withExceptionProcessor() {
|
||||
final List<String> changeTest_from = Arrays.asList("aaa", "bbb", "ccc", "ddd");
|
||||
final List<String> changeTest_to = Arrays.asList("aaa", "bxb", "cxc", "ddd");
|
||||
|
||||
final Patch<String> patch = DiffUtils.diff(changeTest_from, changeTest_to);
|
||||
|
||||
changeTest_from.set(2, "CDC");
|
||||
|
||||
patch.withConflictOutput(Patch.CONFLICT_PRODUCES_MERGE_CONFLICT);
|
||||
|
||||
try {
|
||||
List<String> data = DiffUtils.patch(changeTest_from, patch);
|
||||
assertEquals(11, data.size());
|
||||
|
||||
assertEquals(Arrays.asList("aaa", "bxb", "cxc", "<<<<<< HEAD", "bbb", "CDC", "======", "bbb", "ccc", ">>>>>>> PATCH", "ddd"), data);
|
||||
|
||||
} catch (PatchFailedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,12 @@ package com.github.difflib.text;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -161,7 +163,7 @@ public class DiffRowGeneratorTest {
|
||||
assertEquals(6, rows.size());
|
||||
assertEquals("[CHANGE,<span class=\"editOldInline\">test</span>,anything]", rows.get(0).toString());
|
||||
assertEquals("[CHANGE,anything<span class=\"editOldInline\"> </span>,]", rows.get(1).toString());
|
||||
assertEquals("[CHANGE,<span class=\"editOldInline\"> </span>,]", rows.get(2).toString());
|
||||
assertEquals("[DELETE,<span class=\"editOldInline\"> </span>,]", rows.get(2).toString());
|
||||
assertEquals("[EQUAL,other,other]", rows.get(3).toString());
|
||||
assertEquals("[INSERT,<span class=\"editNewInline\">test</span>,test]", rows.get(4).toString());
|
||||
assertEquals("[INSERT,<span class=\"editNewInline\">test2</span>,test2]", rows.get(5).toString());
|
||||
@@ -341,7 +343,7 @@ public class DiffRowGeneratorTest {
|
||||
Arrays.asList(aa.split("\n")),
|
||||
Arrays.asList(bb.split("\n")));
|
||||
|
||||
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**]]",
|
||||
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [INSERT,,**This is the second line.**]]",
|
||||
rows.toString());
|
||||
|
||||
System.out.println("|original|new|");
|
||||
@@ -365,7 +367,7 @@ public class DiffRowGeneratorTest {
|
||||
Arrays.asList(aa.split("\n")),
|
||||
Arrays.asList(bb.split("\n")));
|
||||
|
||||
assertEquals("[[CHANGE,This is a test ~for diffutils~.,This is a test **senctence**.], [CHANGE,~This is the second line.~,]]",
|
||||
assertEquals("[[CHANGE,This is a test ~for diffutils~.,This is a test **senctence**.], [DELETE,~This is the second line.~,]]",
|
||||
rows.toString());
|
||||
}
|
||||
|
||||
@@ -383,7 +385,7 @@ public class DiffRowGeneratorTest {
|
||||
Arrays.asList(aa.split("\n")),
|
||||
Arrays.asList(bb.split("\n")));
|
||||
|
||||
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**], [CHANGE,,**And one more.**]]",
|
||||
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [INSERT,,**This is the second line.**], [INSERT,,**And one more.**]]",
|
||||
rows.toString());
|
||||
}
|
||||
|
||||
@@ -498,4 +500,187 @@ public class DiffRowGeneratorTest {
|
||||
|
||||
assertEquals("This~//~**/**is~//~**/**a~//~**/**test~.~", rows.get(0).getOldLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProblemTooManyDiffRowsIssue65() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.reportLinesUnchanged(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(false)
|
||||
.replaceOriginalLinefeedInChangesWithSpaces(true)
|
||||
.build();
|
||||
|
||||
List<DiffRow> diffRows = generator.generateDiffRows(
|
||||
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
|
||||
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
|
||||
|
||||
print(diffRows);
|
||||
|
||||
assertThat(diffRows).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProblemTooManyDiffRowsIssue65_NoMerge() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.reportLinesUnchanged(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.mergeOriginalRevised(false)
|
||||
.inlineDiffByWord(false)
|
||||
.build();
|
||||
|
||||
List<DiffRow> diffRows = generator.generateDiffRows(
|
||||
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
|
||||
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
|
||||
|
||||
System.out.println(diffRows);
|
||||
|
||||
assertThat(diffRows).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProblemTooManyDiffRowsIssue65_DiffByWord() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.reportLinesUnchanged(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(true)
|
||||
.build();
|
||||
|
||||
List<DiffRow> diffRows = generator.generateDiffRows(
|
||||
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
|
||||
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
|
||||
|
||||
System.out.println(diffRows);
|
||||
|
||||
assertThat(diffRows).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProblemTooManyDiffRowsIssue65_NoInlineDiff() {
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(false)
|
||||
.reportLinesUnchanged(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(false)
|
||||
.build();
|
||||
|
||||
List<DiffRow> diffRows = generator.generateDiffRows(
|
||||
Arrays.asList("Ich möchte nicht mit einem Bot sprechen.", "Ich soll das schon wieder wiederholen?"),
|
||||
Arrays.asList("Ich möchte nicht mehr mit dir sprechen. Leite mich weiter.", "Kannst du mich zum Kundendienst weiterleiten?"));
|
||||
|
||||
System.out.println(diffRows);
|
||||
|
||||
assertThat(diffRows).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinefeedInStandardTagsWithLineWidthIssue81() {
|
||||
List<String> original = Arrays.asList(("American bobtail jaguar. American bobtail bombay but turkish angora and tomcat.\n"
|
||||
+ "Russian blue leopard. Lion. Tabby scottish fold for russian blue, so savannah yet lynx. Tomcat singapura, cheetah.\n"
|
||||
+ "Bengal tiger panther but singapura but bombay munchkin for cougar.").split("\n"));
|
||||
List<String> revised = Arrays.asList(("bobtail jaguar. American bobtail turkish angora and tomcat.\n"
|
||||
+ "Russian blue leopard. Lion. Tabby scottish folded for russian blue, so savannah yettie? lynx. Tomcat singapura, cheetah.\n"
|
||||
+ "Bengal tiger panther but singapura but bombay munchkin for cougar. And more.").split("\n"));
|
||||
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.ignoreWhiteSpaces(true)
|
||||
.columnWidth(100)
|
||||
.build();
|
||||
List<DiffRow> deltas = generator.generateDiffRows(original, revised);
|
||||
|
||||
System.out.println(deltas);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssue86WrongInlineDiff() throws IOException {
|
||||
String original = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_86_original.txt")).collect(joining("\n"));
|
||||
String revised = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_86_revised.txt")).collect(joining("\n"));
|
||||
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.build();
|
||||
List<DiffRow> rows = generator.generateDiffRows(
|
||||
Arrays.asList(original.split("\n")),
|
||||
Arrays.asList(revised.split("\n")));
|
||||
|
||||
rows.stream()
|
||||
.filter(item -> item.getTag() != DiffRow.Tag.EQUAL)
|
||||
.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectChangeIssue114() throws IOException {
|
||||
List<String> original = Arrays.asList("A", "B", "C", "D", "E");
|
||||
List<String> revised = Arrays.asList("a", "C", "", "E");
|
||||
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(false)
|
||||
.inlineDiffByWord(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.build();
|
||||
List<DiffRow> rows = generator.generateDiffRows(original, revised);
|
||||
|
||||
for (DiffRow diff : rows) {
|
||||
System.out.println(diff);
|
||||
}
|
||||
|
||||
assertThat(rows).extracting(item -> item.getTag().name()).containsExactly("CHANGE", "DELETE", "EQUAL", "CHANGE", "EQUAL");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrectChangeIssue114_2() throws IOException {
|
||||
List<String> original = Arrays.asList("A", "B", "C", "D", "E");
|
||||
List<String> revised = Arrays.asList("a", "C", "", "E");
|
||||
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.inlineDiffByWord(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.build();
|
||||
List<DiffRow> rows = generator.generateDiffRows(original, revised);
|
||||
|
||||
for (DiffRow diff : rows) {
|
||||
System.out.println(diff);
|
||||
}
|
||||
|
||||
assertThat(rows).extracting(item -> item.getTag().name()).containsExactly("CHANGE", "DELETE", "EQUAL", "CHANGE", "EQUAL");
|
||||
assertThat(rows.get(1).toString()).isEqualTo("[DELETE,~B~,]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssue119WrongContextLength() throws IOException {
|
||||
String original = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_119_original.txt")).collect(joining("\n"));
|
||||
String revised = Files.lines(Paths.get("target/test-classes/com/github/difflib/text/issue_119_revised.txt")).collect(joining("\n"));
|
||||
|
||||
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||
.showInlineDiffs(true)
|
||||
.mergeOriginalRevised(true)
|
||||
.inlineDiffByWord(true)
|
||||
.oldTag(f -> "~")
|
||||
.newTag(f -> "**")
|
||||
.build();
|
||||
List<DiffRow> rows = generator.generateDiffRows(
|
||||
Arrays.asList(original.split("\n")),
|
||||
Arrays.asList(revised.split("\n")));
|
||||
|
||||
rows.stream()
|
||||
.filter(item -> item.getTag() != DiffRow.Tag.EQUAL)
|
||||
.forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ public class StringUtilsTest {
|
||||
assertEquals("te<br/>st", StringUtils.wrapText("test", 2));
|
||||
assertEquals("tes<br/>t", StringUtils.wrapText("test", 3));
|
||||
assertEquals("test", StringUtils.wrapText("test", 10));
|
||||
assertEquals(".\uD800\uDC01<br/>.", StringUtils.wrapText(".\uD800\uDC01.", 2));
|
||||
assertEquals("..<br/>\uD800\uDC01", StringUtils.wrapText("..\uD800\uDC01", 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class UnifiedDiffReaderTest {
|
||||
assertThat(file1.getFromFile()).isEqualTo("src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(3);
|
||||
|
||||
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
|
||||
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,7 +101,7 @@ public class UnifiedDiffReaderTest {
|
||||
assertThat(first.getSource().size()).isGreaterThan(0);
|
||||
assertThat(first.getTarget().size()).isGreaterThan(0);
|
||||
|
||||
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
|
||||
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -141,7 +142,7 @@ public class UnifiedDiffReaderTest {
|
||||
assertThat(diff.getTail()).isNull();
|
||||
assertThat(diff.getHeader()).isNull();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParseIssue51() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
@@ -155,6 +156,232 @@ public class UnifiedDiffReaderTest {
|
||||
assertThat(file1.getFromFile()).isEqualTo("f1");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
UnifiedDiffFile file2 = diff.getFiles().get(1);
|
||||
assertThat(file2.getFromFile()).isEqualTo("f2");
|
||||
assertThat(file2.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
assertThat(diff.getTail()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue79() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue79.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||
|
||||
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertThat(file1.getFromFile()).isEqualTo("test/Issue.java");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(0);
|
||||
|
||||
assertThat(diff.getTail()).isNull();
|
||||
assertThat(diff.getHeader()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue84() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue84.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||
|
||||
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertThat(file1.getFromFile()).isEqualTo("config/ant-phase-verify.xml");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
UnifiedDiffFile file2 = diff.getFiles().get(1);
|
||||
assertThat(file2.getFromFile()).isEqualTo("/dev/null");
|
||||
assertThat(file2.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
assertThat(diff.getTail()).isEqualTo("2.7.4");
|
||||
assertThat(diff.getHeader()).startsWith("From b53e612a2ab5ff15d14860e252f84c0f343fe93a Mon Sep 17 00:00:00 2001");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue85() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue85.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||
|
||||
assertEquals(1, diff.getFiles().size());
|
||||
|
||||
final UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertEquals("diff -r 83e41b73d115 -r a4438263b228 tests/test-check-pyflakes.t",
|
||||
file1.getDiffCommand());
|
||||
assertEquals("tests/test-check-pyflakes.t", file1.getFromFile());
|
||||
assertEquals("tests/test-check-pyflakes.t", file1.getToFile());
|
||||
assertEquals(1, file1.getPatch().getDeltas().size());
|
||||
|
||||
assertNull(diff.getTail());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimeStampRegexp() {
|
||||
assertThat("2019-04-18 13:49:39.516149751 +0200").matches(UnifiedDiffReader.TIMESTAMP_REGEXP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue98() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue98.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||
|
||||
assertEquals(1, diff.getFiles().size());
|
||||
|
||||
final UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertEquals("100644",
|
||||
file1.getDeletedFileMode());
|
||||
assertEquals("src/test/java/se/bjurr/violations/lib/model/ViolationTest.java", file1.getFromFile());
|
||||
assertThat(diff.getTail()).isEqualTo("2.25.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue104() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_parsing_issue104.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(6);
|
||||
|
||||
final UnifiedDiffFile file = diff.getFiles().get(2);
|
||||
assertThat(file.getFromFile()).isEqualTo("/dev/null");
|
||||
assertThat(file.getToFile()).isEqualTo("doc/samba_data_tool_path.xml.in");
|
||||
|
||||
assertThat(file.getPatch().toString()).isEqualTo("Patch{deltas=[[ChangeDelta, position: 0, lines: [] to [@SAMBA_DATA_TOOL@]]]}");
|
||||
|
||||
assertThat(diff.getTail()).isEqualTo("2.14.4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue107BazelDiff() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("01-bazel-strip-unused.patch_issue107.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(450);
|
||||
|
||||
final UnifiedDiffFile file = diff.getFiles().get(0);
|
||||
assertThat(file.getFromFile()).isEqualTo("./src/main/java/com/amazonaws/AbortedException.java");
|
||||
assertThat(file.getToFile()).isEqualTo("/home/greg/projects/bazel/third_party/aws-sdk-auth-lite/src/main/java/com/amazonaws/AbortedException.java");
|
||||
|
||||
assertThat(diff.getFiles().stream()
|
||||
.filter(f -> f.isNoNewLineAtTheEndOfTheFile())
|
||||
.count())
|
||||
.isEqualTo(48);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue107_2() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue107.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||
|
||||
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertThat(file1.getFromFile()).isEqualTo("Main.java");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue107_3() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue107_3.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||
|
||||
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||
assertThat(file1.getFromFile()).isEqualTo("Billion laughs attack.md");
|
||||
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue107_4() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue107_4.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(27);
|
||||
|
||||
assertThat(diff.getFiles()).extracting(f -> f.getFromFile()).contains("README.md");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue107_5() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue107_5.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(22);
|
||||
|
||||
assertThat(diff.getFiles()).extracting(f -> f.getFromFile()).contains("rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue110() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("0001-avahi-python-Use-the-agnostic-DBM-interface.patch"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(5);
|
||||
|
||||
final UnifiedDiffFile file = diff.getFiles().get(4);
|
||||
assertThat(file.getSimilarityIndex()).isEqualTo(87);
|
||||
assertThat(file.getRenameFrom()).isEqualTo("service-type-database/build-db.in");
|
||||
assertThat(file.getRenameTo()).isEqualTo("service-type-database/build-db");
|
||||
|
||||
assertThat(file.getFromFile()).isEqualTo("service-type-database/build-db.in");
|
||||
assertThat(file.getToFile()).isEqualTo("service-type-database/build-db");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue117() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue117.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||
|
||||
assertThat(diff.getFiles().get(0).getPatch().getDeltas().get(0).getSource().getChangePosition())
|
||||
.containsExactly(24, 27);
|
||||
assertThat(diff.getFiles().get(0).getPatch().getDeltas().get(0).getTarget().getChangePosition())
|
||||
.containsExactly(24, 27);
|
||||
|
||||
assertThat(diff.getFiles().get(0).getPatch().getDeltas().get(1).getSource().getChangePosition())
|
||||
.containsExactly(64);
|
||||
assertThat(diff.getFiles().get(0).getPatch().getDeltas().get(1).getTarget().getChangePosition())
|
||||
.containsExactly(64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74);
|
||||
|
||||
// diff.getFiles().forEach(f -> {
|
||||
// System.out.println("File: " + f.getFromFile());
|
||||
// f.getPatch().getDeltas().forEach(delta -> {
|
||||
//
|
||||
// System.out.println(delta);
|
||||
// System.out.println("Source: ");
|
||||
// System.out.println(delta.getSource().getPosition());
|
||||
// System.out.println(delta.getSource().getChangePosition());
|
||||
//
|
||||
// System.out.println("Target: ");
|
||||
// System.out.println(delta.getTarget().getPosition());
|
||||
// System.out.println(delta.getTarget().getChangePosition());
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue122() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue122.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||
|
||||
assertThat(diff.getFiles()).extracting(f -> f.getFromFile()).contains("coders/wpg.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseIssue123() throws IOException {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue123.diff"));
|
||||
|
||||
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||
|
||||
assertThat(diff.getFiles()).extracting(f -> f.getFromFile()).contains("src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class UnifiedDiffRoundTripTest {
|
||||
// Patch<String> fromUnifiedPatch = unifiedDiff.getFiles().get(0).getPatch();
|
||||
// patchedLines = fromUnifiedPatch.applyTo(origLines);
|
||||
// }
|
||||
patchedLines = unifiedDiff.spplyPatchTo(file -> originalFile.equals(file), origLines);
|
||||
patchedLines = unifiedDiff.applyPatchTo(file -> originalFile.equals(file), origLines);
|
||||
assertEquals(revLines.size(), patchedLines.size());
|
||||
for (int i = 0; i < revLines.size(); i++) {
|
||||
String l1 = revLines.get(i);
|
||||
|
||||
@@ -46,7 +46,7 @@ public class UnifiedDiffWriterTest {
|
||||
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(new ByteArrayInputStream(str.getBytes()));
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
UnifiedDiffWriter.write(diff, f -> Collections.EMPTY_LIST, writer, 5);
|
||||
UnifiedDiffWriter.write(diff, f -> Collections.emptyList(), writer, 5);
|
||||
System.out.println(writer.toString());
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class UnifiedDiffWriterTest {
|
||||
|
||||
String[] lines = writer.toString().split("\\n");
|
||||
|
||||
assertEquals("--- null", lines[0]);
|
||||
assertEquals("--- /dev/null", lines[0]);
|
||||
assertEquals("+++ revised", lines[1]);
|
||||
assertEquals("@@ -0,0 +1,2 @@", lines[2]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
const world: string = 'world',
|
||||
p: number | undefined = 42;
|
||||
|
||||
console.log(`Hello, ${world}!`);
|
||||
@@ -0,0 +1,4 @@
|
||||
const world: string = 'world';
|
||||
const p: number | undefined = 42;
|
||||
|
||||
console.log(`Hello, ${world}!`);
|
||||
@@ -0,0 +1,7 @@
|
||||
MessageTime,MessageType,Instrument,InstrumentState,TradePrice,TradeVolume,TradeCond,TradeId,AskPrice1,AskVol1,BidPrice1,BidVol1,AskPrice2,AskVol2,BidPrice2,BidVol2,AskPrice3,AskVol3,BidPrice3,BidVol3,AskPrice4,AskVol4,BidPrice4,BidVol4,AskPrice5,AskVol5,BidPrice5,BidVol5
|
||||
2020-04-04T08:00:00.000Z,S,HHD_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T08:00:00.000Z,S,FHK_C23.5_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T13:49:11.522Z,Q,HHD_MAY20,,,,,,2.6,10,2.6,10,,,,,,,,,,,,,,,,
|
||||
2020-04-04T13:49:18.210Z,T,HHD_MAY20,,2.6,1,Screen,0,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T17:00:00.000Z,S,HHD_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T17:00:00.000Z,S,FHK_C23.5_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
@@ -0,0 +1,8 @@
|
||||
MessageTime,MessageType,Instrument,InstrumentState,TradePrice,TradeVolume,TradeCond,TradeId,AskPrice1,AskVol1,BidPrice1,BidVol1,AskPrice2,AskVol2,BidPrice2,BidVol2,AskPrice3,AskVol3,BidPrice3,BidVol3,AskPrice4,AskVol4,BidPrice4,BidVol4,AskPrice5,AskVol5,BidPrice5,BidVol5
|
||||
2020-04-02T08:00:00.000Z,S,HHD_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-02T08:00:00.000Z,S,FHK_C23.5_MAY20,Open,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T13:49:11.522Z,Q,HHD_MAY20,,,,,,2.6,10,2.6,10,,,,,,,,,,,,,,,,
|
||||
2020-04xs-04T17dw:00:00.000Z,Sdwdw,HHD_MAY20dwdw,Closdwde,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T13:49:18.210Z,T,HHD_MAY20,,2.6,2,Screen,0,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T17:00:00.000Z,S,HHD_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
2020-04-04T17:00:00.000Z,S,FHK_C23.5_MAY20,Close,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
@@ -0,0 +1,231 @@
|
||||
From be7992f35ab4ed7ed9907319b429dc079c2b7285 Mon Sep 17 00:00:00 2001
|
||||
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
|
||||
Date: Tue, 11 Jul 2017 21:52:37 +0200
|
||||
Subject: [PATCH] avahi-python: Use the agnostic DBM interface
|
||||
|
||||
Also fixes configure failing if Python 3 is the build python and GDBM is
|
||||
enabled, since Py3 only has anydbm under the name of 'dbm'.
|
||||
|
||||
Not enough to make ServiceTypeDatabase.py compatible with Py3, but it's
|
||||
a start.
|
||||
|
||||
(cherry picked from commit 63750f1be96ad08c407193b08bf3b9ee74310e2d)
|
||||
|
||||
Related: #1561019
|
||||
---
|
||||
avahi-python/avahi/Makefile.am | 15 +----------
|
||||
avahi-python/avahi/ServiceTypeDatabase.py.in | 33 ++++++++++++++++++-------
|
||||
configure.ac | 9 +++----
|
||||
service-type-database/Makefile.am | 18 +++-----------
|
||||
service-type-database/{build-db.in => build-db} | 13 +++++++---
|
||||
5 files changed, 42 insertions(+), 46 deletions(-)
|
||||
rename service-type-database/{build-db.in => build-db} (87%)
|
||||
|
||||
diff --git a/avahi-python/avahi/Makefile.am b/avahi-python/avahi/Makefile.am
|
||||
index 3eb67d0..c906b9b 100644
|
||||
--- a/avahi-python/avahi/Makefile.am
|
||||
+++ b/avahi-python/avahi/Makefile.am
|
||||
@@ -25,29 +25,16 @@ avahidir = $(pythondir)/avahi
|
||||
|
||||
if HAVE_GDBM
|
||||
nodist_avahi_SCRIPTS = ServiceTypeDatabase.py
|
||||
-
|
||||
-ServiceTypeDatabase.py: ServiceTypeDatabase.py.in
|
||||
- $(AM_V_GEN)sed -e 's,@PYTHON\@,$(PYTHON),g' \
|
||||
- -e 's,@DBM\@,gdbm,g' \
|
||||
- -e 's,@FIRST_KEY\@,key = self.db.firstkey(),g' \
|
||||
- -e 's,@CHECK_KEY\@,while key is not None:,g' \
|
||||
- -e 's,@NEXT_KEY\@,key = self.db.nextkey(key),g' \
|
||||
- -e 's,@pkglibdatadir\@,$(pkglibdatadir),g' $< > $@ && \
|
||||
- chmod +x $@
|
||||
endif
|
||||
|
||||
if HAVE_DBM
|
||||
nodist_avahi_SCRIPTS = ServiceTypeDatabase.py
|
||||
+endif
|
||||
|
||||
ServiceTypeDatabase.py: ServiceTypeDatabase.py.in
|
||||
$(AM_V_GEN)sed -e 's,@PYTHON\@,$(PYTHON),g' \
|
||||
- -e 's,@DBM\@,dbm,g' \
|
||||
- -e 's,@FIRST_KEY\@,keys = self.db.keys(),g' \
|
||||
- -e 's,@CHECK_KEY\@,for key in keys:,g' \
|
||||
- -e 's,@NEXT_KEY\@,,g' \
|
||||
-e 's,@pkglibdatadir\@,$(pkglibdatadir),g' $< > $@ && \
|
||||
chmod +x $@
|
||||
-endif
|
||||
|
||||
avahi_PYTHON = $(avahi_SCRIPTS)
|
||||
|
||||
diff --git a/avahi-python/avahi/ServiceTypeDatabase.py.in b/avahi-python/avahi/ServiceTypeDatabase.py.in
|
||||
index 4ddd654..d7f9969 100644
|
||||
--- a/avahi-python/avahi/ServiceTypeDatabase.py.in
|
||||
+++ b/avahi-python/avahi/ServiceTypeDatabase.py.in
|
||||
@@ -17,7 +17,11 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA.
|
||||
|
||||
-import @DBM@
|
||||
+try:
|
||||
+ import anydbm as dbm
|
||||
+except ImportError:
|
||||
+ import dbm
|
||||
+
|
||||
import locale
|
||||
import re
|
||||
|
||||
@@ -28,7 +32,7 @@ class ServiceTypeDatabase:
|
||||
|
||||
def __init__(self, filename = "@pkglibdatadir@/service-types.db"):
|
||||
|
||||
- self.db = @DBM@.open(filename, "r")
|
||||
+ self.db = dbm.open(filename, "r")
|
||||
|
||||
l = locale.getlocale(locale.LC_MESSAGES)
|
||||
|
||||
@@ -90,13 +94,24 @@ class ServiceTypeDatabase:
|
||||
|
||||
def __iter__(self):
|
||||
|
||||
- @FIRST_KEY@
|
||||
- @CHECK_KEY@
|
||||
-
|
||||
- if re.search('_[a-zA-Z0-9-]+\._[a-zA-Z0-9-]+', key) and not re.search('_[a-zA-Z0-9-]+\._[a-zA-Z0-9-]+\[.*\]', key):
|
||||
- yield key
|
||||
-
|
||||
- @NEXT_KEY@
|
||||
+ def want_key(key):
|
||||
+ if not re.search('_[a-zA-Z0-9-]+\._[a-zA-Z0-9-]+', key):
|
||||
+ return False
|
||||
+ if re.search('_[a-zA-Z0-9-]+\._[a-zA-Z0-9-]+\[.*\]', key):
|
||||
+ return False
|
||||
+ return True
|
||||
+
|
||||
+ try:
|
||||
+ key = self.db.firstkey()
|
||||
+ except AttributeError:
|
||||
+ for key in self.db.keys():
|
||||
+ if want_key(key):
|
||||
+ yield key
|
||||
+ else:
|
||||
+ while key is not None:
|
||||
+ if want_key(key):
|
||||
+ yield key
|
||||
+ key = self.db.nextkey(key)
|
||||
|
||||
def __len__(self):
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 6678971..fbbf7cf 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -824,11 +824,10 @@ if test "x$HAVE_PYTHON" = "xyes" ; then
|
||||
fi
|
||||
|
||||
AM_CHECK_PYMOD(socket,,,[AC_MSG_ERROR(Could not find Python module socket)])
|
||||
- if test "x$HAVE_GDBM" = "xyes"; then
|
||||
- AM_CHECK_PYMOD(gdbm,,,[AC_MSG_ERROR(Could not find Python module gdbm)])
|
||||
- fi
|
||||
- if test "x$HAVE_DBM" = "xyes"; then
|
||||
- AM_CHECK_PYMOD(dbm,,,[AC_MSG_ERROR(Could not find Python module dbm)])
|
||||
+ if test "x$HAVE_GDBM" = "xyes" || test "x$HAVE_DBM" = "xyes"; then
|
||||
+ AM_CHECK_PYMOD(anydbm,,,[
|
||||
+ AM_CHECK_PYMOD(dbm,,,[AC_MSG_ERROR(Could not find Python module dbm)])
|
||||
+ ])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
diff --git a/service-type-database/Makefile.am b/service-type-database/Makefile.am
|
||||
index d184fde..f9fa082 100644
|
||||
--- a/service-type-database/Makefile.am
|
||||
+++ b/service-type-database/Makefile.am
|
||||
@@ -15,7 +15,7 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA.
|
||||
|
||||
-EXTRA_DIST=build-db.in service-types
|
||||
+EXTRA_DIST=service-types
|
||||
|
||||
pkglibdatadir=$(libdir)/avahi
|
||||
|
||||
@@ -27,16 +27,11 @@ if HAVE_GDBM
|
||||
noinst_SCRIPTS=build-db
|
||||
pkglibdata_DATA+=service-types.db
|
||||
|
||||
-build-db: build-db.in
|
||||
- $(AM_V_GEN)sed -e 's,@PYTHON\@,$(PYTHON),g' \
|
||||
- -e 's,@DBM\@,gdbm,g' $< > $@ && \
|
||||
- chmod +x $@
|
||||
-
|
||||
-service-types.db: service-types build-db
|
||||
+service-types.db: service-types
|
||||
$(AM_V_GEN)$(PYTHON) build-db $< $@.coming && \
|
||||
mv $@.coming $@
|
||||
|
||||
-CLEANFILES = service-types.db build-db
|
||||
+CLEANFILES = service-types.db
|
||||
|
||||
endif
|
||||
if HAVE_DBM
|
||||
@@ -44,11 +39,6 @@ if HAVE_DBM
|
||||
noinst_SCRIPTS=build-db
|
||||
pkglibdata_DATA+=service-types.db.pag service-types.db.dir
|
||||
|
||||
-build-db: build-db.in
|
||||
- $(AM_V_GEN)sed -e 's,@PYTHON\@,$(PYTHON),g' \
|
||||
- -e 's,@DBM\@,dbm,g' $< > $@ && \
|
||||
- chmod +x $@
|
||||
-
|
||||
service-types.db.pag: service-types.db
|
||||
$(AM_V_GEN)mv service-types.db.coming.pag service-types.db.pag
|
||||
service-types.db.dir: service-types.db
|
||||
@@ -57,7 +47,7 @@ service-types.db: service-types build-db
|
||||
$(AM_V_GEN)$(PYTHON) build-db $< $@.coming && \
|
||||
if test -f "$@.coming"; then mv $@.coming $@; fi
|
||||
|
||||
-CLEANFILES = service-types.db* build-db
|
||||
+CLEANFILES = service-types.db*
|
||||
|
||||
endif
|
||||
endif
|
||||
diff --git a/service-type-database/build-db.in b/service-type-database/build-db
|
||||
similarity index 87%
|
||||
rename from service-type-database/build-db.in
|
||||
rename to service-type-database/build-db
|
||||
index 4cda425..78ee892 100755
|
||||
--- a/service-type-database/build-db.in
|
||||
+++ b/service-type-database/build-db
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!@PYTHON@
|
||||
+#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
# This file is part of avahi.
|
||||
#
|
||||
@@ -17,7 +17,12 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA.
|
||||
|
||||
-import @DBM@, sys
|
||||
+try:
|
||||
+ import anydbm as dbm
|
||||
+except ImportError:
|
||||
+ import dbm
|
||||
+
|
||||
+import sys
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
infn = sys.argv[1]
|
||||
@@ -29,9 +34,9 @@ if len(sys.argv) > 2:
|
||||
else:
|
||||
outfn = infn + ".db"
|
||||
|
||||
-db = @DBM@.open(outfn, "n")
|
||||
+db = dbm.open(outfn, "n")
|
||||
|
||||
-for ln in file(infn, "r"):
|
||||
+for ln in open(infn, "r"):
|
||||
ln = ln.strip(" \r\n\t")
|
||||
|
||||
if ln == "" or ln.startswith("#"):
|
||||
--
|
||||
2.14.3
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
--- a/Main.java
|
||||
+++ b/Main.java
|
||||
@@ -2,2 +2,3 @@ public class Main {
|
||||
public static void main(String[] args) {
|
||||
+ System.out.println("Hello, world!");
|
||||
}
|
||||
\ No newline at end of file
|
||||
--- a/Main2.java
|
||||
+++ b/Main2.java
|
||||
@@ -2,2 +2,3 @@ public class Main {
|
||||
public static void main(String[] args) {
|
||||
+ System.out.println("Hello, world!");
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
diff -r 4d1de0a006b7 -r ace1482360cb Billion laughs attack.md
|
||||
--- a/Billion laughs attack.md Mon Feb 24 13:37:17 2020 +0000
|
||||
+++ b/Billion laughs attack.md Mon Feb 24 14:22:50 2020 +0000
|
||||
@@ -11,14 +11,12 @@
|
||||
|
||||
*The problem is*: when you stay with the mouth open and eyes closed then they may throw trash and you get sick.
|
||||
|
||||
-
|
||||
-SnakeYAML Engine [has a way to restrict the amount of aliases for collections](https://bitbucket.org/asomov/snakeyaml-engine/src/default/src/test/java/org/snakeyaml/engine/usecases/references/ReferencesTest.java) to fail early without allocation too much resources.
|
||||
+SnakeYAML 1.26+ [has a way to restrict the amount of aliases for collections](https://bitbucket.org/asomov/snakeyaml/src/default/src/test/java/org/yaml/snakeyaml/issues/issue377/ReferencesTest.java) to fail early without allocation too much resources.
|
||||
|
||||
# Solution #
|
||||
|
||||
-1. If the YAML is not coming from untrusted source (it is merely a configuration file) then it is a false positive. Just ignore it. The quality of NVD database is very low and contains tons of issues which appear to be false positives.
|
||||
-2. Migrate to [SnakeYAML Engine](https://bitbucket.org/asomov/snakeyaml-engine/src/default/). It has a configuration option to restrict aliases for collections (the aliases for scalars cannot grow and they are not restricted)
|
||||
-3. Check how it is done in SnakeYAML Engine and build your own SnakeYAML version with the same change.
|
||||
-4. Read the YAML and check its quality before giving the document to SnakeYAML (count `*` and `&` for instance)
|
||||
+1. Update to SnakeYAML 1.26. It has a configuration option to restrict aliases for collections (the aliases for scalars cannot grow and they are not restricted)
|
||||
+2. If the YAML is not coming from untrusted source (it is merely a configuration file) then it is a false positive. Just ignore it. The quality of NVD database is very low and contains tons of issues which appear to be false positives.
|
||||
+3. Read the YAML and check its quality before giving the document to SnakeYAML (count `*` and `&` for instance)
|
||||
|
||||
-Enjoy.
|
||||
\ No newline at end of file
|
||||
+Enjoy.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,835 @@
|
||||
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
|
||||
index 1f2a7c4baec..9d636200d61 100644
|
||||
--- a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
|
||||
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
|
||||
@@ -112,7 +112,6 @@ public static void main(String[] args) throws Exception {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("bus.jmx.usePlatformMBeanServer", Boolean.TRUE);
|
||||
properties.put("bus.jmx.enabled", Boolean.TRUE);
|
||||
- properties.put("bus.jmx.createMBServerConnectorFactory", Boolean.FALSE);
|
||||
Bus b = new CXFBusFactory().createBus(null, properties);
|
||||
MetricRegistry registry = new MetricRegistry();
|
||||
CodahaleMetricsProvider.setupJMXReporter(b, registry);
|
||||
diff --git a/distribution/src/main/release/samples/wsdl_first/src/main/resources/server-applicationContext.xml b/distribution/src/main/release/samples/wsdl_first/src/main/resources/server-applicationContext.xml
|
||||
index 8bf5109ec95..391f97c624e 100644
|
||||
--- a/distribution/src/main/release/samples/wsdl_first/src/main/resources/server-applicationContext.xml
|
||||
+++ b/distribution/src/main/release/samples/wsdl_first/src/main/resources/server-applicationContext.xml
|
||||
@@ -45,4 +45,4 @@
|
||||
<bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
|
||||
</jaxws:features>
|
||||
</jaxws:endpoint>
|
||||
-</beans>
|
||||
\ No newline at end of file
|
||||
+</beans>
|
||||
diff --git a/rt/management/pom.xml b/rt/management/pom.xml
|
||||
index f63f3bfa6d7..19ccf6ada0c 100644
|
||||
--- a/rt/management/pom.xml
|
||||
+++ b/rt/management/pom.xml
|
||||
@@ -34,8 +34,7 @@
|
||||
<cxf.module.name>org.apache.cxf.management</cxf.module.name>
|
||||
<cxf.osgi.import>
|
||||
javax.xml.bind*;version="${cxf.osgi.javax.bind.version}",
|
||||
- javax.annotation*;version="${cxf.osgi.javax.annotation.version}",
|
||||
- sun.rmi*;resolution:=optional
|
||||
+ javax.annotation*;version="${cxf.osgi.javax.annotation.version}"
|
||||
</cxf.osgi.import>
|
||||
</properties>
|
||||
<dependencies>
|
||||
diff --git a/rt/management/src/main/java/org/apache/cxf/management/jmx/InstrumentationManagerImpl.java b/rt/management/src/main/java/org/apache/cxf/management/jmx/InstrumentationManagerImpl.java
|
||||
index ee7f0a71fee..d898a4b6f5f 100644
|
||||
--- a/rt/management/src/main/java/org/apache/cxf/management/jmx/InstrumentationManagerImpl.java
|
||||
+++ b/rt/management/src/main/java/org/apache/cxf/management/jmx/InstrumentationManagerImpl.java
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
package org.apache.cxf.management.jmx;
|
||||
|
||||
-import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -53,31 +52,25 @@
|
||||
import org.apache.cxf.management.ManagedComponent;
|
||||
import org.apache.cxf.management.ManagementConstants;
|
||||
import org.apache.cxf.management.jmx.export.runtime.ModelMBeanAssembler;
|
||||
-import org.apache.cxf.management.jmx.type.JMXConnectorPolicyType;
|
||||
|
||||
/**
|
||||
* The manager class for the JMXManagedComponent which hosts the JMXManagedComponents.
|
||||
*/
|
||||
-public class InstrumentationManagerImpl extends JMXConnectorPolicyType
|
||||
+public class InstrumentationManagerImpl
|
||||
implements InstrumentationManager, BusLifeCycleListener {
|
||||
private static final Logger LOG = LogUtils.getL7dLogger(InstrumentationManagerImpl.class);
|
||||
|
||||
private static Map<String, String> mbeanServerIDMap = new HashMap<>();
|
||||
|
||||
private Bus bus;
|
||||
- private MBServerConnectorFactory mcf;
|
||||
private MBeanServer mbs;
|
||||
private Set<ObjectName> busMBeans = new HashSet<>();
|
||||
private boolean connectFailed;
|
||||
private String persistentBusId;
|
||||
- private Map<String, ?> environment;
|
||||
|
||||
- /**
|
||||
- * For backward compatibility, {@link #createMBServerConnectorFactory} is <code>true</code> by default.
|
||||
- */
|
||||
- private boolean createMBServerConnectorFactory = true;
|
||||
private String mbeanServerName = ManagementConstants.DEFAULT_DOMAIN_NAME;
|
||||
private boolean usePlatformMBeanServer;
|
||||
+ private boolean enabled;
|
||||
|
||||
public InstrumentationManagerImpl() {
|
||||
super();
|
||||
@@ -119,16 +112,16 @@ public void setServerName(String s) {
|
||||
mbeanServerName = s;
|
||||
}
|
||||
|
||||
- public void setCreateMBServerConnectorFactory(boolean createMBServerConnectorFactory) {
|
||||
- this.createMBServerConnectorFactory = createMBServerConnectorFactory;
|
||||
- }
|
||||
-
|
||||
public void setUsePlatformMBeanServer(Boolean flag) {
|
||||
usePlatformMBeanServer = flag;
|
||||
}
|
||||
|
||||
- public void setEnvironment(Map<String, ?> env) {
|
||||
- environment = env;
|
||||
+ public void setEnabled(boolean enabled) {
|
||||
+ this.enabled = enabled;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isEnabled() {
|
||||
+ return enabled;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -139,7 +132,6 @@ public void register() {
|
||||
public void init() {
|
||||
if (bus != null && bus.getExtension(MBeanServer.class) != null) {
|
||||
enabled = true;
|
||||
- createMBServerConnectorFactory = false;
|
||||
mbs = bus.getExtension(MBeanServer.class);
|
||||
}
|
||||
if (isEnabled()) {
|
||||
@@ -168,21 +160,6 @@ public void init() {
|
||||
}
|
||||
}
|
||||
|
||||
- if (createMBServerConnectorFactory) {
|
||||
- mcf = MBServerConnectorFactory.getInstance();
|
||||
- mcf.setMBeanServer(mbs);
|
||||
- mcf.setThreaded(isThreaded());
|
||||
- mcf.setDaemon(isDaemon());
|
||||
- mcf.setServiceUrl(getJMXServiceURL());
|
||||
- mcf.setEnvironment(environment);
|
||||
- try {
|
||||
- mcf.createConnector();
|
||||
- } catch (IOException ex) {
|
||||
- connectFailed = true;
|
||||
- LOG.log(Level.SEVERE, "START_CONNECTOR_FAILURE_MSG", new Object[] {ex});
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (!connectFailed && null != bus) {
|
||||
try {
|
||||
//Register Bus here since we can guarantee that Instrumentation
|
||||
@@ -282,14 +259,6 @@ public void shutdown() {
|
||||
return;
|
||||
}
|
||||
|
||||
- if (mcf != null) {
|
||||
- try {
|
||||
- mcf.destroy();
|
||||
- } catch (IOException ex) {
|
||||
- LOG.log(Level.SEVERE, "STOP_CONNECTOR_FAILURE_MSG", new Object[] {ex});
|
||||
- }
|
||||
- }
|
||||
-
|
||||
//Using the array to hold the busMBeans to avoid the CurrentModificationException
|
||||
Object[] mBeans = busMBeans.toArray();
|
||||
for (Object name : mBeans) {
|
||||
@@ -400,12 +369,7 @@ private void readJMXProperties(Bus b) {
|
||||
getBusProperty(b, "bus.jmx.serverName", mbeanServerName);
|
||||
usePlatformMBeanServer =
|
||||
getBusProperty(b, "bus.jmx.usePlatformMBeanServer", usePlatformMBeanServer);
|
||||
- createMBServerConnectorFactory =
|
||||
- getBusProperty(b, "bus.jmx.createMBServerConnectorFactory", createMBServerConnectorFactory);
|
||||
- daemon = getBusProperty(b, "bus.jmx.daemon", daemon);
|
||||
- threaded = getBusProperty(b, "bus.jmx.threaded", threaded);
|
||||
enabled = getBusProperty(b, "bus.jmx.enabled", enabled);
|
||||
- jmxServiceURL = getBusProperty(b, "bus.jmx.JMXServiceURL", jmxServiceURL);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java b/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java
|
||||
deleted file mode 100644
|
||||
index 5eb7059b8fb..00000000000
|
||||
--- a/rt/management/src/main/java/org/apache/cxf/management/jmx/MBServerConnectorFactory.java
|
||||
+++ /dev/null
|
||||
@@ -1,260 +0,0 @@
|
||||
-/**
|
||||
- * Licensed to the Apache Software Foundation (ASF) under one
|
||||
- * or more contributor license agreements. See the NOTICE file
|
||||
- * distributed with this work for additional information
|
||||
- * regarding copyright ownership. The ASF licenses this file
|
||||
- * to you 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 org.apache.cxf.management.jmx;
|
||||
-
|
||||
-import java.io.IOException;
|
||||
-import java.net.URI;
|
||||
-import java.net.URISyntaxException;
|
||||
-import java.rmi.AccessException;
|
||||
-import java.rmi.AlreadyBoundException;
|
||||
-import java.rmi.NotBoundException;
|
||||
-import java.rmi.Remote;
|
||||
-import java.rmi.RemoteException;
|
||||
-import java.util.Map;
|
||||
-import java.util.logging.Level;
|
||||
-import java.util.logging.Logger;
|
||||
-
|
||||
-import javax.management.MBeanServer;
|
||||
-import javax.management.MBeanServerFactory;
|
||||
-import javax.management.remote.JMXConnectorServer;
|
||||
-import javax.management.remote.JMXServiceURL;
|
||||
-import javax.management.remote.rmi.RMIConnectorServer;
|
||||
-import javax.management.remote.rmi.RMIJRMPServerImpl;
|
||||
-
|
||||
-import org.apache.cxf.common.logging.LogUtils;
|
||||
-
|
||||
-
|
||||
-
|
||||
-/**
|
||||
- * Deal with the MBeanServer Connections
|
||||
- *
|
||||
- */
|
||||
-public final class MBServerConnectorFactory {
|
||||
-
|
||||
- public static final String DEFAULT_SERVICE_URL = "service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi";
|
||||
-
|
||||
- private static final Logger LOG = LogUtils.getL7dLogger(MBServerConnectorFactory.class);
|
||||
-
|
||||
- private static MBeanServer server;
|
||||
-
|
||||
- private static String serviceUrl = DEFAULT_SERVICE_URL;
|
||||
-
|
||||
- private static Map<String, ?> environment;
|
||||
-
|
||||
- private static boolean threaded;
|
||||
-
|
||||
- private static boolean daemon;
|
||||
-
|
||||
- private static JMXConnectorServer connectorServer;
|
||||
-
|
||||
- private static Remote remoteServerStub;
|
||||
-
|
||||
- private static RMIJRMPServerImpl rmiServer;
|
||||
-
|
||||
- private static class MBServerConnectorFactoryHolder {
|
||||
- private static final MBServerConnectorFactory INSTANCE =
|
||||
- new MBServerConnectorFactory();
|
||||
- }
|
||||
-
|
||||
- private static class MBeanServerHolder {
|
||||
- private static final MBeanServer INSTANCE =
|
||||
- MBeanServerFactory.createMBeanServer();
|
||||
- }
|
||||
-
|
||||
- private MBServerConnectorFactory() {
|
||||
-
|
||||
- }
|
||||
-
|
||||
- static int getServerPort(final String url) {
|
||||
- int portStart = url.indexOf("localhost") + 10;
|
||||
- int portEnd;
|
||||
- int port = 0;
|
||||
- if (portStart > 0) {
|
||||
- portEnd = indexNotOfNumber(url, portStart);
|
||||
- if (portEnd > portStart) {
|
||||
- final String portString = url.substring(portStart, portEnd);
|
||||
- port = Integer.parseInt(portString);
|
||||
- }
|
||||
- }
|
||||
- return port;
|
||||
- }
|
||||
-
|
||||
- private static int indexNotOfNumber(String str, int index) {
|
||||
- int i = 0;
|
||||
- for (i = index; i < str.length(); i++) {
|
||||
- if (str.charAt(i) < '0' || str.charAt(i) > '9') {
|
||||
- return i;
|
||||
- }
|
||||
- }
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- public static MBServerConnectorFactory getInstance() {
|
||||
- return MBServerConnectorFactoryHolder.INSTANCE;
|
||||
- }
|
||||
-
|
||||
- public void setMBeanServer(MBeanServer ms) {
|
||||
- server = ms;
|
||||
- }
|
||||
-
|
||||
- public void setServiceUrl(String url) {
|
||||
- serviceUrl = url;
|
||||
- }
|
||||
-
|
||||
- public void setEnvironment(Map<String, ?> env) {
|
||||
- environment = env;
|
||||
- }
|
||||
-
|
||||
- public void setThreaded(boolean fthread) {
|
||||
- threaded = fthread;
|
||||
- }
|
||||
-
|
||||
- public void setDaemon(boolean fdaemon) {
|
||||
- daemon = fdaemon;
|
||||
- }
|
||||
-
|
||||
-
|
||||
- public void createConnector() throws IOException {
|
||||
-
|
||||
- if (server == null) {
|
||||
- server = MBeanServerHolder.INSTANCE;
|
||||
- }
|
||||
-
|
||||
- // Create the JMX service URL.
|
||||
- final JMXServiceURL url = new JMXServiceURL(serviceUrl);
|
||||
-
|
||||
- // if the URL is localhost, start up an Registry
|
||||
- if (serviceUrl.indexOf("localhost") > -1
|
||||
- && url.getProtocol().compareToIgnoreCase("rmi") == 0) {
|
||||
- try {
|
||||
- int port = getRegistryPort(serviceUrl);
|
||||
- new JmxRegistry(port, getBindingName(url));
|
||||
-
|
||||
- } catch (Exception ex) {
|
||||
- LOG.log(Level.SEVERE, "CREATE_REGISTRY_FAULT_MSG", new Object[]{ex});
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- rmiServer = new RMIJRMPServerImpl(getServerPort(serviceUrl), null, null, environment);
|
||||
-
|
||||
- // Create the connector server now.
|
||||
- connectorServer = new RMIConnectorServer(url, environment, rmiServer, server);
|
||||
-
|
||||
- if (threaded) {
|
||||
- // Start the connector server asynchronously (in a separate thread).
|
||||
- Thread connectorThread = new Thread() {
|
||||
- public void run() {
|
||||
- try {
|
||||
- connectorServer.start();
|
||||
- remoteServerStub = rmiServer.toStub();
|
||||
- } catch (IOException ex) {
|
||||
- LOG.log(Level.SEVERE, "START_CONNECTOR_FAILURE_MSG", new Object[]{ex});
|
||||
- }
|
||||
- }
|
||||
- };
|
||||
-
|
||||
- connectorThread.setName("JMX Connector Thread [" + serviceUrl + "]");
|
||||
- connectorThread.setDaemon(daemon);
|
||||
- connectorThread.start();
|
||||
- } else {
|
||||
- // Start the connector server in the same thread.
|
||||
- connectorServer.start();
|
||||
- remoteServerStub = rmiServer.toStub();
|
||||
- }
|
||||
-
|
||||
- if (LOG.isLoggable(Level.INFO)) {
|
||||
- LOG.info("JMX connector server started: " + connectorServer);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- static int getRegistryPort(final String url) {
|
||||
- int serverStart = url.indexOf("/jndi/rmi://");
|
||||
- final String serverPart = url.substring(serverStart + 12);
|
||||
- int portStart = serverPart.indexOf(':') + 1;
|
||||
-
|
||||
- int portEnd;
|
||||
- int port = 0;
|
||||
- if (portStart > 0) {
|
||||
- portEnd = indexNotOfNumber(serverPart, portStart);
|
||||
- if (portEnd > portStart) {
|
||||
- final String portString = serverPart.substring(portStart, portEnd);
|
||||
- port = Integer.parseInt(portString);
|
||||
- }
|
||||
- }
|
||||
- return port;
|
||||
- }
|
||||
-
|
||||
- protected static String getBindingName(final JMXServiceURL jmxServiceURL) {
|
||||
- final String urlPath = jmxServiceURL.getURLPath();
|
||||
-
|
||||
- try {
|
||||
- if (urlPath.startsWith("/jndi/")) {
|
||||
- return new URI(urlPath.substring(6)).getPath()
|
||||
- .replaceAll("^/+", "").replaceAll("/+$", "");
|
||||
- }
|
||||
- } catch (URISyntaxException e) {
|
||||
- // ignore
|
||||
- }
|
||||
-
|
||||
- return "jmxrmi"; // use the default
|
||||
- }
|
||||
-
|
||||
- public void destroy() throws IOException {
|
||||
- connectorServer.stop();
|
||||
- if (LOG.isLoggable(Level.INFO)) {
|
||||
- LOG.info("JMX connector server stopped: " + connectorServer);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Better to use the internal API than re-invent the wheel.
|
||||
- */
|
||||
- @SuppressWarnings("restriction")
|
||||
- private class JmxRegistry extends sun.rmi.registry.RegistryImpl {
|
||||
- private final String lookupName;
|
||||
-
|
||||
- JmxRegistry(final int port, final String lookupName) throws RemoteException {
|
||||
- super(port);
|
||||
- this.lookupName = lookupName;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public Remote lookup(String s) throws RemoteException, NotBoundException {
|
||||
- return lookupName.equals(s) ? remoteServerStub : null;
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void bind(String s, Remote remote) throws RemoteException, AlreadyBoundException, AccessException {
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void unbind(String s) throws RemoteException, NotBoundException, AccessException {
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public void rebind(String s, Remote remote) throws RemoteException, AccessException {
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public String[] list() throws RemoteException {
|
||||
- return new String[] {lookupName};
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
diff --git a/rt/management/src/main/java/org/apache/cxf/management/utils/ManagementConsole.java b/rt/management/src/main/java/org/apache/cxf/management/utils/ManagementConsole.java
|
||||
index 3fa2fe2891c..3739ffaa915 100644
|
||||
--- a/rt/management/src/main/java/org/apache/cxf/management/utils/ManagementConsole.java
|
||||
+++ b/rt/management/src/main/java/org/apache/cxf/management/utils/ManagementConsole.java
|
||||
@@ -42,7 +42,7 @@
|
||||
public final class ManagementConsole {
|
||||
private static MBeanServerConnection mbsc;
|
||||
private static final String DEFAULT_JMXSERVICE_URL =
|
||||
- "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi";
|
||||
+ "service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi";
|
||||
private static final Logger LOG = LogUtils.getL7dLogger(ManagementConsole.class);
|
||||
|
||||
String jmxServerURL;
|
||||
diff --git a/rt/management/src/test/java/org/apache/cxf/management/InstrumentationManagerTest.java b/rt/management/src/test/java/org/apache/cxf/management/InstrumentationManagerTest.java
|
||||
index 9ebc7ca4fe2..c505835d10a 100644
|
||||
--- a/rt/management/src/test/java/org/apache/cxf/management/InstrumentationManagerTest.java
|
||||
+++ b/rt/management/src/test/java/org/apache/cxf/management/InstrumentationManagerTest.java
|
||||
@@ -158,7 +158,6 @@ public void testInstrumentBusWithBusProperties() {
|
||||
assertNotNull("Instrumentation Manager of cxf1 should not be null", im1);
|
||||
|
||||
assertTrue(im1.isEnabled());
|
||||
- assertEquals("service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi", im1.getJMXServiceURL());
|
||||
|
||||
cxf2 = (Bus)context.getBean("cxf2");
|
||||
InstrumentationManagerImpl im2 =
|
||||
@@ -166,7 +165,6 @@ public void testInstrumentBusWithBusProperties() {
|
||||
assertNotNull("Instrumentation Manager of cxf2 should not be null", im2);
|
||||
|
||||
assertFalse(im2.isEnabled());
|
||||
- assertEquals("service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi", im2.getJMXServiceURL());
|
||||
|
||||
} finally {
|
||||
if (cxf1 != null) {
|
||||
diff --git a/rt/management/src/test/java/org/apache/cxf/management/jmx/BusRegistrationTest.java b/rt/management/src/test/java/org/apache/cxf/management/jmx/BusRegistrationTest.java
|
||||
index e9f9308289a..6c458f3085b 100644
|
||||
--- a/rt/management/src/test/java/org/apache/cxf/management/jmx/BusRegistrationTest.java
|
||||
+++ b/rt/management/src/test/java/org/apache/cxf/management/jmx/BusRegistrationTest.java
|
||||
@@ -64,12 +64,6 @@ public void tearDown() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
- @Test
|
||||
- public void testRegisterMultipleBuses() throws Exception {
|
||||
- // classic external IM-bean
|
||||
- testRegisterMultipleBuses("managed-spring.xml");
|
||||
- }
|
||||
-
|
||||
@Test
|
||||
public void testRegisterMultipleBuses2() throws Exception {
|
||||
// integrated IM configuration in bus
|
||||
diff --git a/rt/management/src/test/java/org/apache/cxf/management/jmx/JMXManagedComponentManagerTest.java b/rt/management/src/test/java/org/apache/cxf/management/jmx/JMXManagedComponentManagerTest.java
|
||||
index d516da39c06..20a7b091435 100644
|
||||
--- a/rt/management/src/test/java/org/apache/cxf/management/jmx/JMXManagedComponentManagerTest.java
|
||||
+++ b/rt/management/src/test/java/org/apache/cxf/management/jmx/JMXManagedComponentManagerTest.java
|
||||
@@ -28,7 +28,6 @@
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.apache.cxf.management.jmx.export.AnnotationTestInstrumentation;
|
||||
-import org.apache.cxf.testutil.common.TestUtil;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -38,17 +37,13 @@
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class JMXManagedComponentManagerTest {
|
||||
- private static final String PORT = TestUtil.getPortNumber(JMXManagedComponentManagerTest.class);
|
||||
private static final String NAME_ATTRIBUTE = "Name";
|
||||
private InstrumentationManagerImpl manager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
manager = new InstrumentationManagerImpl();
|
||||
- manager.setDaemon(false);
|
||||
- manager.setThreaded(true);
|
||||
manager.setEnabled(true);
|
||||
- manager.setJMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + PORT + "/jmxrmi");
|
||||
manager.init();
|
||||
//Wait for MBeanServer connector to be initialized on separate thread.
|
||||
Thread.sleep(2000);
|
||||
@@ -61,10 +56,6 @@ public void tearDown() throws Exception {
|
||||
|
||||
@Test
|
||||
public void testRegisterInstrumentation() throws Exception {
|
||||
- //manager.setDaemon(false);
|
||||
- //manager.setThreaded(false);
|
||||
- //manager.setJMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi");
|
||||
- //manager.init();
|
||||
|
||||
AnnotationTestInstrumentation im = new AnnotationTestInstrumentation();
|
||||
ObjectName name = new ObjectName("org.apache.cxf:type=foo,name=bar");
|
||||
@@ -128,13 +119,7 @@ public void testBusLifecycleListener() throws Exception {
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
|
||||
this.manager = new InstrumentationManagerImpl();
|
||||
- this.manager.setDaemon(false);
|
||||
- // Turn threading off so that we get the exception in this thread
|
||||
- // and the manager is set into a failed state if the connector
|
||||
- // cannot be created.
|
||||
- this.manager.setThreaded(false);
|
||||
this.manager.setEnabled(true);
|
||||
- this.manager.setJMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + PORT + "/jmxrmi");
|
||||
this.manager.setServer(server);
|
||||
this.manager.init();
|
||||
|
||||
@@ -161,13 +146,7 @@ public void testBusLifecycleListener() throws Exception {
|
||||
}
|
||||
|
||||
this.manager = new InstrumentationManagerImpl();
|
||||
- this.manager.setDaemon(false);
|
||||
- // Turn threading off so that we get the exception in this thread
|
||||
- // and the manager is set into a failed state if the connector
|
||||
- // cannot be created.
|
||||
- this.manager.setThreaded(false);
|
||||
this.manager.setEnabled(true);
|
||||
- this.manager.setJMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + PORT + "/jmxrmi");
|
||||
this.manager.setServer(server);
|
||||
this.manager.init();
|
||||
|
||||
@@ -183,4 +162,4 @@ private ObjectName registerStandardMBean(String name) throws Exception {
|
||||
this.manager.register(hw, oName);
|
||||
return oName;
|
||||
}
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
diff --git a/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java b/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java
|
||||
deleted file mode 100644
|
||||
index 468ec0cbfaf..00000000000
|
||||
--- a/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorFactoryTest.java
|
||||
+++ /dev/null
|
||||
@@ -1,55 +0,0 @@
|
||||
-/**
|
||||
- * Licensed to the Apache Software Foundation (ASF) under one
|
||||
- * or more contributor license agreements. See the NOTICE file
|
||||
- * distributed with this work for additional information
|
||||
- * regarding copyright ownership. The ASF licenses this file
|
||||
- * to you 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 org.apache.cxf.management.jmx;
|
||||
-
|
||||
-import javax.management.remote.JMXServiceURL;
|
||||
-
|
||||
-import org.junit.Assert;
|
||||
-import org.junit.Test;
|
||||
-
|
||||
-
|
||||
-public class MBServerConnectorFactoryTest {
|
||||
-
|
||||
- @Test
|
||||
- public void testGetServerPort() throws Exception {
|
||||
- Assert.assertEquals(9914, MBServerConnectorFactory.getServerPort(
|
||||
- "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"));
|
||||
-
|
||||
- Assert.assertEquals(10002, MBServerConnectorFactory.getServerPort(
|
||||
- "service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi"));
|
||||
- }
|
||||
-
|
||||
- @Test
|
||||
- public void testGetRegistryPort() throws Exception {
|
||||
- Assert.assertEquals(9914, MBServerConnectorFactory.getRegistryPort(
|
||||
- "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"));
|
||||
-
|
||||
- Assert.assertEquals(10001, MBServerConnectorFactory.getRegistryPort(
|
||||
- "service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi"));
|
||||
- }
|
||||
-
|
||||
- @Test
|
||||
- public void testGetBindingName() throws Exception {
|
||||
- Assert.assertEquals("jmxrmi", MBServerConnectorFactory.getBindingName(
|
||||
- new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi")));
|
||||
-
|
||||
- Assert.assertEquals("cxf-jmxrmi", MBServerConnectorFactory.getBindingName(
|
||||
- new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9913/cxf-jmxrmi")));
|
||||
- }
|
||||
-}
|
||||
\ No newline at end of file
|
||||
diff --git a/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorTest.java b/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorTest.java
|
||||
deleted file mode 100644
|
||||
index c01e10fc6f2..00000000000
|
||||
--- a/rt/management/src/test/java/org/apache/cxf/management/jmx/MBServerConnectorTest.java
|
||||
+++ /dev/null
|
||||
@@ -1,57 +0,0 @@
|
||||
-/**
|
||||
- * Licensed to the Apache Software Foundation (ASF) under one
|
||||
- * or more contributor license agreements. See the NOTICE file
|
||||
- * distributed with this work for additional information
|
||||
- * regarding copyright ownership. The ASF licenses this file
|
||||
- * to you 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 org.apache.cxf.management.jmx;
|
||||
-
|
||||
-
|
||||
-
|
||||
-import javax.management.MBeanServer;
|
||||
-import javax.management.MBeanServerFactory;
|
||||
-
|
||||
-import org.apache.cxf.testutil.common.TestUtil;
|
||||
-
|
||||
-import org.junit.Test;
|
||||
-
|
||||
-import static org.junit.Assert.fail;
|
||||
-
|
||||
-
|
||||
-public class MBServerConnectorTest {
|
||||
- private static final String PORT = TestUtil.getPortNumber(MBServerConnectorTest.class);
|
||||
-
|
||||
- @Test
|
||||
- public void testMBServerConnector() {
|
||||
- MBServerConnectorFactory mcf;
|
||||
- MBeanServer mbs;
|
||||
- mbs = MBeanServerFactory.createMBeanServer("test");
|
||||
- mcf = MBServerConnectorFactory.getInstance();
|
||||
- mcf.setMBeanServer(mbs);
|
||||
- mcf.setThreaded(true);
|
||||
- mcf.setDaemon(true);
|
||||
- mcf.setServiceUrl("service:jmx:rmi:///jndi/rmi://localhost:" + PORT + "/jmxrmi");
|
||||
- try {
|
||||
- mcf.createConnector();
|
||||
- Thread.sleep(1000);
|
||||
- mcf.destroy();
|
||||
- } catch (Exception ex) {
|
||||
- ex.printStackTrace();
|
||||
- fail("Some Exception happened to MBServerConnectorTest");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
-}
|
||||
diff --git a/rt/management/src/test/resources/managed-spring.xml b/rt/management/src/test/resources/managed-spring.xml
|
||||
index 81808a54a5a..683c1b3ab32 100644
|
||||
--- a/rt/management/src/test/resources/managed-spring.xml
|
||||
+++ b/rt/management/src/test/resources/managed-spring.xml
|
||||
@@ -24,11 +24,7 @@
|
||||
xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
<cxf:bus id="CXF-Test-Bus" bus="cxf"/>
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
- <property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="threaded" value="false"/>
|
||||
- <property name="daemon" value="false"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"/>
|
||||
</bean>
|
||||
<cxf:workqueue name="default" highWaterMark="15" lowWaterMark="5"/>
|
||||
<cxf:workqueue name="test-wq" highWaterMark="10" lowWaterMark="2"/>
|
||||
diff --git a/rt/management/src/test/resources/managed-spring3.xml b/rt/management/src/test/resources/managed-spring3.xml
|
||||
index 83add997fe0..57009b7cf40 100644
|
||||
--- a/rt/management/src/test/resources/managed-spring3.xml
|
||||
+++ b/rt/management/src/test/resources/managed-spring3.xml
|
||||
@@ -26,9 +26,5 @@
|
||||
<!-- the bus setting at the end should not interfer with the other props -->
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="threaded" value="false"/>
|
||||
- <property name="daemon" value="false"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"/>
|
||||
- <property name="bus" ref="cxf"/>
|
||||
</bean>
|
||||
</beans>
|
||||
\ No newline at end of file
|
||||
diff --git a/rt/management/src/test/resources/no-connector-spring.xml b/rt/management/src/test/resources/no-connector-spring.xml
|
||||
index f6c197d9a2c..565d92dffe0 100644
|
||||
--- a/rt/management/src/test/resources/no-connector-spring.xml
|
||||
+++ b/rt/management/src/test/resources/no-connector-spring.xml
|
||||
@@ -24,6 +24,5 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="createMBServerConnectorFactory" value="false"/>
|
||||
</bean>
|
||||
</beans>
|
||||
\ No newline at end of file
|
||||
diff --git a/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/managed-manager-bean.xml b/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/managed-manager-bean.xml
|
||||
index 8e01539b360..7571a48693d 100644
|
||||
--- a/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/managed-manager-bean.xml
|
||||
+++ b/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/managed-manager-bean.xml
|
||||
@@ -26,9 +26,6 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="threaded" value="false"/>
|
||||
- <property name="daemon" value="false"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"/>
|
||||
</bean>
|
||||
<cxf:bus>
|
||||
<cxf:features>
|
||||
diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/ManagedBusTest.java b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/ManagedBusTest.java
|
||||
index dbde562570a..a40c61d394c 100644
|
||||
--- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/ManagedBusTest.java
|
||||
+++ b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/ManagedBusTest.java
|
||||
@@ -98,8 +98,6 @@ public void testManagedSpringBus() throws Exception {
|
||||
assertNotNull(im);
|
||||
|
||||
InstrumentationManagerImpl imi = (InstrumentationManagerImpl)im;
|
||||
- assertEquals("service:jmx:rmi:///jndi/rmi://localhost:9913/jmxrmi",
|
||||
- imi.getJMXServiceURL());
|
||||
assertFalse(imi.isEnabled());
|
||||
assertNull(imi.getMBeanServer());
|
||||
|
||||
@@ -127,8 +125,6 @@ private void doManagedBusTest(Bus bus, String expect, String reject, int port) t
|
||||
InstrumentationManager im = bus.getExtension(InstrumentationManager.class);
|
||||
assertNotNull(im);
|
||||
InstrumentationManagerImpl imi = (InstrumentationManagerImpl)im;
|
||||
- assertEquals("service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi",
|
||||
- imi.getJMXServiceURL());
|
||||
assertTrue(imi.isEnabled());
|
||||
assertNotNull(imi.getMBeanServer());
|
||||
|
||||
diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/counter-spring.xml b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/counter-spring.xml
|
||||
index e5cc90f9a17..b3d516022d9 100644
|
||||
--- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/counter-spring.xml
|
||||
+++ b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/counter-spring.xml
|
||||
@@ -24,7 +24,6 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:${testutil.ports.CountersClientServerTest.1}/jmxrmi"/>
|
||||
</bean>
|
||||
<bean id="org.apache.cxf.management.counters.CounterRepository" class="org.apache.cxf.management.counters.CounterRepository">
|
||||
<property name="bus" ref="cxf"/>
|
||||
diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-bus.xml b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-bus.xml
|
||||
index 7304a399d39..fed391b4a60 100644
|
||||
--- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-bus.xml
|
||||
+++ b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-bus.xml
|
||||
@@ -24,7 +24,6 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:${testutil.ports.ManagedBusTest.1}/jmxrmi"/>
|
||||
</bean>
|
||||
<bean id="wq" class="org.apache.cxf.workqueue.AutomaticWorkQueueImpl">
|
||||
<property name="name" value="testQueue"/>
|
||||
diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-spring.xml b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-spring.xml
|
||||
index 4beb120a457..fed391b4a60 100644
|
||||
--- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-spring.xml
|
||||
+++ b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/managed-spring.xml
|
||||
@@ -24,7 +24,6 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:${testutil.ports.ManagedClientServerTest.1}/jmxrmi"/>
|
||||
</bean>
|
||||
<bean id="wq" class="org.apache.cxf.workqueue.AutomaticWorkQueueImpl">
|
||||
<property name="name" value="testQueue"/>
|
||||
diff --git a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/persistent-id.xml b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/persistent-id.xml
|
||||
index 118abfe7978..9219b56bcf3 100644
|
||||
--- a/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/persistent-id.xml
|
||||
+++ b/systests/uncategorized/src/test/java/org/apache/cxf/systest/management/persistent-id.xml
|
||||
@@ -24,7 +24,6 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:${testutil.ports.ManagedBusTest.3}/jmxrmi"/>
|
||||
<property name="persistentBusId" value="cxf:managed,bus=test"/>
|
||||
</bean>
|
||||
<bean id="wq" class="org.apache.cxf.workqueue.AutomaticWorkQueueImpl">
|
||||
diff --git a/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-client.xml b/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-client.xml
|
||||
index c0cd5b2700a..514038f02b8 100644
|
||||
--- a/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-client.xml
|
||||
+++ b/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-client.xml
|
||||
@@ -43,7 +43,5 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="createMBServerConnectorFactory" value="false"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"/>
|
||||
</bean>
|
||||
-</beans>
|
||||
\ No newline at end of file
|
||||
+</beans>
|
||||
diff --git a/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-server.xml b/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-server.xml
|
||||
index 823d8f0622e..1ee90cfbae4 100644
|
||||
--- a/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-server.xml
|
||||
+++ b/systests/ws-rm/src/test/java/org/apache/cxf/systest/ws/rm/managed-server.xml
|
||||
@@ -43,6 +43,5 @@
|
||||
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
|
||||
<property name="bus" ref="cxf"/>
|
||||
<property name="enabled" value="true"/>
|
||||
- <property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi"/>
|
||||
</bean>
|
||||
-</beans>
|
||||
\ No newline at end of file
|
||||
+</beans>
|
||||
@@ -0,0 +1,49 @@
|
||||
diff --git a/java-diff-utils/src/main/java/com/github/difflib/text/StringUtils.java b/java-diff-utils/src/main/java/com/github/difflib/text/StringUtils.java
|
||||
index a142548..b7e3549 100644
|
||||
--- a/java-diff-utils/src/main/java/com/github/difflib/text/StringUtils.java
|
||||
+++ b/java-diff-utils/src/main/java/com/github/difflib/text/StringUtils.java
|
||||
@@ -21,10 +21,10 @@
|
||||
final class StringUtils {
|
||||
|
||||
/**
|
||||
- * Replaces all opening an closing tags with <code><</code> or <code>></code>.
|
||||
+ * Replaces all opening and closing tags with <code><</code> or <code>></code>.
|
||||
*
|
||||
* @param str
|
||||
- * @return
|
||||
+ * @return str with some HTML meta characters escaped.
|
||||
*/
|
||||
public static String htmlEntites(String str) {
|
||||
return str.replace("<", "<").replace(">", ">");
|
||||
@@ -61,7 +61,17 @@ public static String wrapText(String line, int columnWidth) {
|
||||
StringBuilder b = new StringBuilder(line);
|
||||
|
||||
for (int count = 0; length > widthIndex; count++) {
|
||||
- b.insert(widthIndex + delimiter * count, "<br/>");
|
||||
+ int breakPoint = widthIndex + delimiter * count;
|
||||
+ if (Character.isHighSurrogate(b.charAt(breakPoint - 1)) &&
|
||||
+ Character.isLowSurrogate(b.charAt(breakPoint))) {
|
||||
+ // Shift a breakpoint that would split a supplemental code-point.
|
||||
+ breakPoint += 1;
|
||||
+ if (breakPoint == b.length()) {
|
||||
+ // Break before instead of after if this is the last code-point.
|
||||
+ breakPoint -= 2;
|
||||
+ }
|
||||
+ }
|
||||
+ b.insert(breakPoint, "<br/>");
|
||||
widthIndex += columnWidth;
|
||||
}
|
||||
|
||||
diff --git a/java-diff-utils/src/test/java/com/github/difflib/text/StringUtilsTest.java b/java-diff-utils/src/test/java/com/github/difflib/text/StringUtilsTest.java
|
||||
index c4b2acc..6867072 100644
|
||||
--- a/java-diff-utils/src/test/java/com/github/difflib/text/StringUtilsTest.java
|
||||
+++ b/java-diff-utils/src/test/java/com/github/difflib/text/StringUtilsTest.java
|
||||
@@ -49,6 +49,8 @@ public void testWrapText_String_int() {
|
||||
assertEquals("te<br/>st", StringUtils.wrapText("test", 2));
|
||||
assertEquals("tes<br/>t", StringUtils.wrapText("test", 3));
|
||||
assertEquals("test", StringUtils.wrapText("test", 10));
|
||||
+ assertEquals(".\uD800\uDC01<br/>.", StringUtils.wrapText(".\uD800\uDC01.", 2));
|
||||
+ assertEquals("..<br/>\uD800\uDC01", StringUtils.wrapText("..\uD800\uDC01", 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
diff -r fcd3ed3394f6 -r 135bdcb88b8d coders/wpg.c
|
||||
--- a/coders/wpg.c Sun Nov 05 01:11:09 2017 +0100
|
||||
+++ b/coders/wpg.c Sun Nov 05 01:35:28 2017 +0100
|
||||
@@ -340,12 +340,15 @@
|
||||
|
||||
|
||||
if(RetVal==MagickFail)
|
||||
+ {
|
||||
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"ImportImagePixelArea failed for row: %ld, bpp: %d", y, bpp);
|
||||
+ return MagickFail;
|
||||
+ }
|
||||
|
||||
- if (!SyncImagePixels(image))
|
||||
+ if(!SyncImagePixels(image))
|
||||
{
|
||||
(void) LogMagickEvent(CoderEvent,GetMagickModule(),"SyncImagePixels failed for row: %ld, bpp: %d", y, bpp);
|
||||
- RetVal = MagickFail;
|
||||
+ return MagickFail;
|
||||
}
|
||||
|
||||
return RetVal;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
Index: src/java/test/org/apache/zookeeper/test/ACLTest.java
|
||||
===================================================================
|
||||
--- src/java/test/org/apache/zookeeper/test/ACLTest.java (revision 1510080)
|
||||
+++ src/java/test/org/apache/zookeeper/test/ACLTest.java (working copy)
|
||||
@@ -28,6 +28,7 @@
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.zookeeper.CreateMode;
|
||||
+import org.apache.zookeeper.KeeperException;
|
||||
import org.apache.zookeeper.PortAssignment;
|
||||
import org.apache.zookeeper.WatchedEvent;
|
||||
import org.apache.zookeeper.Watcher;
|
||||
@@ -35,8 +36,10 @@
|
||||
import org.apache.zookeeper.ZooKeeper;
|
||||
import org.apache.zookeeper.Watcher.Event.KeeperState;
|
||||
import org.apache.zookeeper.ZooDefs.Ids;
|
||||
+import org.apache.zookeeper.ZooDefs.Perms;
|
||||
import org.apache.zookeeper.data.ACL;
|
||||
import org.apache.zookeeper.data.Id;
|
||||
+import org.apache.zookeeper.data.Stat;
|
||||
import org.apache.zookeeper.server.ServerCnxnFactory;
|
||||
import org.apache.zookeeper.server.SyncRequestProcessor;
|
||||
import org.apache.zookeeper.server.ZooKeeperServer;
|
||||
@@ -77,6 +80,48 @@
|
||||
ClientBase.CONNECTION_TIMEOUT));
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Verify that getAcl should fail when there is not
|
||||
+ * read permission to that node
|
||||
+ */
|
||||
+ @Test
|
||||
+ public void testAclReadPermission() throws Exception {
|
||||
+ File tmpDir = ClientBase.createTmpDir();
|
||||
+ ClientBase.setupTestEnv();
|
||||
+ ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
|
||||
+ SyncRequestProcessor.setSnapCount(1000);
|
||||
+ final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
|
||||
+ ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
|
||||
+ f.startup(zks);
|
||||
+ ZooKeeper zk;
|
||||
+ String path = "/node1";
|
||||
+ boolean readPermLimitWorks = false;
|
||||
+ try {
|
||||
+ LOG.info("starting up the zookeeper server .. waiting");
|
||||
+ Assert.assertTrue("waiting for server being up",
|
||||
+ ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
|
||||
+ zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
|
||||
+ Id id = new Id("ip", "127.0.0.1");
|
||||
+ ArrayList<ACL> acl = new ArrayList<ACL>(); // Not set read permission
|
||||
+ acl.add(new ACL(Perms.CREATE, id));
|
||||
+ acl.add(new ACL(Perms.DELETE, id));
|
||||
+ acl.add(new ACL(Perms.WRITE, id));
|
||||
+ acl.add(new ACL(Perms.ADMIN, id));
|
||||
+ zk.create(path, path.getBytes(), acl, CreateMode.PERSISTENT);
|
||||
+ Stat stat = new Stat();
|
||||
+ zk.getACL(path, stat); // Should cause exception without read permission
|
||||
+ } catch (KeeperException.NoAuthException e) {
|
||||
+ readPermLimitWorks = true;
|
||||
+ } finally {
|
||||
+ f.shutdown();
|
||||
+ Assert.assertTrue("waiting for server down",
|
||||
+ ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
|
||||
+ }
|
||||
+ if (!readPermLimitWorks) {
|
||||
+ Assert.fail("Should not reach here as ACL has no read permission");
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/**
|
||||
* Verify that acl optimization of storing just
|
||||
Index: src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java
|
||||
===================================================================
|
||||
--- src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java (revision 1510080)
|
||||
+++ src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java (working copy)
|
||||
@@ -324,6 +324,17 @@
|
||||
GetACLRequest getACLRequest = new GetACLRequest();
|
||||
ByteBufferInputStream.byteBuffer2Record(request.request,
|
||||
getACLRequest);
|
||||
+ DataNode n = zks.getZKDatabase().getNode(getACLRequest.getPath());
|
||||
+ if (n == null) {
|
||||
+ throw new KeeperException.NoNodeException();
|
||||
+ }
|
||||
+ Long aclL;
|
||||
+ synchronized(n) {
|
||||
+ aclL = n.acl;
|
||||
+ }
|
||||
+ PrepRequestProcessor.checkACL(zks, zks.getZKDatabase().convertLong(aclL),
|
||||
+ ZooDefs.Perms.READ,
|
||||
+ request.authInfo);
|
||||
Stat stat = new Stat();
|
||||
List<ACL> acl =
|
||||
zks.getZKDatabase().getACL(getACLRequest.getPath(), stat);
|
||||
@@ -8,4 +8,5 @@ diff -U0 old/f2 new/f2
|
||||
--- old/f2 2019-09-25 14:38:14.000000000 +0200
|
||||
+++ new/f2 2019-09-25 14:38:32.000000000 +0200
|
||||
@@ -1 +1 @@
|
||||
-a\nc
|
||||
-a\nc
|
||||
+a\nb\nd
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
diff --git a/test/Issue.java b/test/Issue.java
|
||||
new file mode 100644
|
||||
index 00000000..9702606e
|
||||
@@ -0,0 +1,109 @@
|
||||
From b53e612a2ab5ff15d14860e252f84c0f343fe93a Mon Sep 17 00:00:00 2001
|
||||
From: nmancus1 <nmancus1
|
||||
Date: Thu, 4 Jun 2020 11:46:34 -0400
|
||||
Subject: [PATCH] minor: Add input file for Java14 instanceof with pattern
|
||||
matching (#7290)
|
||||
|
||||
---
|
||||
config/ant-phase-verify.xml | 2 +
|
||||
.../InputJava14InstanceofWithPatternMatching.java | 76 ++++++++++++++++++++++
|
||||
2 files changed, 78 insertions(+)
|
||||
create mode 100644 src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java14/InputJava14InstanceofWithPatternMatching.java
|
||||
|
||||
diff --git a/config/ant-phase-verify.xml b/config/ant-phase-verify.xml
|
||||
index d27ffef..e0285ce 100644
|
||||
--- a/config/ant-phase-verify.xml
|
||||
+++ b/config/ant-phase-verify.xml
|
||||
@@ -148,6 +148,8 @@
|
||||
<exclude name="**/InputMainFrameModelIncorrectClass.java"/>
|
||||
<exclude name="**/InputBeforeExecutionExclusionFileFilterIncorrectClass.java"/>
|
||||
<exclude name="**/InputJavaParser.java"/>
|
||||
+ <!-- until https://github.com/checkstyle/checkstyle/issues/7290 -->
|
||||
+ <exclude name="**/InputJava14InstanceofWithPatternMatching.java"/>
|
||||
<!-- Cannot parse until Java 14 support -->
|
||||
<exclude name="**/InputJava14Records.java"/>
|
||||
</fileset>
|
||||
diff --git a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java14/InputJava14InstanceofWithPatternMatching.java b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java14/InputJava14InstanceofWithPatternMatching.java
|
||||
new file mode 100644
|
||||
index 0000000..8fa3eba
|
||||
--- /dev/null
|
||||
+++ b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/grammar/java14/InputJava14InstanceofWithPatternMatching.java
|
||||
@@ -0,0 +1,76 @@
|
||||
+//non-compiled with javac: Compilable with Java14
|
||||
+package com.puppycrawl.tools.checkstyle.grammar.java14;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+import java.util.Locale;
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ ...... I removed it
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.7.4
|
||||
@@ -0,0 +1,31 @@
|
||||
# HG changeset patch
|
||||
# User Anton Shestakov <av6@dwimlabs.net>
|
||||
# Date 1591442367 -28800
|
||||
# Node ID a4438263b228dd3e2983d59095c6180b1411f0e8
|
||||
# Parent 83e41b73d115e3717943c2e5a83d36d05670384c
|
||||
tests: skip pyflakes for mercurial/thirdparty/
|
||||
|
||||
The current version of pyflakes (2.2.0) correctly detects one issue:
|
||||
|
||||
mercurial/thirdparty/selectors2.py:335:40 '...'.format(...) has unused arguments at position(s): 1
|
||||
|
||||
But we're not interested in fixing lint errors in third-party code, so we need
|
||||
to exclude at least selectors2.py. And in the discussion for this patch it was
|
||||
decided to just skip the entire thirdparty directory.
|
||||
|
||||
Differential Revision: https://phab.mercurial-scm.org/D8619
|
||||
|
||||
diff -r 83e41b73d115 -r a4438263b228 tests/test-check-pyflakes.t
|
||||
--- a/tests/test-check-pyflakes.t Tue Jun 09 17:13:26 2020 -0400
|
||||
+++ b/tests/test-check-pyflakes.t Sat Jun 06 19:19:27 2020 +0800
|
||||
@@ -16,9 +16,7 @@
|
||||
$ testrepohg locate 'set:**.py or grep("^#!.*python")' \
|
||||
> -X hgext/fsmonitor/pywatchman \
|
||||
> -X mercurial/pycompat.py -X contrib/python-zstandard \
|
||||
- > -X mercurial/thirdparty/cbor \
|
||||
- > -X mercurial/thirdparty/concurrent \
|
||||
- > -X mercurial/thirdparty/zope \
|
||||
+ > -X mercurial/thirdparty \
|
||||
> 2>/dev/null \
|
||||
> | xargs $PYTHON -m pyflakes 2>/dev/null | "$TESTDIR/filterpyflakes.py"
|
||||
contrib/perf.py:*:* undefined name 'xrange' (glob) (?)
|
||||
@@ -0,0 +1,55 @@
|
||||
From fd940c6f66126734e82c00889e7c987e11deea91 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Bjerre <tomas.bjerre85@gmail.com>
|
||||
Date: Sun, 6 Sep 2020 11:20:34 +0200
|
||||
Subject: [PATCH] removing file
|
||||
|
||||
---
|
||||
.../violations/lib/model/ViolationTest.java | 37 -------------------
|
||||
1 file changed, 37 deletions(-)
|
||||
delete mode 100644 src/test/java/se/bjurr/violations/lib/model/ViolationTest.java
|
||||
|
||||
diff --git a/src/test/java/se/bjurr/violations/lib/model/ViolationTest.java b/src/test/java/se/bjurr/violations/lib/model/ViolationTest.java
|
||||
deleted file mode 100644
|
||||
index 3e40b52..0000000
|
||||
--- a/src/test/java/se/bjurr/violations/lib/model/ViolationTest.java
|
||||
+++ /dev/null
|
||||
@@ -1,37 +0,0 @@
|
||||
-package se.bjurr.violations.lib.model;
|
||||
-
|
||||
-import static org.assertj.core.api.Assertions.assertThat;
|
||||
-import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
|
||||
-import static se.bjurr.violations.lib.model.Violation.violationBuilder;
|
||||
-import static se.bjurr.violations.lib.reports.Parser.CHECKSTYLE;
|
||||
-
|
||||
-import org.junit.Test;
|
||||
-import se.bjurr.violations.lib.model.Violation.ViolationBuilder;
|
||||
-import uk.co.jemos.podam.api.PodamFactoryImpl;
|
||||
-
|
||||
-public class ViolationTest {
|
||||
-
|
||||
- @Test
|
||||
- public void testThatFilePathsAreAlwaysFronSlashes() {
|
||||
- final Violation violation =
|
||||
- violationBuilder() //
|
||||
- .setParser(CHECKSTYLE) //
|
||||
- .setFile("c:\\path\\to\\file.xml") //
|
||||
- .setMessage("message") //
|
||||
- .setSeverity(ERROR) //
|
||||
- .setStartLine(1) //
|
||||
- .build();
|
||||
- assertThat(violation.getFile()) //
|
||||
- .isEqualTo("c:/path/to/file.xml");
|
||||
- }
|
||||
-
|
||||
- @Test
|
||||
- public void testThatCopyConstructorWorks() {
|
||||
- final ViolationBuilder originalBuilder =
|
||||
- new PodamFactoryImpl().manufacturePojo(ViolationBuilder.class);
|
||||
- final Violation original = originalBuilder.build();
|
||||
- final Violation copied = new Violation(original);
|
||||
- assertThat(copied) //
|
||||
- .isEqualTo(original);
|
||||
- }
|
||||
-}
|
||||
--
|
||||
2.25.1
|
||||
@@ -0,0 +1,291 @@
|
||||
From 9b73f79a2436760b8278377014bf78a144a427ae Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 1 Feb 2018 14:26:22 +0100
|
||||
Subject: [PATCH 15/23] make Samba data tool configurable
|
||||
|
||||
Allow to specify an alternative path to Samba's net utility at configure
|
||||
time and at run time.
|
||||
|
||||
https://bugs.freedesktop.org/show_bug.cgi?id=100118
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
configure.ac | 13 ++++++++++++
|
||||
doc/adcli.xml | 21 ++++++++++++++++++-
|
||||
doc/samba_data_tool_path.xml.in | 1 +
|
||||
library/adenroll.c | 46 ++++++++++++++++++++++++++++++++++-------
|
||||
library/adenroll.h | 5 +++++
|
||||
tools/computer.c | 16 ++++++++++++++
|
||||
7 files changed, 95 insertions(+), 8 deletions(-)
|
||||
create mode 100644 doc/samba_data_tool_path.xml.in
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index fe86638..68877c7 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -291,6 +291,18 @@ else
|
||||
AC_DEFINE_UNQUOTED(BIN_ECHO, "$BIN_ECHO", [path to echo, used in unit test])
|
||||
fi
|
||||
|
||||
+AC_MSG_CHECKING([where is Samba's net utility])
|
||||
+AC_ARG_WITH([samba_data_tool],
|
||||
+ AC_HELP_STRING([--with-samba-data-tool=/path],
|
||||
+ [Path to Samba's net utility]),
|
||||
+ [],
|
||||
+ [with_samba_data_tool=/usr/bin/net])
|
||||
+AC_MSG_RESULT([$with_samba_data_tool])
|
||||
+
|
||||
+AC_DEFINE_UNQUOTED(SAMBA_DATA_TOOL, "$with_samba_data_tool",
|
||||
+ [Path to Samba's net utility])
|
||||
+
|
||||
+AC_SUBST(SAMBA_DATA_TOOL, [$with_samba_data_tool])
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
ADCLI_LT_RELEASE=$ADCLI_CURRENT:$ADCLI_REVISION:$ADCLI_AGE
|
||||
@@ -300,6 +312,7 @@ AC_CONFIG_FILES([Makefile
|
||||
build/Makefile
|
||||
doc/Makefile
|
||||
doc/version.xml
|
||||
+ doc/samba_data_tool_path.xml
|
||||
library/Makefile
|
||||
tools/Makefile
|
||||
])
|
||||
diff --git a/doc/adcli.xml b/doc/adcli.xml
|
||||
index fbc6c63..c2b7760 100644
|
||||
--- a/doc/adcli.xml
|
||||
+++ b/doc/adcli.xml
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
- "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||||
+[
|
||||
+ <!ENTITY samba_data_tool SYSTEM "samba_data_tool_path.xml">
|
||||
+]>
|
||||
|
||||
<refentry id="adcli">
|
||||
|
||||
@@ -307,6 +310,14 @@ Password for Administrator:
|
||||
<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details.</para></listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
|
||||
+ <listitem><para>If Samba's <command>net</command>
|
||||
+ cannot be found at
|
||||
+ <filename>&samba_data_tool;</filename> this option can
|
||||
+ be used to specific an alternative location with the
|
||||
+ help of an absolute path.</para></listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
@@ -412,6 +423,14 @@ $ adcli update --login-ccache=/tmp/krbcc_123
|
||||
<citerefentry><refentrytitle>smb.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details.</para></listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><option>--samba-data-tool=<parameter>/path/to/net</parameter></option></term>
|
||||
+ <listitem><para>If Samba's <command>net</command>
|
||||
+ cannot be found at
|
||||
+ <filename>&samba_data_tool;</filename> this option can
|
||||
+ be used to specific an alternative location with the
|
||||
+ help of an absolute path.</para></listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
diff --git a/doc/samba_data_tool_path.xml.in b/doc/samba_data_tool_path.xml.in
|
||||
new file mode 100644
|
||||
index 0000000..a667c57
|
||||
--- /dev/null
|
||||
+++ b/doc/samba_data_tool_path.xml.in
|
||||
@@ -0,0 +1 @@
|
||||
+@SAMBA_DATA_TOOL@
|
||||
diff --git a/library/adenroll.c b/library/adenroll.c
|
||||
index 20731cd..a693049 100644
|
||||
--- a/library/adenroll.c
|
||||
+++ b/library/adenroll.c
|
||||
@@ -42,6 +42,10 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#ifndef SAMBA_DATA_TOOL
|
||||
+#define SAMBA_DATA_TOOL "/usr/bin/net"
|
||||
+#endif
|
||||
+
|
||||
static krb5_enctype v60_later_enctypes[] = {
|
||||
ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
||||
ENCTYPE_AES128_CTS_HMAC_SHA1_96,
|
||||
@@ -100,6 +104,7 @@ struct _adcli_enroll {
|
||||
int keytab_enctypes_explicit;
|
||||
unsigned int computer_password_lifetime;
|
||||
int computer_password_lifetime_explicit;
|
||||
+ char *samba_data_tool;
|
||||
};
|
||||
|
||||
static adcli_result
|
||||
@@ -1537,26 +1542,33 @@ static adcli_result
|
||||
update_samba_data (adcli_enroll *enroll)
|
||||
{
|
||||
int ret;
|
||||
- char *argv_pw[] = { "/usr/bin/net", "changesecretpw", "-i", "-f", NULL };
|
||||
- char *argv_sid[] = { "/usr/bin/net", "setdomainsid", NULL, NULL };
|
||||
+ char *argv_pw[] = { NULL, "changesecretpw", "-i", "-f", NULL };
|
||||
+ char *argv_sid[] = { NULL, "setdomainsid", NULL, NULL };
|
||||
+
|
||||
+ argv_pw[0] = (char *) adcli_enroll_get_samba_data_tool (enroll);
|
||||
+ if (argv_pw[0] ==NULL) {
|
||||
+ _adcli_err ("Samba data tool not available.");
|
||||
+ return ADCLI_ERR_FAIL;
|
||||
+ }
|
||||
+ argv_sid[0] = argv_pw[0];
|
||||
|
||||
- _adcli_info ("Trying to set Samba secret.\n");
|
||||
+ _adcli_info ("Trying to set Samba secret.");
|
||||
ret = _adcli_call_external_program (argv_pw[0], argv_pw,
|
||||
enroll->computer_password, NULL, NULL);
|
||||
if (ret != ADCLI_SUCCESS) {
|
||||
- _adcli_err ("Failed to set Samba computer account password.\n");
|
||||
+ _adcli_err ("Failed to set Samba computer account password.");
|
||||
}
|
||||
|
||||
argv_sid[2] = (char *) adcli_conn_get_domain_sid (enroll->conn);
|
||||
if (argv_sid[2] == NULL) {
|
||||
- _adcli_err ("Domain SID not available.\n");
|
||||
+ _adcli_err ("Domain SID not available.");
|
||||
} else {
|
||||
- _adcli_info ("Trying to set domain SID %s for Samba.\n",
|
||||
+ _adcli_info ("Trying to set domain SID %s for Samba.",
|
||||
argv_sid[2]);
|
||||
ret = _adcli_call_external_program (argv_sid[0], argv_sid,
|
||||
NULL, NULL, NULL);
|
||||
if (ret != ADCLI_SUCCESS) {
|
||||
- _adcli_err ("Failed to set Samba domain SID.\n");
|
||||
+ _adcli_err ("Failed to set Samba domain SID.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1951,6 +1963,9 @@ adcli_enroll_new (adcli_conn *conn)
|
||||
enroll->os_name = strdup (value);
|
||||
return_val_if_fail (enroll->os_name != NULL, NULL);
|
||||
|
||||
+ enroll->samba_data_tool = strdup (SAMBA_DATA_TOOL);
|
||||
+ return_val_if_fail (enroll->samba_data_tool != NULL, NULL);
|
||||
+
|
||||
return enroll;
|
||||
}
|
||||
|
||||
@@ -1978,6 +1993,7 @@ enroll_free (adcli_enroll *enroll)
|
||||
free (enroll->os_name);
|
||||
free (enroll->os_version);
|
||||
free (enroll->os_service_pack);
|
||||
+ free (enroll->samba_data_tool);
|
||||
|
||||
free (enroll->user_principal);
|
||||
_adcli_strv_free (enroll->service_names);
|
||||
@@ -2343,3 +2359,19 @@ adcli_enroll_set_computer_password_lifetime (adcli_enroll *enroll,
|
||||
|
||||
enroll->computer_password_lifetime_explicit = 1;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+adcli_enroll_set_samba_data_tool (adcli_enroll *enroll, const char *value)
|
||||
+{
|
||||
+ return_if_fail (enroll != NULL);
|
||||
+ if (value != NULL && value[0] != '\0') {
|
||||
+ _adcli_str_set (&enroll->samba_data_tool, value);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+adcli_enroll_get_samba_data_tool (adcli_enroll *enroll)
|
||||
+{
|
||||
+ return_val_if_fail (enroll != NULL, NULL);
|
||||
+ return enroll->samba_data_tool;
|
||||
+}
|
||||
diff --git a/library/adenroll.h b/library/adenroll.h
|
||||
index 32c9764..31ca0bc 100644
|
||||
--- a/library/adenroll.h
|
||||
+++ b/library/adenroll.h
|
||||
@@ -141,4 +141,9 @@ const char * adcli_enroll_get_os_service_pack (adcli_enroll *enroll);
|
||||
void adcli_enroll_set_os_service_pack (adcli_enroll *enroll,
|
||||
const char *value);
|
||||
|
||||
+void adcli_enroll_set_samba_data_tool (adcli_enroll *enroll,
|
||||
+ const char *value);
|
||||
+
|
||||
+const char * adcli_enroll_get_samba_data_tool (adcli_enroll *enroll);
|
||||
+
|
||||
#endif /* ADENROLL_H_ */
|
||||
diff --git a/tools/computer.c b/tools/computer.c
|
||||
index fc646f2..f86548b 100644
|
||||
--- a/tools/computer.c
|
||||
+++ b/tools/computer.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
static void
|
||||
dump_details (adcli_conn *conn,
|
||||
@@ -107,6 +108,7 @@ typedef enum {
|
||||
opt_user_principal,
|
||||
opt_computer_password_lifetime,
|
||||
opt_add_samba_data,
|
||||
+ opt_samba_data_tool,
|
||||
} Option;
|
||||
|
||||
static adcli_tool_desc common_usages[] = {
|
||||
@@ -145,6 +147,7 @@ static adcli_tool_desc common_usages[] = {
|
||||
"successful join" },
|
||||
{ opt_add_samba_data, "add domain SID and computer account password\n"
|
||||
"to the Samba specific configuration database" },
|
||||
+ { opt_samba_data_tool, "Absolute path to the tool used for add-samba-data" },
|
||||
{ opt_verbose, "show verbose progress and failure messages", },
|
||||
{ 0 },
|
||||
};
|
||||
@@ -160,6 +163,7 @@ parse_option (Option opt,
|
||||
static int stdin_password = 0;
|
||||
char *endptr;
|
||||
unsigned int lifetime;
|
||||
+ int ret;
|
||||
|
||||
switch (opt) {
|
||||
case opt_login_ccache:
|
||||
@@ -265,6 +269,16 @@ parse_option (Option opt,
|
||||
|
||||
adcli_enroll_set_computer_password_lifetime (enroll, lifetime);
|
||||
return;
|
||||
+ case opt_samba_data_tool:
|
||||
+ errno = 0;
|
||||
+ ret = access (optarg, X_OK);
|
||||
+ if (ret != 0) {
|
||||
+ ret = errno;
|
||||
+ errx (EUSAGE, "Failed to access tool to add Samba data: %s", strerror (ret));
|
||||
+ } else {
|
||||
+ adcli_enroll_set_samba_data_tool (enroll, optarg);
|
||||
+ }
|
||||
+ return;
|
||||
case opt_verbose:
|
||||
return;
|
||||
|
||||
@@ -331,6 +345,7 @@ adcli_tool_computer_join (adcli_conn *conn,
|
||||
{ "show-details", no_argument, NULL, opt_show_details },
|
||||
{ "show-password", no_argument, NULL, opt_show_password },
|
||||
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
|
||||
+ { "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
|
||||
{ "verbose", no_argument, NULL, opt_verbose },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ 0 },
|
||||
@@ -434,6 +449,7 @@ adcli_tool_computer_update (adcli_conn *conn,
|
||||
{ "show-details", no_argument, NULL, opt_show_details },
|
||||
{ "show-password", no_argument, NULL, opt_show_password },
|
||||
{ "add-samba-data", no_argument, NULL, opt_add_samba_data },
|
||||
+ { "samba-data-tool", no_argument, NULL, opt_samba_data_tool },
|
||||
{ "verbose", no_argument, NULL, opt_verbose },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ 0 },
|
||||
--
|
||||
2.14.4
|
||||
8
java-diff-utils/src/test/resources/logging.properties
Normal file
8
java-diff-utils/src/test/resources/logging.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
handlers=java.util.logging.ConsoleHandler
|
||||
|
||||
.level=INFO
|
||||
com.github.difflib.unifieddiff.level=INFO
|
||||
|
||||
java.util.logging.ConsoleHandler.level=INFO
|
||||
#java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
|
||||
|
||||
29
java-diff-utils/src/test/resources/mocks/issue89_patch.txt
Normal file
29
java-diff-utils/src/test/resources/mocks/issue89_patch.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
--- Origin.java 2020-06-11 11:06:21.000000000 +0800
|
||||
+++ Update.java 2020-06-11 10:59:48.000000000 +0800
|
||||
@@ -1,9 +1,17 @@
|
||||
package checkstyle_demo.PatchSuppression.MultiChangeInOneFile;
|
||||
|
||||
-public class Origin {
|
||||
+public class Update {
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
+
|
||||
+ public void test2() {
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ public void test3() {
|
||||
+
|
||||
+ }
|
||||
}
|
||||
|
||||
class BasicTest {
|
||||
@@ -16,5 +24,7 @@
|
||||
class Test2 {
|
||||
public void test1() {
|
||||
System.out.println();
|
||||
+ System.out.println();
|
||||
+ System.out.println();
|
||||
}
|
||||
}
|
||||
30
java-diff-utils/src/test/resources/mocks/issue89_revised.txt
Normal file
30
java-diff-utils/src/test/resources/mocks/issue89_revised.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
package checkstyle_demo.PatchSuppression.MultiChangeInOneFile;
|
||||
|
||||
public class issue89_revised {
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
|
||||
public void test2() {
|
||||
|
||||
}
|
||||
|
||||
public void test3() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
private int i;
|
||||
void foo() {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 {
|
||||
public void test1() {
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
@@ -1,174 +1,164 @@
|
||||
/*
|
||||
Copyright 2009 Dmitry Naumenko (dm.naumenko@gmail.com)
|
||||
|
||||
This file is part of Java Diff Utills Library.
|
||||
* Copyright 2009-2017 java-diff-utils.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.github.difflib;
|
||||
|
||||
Java Diff Utills Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Java Diff Utills Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Java Diff Utills Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package difflib;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import difflib.myers.*;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.algorithm.myers.MyersDiff;
|
||||
import com.github.difflib.patch.AbstractDelta;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* Implements the difference and patching engine
|
||||
*
|
||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||
* @version 0.4.1
|
||||
*/
|
||||
public class DiffUtils {
|
||||
private static DiffAlgorithm defaultDiffAlgorithm = new MyersDiff();
|
||||
private static Pattern unifiedDiffChunkRe =
|
||||
Pattern.compile("@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with default diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised) {
|
||||
return DiffUtils.diff(original, revised, defaultDiffAlgorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with given diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @param algorithm the given algorithm
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised, DiffAlgorithm algorithm) {
|
||||
return algorithm.diff(original, revised);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the original text with given patch
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
* @return the revised text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
public static List<?> patch(List<?> original, Patch patch) throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpatch the revised text for a given patch
|
||||
*
|
||||
* @param revised the revised text
|
||||
* @param patch the given patch
|
||||
* @return the original text
|
||||
*/
|
||||
public static List<?> unpatch(List<?> revised, Patch patch) {
|
||||
return patch.restore(revised);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given text in unified format and creates the list of deltas for it.
|
||||
*
|
||||
* @param diff the text in unified format
|
||||
* @return the patch with deltas.
|
||||
*/
|
||||
public static Patch parseUnifiedDiff(List<String> diff) {
|
||||
boolean inPrelude = true;
|
||||
List<Object[]> rawChunk = new ArrayList<Object[]>();
|
||||
Patch patch = new Patch();
|
||||
|
||||
int old_ln = 0, old_n = 0, new_ln = 0, new_n = 0;
|
||||
String tag = "", rest = "";
|
||||
for (String line: diff) {
|
||||
// Skip leading lines until after we've seen one starting with '+++'
|
||||
if (inPrelude) {
|
||||
if (line.startsWith("+++")) {
|
||||
inPrelude = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Matcher m = unifiedDiffChunkRe.matcher(line);
|
||||
if (m.find()) {
|
||||
// Process the lines in the previous chunk
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
for (Object[] raw_line: rawChunk) {
|
||||
tag = (String)raw_line[0];
|
||||
rest = (String)raw_line[1];
|
||||
if (tag.equals(" ") || tag.equals("-")) {
|
||||
oldChunkLines.add(rest);
|
||||
}
|
||||
if (tag.equals(" ") || tag.equals("+")) {
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines),
|
||||
new Chunk(new_ln - 1, new_n, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
// Parse the @@ header
|
||||
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
|
||||
old_n = m.group(2) == null ? 1 : Integer.parseInt(m.group(2));
|
||||
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
||||
new_n = m.group(4) == null ? 1 : Integer.parseInt(m.group(4));
|
||||
old_ln = Integer.parseInt(m.group(1));
|
||||
|
||||
if (old_ln == 0) {
|
||||
old_ln += 1;
|
||||
}
|
||||
if (new_ln == 0) {
|
||||
new_ln += 1;
|
||||
}
|
||||
} else {
|
||||
if (line.length() > 0) {
|
||||
tag = line.substring(0, 1);
|
||||
rest = line.substring(1);
|
||||
if (tag.equals(" ") || tag.equals("+") || tag.equals("-")) {
|
||||
rawChunk.add(new Object[] {tag, rest});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the lines in the last chunk
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
for (Object[] raw_line: rawChunk) {
|
||||
tag = (String)raw_line[0];
|
||||
rest = (String)raw_line[1];
|
||||
if (tag.equals(" ") || tag.equals("-")) {
|
||||
oldChunkLines.add(rest);
|
||||
}
|
||||
if (tag.equals(" ") || tag.equals("+")) {
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines),
|
||||
new Chunk(new_ln - 1, new_n, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
public final class DiffUtils {
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
*
|
||||
* @param <T> types to be diffed
|
||||
* @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}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), progress);
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null);
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null, includeEqualParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised text.
|
||||
*/
|
||||
public static Patch<String> diff(String sourceText, String targetText,
|
||||
DiffAlgorithmListener progress) {
|
||||
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 source The original text. Must not be {@code null}.
|
||||
* @param target The revised text. Must not be {@code null}.
|
||||
*
|
||||
* @param equalizer the equalizer object to replace the default compare algorithm
|
||||
* (Object.equals). If {@code null} the default equalizer of the default algorithm is used..
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> source, List<T> target,
|
||||
BiPredicate<T, T> equalizer) {
|
||||
if (equalizer != null) {
|
||||
return DiffUtils.diff(source, target,
|
||||
new MyersDiff<>(equalizer));
|
||||
}
|
||||
return DiffUtils.diff(source, target, new MyersDiff<>());
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
||||
return diff(original, revised, algorithm, progress, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* @param progress The diff algorithm listener.
|
||||
* @param includeEqualParts Include equal data parts into the patch.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress,
|
||||
boolean includeEqualParts) {
|
||||
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.computeDiff(original, revised, progress), includeEqualParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
*
|
||||
* @param original The original text. Must not be {@code null}.
|
||||
* @param revised The revised text. Must not be {@code null}.
|
||||
* @param algorithm The diff algorithm. Must not be {@code null}.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
||||
return diff(original, revised, algorithm, null);
|
||||
}
|
||||
|
||||
private static List<String> compressLines(List<String> lines, String delimiter) {
|
||||
if (lines.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList(String.join(delimiter, lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the original text with given patch
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
* @return the revised text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
public static <T> List<T> patch(List<T> original, Patch<T> patch)
|
||||
throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpatch the revised text for a given patch
|
||||
*
|
||||
* @param revised the revised text
|
||||
* @param patch the given patch
|
||||
* @return the original text
|
||||
*/
|
||||
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
|
||||
return patch.restore(revised);
|
||||
}
|
||||
|
||||
private DiffUtils() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,308 +1,190 @@
|
||||
/*
|
||||
Copyright 2009 Dmitry Naumenko (dm.naumenko@gmail.com)
|
||||
|
||||
This file is part of Java Diff Utils Library.
|
||||
* Copyright 2009-2017 java-diff-utills.
|
||||
*
|
||||
* 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;
|
||||
|
||||
Java Diff Utils Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Java Diff Utils Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Java Diff Utils Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package difflib;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import difflib.myers.*;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.algorithm.myers.MyersDiff;
|
||||
import com.github.difflib.patch.AbstractDelta;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
/**
|
||||
* Implements the difference and patching engine
|
||||
*
|
||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||
* @version 0.4.1
|
||||
*/
|
||||
public class DiffUtils {
|
||||
private static DiffAlgorithm defaultDiffAlgorithm = new MyersDiff();
|
||||
private static Pattern unifiedDiffChunkRe =
|
||||
Pattern.compile("@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with default diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised) {
|
||||
return DiffUtils.diff(original, revised, defaultDiffAlgorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the difference between the original and revised texts with given diff algorithm
|
||||
*
|
||||
* @param original the original text
|
||||
* @param revised the revised text
|
||||
* @param algorithm the given algorithm
|
||||
* @return the patch describing the difference between the original and revised texts
|
||||
*/
|
||||
public static Patch diff(List<?> original, List<?> revised, DiffAlgorithm algorithm) {
|
||||
return algorithm.diff(original, revised);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the original text with given patch
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
* @return the revised text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
public static List<?> patch(List<?> original, Patch patch) throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpatch the revised text for a given patch
|
||||
*
|
||||
* @param revised the revised text
|
||||
* @param patch the given patch
|
||||
* @return the original text
|
||||
*/
|
||||
public static List<?> unpatch(List<?> revised, Patch patch) {
|
||||
return patch.restore(revised); // bla-bla-bla
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given text in unified format and creates the list of deltas for it.
|
||||
*
|
||||
* @param diff the text in unified format
|
||||
* @return the patch with deltas.
|
||||
*/
|
||||
public static Patch parseUnifiedDiff(List<String> diff) {
|
||||
boolean inPrelude = true;
|
||||
List<Object[]> rawChunk = new ArrayList<Object[]>();
|
||||
Patch patch = new Patch();
|
||||
|
||||
int old_ln = 0, old_n = 0, new_ln = 0, new_n = 0;
|
||||
String tag = "", rest = "";
|
||||
for (String line: diff) {
|
||||
// Skip leading lines until after we've seen one starting with '+++'
|
||||
if (inPrelude) {
|
||||
if (line.startsWith("+++")) {
|
||||
inPrelude = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Matcher m = unifiedDiffChunkRe.matcher(line);
|
||||
if (m.find()) {
|
||||
// Process the lines in the previous chunk
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
for (Object[] raw_line: rawChunk) {
|
||||
tag = (String)raw_line[0];
|
||||
rest = (String)raw_line[1];
|
||||
if (tag.equals(" ") || tag.equals("-")) {
|
||||
oldChunkLines.add(rest);
|
||||
}
|
||||
if (tag.equals(" ") || tag.equals("+")) {
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines),
|
||||
new Chunk(new_ln - 1, new_n, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
// Parse the @@ header
|
||||
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
|
||||
old_n = m.group(2) == null ? 1 : Integer.parseInt(m.group(2));
|
||||
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
||||
new_n = m.group(4) == null ? 1 : Integer.parseInt(m.group(4));
|
||||
old_ln = Integer.parseInt(m.group(1));
|
||||
|
||||
if (old_ln == 0) {
|
||||
old_ln += 1;
|
||||
}
|
||||
if (new_ln == 0) {
|
||||
new_ln += 1;
|
||||
}
|
||||
} else {
|
||||
if (line.length() > 0) {
|
||||
tag = line.substring(0, 1);
|
||||
rest = line.substring(1);
|
||||
if (tag.equals(" ") || tag.equals("+") || tag.equals("-")) {
|
||||
rawChunk.add(new Object[] {tag, rest});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the lines in the last chunk
|
||||
if (rawChunk.size() != 0) {
|
||||
List<String> oldChunkLines = new ArrayList<String>();
|
||||
List<String> newChunkLines = new ArrayList<String>();
|
||||
|
||||
for (Object[] raw_line: rawChunk)
|
||||
{
|
||||
tag = (String)raw_line[0];
|
||||
rest = (String)raw_line[1];
|
||||
if (tag.equals(" ") || tag.equals("-"))
|
||||
{
|
||||
oldChunkLines.add(rest);
|
||||
}
|
||||
if (tag.equals(" ") || tag.equals("+"))
|
||||
{
|
||||
newChunkLines.add(rest);
|
||||
}
|
||||
}
|
||||
|
||||
patch.addDelta(new ChangeDelta(new Chunk(old_ln - 1, old_n, oldChunkLines),
|
||||
new Chunk(new_ln - 1, new_n, newChunkLines)));
|
||||
rawChunk.clear();
|
||||
}
|
||||
|
||||
return patch;
|
||||
}
|
||||
public final class DiffUtills {
|
||||
|
||||
/**
|
||||
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing the Patch.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
* @param fname1 - Filename of the original (unrevised file)
|
||||
* @param fname2 - 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.
|
||||
*/
|
||||
public static List<String> generateUnifiedDiff(String fname1, String fname2, List<String> originalLines, Patch patch, int contextSize ) {
|
||||
List<String> ret = new ArrayList<String>();
|
||||
ret.add( "--- " + fname1 );
|
||||
ret.add( "+++ " + fname2 );
|
||||
|
||||
List<Delta> cur = new ArrayList<Delta>(); // current list of Delta's to process
|
||||
int deltact = patch.getDeltas().size();
|
||||
// if there's more than 1 Delta, we may need to output them together
|
||||
if ( deltact > 1 ) {
|
||||
Delta curDelta = patch.getDelta(0);
|
||||
cur.add( curDelta ); // add the first Delta to the current set
|
||||
for ( int i = 1; i < deltact; i++ ) {
|
||||
int curpos = curDelta.getOriginal().getPosition(); // store the current position of the first Delta
|
||||
Delta nextDelta = patch.getDelta(i); // Check if the next Delta is too close to the current position
|
||||
if ( (curpos + curDelta.getOriginal().getSize() + contextSize) >= ( nextDelta.getOriginal().getPosition()-contextSize ) ) {
|
||||
cur.add( nextDelta ); // if it is, add it to the current set
|
||||
} else {
|
||||
List<String> curBlock = processDeltas( originalLines, cur, contextSize );
|
||||
ret.addAll( curBlock ); // if it isn't, output the current set, then create a new
|
||||
cur.clear(); // set and add the current Delta to it.
|
||||
cur.add( nextDelta );
|
||||
}
|
||||
curDelta = nextDelta;
|
||||
}
|
||||
List<String> curBlock = processDeltas( originalLines, cur, contextSize ); // don't forget to process the last set of Deltas
|
||||
ret.addAll( curBlock );
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
*
|
||||
* @param <T> types to be diffed
|
||||
* @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}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmListener progress) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), progress);
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null);
|
||||
}
|
||||
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, boolean includeEqualParts) {
|
||||
return DiffUtils.diff(original, revised, new MyersDiff<>(), null, includeEqualParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised text.
|
||||
*/
|
||||
public static Patch<String> diff(String sourceText, String targetText,
|
||||
DiffAlgorithmListener progress) {
|
||||
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 source The original text. Must not be {@code null}.
|
||||
* @param target The revised text. Must not be {@code null}.
|
||||
*
|
||||
* @param equalizer the equalizer object to replace the default compare algorithm
|
||||
* (Object.equals). If {@code null} the default equalizer of the default algorithm is used..
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> source, List<T> target,
|
||||
BiPredicate<T, T> equalizer) {
|
||||
if (equalizer != null) {
|
||||
return DiffUtils.diff(source, target,
|
||||
new MyersDiff<>(equalizer));
|
||||
}
|
||||
return DiffUtils.diff(source, target, new MyersDiff<>());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress) {
|
||||
return diff(original, revised, algorithm, progress, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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}.
|
||||
* @param progress The diff algorithm listener.
|
||||
* @param includeEqualParts Include equal data parts into the patch.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||
DiffAlgorithmI<T> algorithm, DiffAlgorithmListener progress,
|
||||
boolean includeEqualParts) {
|
||||
Objects.requireNonNull(original, "original must not be null");
|
||||
Objects.requireNonNull(revised, "revised must not be null");
|
||||
Objects.requireNonNull(algorithm, "algorithm must not be null"); /* BLA BLA BLA */
|
||||
|
||||
/**
|
||||
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
* @param origLines - the lines of the original file
|
||||
* @param deltas - the Deltas to be output as a single block
|
||||
* @param contextSize - the number of lines of context to place around block
|
||||
return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress), includeEqualParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the difference between the original and revised list of elements with default diff
|
||||
* algorithm
|
||||
*
|
||||
* @param original The original text. Must not be {@code null}.
|
||||
* @param revised The revised text. Must not be {@code null}.
|
||||
* @param algorithm The diff algorithm. Must not be {@code null}.
|
||||
* @return The patch describing the difference between the original and revised sequences. Never
|
||||
* {@code null}.
|
||||
*/
|
||||
public static <T> Patch<T> diff(List<T> original, List<T> revised, DiffAlgorithmI<T> algorithm) {
|
||||
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 characters, like DiffRowGenerator does and merges those changes at the end
|
||||
* together again.
|
||||
*
|
||||
* @param original
|
||||
* @param revised
|
||||
* @return
|
||||
*/
|
||||
private static List<String> processDeltas( List<String> origLines, List<Delta> deltas, int contextSize ) {
|
||||
List<String> buffer = new ArrayList<String>();
|
||||
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); // start with the first Delta
|
||||
int origStart = curDelta.getOriginal().getPosition()+1 - contextSize; // note the +1 to overcome the 0-offset Position
|
||||
if ( origStart < 1 ) origStart = 1; // clamp to the start of the file
|
||||
int revStart = curDelta.getRevised().getPosition()+1 - contextSize; // note the +1 to overcome the 0-offset Position
|
||||
if ( revStart < 1 ) revStart = 1; // clamp to the start of the file
|
||||
int contextStart = curDelta.getOriginal().getPosition() - contextSize; // find the start of the wrapper context code
|
||||
if ( contextStart < 0 ) contextStart = 0; // clamp to the start of the file
|
||||
for ( line = contextStart; line < curDelta.getOriginal().getPosition(); line++ ) { // output the context before the first Delta
|
||||
buffer.add( " " + origLines.get( line ) );
|
||||
origTotal++;
|
||||
revTotal++;
|
||||
public static Patch<String> diffInline(String original, String revised) {
|
||||
List<String> origList = new ArrayList<>();
|
||||
List<String> revList = new ArrayList<>();
|
||||
for (Character character : original.toCharArray()) {
|
||||
origList.add(character.toString());
|
||||
}
|
||||
buffer.addAll( getDeltaText( curDelta ) ); // output the first Delta
|
||||
origTotal += curDelta.getOriginal().getLines().size();
|
||||
revTotal += curDelta.getRevised().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().getPosition(); line++ ) {
|
||||
buffer.add( " " + origLines.get( line ) ); // output the code between the last Delta and this one
|
||||
origTotal++;
|
||||
revTotal++;
|
||||
}
|
||||
buffer.addAll( getDeltaText( nextDelta ) ); // output the Delta
|
||||
origTotal += nextDelta.getOriginal().getLines().size();
|
||||
revTotal += nextDelta.getRevised().getLines().size();
|
||||
curDelta = nextDelta;
|
||||
deltaIndex++; // increment the iterator
|
||||
for (Character character : revised.toCharArray()) {
|
||||
revList.add(character.toString());
|
||||
}
|
||||
|
||||
// Now output the post-Delta context code, clamping the end of the file
|
||||
contextStart = curDelta.getOriginal().getPosition() + curDelta.getOriginal().getLines().size();
|
||||
for ( line = contextStart; ( line < (contextStart + contextSize )) && ( line < origLines.size() ); line++ ) {
|
||||
buffer.add( " " + origLines.get( line ) );
|
||||
origTotal++;
|
||||
revTotal++;
|
||||
Patch<String> patch = DiffUtils.diff(origList, revList);
|
||||
for (AbstractDelta<String> delta : patch.getDeltas()) {
|
||||
delta.getSource().setLines(compressLines(delta.getSource().getLines(), ""));
|
||||
delta.getTarget().setLines(compressLines(delta.getTarget().getLines(), ""));
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
|
||||
// Create and insert the block header, conforming to the Unified Diff standard
|
||||
StringBuffer header = new StringBuffer();
|
||||
header.append( "@@ -" );
|
||||
header.append( origStart );
|
||||
header.append( "," );
|
||||
header.append( origTotal );
|
||||
header.append( " +" );
|
||||
header.append( revStart );
|
||||
header.append( "," );
|
||||
header.append( revTotal );
|
||||
header.append( " @@" );
|
||||
buffer.add( 0, header.toString() );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||
* @author Bill James (tankerbay@gmail.com)
|
||||
*
|
||||
* @param delta - the Delta to output
|
||||
* @return list of String lines of code.
|
||||
*/
|
||||
private static List<String> getDeltaText( Delta delta ) {
|
||||
List<String> buffer = new ArrayList<String>();
|
||||
for ( Object line: delta.getOriginal().getLines() ) {
|
||||
buffer.add( "-" + line );
|
||||
private static List<String> compressLines(List<String> lines, String delimiter) {
|
||||
if (lines.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
for ( Object line: delta.getRevised().getLines() ) {
|
||||
buffer.add( "+" + line );
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return Collections.singletonList(String.join(delimiter, lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the original text with given patch
|
||||
*
|
||||
* @param original the original text
|
||||
* @param patch the given patch
|
||||
* @return the revised text
|
||||
* @throws PatchFailedException if can't apply patch
|
||||
*/
|
||||
public static <T> List<T> patch(List<T> original, Patch<T> patch)
|
||||
throws PatchFailedException {
|
||||
return patch.applyTo(original);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpatch the revised text for a given patch
|
||||
*
|
||||
* @param revised the revised text
|
||||
* @param patch the given patch
|
||||
* @return the original text
|
||||
*/
|
||||
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
|
||||
return patch.restore(revised);
|
||||
}
|
||||
|
||||
private DiffUtils() {
|
||||
}
|
||||
}
|
||||
|
||||
10
pom.xml
10
pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.7</version>
|
||||
<version>4.11</version>
|
||||
<name>java-diff-utils-parent</name>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
@@ -12,7 +12,7 @@
|
||||
</modules>
|
||||
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
|
||||
<url>https://github.com/java-diff-utils/java-diff-utils</url>
|
||||
<inceptionYear>2009</inceptionYear>
|
||||
<inceptionYear>2009</inceptionYear>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
@@ -29,7 +29,7 @@
|
||||
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
|
||||
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
|
||||
<tag>java-diff-utils-parent-4.7</tag>
|
||||
<tag>java-diff-utils-parent-4.11</tag>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
<system>GitHub Issues</system>
|
||||
@@ -65,13 +65,13 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<version>5.7.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.15.0</version>
|
||||
<version>3.19.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
Reference in New Issue
Block a user