Ejemplo n.º 1
0
Archivo: KfsGate.cs Proyecto: tmbx/kwm
        /// <summary>
        /// Helper method for MovePath(). 'fromLoc' and 'toLoc' must end with a
        /// delimiter when non-empty.
        /// </summary>
        private bool MovePathRecursive(String fromLoc,
            String toLoc,
            List<String> srcArray,
            KfsPhase1Payload payload,
            bool topLevelFlag,
            ref String typeConflictAction)
        {
            // Remember whether we moved all the sources we had to move.
            bool allMovedFlag = true;

            // Add the missing local directories for the destination.
            Share.AddMissingLocalDirectories(toLoc);

            // Move the sources.
            String fileExistAction = "a";
            String dirExistAction = "a";

            foreach (String srcName in srcArray)
            {
                // Get the objects involved.
                String srcRelPath = fromLoc + srcName;
                String dstRelPath = toLoc + srcName;
                String srcFullPath = Share.MakeAbsolute(srcRelPath);
                String dstFullPath = Share.MakeAbsolute(dstRelPath);
                KfsStatusPath srcStatus = Share.StatusView.GetPath(srcRelPath);
                KfsStatusPath dstStatus = Share.StatusView.GetPath(dstRelPath);
                Debug.Assert(srcStatus != null, "srcStatus == null");
                KfsServerObject srcObject = srcStatus.ServerObject;
                KfsServerObject dstObject = (dstStatus == null) ? null : dstStatus.ServerObject;
                GatePathType srcType = GetInternalPathType(srcRelPath);
                GatePathType dstType = GetInternalPathType(dstRelPath);

                // Stale types, get out of here.
                if (srcType == GatePathType.None ||
                    srcType == GatePathType.Stale ||
                    dstType == GatePathType.Stale)
                    throw new GateSyncException();

                // There is a type conflict.
                else if (dstType != GatePathType.None && srcType != dstType)
                {
                    String prompt = "The entry " + srcRelPath + " conflicts with the entry " + dstRelPath + ".";
                    ShowChoiceDialog(prompt, "sc", ref typeConflictAction);
                    allMovedFlag = false;
                    continue;
                }

                // Add the 'to' directory remotely if the source exists remotely.
                if (srcObject != null) AddMissingServerDirectories(toLoc, payload);

                // We are in a directory-directory situation.
                if (srcType == GatePathType.Dir && dstType == GatePathType.Dir)
                {
                    if (topLevelFlag)
                    {
                        // Skip or overwrite the directory.
                        String prompt = "This folder already contains a folder named '" + dstRelPath + "'." + Environment.NewLine +
                                "If the files in the existing folder have the same name as files in the folder you are moving, they will be replaced. Do you still want to move this folder?";
                        String res = ShowChoiceDialog(prompt, "swc", ref dirExistAction);
                        if (res == "s")
                        {
                            allMovedFlag = false;
                            continue;
                        }
                    }

                    // Move all files and directories contained in the source directory.
                    String newFromLoc = srcRelPath + "/";
                    String newToLoc = dstRelPath + "/";
                    List<String> newSrcArray = new List<String>();
                    foreach (String name in srcStatus.ChildTree.Keys) newSrcArray.Add(name);
                    bool subMovedFlag = MovePathRecursive(newFromLoc, newToLoc, newSrcArray, payload,
                                                          false, ref typeConflictAction);

                    // All subdirectories and files were moved.
                    if (subMovedFlag)
                    {
                        // Ask the server to delete the source if it exists remotely.
                        if (srcStatus.HasServerDir())
                        {
                            payload.AddDeleteOp(false, srcObject.Inode, srcObject.CommitID);
                        }

                        // Otherwise, delete the source locally since the server won't do it
                        // for us.
                        else
                        {
                            File.SetAttributes(srcFullPath, FileAttributes.Normal);
                            Directory.Delete(srcFullPath);
                        }
                    }

                    // Not all subdirectories and files were moved.
                    else allMovedFlag = false;
                }

                // We are in a file-none, file-file or dir-none situation.
                else
                {
                    // Remember whether we are in a file-none or file-file situation.
                    bool fileFlag = (srcType == GatePathType.File);

                    // The destination exists.
                    if (dstStatus != null)
                    {
                        // Skip the source or overwrite the destination.
                        if (topLevelFlag && dstStatus.OnServerAndNotGhost())
                        {
                            String prompt = "The file " + dstRelPath + " already exists.";
                            String res = ShowChoiceDialog(prompt, "swc", ref fileExistAction);
                            if (res == "s")
                            {
                                allMovedFlag = false;
                                continue;
                            }
                        }

                        // Delete the destination file locally if it exists.
                        if (File.Exists(dstFullPath))
                        {
                            File.SetAttributes(dstFullPath, FileAttributes.Normal);
                            File.Delete(dstFullPath);
                        }
                    }

                    // The source exists only locally.
                    if (srcObject == null)
                    {
                        // The destination exists.
                        if (dstStatus != null)
                        {
                            // If the destination file exists remotely and it is not a ghost,
                            // pretend its current version was downloaded. This will make the
                            // source appear as ModifiedCurrent or UnmodifiedCurrent.
                            if (dstStatus.OnServerAndNotGhost())
                            {
                                KfsServerFile f = dstObject as KfsServerFile;
                                Debug.Assert(f != null);
                                f.UpdateDownloadVersion(f.CurrentVersion, true);
                            }
                        }

                        // Move the file or directory locally.
                        if (fileFlag) File.Move(srcFullPath, dstFullPath);
                        else Directory.Move(srcFullPath, dstFullPath);
                    }

                    // The source exists remotely.
                    else
                    {
                        // The destination file also exists remotely. Remove it.
                        if (dstObject != null)
                            payload.AddDeleteOp(true, dstObject.Inode, dstObject.CommitID);

                        // Ask the server to move the file.
                        UInt64 parentInode;
                        UInt64 parentCommitID;
                        String parentRelPath;
                        GetServerObjectPath(dstRelPath, out parentInode, out parentCommitID, out parentRelPath);
                        payload.AddMoveOp(fileFlag,
                                          srcObject.Inode,
                                          srcObject.CommitID,
                                          parentInode,
                                          parentCommitID,
                                          parentRelPath);
                    }
                }
            }

            return allMovedFlag;
        }
