All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.difflib.DiffUtils Maven / Gradle / Ivy

Go to download

The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.

The newest version!
/*-
 * #%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;

import com.github.difflib.algorithm.DiffAlgorithmI;
import com.github.difflib.algorithm.DiffAlgorithmListener;
import com.github.difflib.algorithm.DiffException;
import com.github.difflib.algorithm.myers.MyersDiff;
import com.github.difflib.patch.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;
import static java.util.stream.Collectors.joining;

/**
 * Implements the difference and patching engine
 *
 * @author Dmitry Naumenko
 */
public final class DiffUtils {

    /**
     * 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 progress progress listener
     * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
     * @throws com.github.difflib.algorithm.DiffException
     */
    public static  Patch diff(List original, List revised, DiffAlgorithmListener progress) throws DiffException {
        return DiffUtils.diff(original, revised, new MyersDiff<>(), progress);
    }
    
    public static  Patch diff(List original, List revised) throws DiffException {
        return DiffUtils.diff(original, revised, new MyersDiff<>(), null);
    }

    /**
     * Computes the difference between the original and revised text.
     */
    public static Patch diff(String sourceText, String targetText,
            DiffAlgorithmListener progress) throws DiffException {
        return DiffUtils.diff(
                 Arrays.asList(sourceText.split("\n")), 
                 Arrays.asList(targetText.split("\n")), progress);
    }

    /**
     * Computes the difference between the original and revised list of elements with default diff algorithm
     *
     * @param source The original text. Must not be {@code null}.
     * @param target The revised text. Must not be {@code null}.
     *
     * @param equalizer the equalizer object to replace the default compare algorithm (Object.equals). If {@code null}
     * the default equalizer of the default algorithm is used..
     * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
     */
    public static  Patch diff(List source, List target,
            BiPredicate equalizer) throws DiffException {
        if (equalizer != null) {
            return DiffUtils.diff(source, target,
                    new MyersDiff<>(equalizer));
        }
        return DiffUtils.diff(source, target, new MyersDiff<>());
    }

    /**
     * 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.
     * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
     */
    public static  Patch diff(List original, List revised,
            DiffAlgorithmI algorithm, DiffAlgorithmListener progress) throws DiffException {
        Objects.requireNonNull(original, "original must not be null");
        Objects.requireNonNull(revised, "revised must not be null");
        Objects.requireNonNull(algorithm, "algorithm must not be null");

        return Patch.generate(original, revised, algorithm.computeDiff(original, revised, progress));
    }
    
    /**
     * Computes the difference between the original and revised list of elements with default diff algorithm
     *
     * @param original The original text. Must not be {@code null}.
     * @param revised The revised text. Must not be {@code null}.
     * @param algorithm The diff algorithm. Must not be {@code null}.
     * @return The patch describing the difference between the original and revised sequences. Never {@code null}.
     */
     public static  Patch diff(List original, List revised,
            DiffAlgorithmI algorithm) throws DiffException {
         return diff(original, revised, algorithm, null);
     }

    /**
     * Computes the difference between the given texts inline. This one uses the "trick" to make out of texts lists of
     * characters, like DiffRowGenerator does and merges those changes at the end together again.
     *
     * @param original
     * @param revised
     * @return
     */
    public static Patch diffInline(String original, String revised) throws DiffException {
        List origList = new ArrayList<>();
        List revList = new ArrayList<>();
        for (Character character : original.toCharArray()) {
            origList.add(character.toString());
        }
        for (Character character : revised.toCharArray()) {
            revList.add(character.toString());
        }
        Patch patch = DiffUtils.diff(origList, revList);
        for (AbstractDelta delta : patch.getDeltas()) {
            delta.getSource().setLines(compressLines(delta.getSource().getLines(), ""));
            delta.getTarget().setLines(compressLines(delta.getTarget().getLines(), ""));
        }
        return patch;
    }

    private static List compressLines(List lines, String delimiter) {
        if (lines.isEmpty()) {
            return Collections.emptyList();
        }
        return Collections.singletonList(lines.stream().collect(joining(delimiter)));
    }

    /**
     * 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);
    }

    private DiffUtils() {
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy