de.regnis.q.sequence.line.diff.QDiffNormalGenerator 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.line.*;
/**
* @author Ian Sullivan
* @author TMate Software Ltd.
*/
public final class QDiffNormalGenerator extends QDiffSequenceGenerator implements QDiffGeneratorFactory {
// Constants ==============================================================
public static final String TYPE = "normal";
// Static =================================================================
public static void setup() {
QDiffManager.registerDiffGeneratorFactory(new QDiffNormalGenerator(), QDiffNormalGenerator.TYPE);
}
// Fields =================================================================
private Map myGeneratorsCache;
// Setup ==================================================================
private QDiffNormalGenerator(Map properties) {
super(properties, null);
}
private QDiffNormalGenerator() {
super(null, null);
}
// Implemented ============================================================
public void generateDiffHeader(String item, String leftInfo, String rightInfo, Writer output) throws IOException {
output.write("*** ");
output.write(item);
output.write(getEOL());
}
protected void processBlock(QSequenceDifferenceBlock[] segment, QSequenceLineCache sourceLines, QSequenceLineCache targetLines, String encoding, Writer output)
throws IOException {
for (int i = 0; i < segment.length; i++) {
QSequenceDifferenceBlock block = segment[i];
processBlock(block.getLeftFrom(), block.getLeftTo(), sourceLines, block.getRightFrom(), block.getRightTo(), targetLines, encoding, output);
}
}
public QDiffGenerator createGenerator(Map properties) {
if (myGeneratorsCache == null) {
myGeneratorsCache = new HashMap();
}
QDiffGenerator generator = (QDiffGenerator)myGeneratorsCache.get(properties);
if (generator != null) {
return generator;
}
generator = new QDiffNormalGenerator(properties);
myGeneratorsCache.put(properties, generator);
return generator;
}
// Accessing ==============================================================
protected void processBlock(int sourceStartLine, int sourceEndLine, QSequenceLineCache sourceLines, int targetStartLine, int targetEndLine,
QSequenceLineCache targetLines, String encoding, Writer output) throws IOException {
if (sourceStartLine > sourceEndLine) {
add(sourceStartLine, targetStartLine, targetEndLine, targetLines, encoding, output);
}
else if (targetStartLine > targetEndLine) {
delete(targetStartLine, sourceStartLine, sourceEndLine, sourceLines, encoding, output);
}
else {
change(targetStartLine, targetEndLine, targetLines, sourceStartLine, sourceEndLine, sourceLines, encoding, output);
}
}
protected String displayWhiteSpace(String s) {
if (Boolean.TRUE.toString().equals(getProperties().get(QDiffGeneratorFactory.WHITESPACE_PROPERTY))) {
s = s.replaceAll("\t", "");
s = s.replaceAll(" ", ".");
}
return s;
}
/*
* Normal diff output is a series of one or more blocks in the following
* format change-command < target-file-line < target-file-line... --- >
* source-file-line > source-file-line... There are three types of change
* commands. Each consists of a line number or comma-separated range of
* lines in the target file, a single character indicating the kind of
* change to make, and a line number or comma-separated range of lines in
* the source file. All line numbers are the original line numbers in each
* file.
*/
/**
* Handles a delete of lines from the target.
*
* @param deleteAt the line where the lines would have appeared in the source (0 based)
* @param deleteStart first line deleted from target (0 based).
* @param deleteEnd last line deleted from target (0 based).
* @param deleteLines all the lines from the target file. Could be accessed with deleteStart
and
* deleteEnd
to identify the deleted lines.
*/
protected void delete(int deleteAt, int deleteStart, int deleteEnd, QSequenceLineCache deleteLines, String encoding, Writer output) throws IOException {
/*
* Change command is in the format `rdl' Delete the lines in range r
* from the target file; line l is where they would have appeared in the
* source file had they not been deleted. For example, `5,7d3' means
* delete lines 5--7 of target file; or, if changing source file into
* target file, append lines 5--7 of target file after line 3 of source
* file.
*/
// deleteStart and deleteEnd are 0 based, display a 1 based value.
int displayStart = deleteStart + 1;
int displayEnd = deleteEnd + 1;
int displayAt = deleteAt + 1;
println(displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : "") + "d" + displayAt, output);
int delLine = deleteStart;
while (delLine <= deleteEnd) {
print("<" + displayWhiteSpace(printLine(deleteLines.getLine(delLine++), encoding)), output);
}
}
/**
* Handles the addition of lines to source.
*
* @param addAt the line where the new lines would be added to target (0 based)
* @param addStart the first line added from source (0 based)
* @param addEnd the last line added from source (0 based)
* @param addLines all the lines from the source file. Could be accessed with addStart
and
* addEnd
to identify the added lines.
*/
protected void add(int addAt, int addStart, int addEnd, QSequenceLineCache addLines, String encoding, Writer output) throws IOException {
/*
* Change command is in the format `lar' Add the lines in range r of the
* source file after line l of the target file. For example, `8a12,15'
* means append lines 12--15 of source file after line 8 of target file;
* or, if changing source file into target file, delete lines 12--15 of
* source file.
*/
int displayStart = addStart + 1;
int displayEnd = addEnd + 1;
int displayAt = addAt + 1;
println(displayAt + "a" + displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : ""), output);
int addLine = addStart;
while (addLine <= addEnd) {
print(">" + displayWhiteSpace(printLine(addLines.getLine(addLine++), encoding)), output);
}
}
/**
* Handles a change of a range of lines in target to a range of lines in source.
*
* @param replaceStart the first line in target that will be replaced (0 based)
* @param replaceEnd the last line in target that will be replaced (0 based)
* @param replaceLines all the lines in target
* @param replaceWithStart the first line in source to that will replace the lines in target (0 based)
* @param replaceWithEnd the last line in source to that will replace the lines in target (0 based)
* @param replaceWithLines all the lines in source
*/
protected void change(int replaceStart, int replaceEnd, QSequenceLineCache replaceLines, int replaceWithStart, int replaceWithEnd,
QSequenceLineCache replaceWithLines, String encoding, Writer output) throws IOException {
/*
* Change command is in the format `fct' Replace the lines in range f of
* the target file with lines in range t of the source file. This is
* like a combined add and delete, but more compact. For example,
* `5,7c8,10' means change lines 5--7 of target file to read as lines
* 8--10 of source file; or, if changing source file into target file,
* change lines 8--10 of source file to read as lines 5--7 of target
* file.
*/
int displayStart = replaceStart + 1;
int displayEnd = replaceEnd + 1;
int displayWithStart = replaceWithStart + 1;
int displayWithEnd = replaceWithEnd + 1;
println(displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : "") + "c" + displayWithStart
+ ((displayWithEnd != displayWithStart) ? ("," + displayWithEnd) : ""), output);
int replaceLine = replaceStart;
while (replaceLine <= replaceEnd) {
print("<" + displayWhiteSpace(printLine(replaceLines.getLine(replaceLine++), encoding)), output);
}
println("---", output);
int replaceWithLine = replaceWithStart;
while (replaceWithLine <= replaceWithEnd) {
print(">" + displayWhiteSpace(printLine(replaceWithLines.getLine(replaceWithLine++), encoding)), output);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy