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

info.codesaway.util.Differences Maven / Gradle / Ivy

Go to download

Extends Java's regular expression syntax by adding support for additional Perl and .NET syntax.

The newest version!
package info.codesaway.util;

import java.util.List;
import java.util.Stack;

import info.codesaway.util.lcs.LcsString;

/**
 * List of differences
 */
public final class Differences {
	/**
	 * List of {@link Differences}
	 */
	private final Stack changes;

	/**
	 * Constructs a new differences object initialized with no changes.
	 */
	public Differences() {
		this.changes = new Stack<>();
	}

	/**
	 * Adds all the differences in the passed object to this
	 * Differences object
	 *
	 * @param differences
	 *            differences to add
	 * @return true if this collection changed as a result of the
	 *         call
	 */
	public boolean addAll(final Differences differences) {
		return this.changes.addAll(differences.changes);
	}

	/**
	 * Applies each change, in order, to the original string and outputs the
	 * result
	 *
	 * @param original
	 *            original string on which to apply the changes
	 */
	// public void applyDifferences(String original)
	// {
	// StringBuffer result = new StringBuffer(original);
	//
	// for (Iterator iterator = changes.iterator(); iterator
	// .hasNext();) {
	// iterator.next().applyStep(result);
	// }
	// }

	// public StringBuffer applyLastStep(StringBuffer replacement)
	// {
	// return changes.getLast().applyStep(replacement);
	// }

	/**
	 * Returns the original index (before the list of changes were applied)
	 * for the specified index.
	 *
	 * @param newIndex
	 *            the current index
	 * @return original index (before changes were applied)
	 * @throws IllegalArgumentException
	 *             If the specified index was not in the original string
	 */
	public int getOriginalIndex(final int newIndex) {
		int currentIndex = newIndex;

		// go from the top of the stack, down (descending order)
		for (int i = this.changes.size() - 1; i >= 0; i--) {
			currentIndex = this.changes.get(i).getOriginalIndexStep(currentIndex);
		}

		return currentIndex;
	}

	/**
	 * Returns the string representation of the internal changes.
	 *
	 * @return the internal changes as a string
	 */
	// @Override
	// public String toString()
	// {
	// return changes.toString();
	// }

	/**
	 * Adds a new difference to the list of changes.
	 *
	 * @param index
	 *            index for the insertion
	 * @param string
	 *            the string to insert
	 */
	// public void insert(int index, String string)
	// {
	// if (string.length() == 0)
	// return;
	//
	// changes.add(new InsertDifference(index, string));
	// }

	/**
	 * Adds a new difference to the list of changes.
	 *
	 * @param index
	 *            index for the character to remove
	 */
	// public void deleteCharAt(int index)
	// {
	// delete(index, index + 1);
	// }

