public override void Solve(
IFileSystemInfo localFileSystemInfo,
IObjectId remoteId,
ContentChangeType localContent,
ContentChangeType remoteContent)
{
var obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
if (localFileSystemInfo is IDirectoryInfo) {
obj.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc;
obj.LastRemoteWriteTimeUtc = (remoteId as IFolder).LastModificationDate;
obj.LastChangeToken = (remoteId as IFolder).ChangeToken;
obj.Ignored = (remoteId as IFolder).AreAllChildrenIgnored();
this.Storage.SaveMappedObject(obj);
} else if (localFileSystemInfo is IFileInfo) {
var fileInfo = localFileSystemInfo as IFileInfo;
var doc = remoteId as IDocument;
bool updateLocalDate = false;
bool updateRemoteDate = false;
if (remoteContent == ContentChangeType.NONE) {
if (fileInfo.IsContentChangedTo(obj, true)) {
// Upload local content
updateRemoteDate = true;
try {
var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_MODIFIED_FILE, fileInfo.FullName);
obj.LastChecksum = this.UploadFile(fileInfo, doc, transmission);
obj.LastContentSize = doc.ContentStreamLength ?? fileInfo.Length;
} catch(Exception ex) {
if (ex.InnerException is CmisPermissionDeniedException) {
OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: PermissionDenied", fileInfo.FullName), ex.InnerException);
return;
}
throw;
}
} else {
// Just date sync
if (doc.LastModificationDate != null && fileInfo.LastWriteTimeUtc < (DateTime)doc.LastModificationDate) {
updateLocalDate = true;
} else {
updateRemoteDate = true;
}
}
} else {
byte[] actualLocalHash;
if (fileInfo.IsContentChangedTo(obj, out actualLocalHash, true)) {
// Check if both are changed to the same value
if (actualLocalHash == null) {
using (var f = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {
actualLocalHash = SHA1Managed.Create().ComputeHash(f);
}
}
byte[] remoteHash = doc.ContentStreamHash();
if (remoteHash != null && actualLocalHash.SequenceEqual(remoteHash)) {
// Both files are equal
obj.LastChecksum = remoteHash;
obj.LastContentSize = fileInfo.Length;
// Sync dates
if (doc.LastModificationDate != null && fileInfo.LastWriteTimeUtc < (DateTime)doc.LastModificationDate) {
updateLocalDate = true;
} else {
updateRemoteDate = true;
}
} else {
// Both are different => Check modification dates
// Download remote version and create conflict file
updateLocalDate = true;
obj.LastChecksum = this.DownloadChanges(fileInfo, doc, obj, this.fsFactory, this.transmissionManager, Logger);
obj.LastContentSize = doc.ContentStreamLength ?? 0;
}
} else {
// Download remote content
updateLocalDate = true;
obj.LastChecksum = this.DownloadChanges(fileInfo, doc, obj, this.fsFactory, this.transmissionManager, Logger);
obj.LastContentSize = doc.ContentStreamLength ?? 0;
}
}
if (this.ServerCanModifyDateTimes) {
if (updateLocalDate) {
fileInfo.LastWriteTimeUtc = (DateTime)doc.LastModificationDate;
} else if (updateRemoteDate) {
doc.UpdateLastWriteTimeUtc(fileInfo.LastWriteTimeUtc);
} else {
throw new ArgumentException();
}
}
obj.LastChangeToken = doc.ChangeToken;
obj.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc;
obj.LastRemoteWriteTimeUtc = doc.LastModificationDate;
this.Storage.SaveMappedObject(obj);
}
}
}