/// <summary> /// Solve the specified situation by using the storage, localFile and remoteId. /// Uploads the file content if content has been changed. Otherwise simply saves the /// last modification date. /// </summary> /// <param name="localFileSystemInfo">Local filesystem info instance.</param> /// <param name="remoteId">Remote identifier or object.</param> /// <param name="localContent">Hint if the local content has been changed.</param> /// <param name="remoteContent">Information if the remote content has been changed.</param> public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent = ContentChangeType.NONE, ContentChangeType remoteContent = ContentChangeType.NONE) { if (!localFileSystemInfo.Exists) { throw new ArgumentException("Given local path does not exists: " + localFileSystemInfo.FullName); } // Match local changes to remote changes and updated them remotely IMappedObject mappedObject = this.Storage.GetObject(localFileSystemInfo); if (mappedObject == null) { throw new ArgumentException(string.Format("Could not find db entry for {0} => invoke crawl sync", localFileSystemInfo.FullName)); } if (mappedObject.LastChangeToken != (remoteId as ICmisObjectProperties).ChangeToken) { throw new ArgumentException(string.Format("remote {1} {0} has also been changed since last sync => invoke crawl sync", remoteId.Id, remoteId is IDocument ? "document" : "folder")); } IFileInfo localFile = localFileSystemInfo as IFileInfo; if (localFile != null && localFile.IsContentChangedTo(mappedObject, scanOnlyIfModificationDateDiffers: true)) { Logger.Debug(string.Format("\"{0}\" is different from {1}", localFile.FullName, mappedObject.ToString())); OperationsLogger.Debug(string.Format("Local file \"{0}\" has been changed", localFile.FullName)); var doc = remoteId as IDocument; try { var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName); mappedObject.LastChecksum = UploadFile(localFile, doc, transmission); } catch (Exception ex) { if (ex.InnerException is CmisPermissionDeniedException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: PermissionDenied", localFile.FullName)); return; } else if (ex.InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: StorageException", localFile.FullName), ex); return; } throw; } mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; mappedObject.LastContentSize = localFile.Length; OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName)); } if (this.ServerCanModifyDateTimes) { try { if (remoteId is IDocument) { var doc = remoteId as IDocument; doc.UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate ?? localFileSystemInfo.LastWriteTimeUtc; } else if (remoteId is IFolder) { var folder = remoteId as IFolder; folder.UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = folder.LastModificationDate ?? localFileSystemInfo.LastWriteTimeUtc; } } catch (CmisPermissionDeniedException) { Logger.Debug(string.Format("Locally changed modification date \"{0}\"is not uploaded to the server: PermissionDenied", localFileSystemInfo.LastWriteTimeUtc)); } } mappedObject.LastChangeToken = (remoteId as ICmisObjectProperties).ChangeToken; mappedObject.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mappedObject); }
/// <summary> /// Solve the specified situation by using the storage, localFile and remoteId. /// Uploads the file content if content has been changed. Otherwise simply saves the /// last modification date. /// </summary> /// <param name="localFileSystemInfo">Local filesystem info instance.</param> /// <param name="remoteId">Remote identifier or object.</param> /// <param name="localContent">Hint if the local content has been changed.</param> /// <param name="remoteContent">Information if the remote content has been changed.</param> public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent = ContentChangeType.NONE, ContentChangeType remoteContent = ContentChangeType.NONE) { if (!localFileSystemInfo.Exists) { throw new ArgumentException("Given local path does not exists: " + localFileSystemInfo.FullName); } // Match local changes to remote changes and updated them remotely IMappedObject mappedObject = null; try { string ea = localFileSystemInfo.GetExtendedAttribute(MappedObject.ExtendedAttributeKey); Guid guid; if (Guid.TryParse(ea, out guid)) { mappedObject = this.Storage.GetObjectByGuid(guid); } } catch (Exception) { } if (mappedObject == null) { mappedObject = this.Storage.GetObjectByLocalPath(localFileSystemInfo); } if (mappedObject == null) { throw new ArgumentException(string.Format("Could not find db entry for {0} => invoke crawl sync", localFileSystemInfo.FullName)); } IFileInfo localFile = localFileSystemInfo as IFileInfo; if (localFile != null && localFile.IsContentChangedTo(mappedObject, scanOnlyIfModificationDateDiffers: true)) { Logger.Debug(string.Format("\"{0}\" is different from {1}", localFile.FullName, mappedObject.ToString())); OperationsLogger.Debug(string.Format("Local file \"{0}\" has been changed", localFile.FullName)); IFileUploader uploader = FileTransmission.ContentTaskUtils.CreateUploader(); var doc = remoteId as IDocument; FileTransmissionEvent transmissionEvent = new FileTransmissionEvent(FileTransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName); this.transmissionManager.AddTransmission(transmissionEvent); transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { Started = true }); using (var hashAlg = new SHA1Managed()) using (var file = localFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { try { uploader.UploadFile(doc, file, transmissionEvent, hashAlg); } catch (Exception ex) { transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { FailedException = ex }); if (ex.InnerException is CmisPermissionDeniedException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has been not been uploaded: PermissionDenied", localFile.FullName)); return; } throw; } mappedObject.LastChecksum = hashAlg.Hash; } mappedObject.LastChangeToken = doc.ChangeToken; mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; mappedObject.LastContentSize = localFile.Length; OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName)); transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { Completed = true }); } if (this.ServerCanModifyDateTimes) { try { if (remoteId is IDocument) { (remoteId as IDocument).UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; } else if (remoteId is IFolder) { (remoteId as IFolder).UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; } } catch (CmisPermissionDeniedException) { Logger.Debug(string.Format("Locally changed modification date \"{0}\"is not uploaded to the server: PermissionDenied", localFileSystemInfo.LastWriteTimeUtc)); } } mappedObject.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mappedObject); }
/// <summary> /// Determines if file content is changed to the specified obj. /// </summary> /// <returns><c>true</c> if is the file content is different to the specified obj otherwise, <c>false</c>.</returns> /// <param name="file">File instance.</param> /// <param name="obj">Object to check the file content against.</param> /// <param name="scanOnlyIfModificationDateDiffers">If set to <c>true</c> content scan runs only if the modification date differs to given one.</param> public static bool IsContentChangedTo(this IFileInfo file, IMappedObject obj, bool scanOnlyIfModificationDateDiffers = false) { byte[] actualHash; return(file.IsContentChangedTo(obj, out actualHash, scanOnlyIfModificationDateDiffers)); }
/// <summary> /// Solve the specified situation by using localFile and remote object if the local file content is the only changed content. Otherwise the given fallback will be used. /// </summary> /// <param name="localFileSystemInfo">Local filesystem info instance.</param> /// <param name="remoteId">Remote identifier or object.</param> /// <param name="localContent">Hint if the local content has been changed.</param> /// <param name="remoteContent">Information if the remote content has been changed.</param> public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent, ContentChangeType remoteContent) { if (!(localFileSystemInfo is IFileInfo)) { this.fallbackSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent); return; } IFileInfo localFile = localFileSystemInfo as IFileInfo; IDocument remoteDocument = remoteId as IDocument; if (remoteContent != ContentChangeType.NONE) { this.fallbackSolver.Solve(localFile, remoteId, localContent, remoteContent); return; } bool updateLocalDate = false; bool updateRemoteDate = false; var obj = this.Storage.GetObjectByRemoteId(remoteDocument.Id); if (localFile.IsContentChangedTo(obj, true)) { updateRemoteDate = true; try { var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName); obj.LastChecksum = UploadFileWithPWC(localFile, ref remoteDocument, transmission); obj.ChecksumAlgorithmName = "SHA-1"; obj.LastContentSize = remoteDocument.ContentStreamLength ?? localFile.Length; if (remoteDocument.Id != obj.RemoteObjectId) { this.TransmissionStorage.RemoveObjectByRemoteObjectId(obj.RemoteObjectId); obj.RemoteObjectId = remoteDocument.Id; } } catch (Exception ex) { if (ex.InnerException is CmisPermissionDeniedException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: PermissionDenied", localFile.FullName)); return; } else if (ex.InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: StorageException", localFile.FullName), ex); return; } throw; } } else { // just date sync if (remoteDocument.LastModificationDate != null && localFile.LastWriteTimeUtc < remoteDocument.LastModificationDate) { updateLocalDate = true; } else { updateRemoteDate = true; } } if (this.ServerCanModifyDateTimes) { if (updateLocalDate) { localFile.LastWriteTimeUtc = (DateTime)remoteDocument.LastModificationDate; } else if (updateRemoteDate) { remoteDocument.UpdateLastWriteTimeUtc(localFile.LastWriteTimeUtc); } else { throw new ArgumentException(); } } obj.LastChangeToken = remoteDocument.ChangeToken; obj.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; obj.LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate; this.Storage.SaveMappedObject(obj); }