/// <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); }
public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent = ContentChangeType.NONE, ContentChangeType remoteContent = ContentChangeType.NONE) { if (localFileSystemInfo is IFileInfo && remoteId is IDocument) { var localFile = localFileSystemInfo as IFileInfo; var remoteDocument = remoteId as IDocument; var mappedObject = this.Storage.GetObject(localFile); 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")); } 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)); try { var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName); mappedObject.LastChecksum = this.UploadFileWithPWC(localFile, ref remoteDocument, transmission); mappedObject.ChecksumAlgorithmName = "SHA-1"; if (remoteDocument.Id != mappedObject.RemoteObjectId) { this.TransmissionStorage.RemoveObjectByRemoteObjectId(mappedObject.RemoteObjectId); mappedObject.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; } mappedObject.LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; mappedObject.LastContentSize = localFile.Length; OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName)); } mappedObject.LastChangeToken = remoteDocument.ChangeToken; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; this.Storage.SaveMappedObject(mappedObject); } else { this.folderOrFileContentUnchangedSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent); } return; }
/// <summary> /// Solve the specified situation by using localFile and remote object. /// </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) { Stopwatch completewatch = new Stopwatch(); completewatch.Start(); Logger.Debug("Starting LocalObjectAdded"); localFileSystemInfo.Refresh(); if (!localFileSystemInfo.Exists) { throw new FileNotFoundException(string.Format("Local file/folder {0} has been renamed/moved/deleted", localFileSystemInfo.FullName)); } string parentId = Storage.GetRemoteId(this.GetParent(localFileSystemInfo)); if (parentId == null) { if (this.IsParentReadOnly(localFileSystemInfo)) { return; } else { throw new ArgumentException("ParentId is null => invoke crawl sync to create parent first"); } } ICmisObject addedObject; try { addedObject = this.AddCmisObject(localFileSystemInfo, parentId, this.Session); } catch (CmisConstraintException e) { this.EnsureThatLocalFileNameContainsLegalCharacters(localFileSystemInfo, e); throw; } catch (CmisPermissionDeniedException e) { OperationsLogger.Warn(string.Format("Permission denied while trying to Create the locally added object {0} on the server ({1}).", localFileSystemInfo.FullName, e.Message)); return; } Guid uuid = this.WriteOrUseUuidIfSupported(localFileSystemInfo); OperationsLogger.Info(string.Format("Created remote {2} {0} for {1}", addedObject.Id, localFileSystemInfo.FullName, addedObject is IFolder ? "folder" : "document")); MappedObject mapped = new MappedObject( localFileSystemInfo.Name, addedObject.Id, localFileSystemInfo is IDirectoryInfo ? MappedObjectType.Folder : MappedObjectType.File, parentId, addedObject.ChangeToken) { Guid = uuid, LastRemoteWriteTimeUtc = addedObject.LastModificationDate, LastLocalWriteTimeUtc = localFileSystemInfo is IFileInfo && (localFileSystemInfo as IFileInfo).Length > 0 ? (DateTime?)null : (DateTime?)localFileSystemInfo.LastWriteTimeUtc, LastChangeToken = addedObject.ChangeToken, LastContentSize = localFileSystemInfo is IDirectoryInfo ? -1 : 0, ChecksumAlgorithmName = localFileSystemInfo is IDirectoryInfo ? null : "SHA-1", LastChecksum = localFileSystemInfo is IDirectoryInfo ? null : SHA1.Create().ComputeHash(new byte[0]) }; this.Storage.SaveMappedObject(mapped); var localFile = localFileSystemInfo as IFileInfo; if (localFile != null) { var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_NEW_FILE, localFile.FullName); if (localFile.Length > 0) { Stopwatch watch = new Stopwatch(); OperationsLogger.Debug(string.Format("Uploading file content of {0}", localFile.FullName)); watch.Start(); try { mapped.LastChecksum = this.UploadFile(localFile, addedObject as IDocument, transmission); mapped.ChecksumAlgorithmName = "SHA-1"; } catch (Exception ex) { if (ex is UploadFailedException && (ex as UploadFailedException).InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Could not upload file content of {0}:", localFile.FullName), (ex as UploadFailedException).InnerException); return; } throw; } watch.Stop(); if (this.ServerCanModifyDateTimes) { (addedObject as IDocument).UpdateLastWriteTimeUtc(localFile.LastWriteTimeUtc); } mapped.LastContentSize = localFile.Length; mapped.LastChangeToken = addedObject.ChangeToken; mapped.LastRemoteWriteTimeUtc = addedObject.LastModificationDate; mapped.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mapped); OperationsLogger.Info(string.Format("Uploaded file content of {0} in [{1} msec]", localFile.FullName, watch.ElapsedMilliseconds)); } else { transmission.Length = 0; transmission.Position = 0; transmission.Status = TransmissionStatus.FINISHED; } } completewatch.Stop(); Logger.Debug(string.Format("Finished LocalObjectAdded after [{0} msec]", completewatch.ElapsedMilliseconds)); }
/// <summary> /// Solve the specified situation by using localFile and remote object. /// </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 is IFileInfo) { IFileInfo localFile = localFileSystemInfo as IFileInfo; localFile.Refresh(); if (!localFile.Exists) { throw new FileNotFoundException(string.Format("Local file {0} has been renamed/moved/deleted", localFile.FullName)); } if (localFile.Length == 0) { this.folderOrEmptyFileAddedSolver.Solve(localFileSystemInfo, null, localContent, remoteContent); return; } string parentId = this.Storage.GetRemoteId(localFile.Directory); if (parentId == null) { if (this.IsParentReadOnly(localFile)) { return; } else { throw new ArgumentException("ParentId is null => invoke crawl sync to create parent first"); } } IDocument remoteDocument; try { remoteDocument = this.CreateOrLoadExistingRemoteDocument(localFile, new ObjectId(parentId)); } catch (CmisPermissionDeniedException e) { OperationsLogger.Warn(string.Format("Permission denied while trying to Create the locally added object {0} on the server ({1}).", localFile.FullName, e.Message)); return; } Guid uuid = this.WriteOrUseUuidIfSupported(localFile); var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_NEW_FILE, localFile.FullName); MappedObject mapped = new MappedObject( localFile.Name, remoteDocument.Id, MappedObjectType.File, parentId, remoteDocument.ChangeToken) { Guid = uuid, LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate, LastLocalWriteTimeUtc = (DateTime?)localFileSystemInfo.LastWriteTimeUtc, LastChangeToken = remoteDocument.ChangeToken, LastContentSize = 0, ChecksumAlgorithmName = "SHA-1", LastChecksum = SHA1.Create().ComputeHash(new byte[0]) }; Stopwatch watch = new Stopwatch(); OperationsLogger.Debug(string.Format("Uploading file content of {0}", localFile.FullName)); watch.Start(); try { mapped.LastChecksum = this.UploadFileWithPWC(localFile, ref remoteDocument, transmission); mapped.ChecksumAlgorithmName = "SHA-1"; mapped.RemoteObjectId = remoteDocument.Id; } catch (Exception ex) { if (ex is UploadFailedException && (ex as UploadFailedException).InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Could not upload file content of {0}:", localFile.FullName), (ex as UploadFailedException).InnerException); return; } throw; } watch.Stop(); mapped.LastContentSize = localFile.Length; mapped.LastChangeToken = remoteDocument.ChangeToken; mapped.LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate; mapped.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mapped); OperationsLogger.Info(string.Format("Uploaded file content of {0} in [{1} msec]", localFile.FullName, watch.ElapsedMilliseconds)); } else { this.folderOrEmptyFileAddedSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent); } }
/// <summary> /// Solve the specified situation by using localFile and remote object. /// </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) { Stopwatch completewatch = new Stopwatch(); completewatch.Start(); Logger.Debug("Starting LocalObjectAdded"); string parentId = this.GetParentId(localFileSystemInfo, this.Storage); ICmisObject addedObject; try { addedObject = this.AddCmisObject(localFileSystemInfo, parentId, this.Session); } catch (CmisConstraintException e) { if (!Utils.IsValidISO885915(localFileSystemInfo.Name)) { OperationsLogger.Warn(string.Format("Server denied creation of {0}, perhaps because it contains a UTF-8 character", localFileSystemInfo.Name), e); throw new InteractionNeededException(string.Format("Server denied creation of {0}", localFileSystemInfo.Name), e) { Title = string.Format("Server denied creation of {0}", localFileSystemInfo.Name), Description = string.Format("Server denied creation of {0}, perhaps because it contains a UTF-8 character", localFileSystemInfo.FullName) }; } throw; } catch (CmisPermissionDeniedException e) { OperationsLogger.Warn(string.Format("Permission denied while trying to Create the locally added object {0} on the server ({1}).", localFileSystemInfo.FullName, e.Message)); return; } Guid uuid = this.WriteOrUseUuidIfSupported(localFileSystemInfo); OperationsLogger.Info(string.Format("Created remote {2} {0} for {1}", addedObject.Id, localFileSystemInfo.FullName, addedObject is IFolder ? "folder" : "document")); MappedObject mapped = new MappedObject( localFileSystemInfo.Name, addedObject.Id, localFileSystemInfo is IDirectoryInfo ? MappedObjectType.Folder : MappedObjectType.File, parentId, addedObject.ChangeToken) { Guid = uuid, LastRemoteWriteTimeUtc = addedObject.LastModificationDate, LastLocalWriteTimeUtc = localFileSystemInfo is IFileInfo && (localFileSystemInfo as IFileInfo).Length > 0 ? (DateTime?)null : (DateTime?)localFileSystemInfo.LastWriteTimeUtc, LastChangeToken = addedObject.ChangeToken, LastContentSize = localFileSystemInfo is IDirectoryInfo ? -1 : 0, ChecksumAlgorithmName = localFileSystemInfo is IDirectoryInfo ? null : "SHA-1", LastChecksum = localFileSystemInfo is IDirectoryInfo ? null : SHA1.Create().ComputeHash(new byte[0]) }; this.Storage.SaveMappedObject(mapped); var localFile = localFileSystemInfo as IFileInfo; if (localFile != null) { FileTransmissionEvent transmissionEvent = new FileTransmissionEvent(FileTransmissionType.UPLOAD_NEW_FILE, localFile.FullName); this.transmissionManager.AddTransmission(transmissionEvent); if (localFile.Length > 0) { Stopwatch watch = new Stopwatch(); OperationsLogger.Debug(string.Format("Uploading file content of {0}", localFile.FullName)); watch.Start(); IFileUploader uploader = ContentTaskUtils.CreateUploader(); using (SHA1 hashAlg = new SHA1Managed()) { try { using (var fileStream = localFile.Open(FileMode.Open, FileAccess.Read)) { uploader.UploadFile(addedObject as IDocument, fileStream, transmissionEvent, hashAlg); mapped.ChecksumAlgorithmName = "SHA-1"; mapped.LastChecksum = hashAlg.Hash; } } catch (Exception ex) { if (ex is UploadFailedException && (ex as UploadFailedException).InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Could not upload file content of {0}:", localFile.FullName), (ex as UploadFailedException).InnerException); transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { FailedException = ex }); return; } transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { FailedException = ex }); throw; } } watch.Stop(); if (this.ServerCanModifyDateTimes) { (addedObject as IDocument).UpdateLastWriteTimeUtc(localFile.LastWriteTimeUtc); } mapped.LastContentSize = localFile.Length; mapped.LastChangeToken = addedObject.ChangeToken; mapped.LastRemoteWriteTimeUtc = addedObject.LastModificationDate; mapped.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; if (mapped.RemoteObjectId != addedObject.Id) { this.Storage.RemoveObject(mapped); mapped.RemoteObjectId = addedObject.Id; } this.Storage.SaveMappedObject(mapped); OperationsLogger.Info(string.Format("Uploaded file content of {0} in [{1} msec]", localFile.FullName, watch.ElapsedMilliseconds)); } transmissionEvent.ReportProgress(new TransmissionProgressEventArgs { Completed = true }); } completewatch.Stop(); Logger.Debug(string.Format("Finished LocalObjectAdded after [{0} msec]", completewatch.ElapsedMilliseconds)); }