Beispiel #1
0
        /// <summary>
        /// Move a given relative path to a new name, in the same directory.
        /// </summary>
        public void RenamePath(string srcPath, string newName)
        {
            Debug.Assert(KfsPath.IsValidFileName(newName));

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

            try
            {
                // Check that the new name has no invalid characters.
                if (!KfsPath.IsValidFileName(newName))
                    throw new GateIllegalException("Invalid name (" + newName + "). Note that files and folders cannot contain any of the following characters:\n*, \\, /, ?, :, |, <, >.");

                // Get the relative path to the source directory.
                String dirPath = KfsPath.DirName(srcPath);

                // Make sure the source exists.
                GatePathType srcType = GetInternalPathType(srcPath);
                if (srcType != GatePathType.Dir && srcType != GatePathType.File)
                    throw new GateSyncException();

                // Make sure the destination does not exist.
                String dstPath = dirPath + newName;
                GatePathType dstType = GetInternalPathType(dstPath);
                if (dstType != GatePathType.None)
                    throw new GateIllegalException("A file or folder with the name you specified " +
                                                   "already exists. Please specify a different name.");

                // Check for transfers.
                List<String> transferPathArray = new List<String>();
                transferPathArray.Add(srcPath);
                transferPathArray.Add(dstPath);
                ThrowIfContainFileTransfer(transferPathArray);

                // Get information about the source and the destination.
                bool fileFlag = (srcType == GatePathType.File);
                KfsServerObject srcObject = Share.ServerView.GetObjectByPath(srcPath);

                // The source exists only locally.
                if (srcObject == null)
                {
                    // Move the file or directory locally.
                    if (fileFlag) File.Move(Share.MakeAbsolute(srcPath), Share.MakeAbsolute(dstPath));
                    else Directory.Move(Share.MakeAbsolute(srcPath), Share.MakeAbsolute(dstPath));
                }

                // Ask the server to move the file.
                else
                {
                    KfsPhase1Payload payload = new KfsPhase1Payload();
                    KfsServerObject dirObject = Share.ServerView.GetObjectByPath(dirPath);
                    payload.AddMoveOp(fileFlag,
                                      srcObject.Inode,
                                      srcObject.CommitID,
                                      dirObject.Inode,
                                      dirObject.CommitID,
                                      newName);

                    // Request the move on the server.
                    Debug.Assert(Share.MetaDataManager.Status == MetaDataManagerStatus.Idle);
                    Share.MetaDataManager.QueueOperation(payload, null, MetaDataTask.Move);
                }
            }

            catch (Exception ex)
            {
                HandleException(ex);
            }

            GateExit("RenamePath");
        }
Beispiel #2
0
        /// <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;
        }