}
// abort merger if actions is already conflict
if (action == FileAction.CONFLICTED) {
return action;
}
MetaFile baseFile = getBaseFile(false);
MetaFile tmpFile = getTmpFile();
VltEntryInfo base = entry.base();
VltEntryInfo work = entry.work();
byte[] lineFeed = MimeTypes.isBinary(remoteFile.getContentType())
? null
: LineOutputStream.LS_NATIVE;
// get the remote file
VaultFileCopy copy = null;
boolean remoteUpdated = true;
try {
// first check size and last modified
if (!base.checkModified(remoteFile)) {
remoteUpdated = false;
} else {
File temp = tmpFile.openTempFile();
copy = VaultFileCopy.copy(remoteFile, temp, lineFeed);
// if tmp is equal to the base one, there was no update on the server
if (copy.getMd5().equals(base.getMd5())) {
tmpFile.closeTempFile(tmpFile.length() >= 0);
remoteUpdated = false;
} else {
tmpFile.closeTempFile(false);
}
}
} catch (IOException e) {
throw exception("Error while copying files.", e);
}
if (!remoteUpdated) {
if (work.getMd5().equals(base.getMd5())) {
// fix base
base.setSize(work.getSize());
base.setDate(work.getDate());
return FileAction.VOID;
} else if (remoteFile.lastModified() > 0) {
// normal modification provided
return action;
}
}
try {
// check if binary
boolean remoteBT = getRemoteBinaryType(remoteFile, copy);
boolean localBT = MimeTypes.isBinary(base.getContentType());
if (remoteBT || localBT) {
parent.getContext().printMessage(this, "can't merge. binary content");
entry.conflict(file, baseFile, tmpFile);
return FileAction.CONFLICTED;
}
// do a 3-way diff between the base, the local and the remote one.
// we currently do not use document sources, since we don't really have
// a label to provide (like rev. num, etc).
Reader r0 = baseFile.getReader();
Reader r1 = tmpFile.getReader();
Document baseDoc = new Document(null, LineElementsFactory.create(new MetaFileDocSource(baseFile), r0, false));
Document leftDoc = new Document(null, LineElementsFactory.create(new FileDocumentSource(file), false, Constants.ENCODING));
Document rightDoc = new Document(null, LineElementsFactory.create(new MetaFileDocSource(tmpFile), r1, false));
DocumentDiff3 diff;
try {
diff = baseDoc.diff3(leftDoc, rightDoc);
} finally {
IOUtils.closeQuietly(r0);
IOUtils.closeQuietly(r1);
}
// save the diff output
Writer out = new OutputStreamWriter(FileUtils.openOutputStream(file), Constants.ENCODING);
try {
diff.write(new DiffWriter(out), false);
} catch (IOException e) {
IOUtils.closeQuietly(out);
}
if (diff.hasConflicts()) {
entry.conflict(file, baseFile, tmpFile);
action = FileAction.CONFLICTED;
} else {
// make the tmp file the new base
tmpFile.moveTo(baseFile);
base.update(baseFile, true);
action = FileAction.MERGED;
}
// and update the 'work'