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

pw.prok.kdiff.Patch Maven / Gradle / Ivy

The newest version!
/*
   Copyright 2010 Dmitry Naumenko ([email protected])

   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 pw.prok.kdiff;

import pw.prok.kdiff.delta.Delta;
import pw.prok.kdiff.delta.DeltaComparator;

import java.util.*;

/**
 * Describes the patch holding all deltas between the original and revised texts.
 *
 * @param  The type of the compared elements in the 'lines'.
 */
public class Patch> {
    private String original;
    private Date originalDate;
    private String revised;
    private Date revisedDate;
    private final List> deltas;

    public Patch() {
        this(new ArrayList>());
    }

    public Patch(List> deltas) {
        this.deltas = deltas;
    }

    /**
     * Internal method of Patch class. Should be overriden in case of different result class
     *
     * @param result  final result of patchin/rolling
     * @param hunks   list of hunks
     * @param rejects list of rejected deltas
     * @return PatchResult instance
     */
    protected R createResult(List result, List> hunks, List> rejects) {
        return (R) new PatchResult<>(result, hunks, rejects);
    }

    /**
     * Apply this patch to the given target
     *
     * @param target list of target elements
     * @return the patched text
     */
    public R patch(List target) {
        List result = new ArrayList<>(target);
        List> hunks = new ArrayList<>();
        List> rejects = new ArrayList<>();
        ListIterator> it = getDeltas().listIterator(deltas.size());
        while (it.hasPrevious()) {
            Delta delta = it.previous();
            try {
                Hunk hunk = delta.patch(result);
                if (hunk != null) hunks.add(hunk);
            } catch (PatchFailedException e) {
                rejects.add(delta);
            }
        }
        return createResult(Collections.unmodifiableList(result), Collections.unmodifiableList(hunks), Collections.unmodifiableList(rejects));
    }

    /**
     * Restore the text to original. Opposite to patch() method.
     *
     * @param target the given target
     * @return the restored text
     */
    public R restore(List target) {
        List result = new ArrayList<>(target);
        List> hunks = new ArrayList<>();
        List> rejects = new ArrayList<>();
        ListIterator> it = getDeltas().listIterator(deltas.size());
        while (it.hasPrevious()) {
            Delta delta = it.previous();
            try {
                Hunk hunk = delta.restore(result);
                if (hunk != null) hunks.add(hunk);
            } catch (PatchFailedException e) {
                rejects.add(delta);
            }
        }
        return createResult(Collections.unmodifiableList(result), Collections.unmodifiableList(hunks), Collections.unmodifiableList(rejects));
    }

    /**
     * Add the given delta to this patch
     *
     * @param delta the given delta
     */
    public void addDelta(Delta delta) {
        deltas.add(delta);
    }

    /**
     * Get the list of computed deltas
     *
     * @return the deltas
     */
    public List> getDeltas() {
        Collections.sort(deltas, DeltaComparator.INSTANCE);
        return deltas;
    }

    /**
     * Internal  method of Patch class. Creates new patch container
     *
     * @param deltas initial list of deltas
     * @return new patch instance
     */
    protected Patch createEmpty(List> deltas) {
        return new Patch<>(deltas);
    }

    /**
     * @return a deep copy of this patch
     */
    public Patch copy() {
        final Patch patch = createEmpty(new ArrayList>(deltas.size()));
        patch.original = original;
        patch.originalDate = originalDate;
        patch.revised = revised;
        patch.revisedDate = revisedDate;
        for (Delta delta : getDeltas())
            patch.addDelta(delta.copy());
        return patch;
    }

    /**
     * Merges into self deltas from other patch
     *
     * @param patch patch to merge
     * @return this
     */
    public Patch mergeSelf(Patch patch) {
        final List> deltas = patch.deltas;
        if (this.deltas instanceof ArrayList)
            ((ArrayList) this.deltas).ensureCapacity(this.deltas.size() + deltas.size());
        for (Delta delta : deltas)
            this.deltas.add(delta.copy());
        return this;
    }

    /**
     * Chain of {@link #copy()} and {@link #mergeSelf(Patch)}.
     *
     * @param patch patch to merge
     * @return new patch, which are contains all deltas
     */
    public Patch merge(Patch patch) {
        return copy().mergeSelf(patch);
    }

    /**
     * @return original file name
     */
    public String getOriginal() {
        return original;
    }

    /**
     * @param original new original file name
     * @return patch instance
     */
    public Patch setOriginal(String original) {
        this.original = original;
        return this;
    }

    public Date getOriginalDate() {
        return originalDate;
    }

    public Patch setOriginalDate(Date originalDate) {
        this.originalDate = originalDate;
        return this;
    }

    /**
     * @return revised file name
     */
    public String getRevised() {
        return revised;
    }

    /**
     * @param revised new revised file name
     * @return patch instance
     */
    public Patch setRevised(String revised) {
        this.revised = revised;
        return this;
    }

    public Date getRevisedDate() {
        return revisedDate;
    }

    public Patch setRevisedDate(Date revisedDate) {
        this.revisedDate = revisedDate;
        return this;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy