/// <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);
        }
示例#2
0
        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;
        }
示例#3
0
        /// <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);
            }
        }
示例#5
0
        /// <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));
        }