コード例 #1
0
        ///<inheritdoc>
        public async Task UnlockAsync()
        {
            if (MsOfficeHelper.IsMsOfficeLocked(UserFileSystemPath)) // Required for PowerPoint. It does not block the for writing.
            {
                throw new ClientLockFailedException("The file is blocked for writing.");
            }

            ExternalDataManager customDataManager = Engine.CustomDataManager(UserFileSystemPath, Logger);
            LockManager         lockManager       = customDataManager.LockManager;

            // Set pending icon, so the user has a feedback as unlock operation may take some time.
            await customDataManager.SetLockPendingIconAsync(true);

            // Read lock-token from lock-info file.
            string lockToken = (await lockManager.GetLockInfoAsync()).LockToken;

            // Unlock the item in the remote storage.
            try
            {
                await Program.DavClient.UnlockAsync(new Uri(RemoteStoragePath), lockToken);
            }
            catch (ITHit.WebDAV.Client.Exceptions.ConflictException)
            {
                // The item is already unlocked.
            }

            // Delete lock-mode and lock-token info.
            lockManager.DeleteLock();

            // Remove lock icon and lock info in custom columns.
            await customDataManager.SetLockInfoAsync(null);

            Logger.LogMessage("Unlocked in the remote storage succesefully", UserFileSystemPath);
        }
コード例 #2
0
        ///<inheritdoc>
        public async Task LockAsync(LockMode lockMode)
        {
            Logger.LogMessage($"{nameof(ILock)}.{nameof(LockAsync)}()", UserFileSystemPath);

            ExternalDataManager customDataManager = Engine.CustomDataManager(UserFileSystemPath, Logger);
            LockManager         lockManager       = customDataManager.LockManager;

            if (!await lockManager.IsLockedAsync() &&
                !Engine.CustomDataManager(UserFileSystemPath).IsNew)
            {
                // Set pending icon, so the user has a feedback as lock operation may take some time.
                await customDataManager.SetLockPendingIconAsync(true);

                // Call your remote storage here to lock the item.
                // Save the lock token and other lock info received from the remote storage on the client.
                // Supply the lock-token as part of each remote storage update in File.WriteAsync() method.
                // For demo purposes we just fill some generic data.
                ServerLockInfo lockInfo = new ServerLockInfo()
                {
                    LockToken = "ServerToken", Owner = "You", Exclusive = true, LockExpirationDateUtc = DateTimeOffset.Now.AddMinutes(30)
                };

                // Save lock-token and lock-mode.
                await lockManager.SetLockInfoAsync(lockInfo);

                await lockManager.SetLockModeAsync(lockMode);

                // Set lock icon and lock info in custom columns.
                await customDataManager.SetLockInfoAsync(lockInfo);

                Logger.LogMessage("Locked in remote storage succesefully.", UserFileSystemPath);
            }
        }
コード例 #3
0
        /// <inheritdoc/>
        public async Task <byte[]> CreateFolderAsync(IFolderMetadata folderMetadata)
        {
            string userFileSystemNewItemPath = Path.Combine(UserFileSystemPath, folderMetadata.Name);

            Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFolderAsync)}()", userFileSystemNewItemPath);

            DirectoryInfo remoteStorageItem = new DirectoryInfo(Path.Combine(RemoteStoragePath, folderMetadata.Name));

            remoteStorageItem.Create();

            // Update remote storage folder metadata.
            remoteStorageItem.Attributes        = folderMetadata.Attributes;
            remoteStorageItem.CreationTimeUtc   = folderMetadata.CreationTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = folderMetadata.LastWriteTime.UtcDateTime;
            remoteStorageItem.LastAccessTimeUtc = folderMetadata.LastAccessTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = folderMetadata.LastWriteTime.UtcDateTime;

            // Get ETag from server here and save it on the client.
            string newEtag = "1234567890";

            ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemNewItemPath);

            customDataManager.IsNew = false;
            await customDataManager.ETagManager.SetETagAsync(newEtag);

            await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, newEtag) });

            return(null);
        }
