de.regnis.q.sequence.line.diff.QDiffSequenceGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sequence-library Show documentation
Show all versions of sequence-library Show documentation
Textual Diff and Merge Library
/*
* ====================================================================
* Copyright (c) 2000-2008 SyntEvo GmbH, [email protected]
* All rights reserved.
*
* This software is licensed as described in the file SEQUENCE-LICENSE,
* which you should have received as part of this distribution. Use is
* subject to license terms.
* ====================================================================
*/
package de.regnis.q.sequence.line.diff;
import java.io.*;
import java.util.*;
import de.regnis.q.sequence.*;
import de.regnis.q.sequence.core.*;
import de.regnis.q.sequence.line.*;
import de.regnis.q.sequence.line.simplifier.*;
/**
* @author Ian Sullivan
* @author TMate Software Ltd.
*/
public abstract class QDiffSequenceGenerator implements QDiffGenerator {
// Abstract ===============================================================
protected abstract void processBlock(QSequenceDifferenceBlock[] segment, QSequenceLineCache sourceLines, QSequenceLineCache targetLines, String encoding,
Writer output) throws IOException;
// Fields =================================================================
private final String header;
private Map myProperties;
// Setup ==================================================================
protected QDiffSequenceGenerator(Map properties, String header) {
this.header = header;
myProperties = properties == null ? Collections.EMPTY_MAP : properties;
myProperties = Collections.unmodifiableMap(myProperties);
}
// Implemented ============================================================
public void generateBinaryDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException {
println("Binary files are different", output);
}
public void generateTextDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException {
generateTextDiff(QSequenceLineRAByteData.create(left), QSequenceLineRAByteData.create(right), encoding, output);
}
public void generateTextDiff(QSequenceLineRAData left, QSequenceLineRAData right, String encoding, Writer output) throws IOException {
final QSequenceLineResult result;
try {
result = QSequenceLineMedia.createBlocks(left, right, getSimplifier());
}
catch (QSequenceException ex) {
throw new IOException(ex.getMessage());
}
try {
final List combinedBlocks = combineBlocks(result.getBlocks(), getGutter());
boolean headerWritten = false;
for (Iterator it = combinedBlocks.iterator(); it.hasNext();) {
List segment = (List)it.next();
if (segment.isEmpty()) {
continue;
}
if (!headerWritten && header != null) {
headerWritten = true;
output.write(header);
}
QSequenceDifferenceBlock[] segmentBlocks = (QSequenceDifferenceBlock[])segment.toArray(new QSequenceDifferenceBlock[segment.size()]);
processBlock(segmentBlocks, result.getLeftCache(), result.getRightCache(), encoding, output);
}
}
finally {
result.close();
}
}
public void generateTextDiff(RandomAccessFile left, RandomAccessFile right, String encoding, Writer output) throws IOException {
QSequenceLineRAData leftData = null, rightData = null;
if (left == null) {
leftData = new QSequenceLineRAByteData(new byte[0]);
} else {
leftData = new QSequenceLineRAFileData(left);
}
if (right == null) {
rightData = new QSequenceLineRAByteData(new byte[0]);
} else {
rightData = new QSequenceLineRAFileData(right);
}
generateTextDiff(leftData, rightData, encoding, output);
}
// Accessing ==============================================================
protected Map getProperties() {
return myProperties;
}
protected String getHunkDelimiter() {
final Object hunkDelimiter = getProperties().get(QDiffGeneratorFactory.HUNK_DELIMITER);
if (hunkDelimiter != null && hunkDelimiter instanceof String) {
return (String) hunkDelimiter;
} else {
return "@@";
}
}
protected String getEOL() {
if (getProperties().get(QDiffGeneratorFactory.EOL_PROPERTY) instanceof String) {
return (String)getProperties().get(QDiffGeneratorFactory.EOL_PROPERTY);
}
return System.getProperty("line.separator", "\n");
}
protected QSequenceLineSimplifier getSimplifier() {
final Object ignore = getProperties().get(QDiffGeneratorFactory.IGNORE_SPACE_PROPERTY);
final QSequenceLineSimplifier baseSimplifier;
if (QDiffGeneratorFactory.IGNORE_ALL_SPACE.equals(ignore)) {
baseSimplifier = new QSequenceLineWhiteSpaceSkippingSimplifier();
}
else if (QDiffGeneratorFactory.IGNORE_SPACE_CHANGE.equals(ignore)) {
baseSimplifier = new QSequenceLineWhiteSpaceReducingSimplifier();
}
else {
baseSimplifier = new QSequenceLineDummySimplifier();
}
if (getProperties().containsKey(QDiffGeneratorFactory.IGNORE_EOL_PROPERTY)) {
return new QSequenceLineTeeSimplifier(baseSimplifier, new QSequenceLineEOLUnifyingSimplifier());
}
return baseSimplifier;
}
protected int getGutter() {
Object gutterStr = getProperties().get(QDiffGeneratorFactory.GUTTER_PROPERTY);
if (gutterStr == null) {
return 0;
}
try {
return Integer.parseInt(gutterStr.toString());
}
catch (NumberFormatException e) {
}
return 0;
}
protected String printLine(QSequenceLine line, String encoding) throws IOException {
String str = new String(line.getContentBytes(), encoding);
return str;
}
protected void println(Writer output) throws IOException {
output.write(getEOL());
}
protected void println(String str, Writer output) throws IOException {
if (str != null) {
output.write(str);
}
output.write(getEOL());
}
protected void print(String str, Writer output) throws IOException {
if (str != null) {
output.write(str);
}
}
// Utils ==================================================================
private static List combineBlocks(List blocksList, int gutter) {
List combinedBlocks = new LinkedList();
List currentList = new LinkedList();
QSequenceDifferenceBlock lastBlock = null;
for (Iterator blocks = blocksList.iterator(); blocks.hasNext();) {
QSequenceDifferenceBlock currentBlock = (QSequenceDifferenceBlock)blocks.next();
if (lastBlock != null) {
final int leftDifference = currentBlock.getLeftFrom() - 1 - lastBlock.getLeftTo();
final int rightDifference = currentBlock.getRightFrom() - 1 - lastBlock.getRightTo();
if (leftDifference > 2 * gutter && rightDifference > 2 * gutter) {
combinedBlocks.add(currentList);
currentList = new LinkedList();
}
}
currentList.add(currentBlock);
lastBlock = currentBlock;
}
if (!combinedBlocks.contains(currentList)) {
combinedBlocks.add(currentList);
}
return combinedBlocks;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy