diff --git a/source/org/apache/commons/jrcs/diff/AddDelta.java b/source/org/apache/commons/jrcs/diff/AddDelta.java
new file mode 100644
index 0000000..f116392
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/AddDelta.java
@@ -0,0 +1,131 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds an add-delta between to revisions of a text.
+ *
+ * @version $Id: AddDelta.java,v 1.1 2003/07/14 12:22:29 dchandler Exp $
+ * @author Juanco Anez
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class AddDelta
+ extends Delta
+{
+
+ AddDelta()
+ {
+ super();
+ }
+
+ public AddDelta(int origpos, Chunk rev)
+ {
+ init(new Chunk(origpos, 0), rev);
+ }
+
+ public void verify(List target) throws PatchFailedException
+ {
+ if (original.first() > target.size())
+ {
+ throw new PatchFailedException("original.first() > target.size()");
+ }
+ }
+
+ public void applyTo(List target)
+ {
+ revised.applyAdd(original.first(), target);
+ }
+
+ public void toString(StringBuffer s)
+ {
+ s.append(original.anchor());
+ s.append("a");
+ s.append(revised.rangeString());
+ s.append(Diff.NL);
+ revised.toString(s, "> ", Diff.NL);
+ }
+
+ public void toRCSString(StringBuffer s, String EOL)
+ {
+ s.append("a");
+ s.append(original.anchor());
+ s.append(" ");
+ s.append(revised.size());
+ s.append(EOL);
+ revised.toString(s, "", EOL);
+ }
+
+ public void Accept(RevisionVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ public void accept(RevisionVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+}
+
+
+
+
+
diff --git a/source/org/apache/commons/jrcs/diff/ChangeDelta.java b/source/org/apache/commons/jrcs/diff/ChangeDelta.java
new file mode 100644
index 0000000..d3194f5
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/ChangeDelta.java
@@ -0,0 +1,134 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds an change-delta between to revisions of a text.
+ *
+ * @version $Id: ChangeDelta.java,v 1.1 2003/07/14 12:22:29 dchandler Exp $
+ * @author Juanco Anez
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class ChangeDelta extends Delta
+{
+
+ ChangeDelta()
+ {
+ super();
+ }
+
+ public ChangeDelta(Chunk orig, Chunk rev)
+ {
+ init(orig, rev);
+ }
+
+ public void verify(List target) throws PatchFailedException
+ {
+ if (!original.verify(target))
+ {
+ throw new PatchFailedException();
+ }
+ if (original.first() > target.size())
+ {
+ throw new PatchFailedException("original.first() > target.size()");
+ }
+ }
+
+ public void applyTo(List target)
+ {
+ original.applyDelete(target);
+ revised.applyAdd(original.first(), target);
+ }
+
+ public void toString(StringBuffer s)
+ {
+ original.rangeString(s);
+ s.append("c");
+ revised.rangeString(s);
+ s.append(Diff.NL);
+ original.toString(s, "< ", "\n");
+ s.append("---");
+ s.append(Diff.NL);
+ revised.toString(s, "> ", "\n");
+ }
+
+ public void toRCSString(StringBuffer s, String EOL)
+ {
+ s.append("d");
+ s.append(original.rcsfrom());
+ s.append(" ");
+ s.append(original.size());
+ s.append(EOL);
+ s.append("a");
+ s.append(original.rcsto());
+ s.append(" ");
+ s.append(revised.size());
+ s.append(EOL);
+ revised.toString(s, "", EOL);
+ }
+
+ public void accept(RevisionVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+}
+
diff --git a/source/org/apache/commons/jrcs/diff/Chunk.java b/source/org/apache/commons/jrcs/diff/Chunk.java
new file mode 100644
index 0000000..250f478
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/Chunk.java
@@ -0,0 +1,357 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Holds a information about a parrt of the text involved in
+ * a differencing or patching operation.
+ *
+ * @version $Id: Chunk.java,v 1.1 2003/07/14 12:22:29 dchandler Exp $
+ * @author Juanco Anez
+ * @see Diff
+ * @see Delta
+ */
+public class Chunk
+ extends org.apache.commons.jrcs.util.ToString
+{
+
+ protected int anchor;
+
+ protected int count;
+
+ protected List chunk;
+
+ /**
+ * Creates a chunk that doesn't copy the original text.
+ * @param pos the start position in the text.
+ * @param count the size of the chunk.
+ */
+ public Chunk(int pos, int count)
+ {
+ this.anchor = pos;
+ this.count = (count >= 0 ? count : 0);
+ }
+
+ /**
+ * Creates a chunk and saves a copy the original chunk's text.
+ * @param iseq the original text.
+ * @param pos the start position in the text.
+ * @param count the size of the chunk.
+ */
+ public Chunk(Object[] iseq, int pos, int count)
+ {
+ this(pos, count);
+ chunk = slice(iseq, pos, count);
+ }
+
+ /**
+ * Creates a chunk that will be displaced in the resulting text,
+ * and saves a copy the original chunk's text.
+ * @param iseq the original text.
+ * @param pos the start position in the text.
+ * @param count the size of the chunk.
+ * @param offset the position the chunk should have in the resulting text.
+ */
+ public Chunk(Object[] iseq, int pos, int count, int offset)
+ {
+ this(offset, count);
+ chunk = slice(iseq, pos, count);
+ }
+
+ /**
+ * Creates a chunk and saves a copy the original chunk's text.
+ * @param iseq the original text.
+ * @param pos the start position in the text.
+ * @param count the size of the chunk.
+ */
+ public Chunk(List iseq, int pos, int count)
+ {
+ this(pos, count);
+ chunk = slice(iseq, pos, count);
+ }
+
+ /**
+ * Creates a chunk that will be displaced in the resulting text,
+ * and saves a copy the original chunk's text.
+ * @param iseq the original text.
+ * @param pos the start position in the text.
+ * @param count the size of the chunk.
+ * @param offset the position the chunk should have in the resulting text.
+ */
+ public Chunk(List iseq, int pos, int count, int offset)
+ {
+ this(offset, count);
+ chunk = slice(iseq, pos, count);
+ }
+
+ /**
+ * Returns the anchor position of the chunk.
+ * @return the anchor position.
+ */
+ public int anchor()
+ {
+ return anchor;
+ }
+
+ /**
+ * Returns the size of the chunk.
+ * @return the size.
+ */
+ public int size()
+ {
+ return count;
+ }
+
+ /**
+ * Returns the index of the first line of the chunk.
+ */
+ public int first()
+ {
+ return anchor();
+ }
+
+ /**
+ * Returns the index of the last line of the chunk.
+ */
+ public int last()
+ {
+ return anchor() + size() - 1;
+ }
+
+ /**
+ * Returns the from index of the chunk in RCS terms.
+ */
+ public int rcsfrom()
+ {
+ return anchor + 1;
+ }
+
+ /**
+ * Returns the to index of the chunk in RCS terms.
+ */
+ public int rcsto()
+ {
+ return anchor + count;
+ }
+
+ /**
+ * Returns the text saved for this chunk.
+ * @return the text.
+ */
+ public List chunk()
+ {
+ return chunk;
+ }
+
+ /**
+ * Verifies that this chunk's saved text matches the corresponding
+ * text in the given sequence.
+ * @param target the sequence to verify against.
+ * @return true if the texts match.
+ */
+ public boolean verify(List target)
+ {
+ if (chunk == null)
+ {
+ return true;
+ }
+ if (last() > target.size())
+ {
+ return false;
+ }
+ for (int i = 0; i < count; i++)
+ {
+ if (!target.get(anchor + i).equals(chunk.get(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Delete this chunk from he given text.
+ * @param target the text to delete from.
+ */
+ public void applyDelete(List target)
+ {
+ for (int i = last(); i >= first(); i--)
+ {
+ target.remove(i);
+ }
+ }
+
+ /**
+ * Add the text of this chunk to the target at the given position.
+ * @param start where to add the text.
+ * @param target the text to add to.
+ */
+ public void applyAdd(int start, List target)
+ {
+ Iterator i = chunk.iterator();
+ while (i.hasNext())
+ {
+ target.add(start++, i.next());
+ }
+ }
+
+ /**
+ * Provide a string image of the chunk using the an empty prefix and
+ * postfix.
+ */
+ public void toString(StringBuffer s)
+ {
+ toString(s, "", "");
+ }
+
+ /**
+ * Provide a string image of the chunk using the given prefix and
+ * postfix.
+ * @param s where the string image should be appended.
+ * @param prefix the text thatshould prefix each line.
+ * @param postfix the text that should end each line.
+ */
+ public StringBuffer toString(StringBuffer s, String prefix, String postfix)
+ {
+ if (chunk != null)
+ {
+ Iterator i = chunk.iterator();
+ while (i.hasNext())
+ {
+ s.append(prefix);
+ s.append(i.next());
+ s.append(postfix);
+ }
+ }
+ return s;
+ }
+
+ /**
+ * Retreives the specified part from a {@link List List}.
+ * @param seq the list to retreive a slice from.
+ * @param pos the start position.
+ * @param count the number of items in the slice.
+ * @return a {@link List List} containing the specified items.
+ */
+ public static List slice(List seq, int pos, int count)
+ {
+ if (count <= 0)
+ {
+ return new ArrayList(seq.subList(pos, pos));
+ }
+ else
+ {
+ return new ArrayList(seq.subList(pos, pos + count));
+ }
+ }
+
+ /**
+ * Retrieves a slice from an {@link Object Object} array.
+ * @param seq the list to retreive a slice from.
+ * @param pos the start position.
+ * @param count the number of items in the slice.
+ * @return a {@link List List} containing the specified items.
+ */
+ public static List slice(Object[] seq, int pos, int count)
+ {
+ return slice(Arrays.asList(seq), pos, count);
+ }
+
+ /**
+ * Provide a string representation of the numeric range of this chunk.
+ */
+ public String rangeString()
+ {
+ StringBuffer result = new StringBuffer();
+ rangeString(result);
+ return result.toString();
+ }
+
+ /**
+ * Provide a string representation of the numeric range of this chunk.
+ * @param s where the string representation should be appended.
+ */
+ public void rangeString(StringBuffer s)
+ {
+ rangeString(s, ",");
+ }
+
+ /**
+ * Provide a string representation of the numeric range of this chunk.
+ * @param s where the string representation should be appended.
+ * @param separ what to use as line separator.
+ */
+ public void rangeString(StringBuffer s, String separ)
+ {
+ if (size() <= 1)
+ {
+ s.append(Integer.toString(rcsfrom()));
+ }
+ else
+ {
+ s.append(Integer.toString(rcsfrom()));
+ s.append(separ);
+ s.append(Integer.toString(rcsto()));
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/DeleteDelta.java b/source/org/apache/commons/jrcs/diff/DeleteDelta.java
new file mode 100644
index 0000000..bafaa94
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/DeleteDelta.java
@@ -0,0 +1,121 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds a delete-delta between to revisions of a text.
+ *
+ * @version $Id: DeleteDelta.java,v 1.1 2003/07/14 12:22:29 dchandler Exp $
+ * @author Juanco Anez
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class DeleteDelta
+ extends Delta
+{
+
+ DeleteDelta()
+ {
+ super();
+ }
+
+ public DeleteDelta(Chunk orig)
+ {
+ init(orig, null);
+ }
+
+ public void verify(List target)
+ throws PatchFailedException
+ {
+ if (!original.verify(target))
+ {
+ throw new PatchFailedException();
+ }
+ }
+
+ public void applyTo(List target)
+ {
+ original.applyDelete(target);
+ }
+
+ public void toString(StringBuffer s)
+ {
+ s.append(original.rangeString());
+ s.append("d");
+ s.append(revised.rcsto());
+ s.append(Diff.NL);
+ original.toString(s, "< ", Diff.NL);
+ }
+
+ public void toRCSString(StringBuffer s, String EOL)
+ {
+ s.append("d");
+ s.append(original.rcsfrom());
+ s.append(" ");
+ s.append(original.size());
+ s.append(EOL);
+ }
+
+ public void accept(RevisionVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/Delta.java b/source/org/apache/commons/jrcs/diff/Delta.java
new file mode 100644
index 0000000..5f7243b
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/Delta.java
@@ -0,0 +1,255 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds a "delta" difference between to revisions of a text.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ *
+ * @author Juanco Anez
+ * @author Brian McBride
+ * @see Diff
+ * @see Chunk
+ * @see Revision
+ *
+ * modifications
+ *
+ * 27 Apr 2003 bwm
+ *
+ * Added getOriginal() and getRevised() accessor methods
+ * Added visitor pattern accept() method
+ */
+
+public abstract class Delta
+ extends org.apache.commons.jrcs.util.ToString
+{
+
+ protected Chunk original;
+
+ protected Chunk revised;
+
+ static Class[][] DeltaClass;
+
+ static
+ {
+ DeltaClass = new Class[2][2];
+ try
+ {
+ DeltaClass[0][0] = org.apache.commons.jrcs.diff.ChangeDelta.class;
+ DeltaClass[0][1] = org.apache.commons.jrcs.diff.AddDelta.class;
+ DeltaClass[1][0] = org.apache.commons.jrcs.diff.DeleteDelta.class;
+ DeltaClass[1][1] = org.apache.commons.jrcs.diff.ChangeDelta.class;
+ }
+ catch (Throwable o)
+ {
+
+ }
+ }
+
+ /**
+ * Returns a Delta that corresponds to the given chunks in the
+ * original and revised text respectively.
+ * @param orig the chunk in the original text.
+ * @param rev the chunk in the revised text.
+ */
+ public static Delta newDelta(Chunk orig, Chunk rev)
+ {
+ Class c = DeltaClass[orig.size() > 0 ? 1 : 0]
+ [rev.size() > 0 ? 1 : 0];
+ Delta result;
+ try
+ {
+ result = (Delta) c.newInstance();
+ }
+ catch (Throwable e)
+ {
+ return null;
+ }
+ result.init(orig, rev);
+ return result;
+ }
+
+ /**
+ * Creates an uninitialized delta.
+ */
+ protected Delta()
+ {
+ }
+
+ /**
+ * Creates a delta object with the given chunks from the original
+ * and revised texts.
+ */
+ protected Delta(Chunk orig, Chunk rev)
+ {
+ init(orig, rev);
+ }
+
+ /**
+ * Initializaes the delta with the given chunks from the original
+ * and revised texts.
+ */
+ protected void init(Chunk orig, Chunk rev)
+ {
+ original = orig;
+ revised = rev;
+ }
+
+ /**
+ * Verifies that this delta can be used to patch the given text.
+ * @param target the text to patch.
+ * @throws PatchFailedException if the patch cannot be applied.
+ */
+ public abstract void verify(List target)
+ throws PatchFailedException;
+
+ /**
+ * Applies this delta as a patch to the given text.
+ * @param target the text to patch.
+ * @throws PatchFailedException if the patch cannot be applied.
+ */
+ public final void patch(List target)
+ throws PatchFailedException
+ {
+ verify(target);
+ try
+ {
+ applyTo(target);
+ }
+ catch (Exception e)
+ {
+ throw new PatchFailedException(e.getMessage());
+ }
+ }
+
+ /**
+ * Applies this delta as a patch to the given text.
+ * @param target the text to patch.
+ * @throws PatchFailedException if the patch cannot be applied.
+ */
+ public abstract void applyTo(List target);
+
+ /**
+ * Converts this delta into its Unix diff style string representation.
+ * @param s a {@link StringBuffer StringBuffer} to which the string
+ * representation will be appended.
+ */
+ public void toString(StringBuffer s)
+ {
+ original.rangeString(s);
+ s.append("x");
+ revised.rangeString(s);
+ s.append(Diff.NL);
+ original.toString(s, "> ", "\n");
+ s.append("---");
+ s.append(Diff.NL);
+ revised.toString(s, "< ", "\n");
+ }
+
+ /**
+ * Converts this delta into its RCS style string representation.
+ * @param s a {@link StringBuffer StringBuffer} to which the string
+ * representation will be appended.
+ * @param EOL the string to use as line separator.
+ */
+ public abstract void toRCSString(StringBuffer s, String EOL);
+
+ /**
+ * Converts this delta into its RCS style string representation.
+ * @param EOL the string to use as line separator.
+ */
+ public String toRCSString(String EOL)
+ {
+ StringBuffer s = new StringBuffer();
+ toRCSString(s, EOL);
+ return s.toString();
+ }
+
+ /**
+ * Accessor method to return the chunk representing the original
+ * sequence of items
+ *
+ * @return the original sequence
+ */
+ public Chunk getOriginal()
+ {
+ return original;
+ }
+
+ /**
+ * Accessor method to return the chunk representing the updated
+ * sequence of items.
+ *
+ * @return the updated sequence
+ */
+ public Chunk getRevised()
+ {
+ return revised;
+ }
+
+ /**
+ * Accepts a visitor.
+ *
+ * See the Visitor pattern in "Design Patterns" by the GOF4.
+ * @param visitor The visitor.
+ */
+ public abstract void accept(RevisionVisitor visitor);
+}
diff --git a/source/org/apache/commons/jrcs/diff/Diff.java b/source/org/apache/commons/jrcs/diff/Diff.java
new file mode 100644
index 0000000..0353d26
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/Diff.java
@@ -0,0 +1,344 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.*;
+
+import org.apache.commons.jrcs.diff.myers.MyersDiff;
+import org.apache.commons.jrcs.util.ToString;
+
+/**
+ * Implements a differencing engine that works on arrays of {@link Object Object}.
+ *
+ *
Within this library, the word text means a unit of information
+ * subject to version control.
+ *
+ *
Text is represented as Object[]
because
+ * the diff engine is capable of handling more than plain ascci. In fact,
+ * arrays 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.
+ *
+ * This library provides a framework in which different differencing
+ * algorithms may be used. If no algorithm is specififed, a default
+ * algorithm is used.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ * @author Juanco Anez
+ * @see Delta
+ * @see DiffAlgorithm
+ *
+ * modifications:
+ *
+ * 27 Apr 2003 bwm
+ *
+ * Added some comments whilst trying to figure out the algorithm
+ *
+ * 03 May 2003 bwm
+ *
+ * Factored out the algorithm implementation into a separate difference
+ * algorithm class to allow pluggable algorithms.
+ */
+
+public class Diff
+ extends ToString
+{
+ /** The standard line separator. */
+ public static final String NL = System.getProperty("line.separator");
+
+ /** The line separator to use in RCS format output. */
+ public static final String RCS_EOL = "\n";
+
+ /** The original sequence. */
+ protected final Object[] orig;
+
+ /** The differencing algorithm to use. */
+ protected DiffAlgorithm algorithm;
+
+ /**
+ * Create a differencing object using the default algorithm
+ *
+ * @param the original text that will be compared
+ */
+ public Diff(Object[] original)
+ {
+ this(original, null);
+ }
+
+ /**
+ * Create a differencing object using the given algorithm
+ *
+ * @param o the original text which will be compared against
+ * @param algorithm the difference algorithm to use.
+ */
+ public Diff(Object[] original, DiffAlgorithm algorithm)
+ {
+ if (original == null)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ this.orig = original;
+ if (algorithm != null)
+ this.algorithm = algorithm;
+ else
+ this.algorithm = defaultAlgorithm();
+ }
+
+ protected DiffAlgorithm defaultAlgorithm()
+ {
+ return new MyersDiff();
+ }
+
+ /**
+ * compute the difference between an original and a revision.
+ *
+ * @param orig the original
+ * @param rev the revision to compare with the original.
+ * @return a Revision describing the differences
+ */
+ public static Revision diff(Object[] orig, Object[] rev)
+ throws DifferentiationFailedException
+ {
+ if (orig == null || rev == null)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ return diff(orig, rev, null);
+ }
+
+ /**
+ * compute the difference between an original and a revision.
+ *
+ * @param orig the original
+ * @param rev the revision to compare with the original.
+ * @param algorithm the difference algorithm to use
+ * @return a Revision describing the differences
+ */
+ public static Revision diff(Object[] orig, Object[] rev,
+ DiffAlgorithm algorithm)
+ throws DifferentiationFailedException
+ {
+ if (orig == null || rev == null)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ return new Diff(orig, algorithm).diff(rev);
+ }
+
+ /**
+ * compute the difference between the original and a revision.
+ *
+ * @param rev the revision to compare with the original.
+ * @return a Revision describing the differences
+ */
+ public Revision diff(Object[] rev)
+ throws DifferentiationFailedException
+ {
+ return algorithm.diff(orig, rev);
+ }
+
+ /**
+ * Compares the two input sequences.
+ * @param orig The original sequence.
+ * @param rev The revised sequence.
+ * @return true if the sequences are identical. False otherwise.
+ */
+ public static boolean compare(Object[] orig, Object[] rev)
+ {
+ if (orig.length != rev.length)
+ {
+ return false;
+ }
+ else
+ {
+ for (int i = 0; i < orig.length; i++)
+ {
+ if (!orig[i].equals(rev[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Converts an array of {@link Object Object} to a string
+ * using {@link Diff#NL Diff.NL}
+ * as the line separator.
+ * @param o the array of objects.
+ */
+ public static String arrayToString(Object[] o)
+ {
+ return arrayToString(o, Diff.NL);
+ }
+
+ /**
+ * Edits all of the items in the input sequence.
+ * @param text The input sequence.
+ * @return A sequence of the same length with all the lines
+ * differing from the corresponding ones in the input.
+ */
+ public static Object[] editAll(Object[] text)
+ {
+ Object[] result = new String[text.length];
+
+ for(int i = 0; i < text.length; i++)
+ result[i] = text[i] + " ";
+
+ return result;
+ }
+
+ /**
+ * Performs random edits on the input sequence. Useful for testing.
+ * @param text The input sequence.
+ * @return The sequence with random edits performed.
+ */
+ public static Object[] randomEdit(Object[] text)
+ {
+ return randomEdit(text, text.length);
+ }
+
+ /**
+ * Performs random edits on the input sequence. Useful for testing.
+ * @param text The input sequence.
+ * @param seed A seed value for the randomizer.
+ * @return The sequence with random edits performed.
+ */
+ public static Object[] randomEdit(Object[] text, long seed)
+ {
+ List result = new ArrayList(Arrays.asList(text));
+ Random r = new Random(seed);
+ int nops = r.nextInt(10);
+ for (int i = 0; i < nops; i++)
+ {
+ boolean del = r.nextBoolean();
+ int pos = r.nextInt(result.size() + 1);
+ int len = Math.min(result.size() - pos, 1 + r.nextInt(4));
+ if (del && result.size() > 0)
+ { // delete
+ result.subList(pos, pos + len).clear();
+ }
+ else
+ {
+ for (int k = 0; k < len; k++, pos++)
+ {
+ result.add(pos,
+ "[" + i + "] random edit[" + i + "][" + i + "]");
+ }
+ }
+ }
+ return result.toArray();
+ }
+
+ /**
+ * Shuffles around the items in the input sequence.
+ * @param text The input sequence.
+ * @return The shuffled sequence.
+ */
+ public static Object[] shuffle(Object[] text)
+ {
+ return shuffle(text, text.length);
+ }
+
+ /**
+ * Shuffles around the items in the input sequence.
+ * @param text The input sequence.
+ * @param seed A seed value for randomizing the suffle.
+ * @return The shuffled sequence.
+ */
+ public static Object[] shuffle(Object[] text, long seed)
+ {
+ List result = new ArrayList(Arrays.asList(text));
+ Collections.shuffle(result);
+ return result.toArray();
+ }
+
+ /**
+ * Generate a random sequence of the given size.
+ * @param The size of the sequence to generate.
+ * @return The generated sequence.
+ */
+ public static Object[] randomSequence(int size)
+ {
+ return randomSequence(size, size);
+ }
+
+ /**
+ * Generate a random sequence of the given size.
+ * @param The size of the sequence to generate.
+ * @param seed A seed value for randomizing the generation.
+ * @return The generated sequence.
+ */
+ public static Object[] randomSequence(int size, long seed)
+ {
+ Integer[] result = new Integer[size];
+ Random r = new Random(seed);
+ for(int i = 0; i < result.length; i++)
+ {
+ result[i] = new Integer(r.nextInt(size));
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/DiffAlgorithm.java b/source/org/apache/commons/jrcs/diff/DiffAlgorithm.java
new file mode 100644
index 0000000..bedd52c
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/DiffAlgorithm.java
@@ -0,0 +1,84 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * A simple interface for implementations of differencing algorithms.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ *
+ * @author Brian McBride
+ */
+public interface DiffAlgorithm
+{
+ /**
+ * Computes the difference between the original
+ * sequence and the revised sequence and returns it
+ * as a {@link org.apache.commons.jrcs.diff.Revision Revision}
+ * object.
+ *
+ * The revision can be used to construct the revised sequence
+ * from the original sequence.
+ *
+ * @param rev the revised text
+ * @return the revision script.
+ * @throws DifferentiationFailedException if the diff could not be computed.
+ */
+ public abstract Revision diff(Object[] orig, Object[] rev)
+ throws DifferentiationFailedException;
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/DiffException.java b/source/org/apache/commons/jrcs/diff/DiffException.java
new file mode 100644
index 0000000..069ff59
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/DiffException.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Base class for all exceptions emanating from this package.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ *
+ * @author Juanco Anez
+ */
+public class DiffException extends Exception
+{
+
+ public DiffException()
+ {
+ }
+
+ public DiffException(String msg)
+ {
+ super(msg);
+ }
+}
+
diff --git a/source/org/apache/commons/jrcs/diff/DifferentiationFailedException.java b/source/org/apache/commons/jrcs/diff/DifferentiationFailedException.java
new file mode 100644
index 0000000..e3dc004
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/DifferentiationFailedException.java
@@ -0,0 +1,82 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Thrown whenever the differencing engine cannot produce the differences
+ * between two revisions of ta text.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ *
+ * @author Juanco Anez
+ * @see Diff
+ * @see DiffAlgorithm
+ */
+public class DifferentiationFailedException extends DiffException
+{
+
+ public DifferentiationFailedException()
+ {
+ }
+
+ public DifferentiationFailedException(String msg)
+ {
+ super(msg);
+ }
+}
+
diff --git a/source/org/apache/commons/jrcs/diff/PatchFailedException.java b/source/org/apache/commons/jrcs/diff/PatchFailedException.java
new file mode 100644
index 0000000..3314794
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/PatchFailedException.java
@@ -0,0 +1,82 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Thrown whenever a delta cannot be applied as a patch to a given text.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ * @author Juanco Anez
+ * @see Delta
+ * @see Diff
+ */
+public class PatchFailedException extends DiffException
+{
+
+ public PatchFailedException()
+ {
+ }
+
+ public PatchFailedException(String msg)
+ {
+ super(msg);
+ }
+}
+
+
+
diff --git a/source/org/apache/commons/jrcs/diff/Revision.java b/source/org/apache/commons/jrcs/diff/Revision.java
new file mode 100644
index 0000000..d5c9a02
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/Revision.java
@@ -0,0 +1,253 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.jrcs.util.ToString;
+
+
+/**
+ * A Revision holds the series of deltas that describe the differences
+ * between two sequences.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ *
+ * @author Juanco Anez
+ * @author Brian McBride
+ *
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ * @see Revision
+ *
+ * modifications
+ * 27 Apr 2003 bwm
+ *
+ * Added visitor pattern Visitor interface and accept() method.
+ */
+
+public class Revision
+ extends ToString
+{
+
+ List deltas_ = new LinkedList();
+
+
+ /**
+ * Creates an empty Revision.
+ */
+ public Revision()
+ {
+ }
+
+
+ /**
+ * Adds a delta to this revision.
+ * @param delta the {@link Delta Delta} to add.
+ */
+ public synchronized void addDelta(Delta delta)
+ {
+ if (delta == null)
+ {
+ throw new IllegalArgumentException("new delta is null");
+ }
+ deltas_.add(delta);
+ }
+
+
+ /**
+ * Adds a delta to the start of this revision.
+ * @param delta the {@link Delta Delta} to add.
+ */
+ public synchronized void insertDelta(Delta delta)
+ {
+ if (delta == null)
+ {
+ throw new IllegalArgumentException("new delta is null");
+ }
+ deltas_.add(0, delta);
+ }
+
+
+ /**
+ * Retrieves a delta from this revision by position.
+ * @param i the position of the delta to retrieve.
+ * @return the specified delta
+ */
+ public Delta getDelta(int i)
+ {
+ return (Delta) deltas_.get(i);
+ }
+
+ /**
+ * Returns the number of deltas in this revision.
+ * @return the number of deltas.
+ */
+ public int size()
+ {
+ return deltas_.size();
+ }
+
+ /**
+ * Applies the series of deltas in this revision as patches to
+ * the given text.
+ * @param src the text to patch, which the method doesn't change.
+ * @return the resulting text after the patches have been applied.
+ * @throws PatchFailedException if any of the patches cannot be applied.
+ */
+ public Object[] patch(Object[] src) throws PatchFailedException
+ {
+ List target = new ArrayList(Arrays.asList(src));
+ applyTo(target);
+ return target.toArray();
+ }
+
+ /**
+ * Applies the series of deltas in this revision as patches to
+ * the given text.
+ * @param target the text to patch.
+ * @throws PatchFailedException if any of the patches cannot be applied.
+ */
+ public synchronized void applyTo(List target) throws PatchFailedException
+ {
+ ListIterator i = deltas_.listIterator(deltas_.size());
+ while (i.hasPrevious())
+ {
+ Delta delta = (Delta) i.previous();
+ delta.patch(target);
+ }
+ }
+
+ /**
+ * Converts this revision into its Unix diff style string representation.
+ * @param s a {@link StringBuffer StringBuffer} to which the string
+ * representation will be appended.
+ */
+ public synchronized void toString(StringBuffer s)
+ {
+ Iterator i = deltas_.iterator();
+ while (i.hasNext())
+ {
+ ((Delta) i.next()).toString(s);
+ }
+ }
+
+ /**
+ * Converts this revision into its RCS style string representation.
+ * @param s a {@link StringBuffer StringBuffer} to which the string
+ * representation will be appended.
+ * @param EOL the string to use as line separator.
+ */
+ public synchronized void toRCSString(StringBuffer s, String EOL)
+ {
+ Iterator i = deltas_.iterator();
+ while (i.hasNext())
+ {
+ ((Delta) i.next()).toRCSString(s, EOL);
+ }
+ }
+
+ /**
+ * Converts this revision into its RCS style string representation.
+ * @param s a {@link StringBuffer StringBuffer} to which the string
+ * representation will be appended.
+ */
+ public void toRCSString(StringBuffer s)
+ {
+ toRCSString(s, Diff.NL);
+ }
+
+ /**
+ * Converts this delta into its RCS style string representation.
+ * @param EOL the string to use as line separator.
+ */
+ public String toRCSString(String EOL)
+ {
+ StringBuffer s = new StringBuffer();
+ toRCSString(s, EOL);
+ return s.toString();
+ }
+
+ /**
+ * Converts this delta into its RCS style string representation
+ * using the default line separator.
+ */
+ public String toRCSString()
+ {
+ return toRCSString(Diff.NL);
+ }
+
+ /**
+ * Accepts a visitor.
+ * @param visitor the {@link Visitor} visiting this instance
+ */
+ public void accept(RevisionVisitor visitor) {
+ visitor.visit(this);
+ Iterator iter = deltas_.iterator();
+ while (iter.hasNext()) {
+ ((Delta) iter.next()).accept(visitor);
+ }
+ }
+
+}
diff --git a/source/org/apache/commons/jrcs/diff/RevisionVisitor.java b/source/org/apache/commons/jrcs/diff/RevisionVisitor.java
new file mode 100644
index 0000000..d7bd7ad
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/RevisionVisitor.java
@@ -0,0 +1,73 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Definition of a Visitor interface for {@link Revision Revisions}
+ * See "Design Patterns" by the Gang of Four
+ */
+public interface RevisionVisitor
+{
+ public void visit(Revision revision);
+
+ public void visit(DeleteDelta delta);
+
+ public void visit(ChangeDelta delta);
+
+ public void visit(AddDelta delta);
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/SimpleDiff.java b/source/org/apache/commons/jrcs/diff/SimpleDiff.java
new file mode 100644
index 0000000..2ae0608
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/SimpleDiff.java
@@ -0,0 +1,315 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.*;
+
+/**
+ * Implements a simple differencing algortithm.
+ *
+ * @date $Date: 2003/07/14 12:22:29 $
+ * @version $Revision: 1.1 $
+ * @author Juanco Anez
+ *
+ *
Overview of Algorithm
+ *
+ * by bwm
+ *
+ *
+ * The algorithm is optimised for situations where the input sequences
+ * have few repeated objects. If it is given input with many repeated
+ * objects it will report sub-optimal changes. However, given appropriate
+ * input, it is fast, and linear in memory usage.
+ *
+ * The algorithm consists of the following steps:
+ *
+ * - compute an equivalence set for the input data
+ * - translate each element of the orginal
+ * and revised input sequences to a member of the equivalence set
+ *
+ * - match the the input sequences to determine the deltas, i.e.
+ * the differences between the original and revised sequences.
+ *
+ *
+ * The first step is to compute a an equivalence set for the input data.
+ * The equivalence set is computed from objects that are in the original
+ * input sequence
+ *
+ * eq(x) = the index of the first occurence of x in the original sequence.
+ *
+ *
+ * With this equivalence function, the algorithm can compare integers rather
+ * than strings, which is considerably more efficient.
+ *
+ * The second step is to compute the datastructure on which the
+ * algorithm will operate. Having computed the equivalence function
+ * in the previous step, we can compute two arrays where
+ * indx[i] = eqs(orig[i]) and jndx[i] = eqs(rev[i]). The algorithm can
+ * now operate on indx and jndx instead of orig and rev. Thus, comparisons
+ * are then on O(int == int) instead of O(Object.equals(Object)).
+ *
+ *
+ * The algorithm now matches indx and jndx. Whilst indx[i] == jndx[i]
+ * it skips matching objects in the sequence. In seeking to match objects
+ * in the input sequence it assumes that each object is likely to be unique.
+ * It uses the known characteristics of the unique equivalence function. It can
+ * tell from the eq value if this object appeared in the other sequence
+ * at all. If it did not, there is no point in searching for a match.
+ *
+ * Recall that the eq function value is the index earliest occurrence in
+ * the orig sequence. This information is used to search efficiently for
+ * the next match. The algorithm is perfect when all input objects are
+ * unique, but degrades when input objects are not unique. When input
+ * objects are not unique an optimal match may not be found, but a
+ * correct match will be.
+ *
+ * Having identified common matching objects in the orig and revised
+ * sequences, the differences between them are easily computed.
+ *
+ *
+ * @see Delta
+ * @see Revision
+ * Modifications:
+ *
+ * 27/Apr/2003 bwm
+ * Added some comments whilst trying to figure out the algorithm
+ *
+ * 03 May 2003 bwm
+ * Created this implementation class by refactoring it out of the Diff
+ * class to enable plug in difference algorithms
+ *
+ */
+public class SimpleDiff
+ implements DiffAlgorithm
+{
+
+ static final int NOT_FOUND_i = -2;
+ static final int NOT_FOUND_j = -1;
+ static final int EOS = Integer.MAX_VALUE;
+
+ public SimpleDiff()
+ {
+ }
+
+ protected int scan(int[] ndx, int i, int target)
+ {
+ while (ndx[i] < target)
+ {
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * Compute the difference between original and revised sequences.
+ *
+ * @param orig The original sequence.
+ * @param rev The revised sequence to be compared with the original.
+ * @return A Revision object describing the differences.
+ * @throws DifferenciationFailedException if the diff could not be computed.
+ */
+ public Revision diff(Object[] orig, Object[] rev)
+ throws DifferentiationFailedException
+ {
+ // create map eqs, such that for each item in both orig and rev
+ // eqs(item) = firstOccurrence(item, orig);
+ Map eqs = buildEqSet(orig, rev);
+
+ // create an array such that
+ // indx[i] = NOT_FOUND_i if orig[i] is not in rev
+ // indx[i] = firstOccurrence(orig[i], orig)
+ int[] indx = buildIndex(eqs, orig, NOT_FOUND_i);
+
+ // create an array such that
+ // jndx[j] = NOT_FOUND_j if orig[j] is not in rev
+ // jndx[j] = firstOccurrence(rev[j], orig)
+ int[] jndx = buildIndex(eqs, rev, NOT_FOUND_j);
+
+ // what in effect has been done is to build a unique hash
+ // for each item that is in both orig and rev
+ // and to label each item in orig and new with that hash value
+ // or a marker that the item is not common to both.
+
+ eqs = null; // let gc know we're done with this
+
+ Revision deltas = new Revision(); //!!! new Revision()
+ int i = 0;
+ int j = 0;
+
+ // skip matching
+ // skip leading items that are equal
+ // could be written
+ // for (i=0; indx[i] != EOS && indx[i] == jndx[i]; i++);
+ // j = i;
+ for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++)
+ {
+ /* void */
+ }
+
+ while (indx[i] != jndx[j])
+ { // only equal if both == EOS
+ // they are different
+ int ia = i;
+ int ja = j;
+
+ // size of this delta
+ do
+ {
+ // look down rev for a match
+ // stop at a match
+ // or if the FO(rev[j]) > FO(orig[i])
+ // or at the end
+ while (jndx[j] < 0 || jndx[j] < indx[i])
+ {
+ j++;
+ }
+ // look down orig for a match
+ // stop at a match
+ // or if the FO(orig[i]) > FO(rev[j])
+ // or at the end
+ while (indx[i] < 0 || indx[i] < jndx[j])
+ {
+ i++;
+ }
+
+ // this doesn't do a compare each line with each other line
+ // so it won't find all matching lines
+ }
+ while (indx[i] != jndx[j]);
+
+ // on exit we have a match
+
+ // they are equal, reverse any exedent matches
+ // it is possible to overshoot, so count back matching items
+ while (i > ia && j > ja && indx[i - 1] == jndx[j - 1])
+ {
+ --i;
+ --j;
+ }
+
+ deltas.addDelta(Delta.newDelta(new Chunk(orig, ia, i - ia),
+ new Chunk(rev, ja, j - ja)));
+ // skip matching
+ for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++)
+ {
+ /* void */
+ }
+ }
+ return deltas;
+ }
+
+ /**
+ * create a Map
from each common item in orig and rev
+ * to the index of its first occurrence in orig
+ *
+ * @param orig the original sequence of items
+ * @param rev the revised sequence of items
+ */
+ protected Map buildEqSet(Object[] orig, Object[] rev)
+ {
+ // construct a set of the objects that orig and rev have in common
+
+ // first construct a set containing all the elements in orig
+ Set items = new HashSet(Arrays.asList(orig));
+
+ // then remove all those not in rev
+ items.retainAll(Arrays.asList(rev));
+
+ Map eqs = new HashMap();
+ for (int i = 0; i < orig.length; i++)
+ {
+ // if its a common item and hasn't been found before
+ if (items.contains(orig[i]))
+ {
+ // add it to the map
+ eqs.put(orig[i], new Integer(i));
+ // and make sure its not considered again
+ items.remove(orig[i]);
+ }
+ }
+ return eqs;
+ }
+
+ /**
+ * build a an array such each a[i] = eqs([i]) or NF if eqs([i]) undefined
+ *
+ * @param eqs a mapping from Object to Integer
+ * @param seq a sequence of objects
+ * @param NF the not found marker
+ */
+ protected int[] buildIndex(Map eqs, Object[] seq, int NF)
+ {
+ int[] result = new int[seq.length + 1];
+ for (int i = 0; i < seq.length; i++)
+ {
+ Integer value = (Integer) eqs.get(seq[i]);
+ if (value == null || value.intValue() < 0)
+ {
+ result[i] = NF;
+ }
+ else
+ {
+ result[i] = value.intValue();
+ }
+ }
+ result[seq.length] = EOS;
+ return result;
+ }
+
+}
diff --git a/source/org/apache/commons/jrcs/diff/myers/DiffNode.java b/source/org/apache/commons/jrcs/diff/myers/DiffNode.java
new file mode 100644
index 0000000..45fd8f0
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/myers/DiffNode.java
@@ -0,0 +1,57 @@
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ * Title:
+ * Description:
+ * Copyright: Copyright (c) 2002
+ * Company:
+ * @author not attributable
+ * @version 1.0
+ */
+
+/**
+ * A diffnode in a diffpath.
+ *
+ * A DiffNode and its previous node mark a delta between
+ * two input sequences, that is, two differing subsequences
+ * between (possibly zero length) matching sequences.
+ *
+ * {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression
+ * of diffpaths, as each snake is represented by a single {@link Snake Snake}
+ * node and each contiguous series of insertions and deletions is represented
+ * by a single {@link DiffNode DiffNodes}.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:29 $
+ * @author Juanco Anez
+ *
+ */
+public final class DiffNode
+ extends PathNode
+{
+ /**
+ * Constructs a DiffNode.
+ *
+ * DiffNodes are compressed. That means that
+ * the path pointed to by the prev
parameter
+ * will be followed using {@link PathNode#previousSnake}
+ * until a non-diff node is found.
+ *
+ * @param the position in the original sequence
+ * @param the position in the revised sequence
+ * @param prev the previous node in the path.
+ */
+ public DiffNode(int i, int j, PathNode prev)
+ {
+ super(i, j, (prev == null ? null : prev.previousSnake()) );
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return false, always
+ */
+ public boolean isSnake()
+ {
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/myers/MyersDiff.java b/source/org/apache/commons/jrcs/diff/myers/MyersDiff.java
new file mode 100644
index 0000000..32ebb1f
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/myers/MyersDiff.java
@@ -0,0 +1,222 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+import org.apache.commons.jrcs.diff.*;
+
+/**
+ * A clean-room implementation of
+ *
+ * Eugene Myers differencing algorithm.
+ *
+ * See the paper at
+ *
+ * http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:30 $
+ * @author Juanco Anez
+ * @see Delta
+ * @see Revision
+ * @see Diff
+ */
+public class MyersDiff
+ implements DiffAlgorithm
+{
+ /**
+ * Constructs an instance of the Myers differencing algorithm.
+ */
+ public MyersDiff()
+ {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Revision diff(Object[] orig, Object[] rev)
+ throws DifferentiationFailedException
+ {
+ PathNode path = buildPath(orig, rev);
+ return buildRevision(path, orig, rev);
+ }
+
+ /**
+ * Computes the minimum diffpath that expresses de differences
+ * between the original and revised sequences, according
+ * to Gene Myers differencing algorithm.
+ *
+ * @param orig The original sequence.
+ * @param rev The revised sequence.
+ * @return A minimum {@link PathNode Path} accross the differences graph.
+ * @throws DifferentiationFailedException if a diff path could not be found.
+ */
+ public static PathNode buildPath(Object[] orig, Object[] rev)
+ throws DifferentiationFailedException
+ {
+ if (orig == null)
+ throw new IllegalArgumentException("original sequence is null");
+ if (rev == null)
+ throw new IllegalArgumentException("revised sequence is null");
+
+ // these are local constants
+ final int N = orig.length;
+ final int M = rev.length;
+
+ final int MAX = N + M + 1;
+ final int size = 1 + 2 * MAX;
+ final int middle = (size + 1) / 2;
+ final PathNode diagonal[] = new PathNode[size];
+
+ PathNode path = null;
+
+ diagonal[middle + 1] = new Snake(0, -1, null);
+ for (int d = 0; d < MAX; d++)
+ {
+ for (int k = -d; k <= d; k += 2)
+ {
+ final int kmiddle = middle + k;
+ final int kplus = kmiddle + 1;
+ final int kminus = kmiddle - 1;
+ PathNode prev = null;
+
+ int i;
+ if ( (k == -d) ||
+ (k != d && diagonal[kminus].i < diagonal[kplus].i))
+ {
+ i = diagonal[kplus].i;
+ prev = diagonal[kplus];
+ }
+ else
+ {
+ i = diagonal[kminus].i + 1;
+ prev = diagonal[kminus];
+ }
+
+ diagonal[kminus] = null; // no longer used
+
+ int j = i - k;
+
+ PathNode node = new DiffNode(i, j, prev);
+
+ // orig and rev are zero-based
+ // but the algorithm is one-based
+ // that's why there's no +1 when indexing the sequences
+ while (i < N && j < M && orig[i].equals(rev[j]))
+ {
+ i++;
+ j++;
+ }
+ if (i > node.i)
+ node = new Snake(i, j, node);
+
+ diagonal[kmiddle] = node;
+
+ if (i >= N && j >= M)
+ {
+ return diagonal[kmiddle];
+ }
+ }
+ diagonal[middle+d-1] = null;
+
+ }
+ // According to Myers, this cannot happen
+ throw new DifferentiationFailedException("could not find a diff path");
+ }
+
+ /**
+ * Constructs a {@link Revision} from a difference path.
+ *
+ * @param path The path.
+ * @param orig The original sequence.
+ * @param rev The revised sequence.
+ * @return A {@link Revision} script corresponding to the path.
+ * @throws DifferentiationFailedException if a {@link Revision} could
+ * not be built from the given path.
+ */
+ public static Revision buildRevision(PathNode path, Object[] orig, Object[] rev)
+ {
+ if (path == null)
+ throw new IllegalArgumentException("path is null");
+ if (orig == null)
+ throw new IllegalArgumentException("original sequence is null");
+ if (rev == null)
+ throw new IllegalArgumentException("revised sequence is null");
+
+ Revision revision = new Revision();
+ if (path.isSnake())
+ path = path.prev;
+ while (path != null && path.prev != null && path.prev.j >= 0)
+ {
+ if(path.isSnake())
+ throw new IllegalStateException("bad diffpath: found snake when looking for diff");
+ int i = path.i;
+ int j = path.j;
+
+ path = path.prev;
+ int ianchor = path.i;
+ int janchor = path.j;
+
+ Delta delta = Delta.newDelta(new Chunk(orig, ianchor, i - ianchor),
+ new Chunk(rev, janchor, j - janchor));
+ revision.insertDelta(delta);
+ if (path.isSnake())
+ path = path.prev;
+ }
+ return revision;
+ }
+
+}
diff --git a/source/org/apache/commons/jrcs/diff/myers/PathNode.java b/source/org/apache/commons/jrcs/diff/myers/PathNode.java
new file mode 100644
index 0000000..99ba15a
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/myers/PathNode.java
@@ -0,0 +1,146 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ * A node in a diffpath.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:30 $
+ * @author Juanco Anez
+ *
+ * @see DiffNode
+ * @see Snake
+ *
+ */
+public abstract class PathNode
+{
+ /** Position in the original sequence. */
+ public final int i;
+ /** Position in the revised sequence. */
+ public final int j;
+ /** The previous node in the path. */
+ public final PathNode prev;
+
+ /**
+ * Concatenates a new path node with an existing diffpath.
+ * @param i The position in the original sequence for the new node.
+ * @param j The position in the revised sequence for the new node.
+ * @param prev The previous node in the path.
+ */
+ public PathNode(int i, int j, PathNode prev)
+ {
+ this.i = i;
+ this.j = j;
+ this.prev = prev;
+ }
+
+ /**
+ * Is this node a {@link Snake Snake node}?
+ * @return true if this is a {@link Snake Snake node}
+ */
+ public abstract boolean isSnake();
+
+ /**
+ * Is this a bootstrap node?
+ *
+ * In bottstrap nodes one of the two corrdinates is
+ * less than zero.
+ * @return tru if this is a bootstrap node.
+ */
+ public boolean isBootstrap()
+ {
+ return i < 0 || j < 0;
+ }
+
+ /**
+ * Skips sequences of {@link DiffNode DiffNodes} until a
+ * {@link Snake} or bootstrap node is found, or the end
+ * of the path is reached.
+ * @return The next first {@link Snake} or bootstrap node in the path, or
+ * null
+ * if none found.
+ */
+ public final PathNode previousSnake()
+ {
+ if (isBootstrap())
+ return null;
+ if (!isSnake() && prev != null)
+ return prev.previousSnake();
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer("[");
+ PathNode node = this;
+ while (node != null)
+ {
+ buf.append("(");
+ buf.append(Integer.toString(node.i));
+ buf.append(",");
+ buf.append(Integer.toString(node.j));
+ buf.append(")");
+ node = node.prev;
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/diff/myers/Snake.java b/source/org/apache/commons/jrcs/diff/myers/Snake.java
new file mode 100644
index 0000000..46c1d69
--- /dev/null
+++ b/source/org/apache/commons/jrcs/diff/myers/Snake.java
@@ -0,0 +1,97 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ * Represents a snake in a diffpath.
+ *
+ *
+ * {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression
+ * of diffpaths, as each snake is represented by a single {@link Snake Snake}
+ * node and each contiguous series of insertions and deletions is represented
+ * by a single {@link DiffNode DiffNodes}.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:30 $
+ * @author Juanco Anez
+ *
+ */
+public final class Snake
+ extends PathNode
+{
+ /**
+ * Constructs a snake node.
+ *
+ * @param the position in the original sequence
+ * @param the position in the revised sequence
+ * @param prev the previous node in the path.
+ */
+ public Snake(int i, int j, PathNode prev)
+ {
+ super(i, j, prev);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return true always
+ */
+ public boolean isSnake()
+ {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/source/org/apache/commons/jrcs/tools/JDiff.java b/source/org/apache/commons/jrcs/tools/JDiff.java
new file mode 100644
index 0000000..c41a847
--- /dev/null
+++ b/source/org/apache/commons/jrcs/tools/JDiff.java
@@ -0,0 +1,153 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.tools;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.jrcs.diff.Diff;
+import org.apache.commons.jrcs.diff.Revision;
+
+
+/**
+ * A program to compare two files.
+ *
JDiff produces the deltas between the two given files in Unix diff
+ * format.
+ *
+ * The program was written as a simple test of the
+ * {@linkplain org.apache.commons.jrcs.diff diff} package.
+ */
+public class JDiff
+{
+
+ static final String[] loadFile(String name) throws IOException
+ {
+ BufferedReader data = new BufferedReader(new FileReader(name));
+ List lines = new ArrayList();
+ String s;
+ while ((s = data.readLine()) != null)
+ {
+ lines.add(s);
+ }
+ return (String[])lines.toArray(new String[lines.size()]);
+ }
+
+ static final void usage(String name)
+ {
+ System.err.println("Usage: " + name + " file1 file2");
+ }
+
+ public static void main(String[] argv) throws Exception
+ {
+ if (argv.length < 2)
+ {
+ usage("JDiff");
+ System.exit(2); // THDL modification
+ }
+ else
+ {
+ Object[] orig = loadFile(argv[0]);
+ Object[] rev = loadFile(argv[1]);
+
+ Diff df = new Diff(orig);
+ Revision r = df.diff(rev);
+ if (r.size() == 0) // THDL modification
+ System.exit(0); // THDL modification
+
+ System.err.println("------");
+ System.out.print(r.toString());
+ System.err.println("------" + new Date());
+
+ try
+ {
+ Object[] reco = r.patch(orig);
+ //String recos = Diff.arrayToString(reco);
+ if (!Diff.compare(rev, reco))
+ {
+ System.err.println("INTERNAL ERROR:"
+ + "files differ after patching!");
+ }
+ }
+ catch (Throwable o)
+ {
+ System.out.println("Patch failed");
+ }
+ System.exit(1); // THDL modification
+ }
+ }
+
+ /** THDL modification -- returns the Revision that gets you from
+ file x to file y, or null on error. */
+ public static Revision getDiff(String x, String y)
+ {
+ try {
+ Object[] orig = loadFile(x);
+ Object[] rev = loadFile(y);
+
+ Diff df = new Diff(orig);
+ return df.diff(rev);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
+
diff --git a/source/org/apache/commons/jrcs/util/ToString.java b/source/org/apache/commons/jrcs/util/ToString.java
new file mode 100644
index 0000000..fda3240
--- /dev/null
+++ b/source/org/apache/commons/jrcs/util/ToString.java
@@ -0,0 +1,154 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.apache.commons.jrcs.util;
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * This class delegates handling of the to a StringBuffer based version.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003/07/14 12:22:30 $
+ * @author Juanco Anez
+ */
+public class ToString
+{
+ public ToString()
+ {
+ }
+
+ /**
+ * Default implementation of the
+ * {@link java.lang.Object#toString toString() } method that
+ * delegates work to a {@link java.lang.StringBuffer StringBuffer}
+ * base version.
+ */
+ public String toString()
+ {
+ StringBuffer s = new StringBuffer();
+ toString(s);
+ return s.toString();
+ }
+
+ /**
+ * Place a string image of the object in a StringBuffer.
+ * @param s the string buffer.
+ */
+ public void toString(StringBuffer s)
+ {
+ s.append(super.toString());
+ }
+
+
+
+ /**
+ * Breaks a string into an array of strings.
+ * Use the value of the line.separator
system property
+ * as the linebreak character.
+ * @param value the string to convert.
+ */
+ public static String[] stringToArray(String value)
+ {
+ BufferedReader reader = new BufferedReader(new StringReader(value));
+ List l = new LinkedList();
+ String s;
+ try
+ {
+ while ((s = reader.readLine()) != null)
+ {
+ l.add(s);
+ }
+ }
+ catch (java.io.IOException e)
+ {
+ }
+ return (String[]) l.toArray(new String[l.size()]);
+ }
+
+ /**
+ * Converts an array of {@link Object Object} to a string
+ * Use the value of the line.separator
system property
+ * the line separator.
+ * @param o the array of objects.
+ */
+ public static String arrayToString(Object[] o)
+ {
+ return arrayToString(o, System.getProperty("line.separator"));
+ }
+
+ /**
+ * Converts an array of {@link Object Object} to a string
+ * using the given line separator.
+ * @param o the array of objects.
+ * @param EOL the string to use as line separator.
+ */
+ public static String arrayToString(Object[] o, String EOL)
+ {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < o.length - 1; i++)
+ {
+ buf.append(o[i]);
+ buf.append(EOL);
+ }
+ buf.append(o[o.length - 1]);
+ return buf.toString();
+ }
+}
+