コード例 #4
0
        /// <inheritdoc/>
        public async Task GetChildrenAsync(string pattern, IOperationContext operationContext, IFolderListingResultContext resultContext)
        {
            // This method has a 60 sec timeout.
            // To process longer requests and reset the timout timer call one of the following:
            // - resultContext.ReturnChildren() method.
            // - resultContext.ReportProgress() method.

            Logger.LogMessage($"{nameof(IFolder)}.{nameof(GetChildrenAsync)}({pattern})", UserFileSystemPath);

            IEnumerable <FileSystemInfo> remoteStorageChildren = new DirectoryInfo(RemoteStoragePath).EnumerateFileSystemInfos(pattern);

            List <IFileSystemItemMetadata> userFileSystemChildren = new List <IFileSystemItemMetadata>();

            foreach (FileSystemInfo remoteStorageItem in remoteStorageChildren)
            {
                IFileSystemItemMetadata itemInfo = Mapping.GetUserFileSysteItemMetadata(remoteStorageItem);

                string userFileSystemItemPath = Path.Combine(UserFileSystemPath, itemInfo.Name);

                // Filtering existing files/folders. This is only required to avoid extra errors in the log.
                if (!FsPath.Exists(userFileSystemItemPath))
                {
                    Logger.LogMessage("Creating", userFileSystemItemPath);
                    userFileSystemChildren.Add(itemInfo);
                }

                ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemItemPath);

                // Mark this item as not new, which is required for correct MS Office saving opertions.
                customDataManager.IsNew = false;

                // Save ETag on the client side, to be sent to the remote storage as part of the update.
                await customDataManager.ETagManager.SetETagAsync("1234567890");
            }

            // To signal that the children enumeration is completed
            // always call ReturnChildren(), even if the folder is empty.
            resultContext.ReturnChildren(userFileSystemChildren.ToArray(), userFileSystemChildren.Count());

            // Show some custom column in file manager for demo purposes.
            foreach (IFileSystemItemMetadata itemInfo in userFileSystemChildren)
            {
                string userFileSystemItemPath = Path.Combine(UserFileSystemPath, itemInfo.Name);

                FileSystemItemPropertyData eTagColumn = new FileSystemItemPropertyData((int)CustomColumnIds.ETag, "1234567890");
                await Engine.CustomDataManager(userFileSystemItemPath).SetCustomColumnsAsync(new [] { eTagColumn });
            }
        }
コード例 #5
0
        /// <inheritdoc/>
        public async Task WriteAsync(IFileMetadata fileMetadata, Stream content = null)
        {
            if (MsOfficeHelper.IsMsOfficeLocked(UserFileSystemPath)) // Required for PowerPoint. It does not block the for writing.
            {
                throw new ClientLockFailedException("The file is blocked for writing.");
            }

            Logger.LogMessage($"{nameof(IFile)}.{nameof(WriteAsync)}()", UserFileSystemPath);

            ExternalDataManager customDataManager = Engine.CustomDataManager(UserFileSystemPath);
            // Send the ETag to the server as part of the update to ensure the file in the remote storge is not modified since last read.
            string oldEtag = await customDataManager.ETagManager.GetETagAsync();

            // Send the lock-token to the server as part of the update.
            string lockToken = (await customDataManager.LockManager.GetLockInfoAsync())?.LockToken;


            if (content != null)
            {
                long contentLength = content != null ? content.Length : 0;

                IWebRequestAsync request = await Program.DavClient.GetFileWriteRequestAsync(
                    new Uri(RemoteStoragePath), null, contentLength, 0, -1, lockToken, oldEtag);

                // Update remote storage file content.
                using (Stream davContentStream = await request.GetRequestStreamAsync())
                {
                    if (content != null)
                    {
                        await content.CopyToAsync(davContentStream);
                    }

                    // Get the new ETag returned by the server (if any).
                    IWebResponseAsync response = await request.GetResponseAsync();

                    string eTagNew = response.Headers["ETag"];
                    response.Close();

                    // Store ETag unlil the next update.
                    // This will also mark the item as not new, which is required for correct MS Office saving opertions.
                    await customDataManager.ETagManager.SetETagAsync(eTagNew);

                    // Update ETag in custom column displayed in file manager.
                    await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, eTagNew) });
                }
            }
        }
