/// <summary> /// Determines whether the client has submitted lock tokens for all locked files in the subtree. /// </summary> /// <returns>Returns <c>true</c> if lock tockens for all locked files in the subtree are submitted.</returns> internal async Task <bool> ClientHasTokenForTreeAsync() { if (!await ClientHasTokenAsync()) { return(false); } foreach (IHierarchyItemAsync child in (await GetChildrenAsync(new PropertyName[0], null, null, null)).Page) { DavFolder childFolder = child as DavFolder; if (childFolder != null) { if (!await childFolder.ClientHasTokenForTreeAsync()) { return(false); } } else { DavHierarchyItem childItem = child as DavHierarchyItem; if (!await childItem.ClientHasTokenAsync()) { return(false); } } } return(true); }
/// <summary> /// Moves this file to different folder and renames it. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New file name.</param> /// <param name="multistatus">Container for errors with items other than this file.</param> public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus) { DavFolder destDavFolder = destFolder as DavFolder; if (destFolder == null) { throw new DavException("Destination folder doesn't exist.", DavStatus.CONFLICT); } DavFolder parent = await GetParentAsync(); if (parent == null) { throw new DavException("Cannot move root.", DavStatus.CONFLICT); } if (!await ClientHasTokenAsync() || !await destDavFolder.ClientHasTokenAsync() || !await parent.ClientHasTokenAsync()) { throw new LockedException(); } DavHierarchyItem destItem = await destDavFolder.FindChildAsync(destName); if (destItem != null) { try { await destItem.DeleteAsync(multistatus); } catch (DavException ex) { multistatus.AddInnerException(destItem.Path, ex); return; } } await MoveThisItemAsync(destDavFolder, destName, parent); // Refresh client UI. await Context.socketService.NotifyRefreshAsync(parent.Path); await Context.socketService.NotifyRefreshAsync(destDavFolder.Path); }
protected static async Task FindLocksDownAsync(IHierarchyItemAsync root, bool skipShared) { IFolderAsync folder = root as IFolderAsync; if (folder != null) { foreach (IHierarchyItemAsync child in (await folder.GetChildrenAsync(new PropertyName[0], null, null, null)).Page) { DavHierarchyItem dbchild = child as DavHierarchyItem; if (await dbchild.ItemHasLockAsync(skipShared)) { MultistatusException mex = new MultistatusException(); mex.AddInnerException(dbchild.Path, new LockedException()); throw mex; } await FindLocksDownAsync(child, skipShared); } } }
/// <summary> /// Deletes this folder. /// </summary> /// <param name="multistatus">Container for errors. /// If some child file/folder fails to remove we report error in this container.</param> public override async Task DeleteAsync(MultistatusException multistatus) { DavFolder parent = await GetParentAsync(); if (parent == null) { throw new DavException("Cannot delete root.", DavStatus.CONFLICT); } if (!await parent.ClientHasTokenAsync()) { throw new LockedException(); } if (!await ClientHasTokenAsync()) { throw new LockedException(); } bool deletedAllChildren = true; foreach (IHierarchyItemAsync child in (await GetChildrenAsync(new PropertyName[0], null, null, null)).Page) { DavHierarchyItem dbchild = child as DavHierarchyItem; try { await dbchild.DeleteAsync(multistatus); } catch (DavException ex) { multistatus.AddInnerException(dbchild.Path, ex); deletedAllChildren = false; } } if (deletedAllChildren) { await DeleteThisItemAsync(parent); await Context.socketService.NotifyDeletedAsync(Path); } }
/// <summary> /// Copies this file to another folder. /// </summary> /// <param name="destFolder">Destination folder.</param> /// <param name="destName">New file name in destination folder.</param> /// <param name="deep">Is not used.</param> /// <param name="multistatus">Container for errors with items other than this file.</param> public override async Task CopyToAsync( IItemCollectionAsync destFolder, string destName, bool deep, MultistatusException multistatus) { DavFolder destDavFolder = destFolder as DavFolder; if (destFolder == null) { throw new DavException("Destination folder doesn't exist.", DavStatus.CONFLICT); } if (!await destDavFolder.ClientHasTokenAsync()) { throw new LockedException("Doesn't have token for destination folder."); } DavHierarchyItem destItem = await destDavFolder.FindChildAsync(destName); if (destItem != null) { try { await destItem.DeleteAsync(multistatus); } catch (DavException ex) { multistatus.AddInnerException(destItem.Path, ex); return; } } await CopyThisItemAsync(destDavFolder, null, destName); await Context.socketService.NotifyRefreshAsync(destDavFolder.Path); }
internal async Task <DavFolder> CopyThisItemAsync(DavFolder destFolder, DavHierarchyItem destItem, string destName) { // returns created folder, if any, otherwise null DavFolder createdFolder = null; Guid destID; if (destItem == null) { // copy item string commandText = @"INSERT INTO Item( ItemId , Name , Created , Modified , ParentItemId , ItemType , Content , ContentType , SerialNumber , TotalContentLength , LastChunkSaved , FileAttributes ) SELECT @Identity , @Name , GETUTCDATE() , GETUTCDATE() , @Parent , ItemType , Content , ContentType , SerialNumber , TotalContentLength , LastChunkSaved , FileAttributes FROM Item WHERE ItemId = @ItemId"; destID = Guid.NewGuid(); await Context.ExecuteNonQueryAsync( commandText, "@Name", destName, "@Parent", destFolder.ItemId, "@ItemId", ItemId, "@Identity", destID); await destFolder.UpdateModifiedAsync(); if (this is IFolderAsync) { createdFolder = new DavFolder( Context, destID, destFolder.ItemId, destName, destFolder.Path + EncodeUtil.EncodeUrlPart(destName) + "/", DateTime.UtcNow, DateTime.UtcNow, fileAttributes); } } else { // update existing destination destID = destItem.ItemId; string commandText = @"UPDATE Item SET Modified = GETUTCDATE() , ItemType = src.ItemType , ContentType = src.ContentType FROM (SELECT * FROM Item WHERE ItemId=@SrcID) src WHERE Item.ItemId=@DestID"; await Context.ExecuteNonQueryAsync( commandText, "@SrcID", ItemId, "@DestID", destID); // remove old properties from the destination await Context.ExecuteNonQueryAsync( "DELETE FROM Property WHERE ItemID = @ItemID", "@ItemID", destID); } // copy properties string command = @"INSERT INTO Property(ItemID, Name, Namespace, PropVal) SELECT @DestID, Name, Namespace, PropVal FROM Property WHERE ItemID = @SrcID"; await Context.ExecuteNonQueryAsync( command, "@SrcID", ItemId, "@DestID", destID); return(createdFolder); }
/// <summary> /// Moves this folder to destination folder with option to rename. /// </summary> /// <param name="destFolder">Folder to copy this folder to.</param> /// <param name="destName">New name of this folder.</param> /// <param name="multistatus">Container for errors. We put here errors occurring while moving /// individual files/folders.</param> public override async Task MoveToAsync(IItemCollectionAsync destFolder, string destName, MultistatusException multistatus) { // in this function we move item by item, because we want to check if each item is not locked. DavFolder destDavFolder = destFolder as DavFolder; if (destFolder == null) { throw new DavException("Destination folder doesn't exist", DavStatus.CONFLICT); } if (isRecursive(destDavFolder)) { throw new DavException("Cannot move folder to its subtree", DavStatus.FORBIDDEN); } DavFolder parent = await GetParentAsync(); if (parent == null) { throw new DavException("Cannot move root", DavStatus.CONFLICT); } if (!await ClientHasTokenAsync() || !await destDavFolder.ClientHasTokenAsync() || !await parent.ClientHasTokenAsync()) { throw new LockedException(); } DavHierarchyItem destItem = await destDavFolder.FindChildAsync(destName); DavFolder newDestFolder; // copy this folder if (destItem != null) { if (destItem is IFileAsync) { try { await destItem.DeleteAsync(multistatus); } catch (DavException ex) { multistatus.AddInnerException(destItem.Path, ex); return; } newDestFolder = await CopyThisItemAsync(destDavFolder, null, destName); } else { newDestFolder = destItem as DavFolder; if (newDestFolder == null) { multistatus.AddInnerException( destItem.Path, new DavException("Destionation item is not folder", DavStatus.CONFLICT)); } } } else { newDestFolder = await CopyThisItemAsync(destDavFolder, null, destName); } // move children bool movedAllChildren = true; foreach (IHierarchyItemAsync child in (await GetChildrenAsync(new PropertyName[0], null, null, null)).Page) { DavHierarchyItem dbchild = child as DavHierarchyItem; try { await dbchild.MoveToAsync(newDestFolder, child.Name, multistatus); } catch (DavException ex) { multistatus.AddInnerException(dbchild.Path, ex); movedAllChildren = false; } } if (movedAllChildren) { await DeleteThisItemAsync(parent); } // Refresh client UI. await Context.socketService.NotifyMovedAsync(Path, newDestFolder.Path); }