Merge remote-tracking branch 'origin/master' into simulator

This commit is contained in:
Nidhi Sawhney committed 2012-04-22 16:27:21 +02:00
commit 698ada3fb1
862 files changed
+250644 -249763

No files matched your search

@@ -1 +1 @@
bin/
bin/
+13 -13
View File
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.googlecode.java-diff-utils</artifactId>
<version>1.3.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.googlecode.java-diff-utils</artifactId>
<version>1.3.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
@@ -1,92 +1,92 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the change-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class ChangeDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public ChangeDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
*
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getRevised().getLines()) {
target.add(position + i, line);
i++;
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getOriginal().getLines()) {
target.add(position + i, line);
i++;
}
}
/**
* {@inheritDoc}
*/
public void verify(List<T> target) throws PatchFailedException {
getOriginal().verify(target);
if (getOriginal().getPosition() > target.size()) {
throw new PatchFailedException("Incorrect patch for delta: "
+ "delta original position > target size");
}
}
@Override
public String toString() {
return "[ChangeDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + " to " + getRevised().getLines() + "]";
}
@Override
public TYPE getType() {
return Delta.TYPE.CHANGE;
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the change-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class ChangeDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public ChangeDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
*
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getRevised().getLines()) {
target.add(position + i, line);
i++;
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
int i = 0;
for (T line : getOriginal().getLines()) {
target.add(position + i, line);
i++;
}
}
/**
* {@inheritDoc}
*/
public void verify(List<T> target) throws PatchFailedException {
getOriginal().verify(target);
if (getOriginal().getPosition() > target.size()) {
throw new PatchFailedException("Incorrect patch for delta: "
+ "delta original position > target size");
}
}
@Override
public String toString() {
return "[ChangeDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + " to " + getRevised().getLines() + "]";
}
@Override
public TYPE getType() {
return Delta.TYPE.CHANGE;
}
}
@@ -1,158 +1,158 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Arrays;
import java.util.List;
/**
* Holds the information about the part of text involved in the diff process
*
* <p>
* Text is represented as <code>Object[]</code> because the diff engine is
* capable of handling more than plain ascci. In fact, arrays or lists of any
* type that implements {@link java.lang.Object#hashCode hashCode()} and
* {@link java.lang.Object#equals equals()} correctly can be subject to
* differencing using this library.
* </p>
*
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
*/
public class Chunk<T> {
private final int position;
private List<T> lines;
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position
* the start position
* @param lines
* the affected lines
*/
public Chunk(int position, List<T> lines) {
this.position = position;
this.lines = lines;
}
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position
* the start position
* @param lines
* the affected lines
*/
public Chunk(int position, T[] lines) {
this.position = position;
this.lines = Arrays.asList(lines);
}
/**
* Verifies that this chunk's saved text matches the corresponding text in
* the given sequence.
*
* @param target
* the sequence to verify against.
*/
public void verify(List<T> target) throws PatchFailedException {
if (last() > target.size()) {
throw new PatchFailedException("Incorrect Chunk: the position of chunk > target size");
}
for (int i = 0; i < size(); i++) {
if (!target.get(position + i).equals(lines.get(i))) {
throw new PatchFailedException(
"Incorrect Chunk: the chunk content doesn't match the target");
}
}
}
/**
* @return the start position of chunk in the text
*/
public int getPosition() {
return position;
}
public void setLines(List<T> lines) {
this.lines = lines;
}
/**
* @return the affected lines
*/
public List<T> getLines() {
return lines;
}
public int size() {
return lines.size();
}
/**
* Returns the index of the last line of the chunk.
*/
public int last() {
return getPosition() + size() - 1;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
result = prime * result + position;
result = prime * result + size();
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
Chunk<T> other = (Chunk<T>) obj;
if (lines == null) {
if (other.lines != null)
return false;
} else if (!lines.equals(other.lines))
return false;
if (position != other.position)
return false;
return true;
}
@Override
public String toString() {
return "[position: " + position + ", size: " + size() + ", lines: " + lines + "]";
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Arrays;
import java.util.List;
/**
* Holds the information about the part of text involved in the diff process
*
* <p>
* Text is represented as <code>Object[]</code> because the diff engine is
* capable of handling more than plain ascci. In fact, arrays or lists of any
* type that implements {@link java.lang.Object#hashCode hashCode()} and
* {@link java.lang.Object#equals equals()} correctly can be subject to
* differencing using this library.
* </p>
*
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
*/
public class Chunk<T> {
private final int position;
private List<T> lines;
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position
* the start position
* @param lines
* the affected lines
*/
public Chunk(int position, List<T> lines) {
this.position = position;
this.lines = lines;
}
/**
* Creates a chunk and saves a copy of affected lines
*
* @param position
* the start position
* @param lines
* the affected lines
*/
public Chunk(int position, T[] lines) {
this.position = position;
this.lines = Arrays.asList(lines);
}
/**
* Verifies that this chunk's saved text matches the corresponding text in
* the given sequence.
*
* @param target
* the sequence to verify against.
*/
public void verify(List<T> target) throws PatchFailedException {
if (last() > target.size()) {
throw new PatchFailedException("Incorrect Chunk: the position of chunk > target size");
}
for (int i = 0; i < size(); i++) {
if (!target.get(position + i).equals(lines.get(i))) {
throw new PatchFailedException(
"Incorrect Chunk: the chunk content doesn't match the target");
}
}
}
/**
* @return the start position of chunk in the text
*/
public int getPosition() {
return position;
}
public void setLines(List<T> lines) {
this.lines = lines;
}
/**
* @return the affected lines
*/
public List<T> getLines() {
return lines;
}
public int size() {
return lines.size();
}
/**
* Returns the index of the last line of the chunk.
*/
public int last() {
return getPosition() + size() - 1;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
result = prime * result + position;
result = prime * result + size();
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
Chunk<T> other = (Chunk<T>) obj;
if (lines == null) {
if (other.lines != null)
return false;
} else if (!lines.equals(other.lines))
return false;
if (position != other.position)
return false;
return true;
}
@Override
public String toString() {
return "[position: " + position + ", size: " + size() + ", lines: " + lines + "]";
}
}
@@ -1,76 +1,76 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the delete-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class DeleteDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public DeleteDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
*
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = this.getRevised().getPosition();
List<T> lines = this.getOriginal().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
}
@Override
public TYPE getType() {
return Delta.TYPE.DELETE;
}
@Override
public void verify(List<T> target) throws PatchFailedException {
getOriginal().verify(target);
}
@Override
public String toString() {
return "[DeleteDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + "]";
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the delete-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class DeleteDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public DeleteDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
*
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = getOriginal().getPosition();
int size = getOriginal().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = this.getRevised().getPosition();
List<T> lines = this.getOriginal().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
}
@Override
public TYPE getType() {
return Delta.TYPE.DELETE;
}
@Override
public void verify(List<T> target) throws PatchFailedException {
getOriginal().verify(target);
}
@Override
public String toString() {
return "[DeleteDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getOriginal().getLines() + "]";
}
}
@@ -1,144 +1,144 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.*;
/**
* Describes the delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public abstract class Delta<T> {
private Chunk<T> original;
private Chunk<T> revised;
public enum TYPE {
CHANGE, DELETE, INSERT
}
/**
* Construct the delta for original and revised chunks
*
* @param original chunk describes the original text
* @param revised chunk describes the revised text
*/
public Delta(Chunk<T> original, Chunk<T> revised) {
this.original = original;
this.revised = revised;
}
/**
* 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<T> target) throws PatchFailedException;
/**
* Applies this delta as the patch for a given target
*
* @param target the given target
* @throws PatchFailedException
*/
public abstract void applyTo(List<T> target) throws PatchFailedException;
/**
* Cancel this delta for a given revised text. The action is opposite to
* patch.
*
* @param target the given revised text
*/
public abstract void restore(List<T> target);
/**
* Returns the type of delta
* @return the type enum
*/
public abstract TYPE getType();
/**
* @return the Chunk describing the original text
*/
public Chunk<T> getOriginal() {
return original;
}
/**
* @param original the Chunk describing the original text to set
*/
public void setOriginal(Chunk<T> original) {
this.original = original;
}
/**
* @return the Chunk describing the revised text
*/
public Chunk<T> getRevised() {
return revised;
}
/**
* @param revised the Chunk describing the revised text to set
*/
public void setRevised(Chunk<T> revised) {
this.revised = revised;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((original == null) ? 0 : original.hashCode());
result = prime * result + ((revised == null) ? 0 : revised.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
Delta<T> other = (Delta<T>) obj;
if (original == null) {
if (other.original != null)
return false;
} else if (!original.equals(other.original))
return false;
if (revised == null) {
if (other.revised != null)
return false;
} else if (!revised.equals(other.revised))
return false;
return true;
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.*;
/**
* Describes the delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public abstract class Delta<T> {
private Chunk<T> original;
private Chunk<T> revised;
public enum TYPE {
CHANGE, DELETE, INSERT
}
/**
* Construct the delta for original and revised chunks
*
* @param original chunk describes the original text
* @param revised chunk describes the revised text
*/
public Delta(Chunk<T> original, Chunk<T> revised) {
this.original = original;
this.revised = revised;
}
/**
* 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<T> target) throws PatchFailedException;
/**
* Applies this delta as the patch for a given target
*
* @param target the given target
* @throws PatchFailedException
*/
public abstract void applyTo(List<T> target) throws PatchFailedException;
/**
* Cancel this delta for a given revised text. The action is opposite to
* patch.
*
* @param target the given revised text
*/
public abstract void restore(List<T> target);
/**
* Returns the type of delta
* @return the type enum
*/
public abstract TYPE getType();
/**
* @return the Chunk describing the original text
*/
public Chunk<T> getOriginal() {
return original;
}
/**
* @param original the Chunk describing the original text to set
*/
public void setOriginal(Chunk<T> original) {
this.original = original;
}
/**
* @return the Chunk describing the revised text
*/
public Chunk<T> getRevised() {
return revised;
}
/**
* @param revised the Chunk describing the revised text to set
*/
public void setRevised(Chunk<T> revised) {
this.revised = revised;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((original == null) ? 0 : original.hashCode());
result = prime * result + ((revised == null) ? 0 : revised.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
Delta<T> other = (Delta<T>) obj;
if (original == null) {
if (other.original != null)
return false;
} else if (!original.equals(other.original))
return false;
if (revised == null) {
if (other.revised != null)
return false;
} else if (!revised.equals(other.revised))
return false;
return true;
}
}
@@ -1,44 +1,44 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* The general interface for computing diffs between two texts
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public interface DiffAlgorithm<T> {
/**
* Computes the difference between the original sequence and the revised
* sequence and returns it as a {@link difflib.Patch Patch} object.
*
* @param original the original text
* @param revised the revised text
* @return the patch
*/
public Patch<T> diff(T[] original, T[] revised);
/**
* Computes the difference between the original sequence and the revised
* sequence and returns it as a {@link difflib.Patch Patch} object.
*
* @param original the original text
* @param revised the revised text
* @return the patch
*/
public Patch<T> diff(Iterable<T> original, Iterable<T> revised);
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* The general interface for computing diffs between two texts
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public interface DiffAlgorithm<T> {
/**
* Computes the difference between the original sequence and the revised
* sequence and returns it as a {@link difflib.Patch Patch} object.
*
* @param original the original text
* @param revised the revised text
* @return the patch
*/
public Patch<T> diff(T[] original, T[] revised);
/**
* Computes the difference between the original sequence and the revised
* sequence and returns it as a {@link difflib.Patch Patch} object.
*
* @param original the original text
* @param revised the revised text
* @return the patch
*/
public Patch<T> diff(Iterable<T> original, Iterable<T> revised);
}
@@ -1,33 +1,33 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Base class for all exceptions emanating from this package.
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class DiffException extends Exception {
private static final long serialVersionUID = 1L;
public DiffException() {
}
public DiffException(String msg) {
super(msg);
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Base class for all exceptions emanating from this package.
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class DiffException extends Exception {
private static final long serialVersionUID = 1L;
public DiffException() {
}
public DiffException(String msg) {
super(msg);
}
}
@@ -1,131 +1,131 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Describes the diff row in form [tag, oldLine, newLine) for showing the
* difference between two texts
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class DiffRow {
private Tag tag;
private String oldLine;
private String newLine;
public DiffRow(Tag tag, String oldLine, String newLine) {
this.tag = tag;
this.oldLine = oldLine;
this.newLine = newLine;
}
public enum Tag {
INSERT, DELETE, CHANGE, EQUAL
}
/**
* @return the tag
*/
public Tag getTag() {
return tag;
}
/**
* @param tag the tag to set
*/
public void setTag(Tag tag) {
this.tag = tag;
}
/**
* @return the oldLine
*/
public String getOldLine() {
return oldLine;
}
/**
* @param oldLine the oldLine to set
*/
public void setOldLine(String oldLine) {
this.oldLine = oldLine;
}
/**
* @return the newLine
*/
public String getNewLine() {
return newLine;
}
/**
* @param newLine the newLine to set
*/
public void setNewLine(String newLine) {
this.newLine = newLine;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((newLine == null) ? 0 : newLine.hashCode());
result = prime * result + ((oldLine == null) ? 0 : oldLine.hashCode());
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DiffRow other = (DiffRow) obj;
if (newLine == null) {
if (other.newLine != null)
return false;
} else if (!newLine.equals(other.newLine))
return false;
if (oldLine == null) {
if (other.oldLine != null)
return false;
} else if (!oldLine.equals(other.oldLine))
return false;
if (tag == null) {
if (other.tag != null)
return false;
} else if (!tag.equals(other.tag))
return false;
return true;
}
public String toString() {
return "[" + this.tag + "," + this.oldLine + "," + this.newLine + "]";
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Describes the diff row in form [tag, oldLine, newLine) for showing the
* difference between two texts
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class DiffRow {
private Tag tag;
private String oldLine;
private String newLine;
public DiffRow(Tag tag, String oldLine, String newLine) {
this.tag = tag;
this.oldLine = oldLine;
this.newLine = newLine;
}
public enum Tag {
INSERT, DELETE, CHANGE, EQUAL
}
/**
* @return the tag
*/
public Tag getTag() {
return tag;
}
/**
* @param tag the tag to set
*/
public void setTag(Tag tag) {
this.tag = tag;
}
/**
* @return the oldLine
*/
public String getOldLine() {
return oldLine;
}
/**
* @param oldLine the oldLine to set
*/
public void setOldLine(String oldLine) {
this.oldLine = oldLine;
}
/**
* @return the newLine
*/
public String getNewLine() {
return newLine;
}
/**
* @param newLine the newLine to set
*/
public void setNewLine(String newLine) {
this.newLine = newLine;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((newLine == null) ? 0 : newLine.hashCode());
result = prime * result + ((oldLine == null) ? 0 : oldLine.hashCode());
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DiffRow other = (DiffRow) obj;
if (newLine == null) {
if (other.newLine != null)
return false;
} else if (!newLine.equals(other.newLine))
return false;
if (oldLine == null) {
if (other.oldLine != null)
return false;
} else if (!oldLine.equals(other.oldLine))
return false;
if (tag == null) {
if (other.tag != null)
return false;
} else if (!tag.equals(other.tag))
return false;
return true;
}
public String toString() {
return "[" + this.tag + "," + this.oldLine + "," + this.newLine + "]";
}
}
@@ -1,336 +1,336 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import difflib.myers.MyersDiff;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Implements the difference and patching engine
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @version 0.4.1
*/
public class DiffUtils {
private static Pattern unifiedDiffChunkRe =
Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
/**
* Compute the difference between the original and revised texts with default diff algorithm
*
* @param original the original text
* @param revised the revised text
* @return the patch describing the difference between the original and revised texts
*/
public static <T> Patch<T> diff(Iterable<T> original, Iterable<T> revised) {
return DiffUtils.diff(original, revised, new MyersDiff<T>());
}
/**
* Compute the difference between the original and revised texts with given diff algorithm
*
* @param original the original text
* @param revised the revised text
* @param algorithm the given algorithm
* @return the patch describing the difference between the original and revised texts
*/
public static <T> Patch<T> diff(Iterable<T> original, Iterable<T> revised, DiffAlgorithm<T> algorithm) {
return algorithm.diff(original, revised);
}
/**
* Patch the original text with given patch
*
* @param original the original text
* @param patch the given patch
* @return the revised text
* @throws PatchFailedException if can't apply patch
*/
public static <T> List<T> patch(List<T> original, Patch<T> patch) throws PatchFailedException {
return patch.applyTo(original);
}
/**
* Unpatch the revised text for a given patch
*
* @param revised the revised text
* @param patch the given patch
* @return the original text
*/
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
return patch.restore(revised);
}
/**
* Parse the given text in unified format and creates the list of deltas for it.
*
* @param diff the text in unified format
* @return the patch with deltas.
*/
public static Patch<String> parseUnifiedDiff(List<String> diff) {
boolean inPrelude = true;
List<Object[]> rawChunk = new ArrayList<Object[]>();
Patch<String> patch = new Patch<String>();
int old_ln = 0, new_ln = 0;
String tag;
String rest;
for (String line : diff) {
// Skip leading lines until after we've seen one starting with '+++'
if (inPrelude) {
if (line.startsWith("+++")) {
inPrelude = false;
}
continue;
}
Matcher m = unifiedDiffChunkRe.matcher(line);
if (m.find()) {
// Process the lines in the previous chunk
if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();
for (Object[] raw_line : rawChunk) {
tag = (String) raw_line[0];
rest = (String) raw_line[1];
if (tag.equals(" ") || tag.equals("-")) {
oldChunkLines.add(rest);
}
if (tag.equals(" ") || tag.equals("+")) {
newChunkLines.add(rest);
}
}
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines),
new Chunk<String>(new_ln - 1, newChunkLines)));
rawChunk.clear();
}
// Parse the @@ header
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
if (old_ln == 0) {
old_ln += 1;
}
if (new_ln == 0) {
new_ln += 1;
}
} else {
if (line.length() > 0) {
tag = line.substring(0, 1);
rest = line.substring(1);
if (tag.equals(" ") || tag.equals("+") || tag.equals("-")) {
rawChunk.add(new Object[]{tag, rest});
}
} else {
rawChunk.add(new Object[]{" ", ""});
}
}
}
// Process the lines in the last chunk
if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();
for (Object[] raw_line : rawChunk) {
tag = (String) raw_line[0];
rest = (String) raw_line[1];
if (tag.equals(" ") || tag.equals("-")) {
oldChunkLines.add(rest);
}
if (tag.equals(" ") || tag.equals("+")) {
newChunkLines.add(rest);
}
}
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines), new Chunk<String>(
new_ln - 1, newChunkLines)));
rawChunk.clear();
}
return patch;
}
/**
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing the Patch.
*
* @param original - Filename of the original (unrevised file)
* @param revised - Filename of the revised file
* @param originalLines - Lines of the original file
* @param patch - Patch created by the diff() function
* @param contextSize - number of lines of context output around each difference in the file.
* @return List of strings representing the Unified Diff representation of the Patch argument.
* @author Bill James (tankerbay@gmail.com)
*/
public static List<String> generateUnifiedDiff(String original, String revised,
List<String> originalLines, Patch<String> patch, int contextSize) {
if (!patch.getDeltas().isEmpty()) {
List<String> ret = new ArrayList<String>();
ret.add("--- " + original);
ret.add("+++ " + revised);
List<Delta<String>> patchDeltas = new ArrayList<Delta<String>>(patch.getDeltas());
// code outside the if block also works for single-delta issues.
List<Delta<String>> deltas = new ArrayList<Delta<String>>(); // current list of Delta's to process
Delta<String> delta = patchDeltas.get(0);
deltas.add(delta); // add the first Delta to the current set
// if there's more than 1 Delta, we may need to output them together
if (patchDeltas.size() > 1) {
for (int i = 1; i < patchDeltas.size(); i++) {
int position = delta.getOriginal().getPosition(); // store the current position of
// the first Delta
// Check if the next Delta is too close to the current position.
// And if it is, add it to the current set
Delta<String> nextDelta = patchDeltas.get(i);
if ((position + delta.getOriginal().size() + contextSize) >=
(nextDelta.getOriginal().getPosition() - contextSize)) {
deltas.add(nextDelta);
} else {
// if it isn't, output the current set,
// then create a new set and add the current Delta to it.
List<String> curBlock = processDeltas(originalLines, deltas, contextSize);
ret.addAll(curBlock);
deltas.clear();
deltas.add(nextDelta);
}
delta = nextDelta;
}
}
// don't forget to process the last set of Deltas
List<String> curBlock = processDeltas(originalLines, deltas, contextSize);
ret.addAll(curBlock);
return ret;
}
return new ArrayList<String>();
}
/**
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
*
* @param origLines - the lines of the original file
* @param deltas - the Deltas to be output as a single block
* @param contextSize - the number of lines of context to place around block
* @return
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> processDeltas(List<String> origLines, List<Delta<String>> deltas,
int contextSize) {
List<String> buffer = new ArrayList<String>();
int origTotal = 0; // counter for total lines output from Original
int revTotal = 0; // counter for total lines output from Original
int line;
Delta<String> curDelta = deltas.get(0);
// NOTE: +1 to overcome the 0-offset Position
int origStart = curDelta.getOriginal().getPosition() + 1 - contextSize;
if (origStart < 1) {
origStart = 1;
}
int revStart = curDelta.getRevised().getPosition() + 1 - contextSize;
if (revStart < 1) {
revStart = 1;
}
// find the start of the wrapper context code
int contextStart = curDelta.getOriginal().getPosition() - contextSize;
if (contextStart < 0) {
contextStart = 0; // clamp to the start of the file
}
// output the context before the first Delta
for (line = contextStart; line < curDelta.getOriginal().getPosition(); line++) { //
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
// output the first Delta
buffer.addAll(getDeltaText(curDelta));
origTotal += curDelta.getOriginal().getLines().size();
revTotal += curDelta.getRevised().getLines().size();
int deltaIndex = 1;
while (deltaIndex < deltas.size()) { // for each of the other Deltas
Delta<String> nextDelta = deltas.get(deltaIndex);
int intermediateStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
for (line = intermediateStart; line < nextDelta.getOriginal().getPosition(); line++) {
// output the code between the last Delta and this one
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
buffer.addAll(getDeltaText(nextDelta)); // output the Delta
origTotal += nextDelta.getOriginal().getLines().size();
revTotal += nextDelta.getRevised().getLines().size();
curDelta = nextDelta;
deltaIndex++;
}
// Now output the post-Delta context code, clamping the end of the file
contextStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
for (line = contextStart; (line < (contextStart + contextSize))
&& (line < origLines.size()); line++) {
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
// Create and insert the block header, conforming to the Unified Diff standard
StringBuffer header = new StringBuffer();
header.append("@@ -");
header.append(origStart);
header.append(",");
header.append(origTotal);
header.append(" +");
header.append(revStart);
header.append(",");
header.append(revTotal);
header.append(" @@");
buffer.add(0, header.toString());
return buffer;
}
/**
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
*
* @param delta - the Delta to output
* @return list of String lines of code.
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> getDeltaText(Delta<String> delta) {
List<String> buffer = new ArrayList<String>();
for (Object line : delta.getOriginal().getLines()) {
buffer.add("-" + line);
}
for (Object line : delta.getRevised().getLines()) {
buffer.add("+" + line);
}
return buffer;
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import difflib.myers.MyersDiff;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Implements the difference and patching engine
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
* @version 0.4.1
*/
public class DiffUtils {
private static Pattern unifiedDiffChunkRe =
Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@$");
/**
* Compute the difference between the original and revised texts with default diff algorithm
*
* @param original the original text
* @param revised the revised text
* @return the patch describing the difference between the original and revised texts
*/
public static <T> Patch<T> diff(Iterable<T> original, Iterable<T> revised) {
return DiffUtils.diff(original, revised, new MyersDiff<T>());
}
/**
* Compute the difference between the original and revised texts with given diff algorithm
*
* @param original the original text
* @param revised the revised text
* @param algorithm the given algorithm
* @return the patch describing the difference between the original and revised texts
*/
public static <T> Patch<T> diff(Iterable<T> original, Iterable<T> revised, DiffAlgorithm<T> algorithm) {
return algorithm.diff(original, revised);
}
/**
* Patch the original text with given patch
*
* @param original the original text
* @param patch the given patch
* @return the revised text
* @throws PatchFailedException if can't apply patch
*/
public static <T> List<T> patch(List<T> original, Patch<T> patch) throws PatchFailedException {
return patch.applyTo(original);
}
/**
* Unpatch the revised text for a given patch
*
* @param revised the revised text
* @param patch the given patch
* @return the original text
*/
public static <T> List<T> unpatch(List<T> revised, Patch<T> patch) {
return patch.restore(revised);
}
/**
* Parse the given text in unified format and creates the list of deltas for it.
*
* @param diff the text in unified format
* @return the patch with deltas.
*/
public static Patch<String> parseUnifiedDiff(List<String> diff) {
boolean inPrelude = true;
List<Object[]> rawChunk = new ArrayList<Object[]>();
Patch<String> patch = new Patch<String>();
int old_ln = 0, new_ln = 0;
String tag;
String rest;
for (String line : diff) {
// Skip leading lines until after we've seen one starting with '+++'
if (inPrelude) {
if (line.startsWith("+++")) {
inPrelude = false;
}
continue;
}
Matcher m = unifiedDiffChunkRe.matcher(line);
if (m.find()) {
// Process the lines in the previous chunk
if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();
for (Object[] raw_line : rawChunk) {
tag = (String) raw_line[0];
rest = (String) raw_line[1];
if (tag.equals(" ") || tag.equals("-")) {
oldChunkLines.add(rest);
}
if (tag.equals(" ") || tag.equals("+")) {
newChunkLines.add(rest);
}
}
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines),
new Chunk<String>(new_ln - 1, newChunkLines)));
rawChunk.clear();
}
// Parse the @@ header
old_ln = m.group(1) == null ? 1 : Integer.parseInt(m.group(1));
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
if (old_ln == 0) {
old_ln += 1;
}
if (new_ln == 0) {
new_ln += 1;
}
} else {
if (line.length() > 0) {
tag = line.substring(0, 1);
rest = line.substring(1);
if (tag.equals(" ") || tag.equals("+") || tag.equals("-")) {
rawChunk.add(new Object[]{tag, rest});
}
} else {
rawChunk.add(new Object[]{" ", ""});
}
}
}
// Process the lines in the last chunk
if (rawChunk.size() != 0) {
List<String> oldChunkLines = new ArrayList<String>();
List<String> newChunkLines = new ArrayList<String>();
for (Object[] raw_line : rawChunk) {
tag = (String) raw_line[0];
rest = (String) raw_line[1];
if (tag.equals(" ") || tag.equals("-")) {
oldChunkLines.add(rest);
}
if (tag.equals(" ") || tag.equals("+")) {
newChunkLines.add(rest);
}
}
patch.addDelta(new ChangeDelta<String>(new Chunk<String>(old_ln - 1, oldChunkLines), new Chunk<String>(
new_ln - 1, newChunkLines)));
rawChunk.clear();
}
return patch;
}
/**
* generateUnifiedDiff takes a Patch and some other arguments, returning the Unified Diff format text representing the Patch.
*
* @param original - Filename of the original (unrevised file)
* @param revised - Filename of the revised file
* @param originalLines - Lines of the original file
* @param patch - Patch created by the diff() function
* @param contextSize - number of lines of context output around each difference in the file.
* @return List of strings representing the Unified Diff representation of the Patch argument.
* @author Bill James (tankerbay@gmail.com)
*/
public static List<String> generateUnifiedDiff(String original, String revised,
List<String> originalLines, Patch<String> patch, int contextSize) {
if (!patch.getDeltas().isEmpty()) {
List<String> ret = new ArrayList<String>();
ret.add("--- " + original);
ret.add("+++ " + revised);
List<Delta<String>> patchDeltas = new ArrayList<Delta<String>>(patch.getDeltas());
// code outside the if block also works for single-delta issues.
List<Delta<String>> deltas = new ArrayList<Delta<String>>(); // current list of Delta's to process
Delta<String> delta = patchDeltas.get(0);
deltas.add(delta); // add the first Delta to the current set
// if there's more than 1 Delta, we may need to output them together
if (patchDeltas.size() > 1) {
for (int i = 1; i < patchDeltas.size(); i++) {
int position = delta.getOriginal().getPosition(); // store the current position of
// the first Delta
// Check if the next Delta is too close to the current position.
// And if it is, add it to the current set
Delta<String> nextDelta = patchDeltas.get(i);
if ((position + delta.getOriginal().size() + contextSize) >=
(nextDelta.getOriginal().getPosition() - contextSize)) {
deltas.add(nextDelta);
} else {
// if it isn't, output the current set,
// then create a new set and add the current Delta to it.
List<String> curBlock = processDeltas(originalLines, deltas, contextSize);
ret.addAll(curBlock);
deltas.clear();
deltas.add(nextDelta);
}
delta = nextDelta;
}
}
// don't forget to process the last set of Deltas
List<String> curBlock = processDeltas(originalLines, deltas, contextSize);
ret.addAll(curBlock);
return ret;
}
return new ArrayList<String>();
}
/**
* processDeltas takes a list of Deltas and outputs them together in a single block of Unified-Diff-format text.
*
* @param origLines - the lines of the original file
* @param deltas - the Deltas to be output as a single block
* @param contextSize - the number of lines of context to place around block
* @return
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> processDeltas(List<String> origLines, List<Delta<String>> deltas,
int contextSize) {
List<String> buffer = new ArrayList<String>();
int origTotal = 0; // counter for total lines output from Original
int revTotal = 0; // counter for total lines output from Original
int line;
Delta<String> curDelta = deltas.get(0);
// NOTE: +1 to overcome the 0-offset Position
int origStart = curDelta.getOriginal().getPosition() + 1 - contextSize;
if (origStart < 1) {
origStart = 1;
}
int revStart = curDelta.getRevised().getPosition() + 1 - contextSize;
if (revStart < 1) {
revStart = 1;
}
// find the start of the wrapper context code
int contextStart = curDelta.getOriginal().getPosition() - contextSize;
if (contextStart < 0) {
contextStart = 0; // clamp to the start of the file
}
// output the context before the first Delta
for (line = contextStart; line < curDelta.getOriginal().getPosition(); line++) { //
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
// output the first Delta
buffer.addAll(getDeltaText(curDelta));
origTotal += curDelta.getOriginal().getLines().size();
revTotal += curDelta.getRevised().getLines().size();
int deltaIndex = 1;
while (deltaIndex < deltas.size()) { // for each of the other Deltas
Delta<String> nextDelta = deltas.get(deltaIndex);
int intermediateStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
for (line = intermediateStart; line < nextDelta.getOriginal().getPosition(); line++) {
// output the code between the last Delta and this one
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
buffer.addAll(getDeltaText(nextDelta)); // output the Delta
origTotal += nextDelta.getOriginal().getLines().size();
revTotal += nextDelta.getRevised().getLines().size();
curDelta = nextDelta;
deltaIndex++;
}
// Now output the post-Delta context code, clamping the end of the file
contextStart = curDelta.getOriginal().getPosition()
+ curDelta.getOriginal().getLines().size();
for (line = contextStart; (line < (contextStart + contextSize))
&& (line < origLines.size()); line++) {
buffer.add(" " + origLines.get(line));
origTotal++;
revTotal++;
}
// Create and insert the block header, conforming to the Unified Diff standard
StringBuffer header = new StringBuffer();
header.append("@@ -");
header.append(origStart);
header.append(",");
header.append(origTotal);
header.append(" +");
header.append(revStart);
header.append(",");
header.append(revTotal);
header.append(" @@");
buffer.add(0, header.toString());
return buffer;
}
/**
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
*
* @param delta - the Delta to output
* @return list of String lines of code.
* @author Bill James (tankerbay@gmail.com)
*/
private static List<String> getDeltaText(Delta<String> delta) {
List<String> buffer = new ArrayList<String>();
for (Object line : delta.getOriginal().getLines()) {
buffer.add("-" + line);
}
for (Object line : delta.getRevised().getLines()) {
buffer.add("+" + line);
}
return buffer;
}
}
@@ -1,78 +1,78 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the add-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class InsertDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public InsertDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = this.getOriginal().getPosition();
List<T> lines = this.getRevised().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
}
@Override
public void verify(List<T> target) throws PatchFailedException {
if (getOriginal().getPosition() > target.size()) {
throw new PatchFailedException("Incorrect patch for delta: "
+ "delta original position > target size");
}
}
public TYPE getType() {
return Delta.TYPE.INSERT;
}
@Override
public String toString() {
return "[InsertDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getRevised().getLines() + "]";
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.List;
/**
* Describes the add-delta between original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class InsertDelta<T> extends Delta<T> {
/**
* {@inheritDoc}
*/
public InsertDelta(Chunk<T> original, Chunk<T> revised) {
super(original, revised);
}
/**
* {@inheritDoc}
* @throws PatchFailedException
*/
@Override
public void applyTo(List<T> target) throws PatchFailedException {
verify(target);
int position = this.getOriginal().getPosition();
List<T> lines = this.getRevised().getLines();
for (int i = 0; i < lines.size(); i++) {
target.add(position + i, lines.get(i));
}
}
/**
* {@inheritDoc}
*/
@Override
public void restore(List<T> target) {
int position = getRevised().getPosition();
int size = getRevised().size();
for (int i = 0; i < size; i++) {
target.remove(position);
}
}
@Override
public void verify(List<T> target) throws PatchFailedException {
if (getOriginal().getPosition() > target.size()) {
throw new PatchFailedException("Incorrect patch for delta: "
+ "delta original position > target size");
}
}
public TYPE getType() {
return Delta.TYPE.INSERT;
}
@Override
public String toString() {
return "[InsertDelta, position: " + getOriginal().getPosition() + ", lines: "
+ getRevised().getLines() + "]";
}
}
@@ -1,109 +1,109 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
* Describes the patch holding all deltas between the original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class Patch<T> {
private List<Delta<T>> deltas = new LinkedList<Delta<T>>();
/**
* Apply this patch to the given target, producing a new list as result
* @return the patched text
* @throws PatchFailedException if can't apply patch
*/
public List<T> applyTo(List<T> target) throws PatchFailedException {
List<T> result = new LinkedList<T>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.applyTo(result);
}
return result;
}
/**
* Apply this patch to the given target in-place, updating the <code>target</code> list
* @return the patched text
* @throws PatchFailedException if can't apply patch
*/
public List<T> applyToInPlace(List<T> target) throws PatchFailedException {
List<T> result = target;
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.applyTo(result);
}
return result;
}
/**
* Restore the text to original. Opposite to applyTo() method.
* @param target the given target
* @return the restored text
*/
public List<T> restore(List<T> target) {
List<T> result = new LinkedList<T>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.restore(result);
}
return result;
}
/**
* Add the given delta to this patch
* @param delta the given delta
*/
public void addDelta(Delta<T> delta) {
deltas.add(delta);
}
/**
* Get the list of computed deltas
* @return the deltas
*/
public List<Delta<T>> getDeltas() {
Collections.sort(deltas, new DeltaComparator<T>());
return deltas;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append('[');
boolean first = true;
for (Delta<T> delta : getDeltas()) {
if (first) {
first = false;
} else {
result.append(", ");
}
result.append(delta);
}
result.append(']');
return result.toString();
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
* Describes the patch holding all deltas between the original and revised texts.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
public class Patch<T> {
private List<Delta<T>> deltas = new LinkedList<Delta<T>>();
/**
* Apply this patch to the given target, producing a new list as result
* @return the patched text
* @throws PatchFailedException if can't apply patch
*/
public List<T> applyTo(List<T> target) throws PatchFailedException {
List<T> result = new LinkedList<T>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.applyTo(result);
}
return result;
}
/**
* Apply this patch to the given target in-place, updating the <code>target</code> list
* @return the patched text
* @throws PatchFailedException if can't apply patch
*/
public List<T> applyToInPlace(List<T> target) throws PatchFailedException {
List<T> result = target;
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.applyTo(result);
}
return result;
}
/**
* Restore the text to original. Opposite to applyTo() method.
* @param target the given target
* @return the restored text
*/
public List<T> restore(List<T> target) {
List<T> result = new LinkedList<T>(target);
ListIterator<Delta<T>> it = getDeltas().listIterator(deltas.size());
while (it.hasPrevious()) {
Delta<T> delta = it.previous();
delta.restore(result);
}
return result;
}
/**
* Add the given delta to this patch
* @param delta the given delta
*/
public void addDelta(Delta<T> delta) {
deltas.add(delta);
}
/**
* Get the list of computed deltas
* @return the deltas
*/
public List<Delta<T>> getDeltas() {
Collections.sort(deltas, new DeltaComparator<T>());
return deltas;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append('[');
boolean first = true;
for (Delta<T> delta : getDeltas()) {
if (first) {
first = false;
} else {
result.append(", ");
}
result.append(delta);
}
result.append(']');
return result.toString();
}
}
@@ -1,33 +1,33 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Thrown whenever a delta cannot be applied as a patch to a given text.
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class PatchFailedException extends DiffException {
private static final long serialVersionUID = 1L;
public PatchFailedException() {
}
public PatchFailedException(String msg) {
super(msg);
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
/**
* Thrown whenever a delta cannot be applied as a patch to a given text.
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class PatchFailedException extends DiffException {
private static final long serialVersionUID = 1L;
public PatchFailedException() {
}
public PatchFailedException(String msg) {
super(msg);
}
}
@@ -1,83 +1,83 @@
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class StringUtills {
public static <T> String join(final Iterable<T> objs, final String delimiter) {
Iterator<T> iter = objs.iterator();
if (!iter.hasNext()) {
return "";
}
StringBuffer buffer = new StringBuffer(String.valueOf(iter.next()));
while (iter.hasNext()) {
buffer.append(delimiter).append(String.valueOf(iter.next()));
}
return buffer.toString();
}
public static String expandTabs(String str) {
return str.replace("\t", " ");
}
public static String htmlEntites(String str) {
return str.replace("<", "&lt;").replace(">", "&gt;");
}
public static String normalize(String str) {
return expandTabs(htmlEntites(str));
}
public static List<String> normalize(List<String> list) {
List<String> result = new LinkedList<String>();
for (String line : list) {
result.add(normalize(line));
}
return result;
}
public static List<String> wrapText(List<String> list, int columnWidth) {
List<String> result = new LinkedList<String>();
for (String line : list) {
result.add(wrapText(line, columnWidth));
}
return result;
}
/**
* Wrap the text with the given column width
* @param line the text
* @param columnWidth the given column
* @return the wrapped text
*/
public static String wrapText(String line, int columnWidth) {
int lenght = line.length();
int delimiter = "<br>".length();
int widthIndex = columnWidth;
for (int count = 0; lenght > widthIndex; count++) {
line = line.subSequence(0, widthIndex + delimiter * count) + "<br>"
+ line.substring(widthIndex + delimiter * count);
widthIndex += columnWidth;
}
return line;
}
}
/*
Copyright 2010 Dmitry Naumenko (dm.naumenko@gmail.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class StringUtills {
public static <T> String join(final Iterable<T> objs, final String delimiter) {
Iterator<T> iter = objs.iterator();
if (!iter.hasNext()) {
return "";
}
StringBuffer buffer = new StringBuffer(String.valueOf(iter.next()));
while (iter.hasNext()) {
buffer.append(delimiter).append(String.valueOf(iter.next()));
}
return buffer.toString();
}
public static String expandTabs(String str) {
return str.replace("\t", " ");
}
public static String htmlEntites(String str) {
return str.replace("<", "&lt;").replace(">", "&gt;");
}
public static String normalize(String str) {
return expandTabs(htmlEntites(str));
}
public static List<String> normalize(List<String> list) {
List<String> result = new LinkedList<String>();
for (String line : list) {
result.add(normalize(line));
}
return result;
}
public static List<String> wrapText(List<String> list, int columnWidth) {
List<String> result = new LinkedList<String>();
for (String line : list) {
result.add(wrapText(line, columnWidth));
}
return result;
}
/**
* Wrap the text with the given column width
* @param line the text
* @param columnWidth the given column
* @return the wrapped text
*/
public static String wrapText(String line, int columnWidth) {
int lenght = line.length();
int delimiter = "<br>".length();
int widthIndex = columnWidth;
for (int count = 0; lenght > widthIndex; count++) {
line = line.subSequence(0, widthIndex + delimiter * count) + "<br>"
+ line.substring(widthIndex + delimiter * count);
widthIndex += columnWidth;
}
return line;
}
}
@@ -1,77 +1,77 @@
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Base class for all exceptions emanating from this package.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class DiffException extends Exception {
private static final long serialVersionUID = 1L;
public DiffException() {
}
public DiffException(String msg) {
super(msg);
}
}
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Base class for all exceptions emanating from this package.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class DiffException extends Exception {
private static final long serialVersionUID = 1L;
public DiffException() {
}
public DiffException(String msg) {
super(msg);
}
}
@@ -1,53 +1,53 @@
package difflib.myers;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
/**
* A diffnode in a diffpath.
* <p>
* 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: 60 $ $Date: 2003-05-10 21:56:10 +0300 (Суб, 10 Май 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
*/
public final class DiffNode extends PathNode {
/**
* Constructs a DiffNode.
* <p>
* DiffNodes are compressed. That means that
* the path pointed to by the <code>prev</code> 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;
}
package difflib.myers;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
/**
* A diffnode in a diffpath.
* <p>
* 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: 60 $ $Date: 2003-05-10 21:56:10 +0300 (Суб, 10 Май 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
*/
public final class DiffNode extends PathNode {
/**
* Constructs a DiffNode.
* <p>
* DiffNodes are compressed. That means that
* the path pointed to by the <code>prev</code> 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;
}
}
@@ -1,79 +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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Thrown whenever the differencing engine cannot produce the differences
* between two revisions of ta text.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
* @see MyersDiff
* @see difflib.DiffAlgorithm
*/
public class DifferentiationFailedException extends DiffException {
private static final long serialVersionUID = 1L;
public DifferentiationFailedException() {
}
public DifferentiationFailedException(String msg) {
super(msg);
}
}
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Thrown whenever the differencing engine cannot produce the differences
* between two revisions of ta text.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
* @see MyersDiff
* @see difflib.DiffAlgorithm
*/
public class DifferentiationFailedException extends DiffException {
private static final long serialVersionUID = 1L;
public DifferentiationFailedException() {
}
public DifferentiationFailedException(String msg) {
super(msg);
}
}
@@ -1,270 +1,270 @@
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import difflib.ChangeDelta;
import difflib.Chunk;
import difflib.DeleteDelta;
import difflib.Delta;
import difflib.DiffAlgorithm;
import difflib.InsertDelta;
import difflib.Patch;
/**
* A clean-room implementation of <a href="http://www.cs.arizona.edu/people/gene/">
* Eugene Myers</a> differencing algorithm.
*
* <p> See the paper at <a href="http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps">
* http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps</a></p>
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class MyersDiff<T> implements DiffAlgorithm<T> {
/**
* Constructs an instance of the Myers differencing algorithm.
*/
public MyersDiff() {
}
/**
* {@inheritDoc}
*
* Return empty diff if get the error while procession the difference.
*/
public Patch<T> diff(Iterable<T> original, Iterable<T> revised) {
List<T> originalList = new ArrayList<T>();
for (T o : original) {
originalList.add(o);
}
@SuppressWarnings("unchecked")
T[] originalArray = (T[]) originalList.toArray();
List<T> revisedList = new ArrayList<T>();
for (T o : revised) {
revisedList.add(o);
}
@SuppressWarnings("unchecked")
T[] revisedArray = (T[]) revisedList.toArray();
return diff(originalArray, revisedArray);
}
/**
* {@inheritDoc}
*
* Return empty diff if get the error while procession the difference.
*/
public Patch<T> diff(T[] orig, T[] rev) {
PathNode path;
try {
path = buildPath(orig, rev);
return buildRevision(path, orig, rev);
} catch (DifferentiationFailedException e) {
e.printStackTrace();
}
return new Patch<T>();
}
/**
* 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 / 2;
final PathNode diagonal[] = new PathNode[size];
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 Patch} from a difference path.
*
* @param path The path.
* @param orig The original sequence.
* @param rev The revised sequence.
* @return A {@link Patch} script corresponding to the path.
* @throws DifferentiationFailedException if a {@link Patch} could
* not be built from the given path.
*/
public static <T> Patch<T> buildRevision(PathNode path, T[] orig, T[] 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");
Patch<T> patch = new Patch<T>();
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;
Chunk<T> original = new Chunk<T>(ianchor, copyOfRange(orig, ianchor, i));
Chunk<T> revised = new Chunk<T>(janchor, copyOfRange(rev, janchor, j));
Delta<T> delta = null;
if (original.size() == 0 && revised.size() != 0) {
delta = new InsertDelta<T>(original, revised);
} else if (original.size() > 0 && revised.size() == 0) {
delta = new DeleteDelta<T>(original, revised);
} else {
delta = new ChangeDelta<T>(original, revised);
}
patch.addDelta(delta);
if (path.isSnake())
path = path.prev;
}
return patch;
}
/**
* Copied here from JDK 1.6
*/
@SuppressWarnings("unchecked")
public static <T> T[] copyOfRange(T[] original, int from, int to) {
return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
}
/**
* Copied here from JDK 1.6
*/
@SuppressWarnings("unchecked")
public static <T, U> T[] copyOfRange(U[] original, int from, int to,
Class<? extends T[]> newType) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
T[] copy = ((Object) newType == (Object) Object[].class) ? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
return copy;
}
}
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import difflib.ChangeDelta;
import difflib.Chunk;
import difflib.DeleteDelta;
import difflib.Delta;
import difflib.DiffAlgorithm;
import difflib.InsertDelta;
import difflib.Patch;
/**
* A clean-room implementation of <a href="http://www.cs.arizona.edu/people/gene/">
* Eugene Myers</a> differencing algorithm.
*
* <p> See the paper at <a href="http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps">
* http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps</a></p>
*
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*/
public class MyersDiff<T> implements DiffAlgorithm<T> {
/**
* Constructs an instance of the Myers differencing algorithm.
*/
public MyersDiff() {
}
/**
* {@inheritDoc}
*
* Return empty diff if get the error while procession the difference.
*/
public Patch<T> diff(Iterable<T> original, Iterable<T> revised) {
List<T> originalList = new ArrayList<T>();
for (T o : original) {
originalList.add(o);
}
@SuppressWarnings("unchecked")
T[] originalArray = (T[]) originalList.toArray();
List<T> revisedList = new ArrayList<T>();
for (T o : revised) {
revisedList.add(o);
}
@SuppressWarnings("unchecked")
T[] revisedArray = (T[]) revisedList.toArray();
return diff(originalArray, revisedArray);
}
/**
* {@inheritDoc}
*
* Return empty diff if get the error while procession the difference.
*/
public Patch<T> diff(T[] orig, T[] rev) {
PathNode path;
try {
path = buildPath(orig, rev);
return buildRevision(path, orig, rev);
} catch (DifferentiationFailedException e) {
e.printStackTrace();
}
return new Patch<T>();
}
/**
* 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 / 2;
final PathNode diagonal[] = new PathNode[size];
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 Patch} from a difference path.
*
* @param path The path.
* @param orig The original sequence.
* @param rev The revised sequence.
* @return A {@link Patch} script corresponding to the path.
* @throws DifferentiationFailedException if a {@link Patch} could
* not be built from the given path.
*/
public static <T> Patch<T> buildRevision(PathNode path, T[] orig, T[] 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");
Patch<T> patch = new Patch<T>();
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;
Chunk<T> original = new Chunk<T>(ianchor, copyOfRange(orig, ianchor, i));
Chunk<T> revised = new Chunk<T>(janchor, copyOfRange(rev, janchor, j));
Delta<T> delta = null;
if (original.size() == 0 && revised.size() != 0) {
delta = new InsertDelta<T>(original, revised);
} else if (original.size() > 0 && revised.size() == 0) {
delta = new DeleteDelta<T>(original, revised);
} else {
delta = new ChangeDelta<T>(original, revised);
}
patch.addDelta(delta);
if (path.isSnake())
path = path.prev;
}
return patch;
}
/**
* Copied here from JDK 1.6
*/
@SuppressWarnings("unchecked")
public static <T> T[] copyOfRange(T[] original, int from, int to) {
return copyOfRange(original, from, to, (Class<T[]>) original.getClass());
}
/**
* Copied here from JDK 1.6
*/
@SuppressWarnings("unchecked")
public static <T, U> T[] copyOfRange(U[] original, int from, int to,
Class<? extends T[]> newType) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
T[] copy = ((Object) newType == (Object) Object[].class) ? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
return copy;
}
}
@@ -1,140 +1,140 @@
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* A node in a diffpath.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
* @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?
* <p>
* 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
* <code>null</code>
* 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();
}
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* A node in a diffpath.
*
* @version $Revision: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
* @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?
* <p>
* 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
* <code>null</code>
* 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();
}
}
@@ -1,93 +1,93 @@
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Represents a snake in a diffpath.
* <p>
*
* {@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: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
*/
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;
}
/*
* ====================================================================
*
* 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 acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements 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 Software Foundation.
*
* 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
* <http://www.apache.org/>.
*
*/
package difflib.myers;
/**
* Represents a snake in a diffpath.
* <p>
*
* {@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: 69 $ $Date: 2003-10-13 11:00:44 +0300 (Пнд, 13 Окт 2003) $
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
*
*/
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;
}
}
@@ -1,42 +1,42 @@
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
<!--
/*
Copyright 2009 Dmitry Naumenko (dm.naumenko@gmail.com)
This file is part of Java Diff Utills Library.
Java Diff Utills Library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Java Diff Utills Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Java Diff Utills Library. If not, see <http://www.gnu.org/licenses/>.
*/
-->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
<title></title>
</head>
<body>
<p>
The {@link difflib.myers diff.myers} package
implements <a href=
"http://www.cs.arizona.edu/people/gene/">Gene Myers</a>'
differencing algorithm.
</p>
<p>
Myer's algorithm produces optimum results (minimum diffs), but
consumes considerably more memory than SimpleDiff, so its not
suitable for very large files.
</p>
@author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
</body>
</html>
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
<!--
/*
Copyright 2009 Dmitry Naumenko (dm.naumenko@gmail.com)
This file is part of Java Diff Utills Library.
Java Diff Utills Library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Java Diff Utills Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Java Diff Utills Library. If not, see <http://www.gnu.org/licenses/>.
*/
-->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
<title></title>
</head>
<body>
<p>
The {@link difflib.myers diff.myers} package
implements <a href=
"http://www.cs.arizona.edu/people/gene/">Gene Myers</a>'
differencing algorithm.
</p>
<p>
Myer's algorithm produces optimum results (minimum diffs), but
consumes considerably more memory than SimpleDiff, so its not
suitable for very large files.
</p>
@author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
</body>
</html>
@@ -1,70 +1,70 @@
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
<!--
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Maven" 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",
* "Apache Maven", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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
* <http://www.apache.org/>.
*/
-->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
<title></title>
</head>
<body>
<p>
The {@link difflib difflib} package
implements general operation with diff files.
</p>
@author <a href="mailto:dm.naumenko@gmail.com">Dmitry Naumenko</a>
</body>
</html>
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
<!--
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 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 acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Maven" 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",
* "Apache Maven", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* 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
* <http://www.apache.org/>.
*/
-->
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
<title></title>
</head>
<body>
<p>
The {@link difflib difflib} package
implements general operation with diff files.
</p>
@author <a href="mailto:dm.naumenko@gmail.com">Dmitry Naumenko</a>
</body>
</html>