コード例 #6
0
        /// <inheritdoc/>
        public async Task WriteAsync(IFileMetadata fileMetadata, Stream content = null)
        {
            if (MsOfficeHelper.IsMsOfficeLocked(UserFileSystemPath)) // Required for PowerPoint. It does not block the for writing.
            {
                throw new ClientLockFailedException("The file is blocked for writing.");
            }

            Logger.LogMessage($"{nameof(IFile)}.{nameof(WriteAsync)}()", UserFileSystemPath);

            ExternalDataManager customDataManager = Engine.CustomDataManager(UserFileSystemPath);
            // Send the ETag to the server as part of the update to ensure the file in the remote storge is not modified since last read.
            string oldEtag = await customDataManager.ETagManager.GetETagAsync();

            // Send the lock-token to the server as part of the update.
            string lockToken = (await customDataManager.LockManager.GetLockInfoAsync())?.LockToken;

            FileInfo remoteStorageItem = new FileInfo(RemoteStoragePath);

            if (content != null)
            {
                // Upload remote storage file content.
                await using (FileStream remoteStorageStream = remoteStorageItem.Open(FileMode.Open, FileAccess.Write, FileShare.Delete))
                {
                    await content.CopyToAsync(remoteStorageStream);

                    remoteStorageStream.SetLength(content.Length);
                }
            }

            // Update remote storage file metadata.
            remoteStorageItem.Attributes        = fileMetadata.Attributes;
            remoteStorageItem.CreationTimeUtc   = fileMetadata.CreationTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = fileMetadata.LastWriteTime.UtcDateTime;
            remoteStorageItem.LastAccessTimeUtc = fileMetadata.LastAccessTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = fileMetadata.LastWriteTime.UtcDateTime;

            // Get the new ETag from server here as part of the update and save it on the client.
            string newEtag = "1234567890";
            await customDataManager.ETagManager.SetETagAsync(newEtag);

            await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, newEtag) });
        }
コード例 #7
0
        /// <inheritdoc/>
        public async Task <byte[]> CreateFileAsync(IFileMetadata fileMetadata, Stream content = null)
        {
            string userFileSystemNewItemPath = Path.Combine(UserFileSystemPath, fileMetadata.Name);

            Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFileAsync)}()", userFileSystemNewItemPath);

            FileInfo remoteStorageItem = new FileInfo(Path.Combine(RemoteStoragePath, fileMetadata.Name));

            // Upload remote storage file content.
            await using (FileStream remoteStorageStream = remoteStorageItem.Open(FileMode.CreateNew, FileAccess.Write, FileShare.Delete))
            {
                if (content != null)
                {
                    await content.CopyToAsync(remoteStorageStream);

                    remoteStorageStream.SetLength(content.Length);
                }
            }

            // Update remote storage file metadata.
            remoteStorageItem.Attributes        = fileMetadata.Attributes;
            remoteStorageItem.CreationTimeUtc   = fileMetadata.CreationTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = fileMetadata.LastWriteTime.UtcDateTime;
            remoteStorageItem.LastAccessTimeUtc = fileMetadata.LastAccessTime.UtcDateTime;
            remoteStorageItem.LastWriteTimeUtc  = fileMetadata.LastWriteTime.UtcDateTime;

            // Get ETag from server here and save it on the client.
            string newEtag = "1234567890";

            ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemNewItemPath);

            // Mark this item as not new, which is required for correct MS Office saving opertions.
            customDataManager.IsNew = false;

            await customDataManager.ETagManager.SetETagAsync(newEtag);

            // Update ETag in custom column displayed in file manager.
            await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, newEtag) });

            return(null);
        }
コード例 #8
0
        /// <inheritdoc/>
        public async Task <byte[]> CreateFileAsync(IFileMetadata fileMetadata, Stream content = null)
        {
            string userFileSystemNewItemPath = Path.Combine(UserFileSystemPath, fileMetadata.Name);

            Logger.LogMessage($"{nameof(IFolder)}.{nameof(CreateFileAsync)}()", userFileSystemNewItemPath);

            Uri newFileUri = new Uri(new Uri(RemoteStoragePath), fileMetadata.Name);

            long contentLength = content != null ? content.Length : 0;

            IWebRequestAsync request = await Program.DavClient.GetFileWriteRequestAsync(newFileUri, null, contentLength);

            // Update remote storage file content.
            using (Stream davContentStream = await request.GetRequestStreamAsync())
            {
                if (content != null)
                {
                    await content.CopyToAsync(davContentStream);
                }

                // Get the new ETag returned by the server (if any).
                IWebResponseAsync response = await request.GetResponseAsync();

                string eTagNew = response.Headers["ETag"];
                response.Close();

                ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemNewItemPath);

                // Store ETag unlil the next update.
                // This will also mark the item as not new, which is required for correct MS Office saving opertions.
                await customDataManager.ETagManager.SetETagAsync(eTagNew);

                customDataManager.IsNew = false; // Mark file as not new just in case the server did not return the ETag.

                // Update ETag in custom column displayed in file manager.
                await customDataManager.SetCustomColumnsAsync(new[] { new FileSystemItemPropertyData((int)CustomColumnIds.ETag, eTagNew) });
            }

            return(null);
        }