	/**
	 * Adds a new difference to the list of changes.
	 *
	 * 

If start and end are equal, no difference * will be added. * * @param start * the begin index, inclusive * @param end * the end index, exclusive. */ // public void delete(int start, int end) // { // if (start == end) // return; // // changes.add(new DeleteDifference(start, end)); // } /** * Adds a new difference to the list of changes. * *

Implementation notes:

* *

The replacement consists of the insertions and deletions required to * change the original string to the replacement string.

* *

The differences are detected using the {@link LcsString#getDiff()} method.

* * @param start * initial position for the replacement * @param original * the original string * @param replacement * the replacement string */ // public void replace(int start, String original, String replacement) // { // if (original.equals(replacement)) // return; // // int end = start + original.length(); // LcsString seq = new LcsString(original, replacement); // // changes.add(new ReplaceDifferencePlus(start, end, replacement, // seq.getDiff())); // } /** * Adds a new difference to the list of changes. * *

Implementation notes:

* *

The replacement consists of the insertions and deletions required to * change the original string to the replacement string.

* *

The differences are detected using the {@link LcsString#getDiff0()} method.

* * @param start * initial position for the replacement * @param original * the original string * @param replacement * the replacement string */ public void replace0(final int start, final String original, final String replacement) { if (original.equals(replacement)) { return; } LcsString seq = new LcsString(original, replacement); int end = start + original.length(); this.changes.add(new ReplaceDifferencePlus(start, end, replacement, seq .getDiff0())); } /** * Adds a new difference to the list of changes. * * @param start * the begin index, inclusive * @param end * the end index, exclusive. * @param replacement * the replacement string */ // public void replace(int start, int end, String replacement) // { // changes.add(new ReplaceDifference(start, end, replacement)); // } /** * Class to handle an insertion */ private static class InsertDifference extends Difference { /** * Constructs a new InsertDifference * * @param index * index for the insertion * @param insertion * the string to insert */ InsertDifference(final int index, final String insertion) { // super(DifferenceOperation.INSERT, index, // index + insertion.length(), insertion); super(DifferenceOperation.INSERT, index, index + insertion.length()); } /** * {@inheritDoc} */ // @Override // public String toString() // { // return "Insert " + getReplacement() + " at " + getStart(); // } // @Override // protected StringBuffer applyStep(StringBuffer input) // { // return input.insert(getStart(), getStr()); // } /** * {@inheritDoc} */ @Override protected boolean inOriginal(final int currentIndex) { int start = this.getStart(); int end = this.getEnd(); return currentIndex < start || currentIndex > end; } /** * {@inheritDoc} */ @Override protected int getOriginalIndexStep_Private(final int currentIndex) { int newIndex = currentIndex; if (currentIndex > this.getStart()) { newIndex -= this.getLength(); } return newIndex; } } /** * Class to handle a deletion */ private static class DeleteDifference extends Difference { /** * Constructs a new DeleteDifference * * @param start * the begin index, inclusive * @param end * the end index, exclusive. */ DeleteDifference(final int start, final int end) { // super(DifferenceOperation.DELETE, start, end, ""); super(DifferenceOperation.DELETE, start, end); } /** * {@inheritDoc} */ // @Override // public String toString() // { // return "Delete " + getStart() + " to " + getEnd(); // } // @Override // protected StringBuffer applyStep(StringBuffer input) // { // return input.delete(getStart(), getEnd()); // } /** * {@inheritDoc} */ @Override protected int getOriginalIndexStep_Private(final int currentIndex) { int newIndex = currentIndex; if (currentIndex >= this.getStart()) { newIndex += this.getLength(); } return newIndex; } } /** * Class to handle a replacement */ /* *

* Unlike {@link ReplaceDifference}, the replacement is the insertions and * deletions to change the original string to the replacement string. *

*/ private static class ReplaceDifferencePlus extends Difference { /** * List of differences in this replacement */ private final Stack differences; /** * Constructs a new ReplaceDifferencePlus * * @param start * the begin index, inclusive * @param end * the end index, exclusive. * @param replacement * the replacement string * @param diff * the list of differences */ ReplaceDifferencePlus(final int start, final int end, final String replacement, final List diff) { // super(DifferenceOperation.REPLACE, start, end, replacement); super(DifferenceOperation.REPLACE, start, end); this.differences = new Stack<>(); int itemStart = start; for (String string : diff) { // -1 because the leading character ("+", "-", or " ") int length = string.length() - 1; if (string.charAt(0) == '+') { // insert this.differences.add(new InsertDifference(start, string .substring(1))); } else if (string.charAt(0) == '-') { // remove int itemEnd = start + length; this.differences.add(new DeleteDifference(itemStart, itemEnd)); } } } /** * {@inheritDoc} */ // @Override // public String toString() // { // return "Replace " + getStart() + " to " + getEnd() + " with " // + getReplacement() + "\t" + differences; // } // @Override // protected StringBuffer applyStep(StringBuffer input) // { // for (Difference difference : differences) { // difference.applyStep(input); // } // // return input; // } /** * {@inheritDoc} * * @throws IllegalArgumentException {@inheritDoc} */ @Override protected int getOriginalIndexStep_Private(final int currentIndex) { int newIndex = currentIndex; // go from the top of the stack, down (descending order) for (int i = this.differences.size() - 1; i >= 0; i--) { Difference difference = this.differences.get(i); newIndex = difference.getOriginalIndexStep(newIndex); } return newIndex; } } /** * Class to handle a replacement */ // private static class ReplaceDifference extends Difference // { // /** // * Constructs a new ReplaceDifferencePlus // * // * @param start // * the begin index, inclusive // * @param end // * the end index, exclusive. // * @param replacement // * the replacement string // */ // protected ReplaceDifference(int start, int end, String replacement) // { // super(DifferenceOperation.REPLACE, start, end, replacement); // } // // /** // * {@inheritDoc} // */ // // @Override // // public String toString() // // { // // return "Replace " + getStart() + " to " + getEnd() + " with " // // + getReplacement(); // // } // // // @Override // // protected StringBuffer applyStep(StringBuffer input) // // { // // return input.replace(getStart(), getEnd(), getStr()); // // } // // /** // * {@inheritDoc} // */ // @Override // protected boolean inOriginal(int currentIndex) // { // int start = getStart(); // int end = start + getReplacement().length(); // // return currentIndex < start || currentIndex > end; // } // // /** // * {@inheritDoc} // */ // @Override // protected int getOriginalIndexStep_Private(int currentIndex) // { // int newIndex = currentIndex; // // if (currentIndex > getStart()) // newIndex += getLength() - getReplacement().length(); // // return newIndex; // } // } /** * Abstract class for a difference */ private static abstract class Difference { /** * The difference operation for this difference */ private final DifferenceOperation diffOp; /** * The start index for the difference */ private final int start; /** * The end index for the difference */ private final int end; /** * The inserted string or replacement string */ // private final String replacement; /** * Constructor for an insertion * * @param diffOp * the difference operation for this difference * @param start * the start index for the difference * @param end * the end index for the difference */ // Difference(DifferenceOperation diffOp, int start, int end, // String replacement) /* * @param replacement * the inserted string or replacement string */ Difference(final DifferenceOperation diffOp, final int start, final int end) { this.diffOp = diffOp; this.start = start; this.end = end; // this.replacement = replacement; } /** * Returns the difference operation for this difference. * * @return the difference operation for this difference */ @SuppressWarnings("unused") public DifferenceOperation getDiffOp() { return this.diffOp; } /** * Returns the start index for the difference. * * @return the start index for the difference */ public int getStart() { return this.start; } /** * Returns the start index for the difference. * * @return the start index for the difference */ public int getEnd() { return this.end; } /** * Returns the length of the replacement * * @return the length of the replacement */ public int getLength() { return this.getEnd() - this.getStart(); } /** * Returns the inserted / replacement string * * @return the inserted / replacement string */ // public String getReplacement() // { // return this.replacement; // } /** * Returns a string representation of this difference. * * @return a string representation of this difference */ // @Override // public abstract String toString(); // protected abstract StringBuffer applyStep(StringBuffer input); /** * Returns whether the given index is in the original value. * * @param currentIndex * the current index * * @return whether the given index is in the original value */ protected boolean inOriginal(final int currentIndex) { return true; } /** * Returns the index prior to performing this difference. * * @param currentIndex * the current index * @return the offset by which this Difference affects the original * index * @throws IllegalArgumentException * If the specified index was not in the original string */ final int getOriginalIndexStep(final int currentIndex) { if (!this.inOriginal(currentIndex)) { throw new IllegalArgumentException( "The specified index was not in the original string"); } return this.getOriginalIndexStep_Private(currentIndex); } /** * Returns the index prior to performing this difference. * * @param currentIndex * the current index * @return the offset by which this Difference affects the * original index * @throws IllegalArgumentException * If the specified index was not in the original string */ protected abstract int getOriginalIndexStep_Private(int currentIndex); } /** * Enumeration of difference operations */ private static enum DifferenceOperation { /** * An insertion operation */ INSERT, /** * A deletion operation */ DELETE, /** * A replacement operation */ REPLACE } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy