/// <summary>
 /// Determines whether <paramref name="destFolder"/> is inside this folder.
 /// </summary>
 /// <param name="destFolder">Folder to check.</param>
 /// <returns>Returns <c>true</c> if <paramref name="destFolder"/> is inside thid folder.</returns>
 private bool IsRecursive(DavFolder destFolder)
 {
     return(destFolder.Path.StartsWith(Path));
 }
Esempio n. 2
0
        /// <summary>
        /// Called when this file is being moved or renamed.
        /// </summary>
        /// <param name="destFolder">Destination folder.</param>
        /// <param name="destName">New name of this file.</param>
        /// <param name="multistatus">Information about items that failed to move.</param>
        public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus)
        {
            await RequireHasTokenAsync();

            DavFolder targetFolder = (DavFolder)destFolder;

            if (targetFolder == null || !Directory.Exists(targetFolder.FullPath))
            {
                throw new DavException("Target directory doesn't exist", DavStatus.CONFLICT);
            }

            string newDirPath = System.IO.Path.Combine(targetFolder.FullPath, destName);
            string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName);

            // If an item with the same name exists in target directory - remove it.
            try
            {
                IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath) as IHierarchyItemAsync;

                if (item != null)
                {
                    await item.DeleteAsync(multistatus);
                }
            }
            catch (DavException ex)
            {
                // Report exception to client and continue with other items by returning from recursion.
                multistatus.AddInnerException(targetPath, ex);
                return;
            }

            // Move the file.
            try
            {
                File.Move(fileSystemInfo.FullName, newDirPath);

                var newFileInfo = new FileInfo(newDirPath);
                if (FileSystemInfoExtension.IsUsingFileSystemAttribute)
                {
                    await fileSystemInfo.MoveExtendedAttributes(newFileInfo);
                }

                // Locks should not be copied, delete them.
                if (await newFileInfo.HasExtendedAttributeAsync("Locks"))
                {
                    await newFileInfo.DeleteExtendedAttributeAsync("Locks");
                }
            }
            catch (UnauthorizedAccessException)
            {
                // Exception occurred with the item for which MoveTo was called - fail the operation.
                NeedPrivilegesException ex = new NeedPrivilegesException("Not enough privileges");
                ex.AddRequiredPrivilege(targetPath, Privilege.Bind);

                string parentPath = System.IO.Path.GetDirectoryName(Path);
                ex.AddRequiredPrivilege(parentPath, Privilege.Unbind);
                throw ex;
            }
            // Refresh client UI.
            await context.socketService.NotifyRefreshAsync(GetParentPath(Path));

            await context.socketService.NotifyRefreshAsync(targetFolder.Path);
        }
        /// <summary>
        /// Called when this folder is being moved or renamed.
        /// </summary>
        /// <param name="destFolder">Destination folder.</param>
        /// <param name="destName">New name of this folder.</param>
        /// <param name="multistatus">Information about child items that failed to move.</param>
        public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus)
        {
            await RequireHasTokenAsync();

            if (!(destFolder is DavFolder))
            {
                throw new DavException("Target folder doesn't exist", DavStatus.CONFLICT);
            }

            DavFolder targetFolder = (DavFolder)destFolder;

            if (IsRecursive(targetFolder))
            {
                throw new DavException("Cannot move folder to its subtree.", DavStatus.FORBIDDEN);
            }

            string newDirPath = System.IO.Path.Combine(targetFolder.FullPath, destName);
            string targetPath = targetFolder.Path + EncodeUtil.EncodeUrlPart(destName);

            try
            {
                // Remove item with the same name at destination if it exists.
                IHierarchyItemAsync item = await context.GetHierarchyItemAsync(targetPath) as IHierarchyItemAsync;

                if (item != null)
                {
                    await item.DeleteAsync(multistatus);
                }

                await targetFolder.CreateFolderAsync(destName);
            }
            catch (DavException ex)
            {
                // Continue the operation but report error with destination path to client.
                multistatus.AddInnerException(targetPath, ex);
                return;
            }

            // Move child items.
            bool         movedSuccessfully = true;
            IFolderAsync createdFolder     = (IFolderAsync)await context.GetHierarchyItemAsync(targetPath);

            foreach (DavHierarchyItem item in (await GetChildrenAsync(new PropertyName[0], null, null, new List <OrderProperty>())).Page)
            {
                try
                {
                    await item.MoveToAsync(createdFolder, item.Name, multistatus);
                }
                catch (DavException ex)
                {
                    // Continue the operation but report error with child item to client.
                    multistatus.AddInnerException(item.Path, ex);
                    movedSuccessfully = false;
                }
            }

            if (movedSuccessfully)
            {
                await DeleteAsync(multistatus);
            }
            // Refresh client UI.
            await context.socketService.NotifyDeleteAsync(Path);

            await context.socketService.NotifyRefreshAsync(GetParentPath(targetPath));
        }