Ejemplo n.º 2
0
Archivo: KfsGate.cs Proyecto: tmbx/kwm
        /// <summary>
        /// Delete the selected relative paths recursively.
        /// </summary>
        public void DeletePath(List<String> pathArray)
        {
            GateEntry("DeletePath");

            // Disallow all user operations until the pipeline stabilized.
            Share.DisallowUserOp("DeletePath() called", AllowedOpStatus.None);

            try
            {
                // Check for transfers.
                ThrowIfContainFileTransfer(pathArray);

                // Get the entries to delete, both locally and remotely.
                HashedSet<String> seenSet = new HashedSet<String>();
                List<String> fileArray = new List<String>();
                List<String> dirArray = new List<String>();
                KfsPhase1Payload payload = new KfsPhase1Payload();

                foreach (String path in pathArray)
                {
                    // Get the paths in leaf-first order, so that we delete entries in
                    // directories before their parents.
                    foreach (KfsStatusPath sp in Share.StatusView.GetPathArray(path, true))
                    {
                        // Skip already processed paths.
                        if (seenSet.Contains(sp.Path)) continue;

                        // Remember that we have processed that path.
                        seenSet.Add(sp.Path);

                        // Sanity check.
                        if (sp.IsUndetermined() || sp.IsTypeConflict()) throw new GateSyncException();

                        // Handle remote deletion.
                        if (sp.HasServerFile())
                            payload.AddDeleteOp(true, sp.ServerObject.Inode, sp.ServerObject.CommitID);

                        else if (sp.HasServerDir())
                            payload.AddDeleteOp(false, sp.ServerObject.Inode, sp.ServerObject.CommitID);

                        // Handle local deletion.
                        if (sp.HasLocalFile()) fileArray.Add(sp.Path);
                        else if (sp.HasLocalDir()) dirArray.Add(sp.Path);
                    }
                }

                // Delete the files and directories locally.
                foreach (String path in fileArray)
                {
                    try
                    {
                        string absPath = Share.MakeAbsolute(path);
                        File.SetAttributes(absPath, FileAttributes.Normal);
                        File.Delete(absPath);
                    }
                    // Silently ignore NotFoundExceptions since we WANT
                    // to have this path removed from the disk.
                    catch (FileNotFoundException)
                    {
                    }
                    catch (DirectoryNotFoundException)
                    {
                    }

                }
                foreach (String path in dirArray)
                {
                    try
                    {
                        string absPath = Share.MakeAbsolute(path);
                        File.SetAttributes(absPath, FileAttributes.Normal);
                        Directory.Delete(Share.MakeAbsolute(path));
                    }
                    // Silently ignore NotFoundExceptions since we WANT
                    // to have this path removed from the disk.
                    catch (FileNotFoundException)
                    {
                    }
                    catch (DirectoryNotFoundException)
                    {
                    }
                }

                // Request the deletion on the server.
                Debug.Assert(Share.MetaDataManager.Status == MetaDataManagerStatus.Idle);
                if (payload.OpList.Count > 0)
                    Share.MetaDataManager.QueueOperation(payload, null, MetaDataTask.Delete);
            }

            catch (IOException ex)
            {
                Misc.KwmTellUser("Unable to delete the selected file or folder : " +
                                  Environment.NewLine + Environment.NewLine + ex.Message,
                                  "Error Deleting File or Folder",
                                  MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }

            GateExit("DeletePath");
        }
Ejemplo n.º 3
0
Archivo: KfsGate.cs Proyecto: tmbx/kwm
 /// <summary>
 /// Add an operation to delete the ghost specified in the payload
 /// specified.
 /// </summary>
 private void DeleteGhost(KfsServerObject o, KfsPhase1Payload p)
 {
     Debug.Assert(o.IsGhost());
     p.AddDeleteOp(true, o.Inode, o.CommitID);
 }