コード例 #9
0
        ///<inheritdoc>
        public async Task LockAsync(LockMode lockMode)
        {
            Logger.LogMessage($"{nameof(ILock)}.{nameof(LockAsync)}()", UserFileSystemPath);

            ExternalDataManager customDataManager = Engine.CustomDataManager(UserFileSystemPath, Logger);
            LockManager         lockManager       = customDataManager.LockManager;

            if (!await lockManager.IsLockedAsync() &&
                !Engine.CustomDataManager(UserFileSystemPath).IsNew)
            {
                // Set pending icon, so the user has a feedback as lock operation may take some time.
                await customDataManager.SetLockPendingIconAsync(true);

                // Call your remote storage here to lock the item.
                // Save the lock token and other lock info received from the remote storage on the client.
                // Supply the lock-token as part of each remote storage update in IFile.WriteAsync() method.

                LockInfo lockInfo = await Program.DavClient.LockAsync(new Uri(RemoteStoragePath), LockScope.Exclusive, false, null, TimeSpan.MaxValue);

                ServerLockInfo serverLockInfo = new ServerLockInfo
                {
                    LockToken             = lockInfo.LockToken.LockToken,
                    Exclusive             = lockInfo.LockScope == LockScope.Exclusive,
                    Owner                 = lockInfo.Owner,
                    LockExpirationDateUtc = DateTimeOffset.Now.Add(lockInfo.TimeOut)
                };

                // Save lock-token and lock-mode.
                await lockManager.SetLockInfoAsync(serverLockInfo);

                await lockManager.SetLockModeAsync(lockMode);

                // Set lock icon and lock info in custom columns.
                await customDataManager.SetLockInfoAsync(serverLockInfo);

                Logger.LogMessage("Locked in remote storage succesefully.", UserFileSystemPath);
            }
        }
コード例 #10
0
        /// <inheritdoc/>
        public async Task GetChildrenAsync(string pattern, IOperationContext operationContext, IFolderListingResultContext resultContext)
        {
            // This method has a 60 sec timeout.
            // To process longer requests and reset the timout timer call one of the following:
            // - resultContext.ReturnChildren() method.
            // - resultContext.ReportProgress() method.

            Logger.LogMessage($"{nameof(IFolder)}.{nameof(GetChildrenAsync)}({pattern})", UserFileSystemPath);

            IHierarchyItemAsync[] remoteStorageChildren = null;
            // Retry the request in case the log-in dialog is shown.
            try
            {
                remoteStorageChildren = await Program.DavClient.GetChildrenAsync(new Uri(RemoteStoragePath), false);
            }
            catch (ITHit.WebDAV.Client.Exceptions.Redirect302Exception)
            {
                remoteStorageChildren = await Program.DavClient.GetChildrenAsync(new Uri(RemoteStoragePath), false);
            }

            List <FileSystemItemMetadataExt> userFileSystemChildren = new List <FileSystemItemMetadataExt>();


            foreach (IHierarchyItemAsync remoteStorageItem in remoteStorageChildren)
            {
                FileSystemItemMetadataExt itemInfo = Mapping.GetUserFileSystemItemMetadata(remoteStorageItem);

                string userFileSystemItemPath = Path.Combine(UserFileSystemPath, itemInfo.Name);

                // Filtering existing files/folders. This is only required to avoid extra errors in the log.
                if (!FsPath.Exists(userFileSystemItemPath))
                {
                    Logger.LogMessage("Creating", userFileSystemItemPath);
                    userFileSystemChildren.Add(itemInfo);
                }

                ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemItemPath);

                // Mark this item as not new, which is required for correct MS Office saving opertions.
                customDataManager.IsNew = false;
            }

            // To signal that the children enumeration is completed
            // always call ReturnChildren(), even if the folder is empty.
            resultContext.ReturnChildren(userFileSystemChildren.ToArray(), userFileSystemChildren.Count());

            // Save ETags, the read-only attribute and all custom columns data.
            foreach (FileSystemItemMetadataExt child in userFileSystemChildren)
            {
                string userFileSystemItemPath         = Path.Combine(UserFileSystemPath, child.Name);
                ExternalDataManager customDataManager = Engine.CustomDataManager(userFileSystemItemPath);

                // Save ETag on the client side, to be sent to the remote storage as part of the update.
                // Setting ETag also marks an item as not new.

                // ETags must correspond with a server file/folder, NOT with a client placeholder.
                // It should NOT be moved/deleted/updated when a placeholder in the user file system is moved/deleted/updated.
                // It should be moved/deleted when a file/folder in the remote storage is moved/deleted.
                await customDataManager.ETagManager.SetETagAsync(child.ETag);

                // Set the read-only attribute and all custom columns data.
                await customDataManager.SetLockedByAnotherUserAsync(child.LockedByAnotherUser);

                await customDataManager.SetCustomColumnsAsync(child.CustomProperties);
            }
        }