QSequenceLineRAData localData, QSequenceLineRAData latestData,
SVNDiffOptions options,
OutputStream result,
SVNDiffConflictChoiceStyle style) throws IOException {
final QSequenceLineResult localResult;
final QSequenceLineResult latestResult;
final QSequenceLineTeeSimplifier mySimplifer = createSimplifier(options);
try {
localResult = QSequenceLineMedia.createBlocks(baseData, localData, mySimplifer);
latestResult = QSequenceLineMedia.createBlocks(baseData, latestData, mySimplifer);
}
catch (QSequenceException ex) {
throw new IOException(ex.getMessage());
}
try {
final QSequenceLineCache baseLines = localResult.getLeftCache();
final QSequenceLineCache localLines = localResult.getRightCache();
final QSequenceLineCache latestLines = latestResult.getRightCache();
final FSMergerBySequenceList local = new FSMergerBySequenceList(localResult.getBlocks());
final FSMergerBySequenceList latest = new FSMergerBySequenceList(latestResult.getBlocks());
final List transformedLocalLines = transformLocalLines(localResult.getBlocks(), localLines);
int baseLineIndex = -1;
boolean conflict = false;
boolean merged = false;
while (local.hasCurrent() || latest.hasCurrent()) {
if (local.hasCurrent() && latest.hasCurrent() && isEqualChange(local.current(), latest.current(), localLines, latestLines)) {
baseLineIndex = appendLines(result, local.current(), localLines, baseLineIndex, transformedLocalLines);
local.forward();
latest.forward();
continue;
}
if (local.hasCurrent() && latest.hasCurrent()) {
final QSequenceDifferenceBlock localStartBlock = local.current();
final QSequenceDifferenceBlock latestStartBlock = latest.current();
if (checkConflict(local, latest, localLines, latestLines, baseLines.getLineCount())) {
if (style == SVNDiffConflictChoiceStyle.CHOOSE_LATEST) {
baseLineIndex = appendLines(result, latest.current(), latestLines, baseLineIndex, transformedLocalLines);
local.forward();
latest.forward();
merged = true;
} else if (style == SVNDiffConflictChoiceStyle.CHOOSE_MODIFIED) {
baseLineIndex = appendLines(result, local.current(), localLines, baseLineIndex, transformedLocalLines);
local.forward();
latest.forward();
merged = true;
} else {
//TODO: this is actually SVNDiffConflictChoiceStyle.CHOOSE_MODIFIED_LATEST style
baseLineIndex = createConflict(result, localStartBlock, local.current(), latestStartBlock, latest.current(), localLines, latestLines, baseLineIndex, transformedLocalLines);
local.forward();
latest.forward();
conflict = true;
}
continue;
}
}
if (local.hasCurrent() && isBefore(local.current(), latest.hasCurrent() ? latest.current() : null)) {
baseLineIndex = appendLines(result, local.current(), localLines, baseLineIndex, transformedLocalLines);
local.forward();
merged = true;
continue;
}
if (latest.hasCurrent()) {
baseLineIndex = appendLines(result, latest.current(), latestLines, baseLineIndex, transformedLocalLines);
latest.forward();
merged = true;
}
}
appendTransformedLocalLines(baseLineIndex, baseLines.getLineCount(), transformedLocalLines, result);
if (conflict) {
return CONFLICTED;
}
else if (merged) {
return MERGED;
}
else {
return NOT_MODIFIED;
}
}
finally {
latestResult.close();
localResult.close();
}
}