예제 #1
1
        //Appends the any xml file/folder nodes onto the folder
        private void AddXmlNodes(FolderCompareObject folder, int numOfPaths, XmlDocument xmlDoc)
        {
            List<XMLCompareObject> xmlObjList = new List<XMLCompareObject>();
            List<string> xmlFolderList = new List<string>();

            for (int i = 0; i < numOfPaths; i++)
            {
                string path = Path.Combine(folder.GetSmartParentPath(i), folder.Name);

                if (Directory.Exists(path))
                {
                    DirectoryInfo dirInfo = new DirectoryInfo(path);
                    FileInfo[] fileList = dirInfo.GetFiles();
                    DirectoryInfo[] dirInfoList = dirInfo.GetDirectories();
                    string xmlPath = Path.Combine(path, CommonXMLConstants.MetadataPath);

                    if (!File.Exists(xmlPath))
                        continue;

                    CommonMethods.LoadXML(ref xmlDoc, xmlPath);
                    xmlObjList = GetAllFilesInXML(xmlDoc);
                    xmlFolderList = GetAllFoldersInXML(xmlDoc);
                    RemoveSimilarFiles(xmlObjList, fileList);
                    RemoveSimilarFolders(xmlFolderList, dirInfoList);
                }

                AddFileToChild(xmlObjList, folder, i, numOfPaths);
                AddFolderToChild(xmlFolderList, folder, i, numOfPaths);
                xmlObjList.Clear();
                xmlFolderList.Clear();
            }
        }
예제 #2
0
        /// <summary>
        /// Visit implementaton for <see cref="FolderCompareObject"/>.
        /// </summary>
        /// <param name="folder">The <see cref="FolderCompareObject"/> to process.</param>
        /// <param name="numOfPaths">The total number of folders to sync.</param>
        public void Visit(FolderCompareObject folder, int numOfPaths)
        {
            _nodesCount++;
            _syncProgress.Message = folder.Name;

            if (folder.Invalid)
            {
                _syncProgress.Fail();
                return;
            }

            int maxPriorityPos = folder.SourcePosition; // Get the position of the source file.

            if (folder.Priority[maxPriorityPos] > 0)
            {
                switch (folder.ChangeType[maxPriorityPos])
                {
                    case MetaChangeType.Delete:
                        DeleteFolder(folder, numOfPaths, maxPriorityPos);
                        break;
                    case MetaChangeType.New:
                    case MetaChangeType.NoChange:
                        CreateFolder(folder, numOfPaths, maxPriorityPos);
                        break;
                    case MetaChangeType.Rename:
                        MoveFolder(folder, numOfPaths, maxPriorityPos);
                        break;
                }
            }
            _syncProgress.Complete();
        }
예제 #3
0
        /// <summary>
        /// Visit <see cref="FolderCompareObject"/> implementation for BuilderVisitor.
        /// </summary>
        /// <param name="folder">The <see cref="FolderCompareObject"/> to build and process.</param>
        /// <param name="numOfPaths">The total number of folders to keep in sync.</param>
        public void Visit(FolderCompareObject folder, int numOfPaths)
        {
            try
            {
                RootCompareObject root = folder as RootCompareObject;

                for (int index = 0; index < numOfPaths; index++)
                {
                    string path = root == null ? Path.Combine(folder.GetSmartParentPath(index), folder.Name) : root.Paths[index];
                    DirectoryInfo f = new DirectoryInfo(path);

                    if (f.Exists)
                    {
                        if (_progress != null)
                        {
                            _progress.Message = f.FullName;
                            _progress.Update();
                        }

                        ProcessFolders(folder, numOfPaths, f, index);
                        ProcessFiles(folder, numOfPaths, f, index);
                    }
                }
            }
            catch (UnauthorizedAccessException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to unauthorized access."));
            }
            catch (PathTooLongException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to path being too long."));
            }
        }
예제 #4
0
        /// <summary>
        /// Visit implementation for <see cref="FolderCompareObject"/>.
        /// </summary>
        /// <param name="folder">The <see cref="FolderCompareObject"/> to process.</param>
        /// <param name="numOfPaths">The total number of folders to keep in sync.</param>
        public void Visit(FolderCompareObject folder, int numOfPaths)
        {
            if (folder.Invalid)
                return;

            CompareFolders(folder, numOfPaths);
            _totalNodes++;
        }
예제 #5
0
        private long[] _metaLastWriteTimeUtc; // Array to store the last write time of each file based on metadata.

        /// <summary>
        /// Initializes a <c>FileCompareObject</c> given the name of the file, the number of paths to synchronize, and the parent of this file.
        /// </summary>
        /// <param name="name">A <see cref="string"/> containing the name of this <c>FileCompareObject</c>.</param>
        /// <param name="numOfPaths">An <see cref="int"/> containing the number of paths to synchronize.</param>
        /// <param name="parent">The <see cref="FolderCompareObject"/> which is the parent of this <c>FileCompareObject</c>.</param>
        public FileCompareObject(string name, int numOfPaths, FolderCompareObject parent)
            : base(name, numOfPaths, parent)
        {
            _hash = new string[numOfPaths];
            _length = new long[numOfPaths];
            _lastWriteTimeUtc = new long[numOfPaths];

            _metaHash = new string[numOfPaths];
            _metaLength = new long[numOfPaths];
            _metaLastWriteTimeUtc = new long[numOfPaths];
        }
예제 #6
0
        /// <summary>
        /// Helper Method to traverse a FolderCompareObjects and all foldercompareobjects and filecompareobjects under it
        /// </summary>
        /// <param name="folder">FolderCompareObject to start the traversal</param>
        /// <param name="numOfPaths">No. of paths available</param>
        /// <param name="visitor">A particular visit to visit the RCOs. In this case, it will be the PreviewVisitor</param>
        private static void TraverseFolderHelper(FolderCompareObject folder, int numOfPaths, IVisitor visitor)
        {
            visitor.Visit(folder, numOfPaths);

            Dictionary<string, BaseCompareObject>.ValueCollection values = folder.Contents.Values;
            FolderCompareObject fco;
            foreach (BaseCompareObject o in values)
            {
                if ((fco = o as FolderCompareObject) != null)
                    TraverseFolderHelper(fco, numOfPaths, visitor);
                else
                    visitor.Visit(o as FileCompareObject, numOfPaths);
            }
        }
예제 #7
0
        // Detect folder renames, if any.
        private void DetectFolderRename(FolderCompareObject folder, int numOfPaths)
        {
            List<int> deleteIndexes = new List<int>(); // Keeps a list of deleted indexes
            List<int> unchangedIndexes = new List<int>(); // Keeps a list of unchanged indexes

            for (int i = 0; i < numOfPaths; i++)
            {
                switch (folder.ChangeType[i])
                {
                    case MetaChangeType.Delete:
                        deleteIndexes.Add(i);
                        break;
                    case MetaChangeType.NoChange:
                        unchangedIndexes.Add(i);
                        break;
                }
            }

            // 1. If there exists a folder for which meta exists is true and exists is false, it is (aka changeType.delete)
            //    highly probable that it is a folder rename
            // 2. We check all folders which has the same meta name but different name as the non-existent folder
            // 3. If the count is 1, we shall proceed to rename
            FolderCompareObject folderObject;

            if (deleteIndexes.Count > 0)
            {
                int renameCount;
                folderObject = folder.Parent.GetRenamedFolder(folder.Name, out renameCount);

                if (renameCount > 1) // Multiple renames detected, set all unchanged to New so they will be propagated again
                {
                    foreach (int j in unchangedIndexes)
                        folder.ChangeType[j] = MetaChangeType.New;
                    return; // Exit
                }

                if (folderObject != null) // If folderObject != null and we reach here implies renameCounter is 1.
                {
                    for (int i = 0; i < numOfPaths; i++)
                    {
                        if (!folderObject.Exists[i]) // Remove all delete indexes if folder object does not exist at specified index
                            deleteIndexes.Remove(i); // so that only those that exist will be merged
                    }

                    MergeRenamedFolder(folder, folderObject, deleteIndexes);
                }

            }
        }
예제 #8
0
        private LastKnownState?[] _lastKnownState; // Stores the last known state, eg. delete, if the file system object is no longer found.

        /// <summary>
        /// Initializes a <c>BaseCompareObject</c> given the name, the number of paths to synchronize, and the parent of it.
        /// </summary>
        /// <param name="name">A <see cref="string"/> containing the name.</param>
        /// <param name="numOfPaths">An <see cref="int"/> with the number of paths to synchronize.</param>
        /// <param name="parent">A <see cref="FolderCompareObject"/> which is the parent of this object. It can be null, in the case where this object is a <see cref="RootCompareObject"/>.</param>
        protected BaseCompareObject(string name, int numOfPaths, FolderCompareObject parent)
        {
            _name = name;
            _creationTimeUtc = new long[numOfPaths];
            _exists = new bool[numOfPaths];
            _finalState = new FinalState?[numOfPaths];
            _metaCreationTimeUtc = new long[numOfPaths];
            _metaExists = new bool[numOfPaths];
            _metaUpdated = new long[numOfPaths];
            _changeType = new MetaChangeType?[numOfPaths];
            _priority = new int[numOfPaths];
            _parent = parent;
            _invalid = false;
            _lastKnownState = new LastKnownState?[numOfPaths];
        }
예제 #9
0
        /// <summary>
        /// Visits each folder node and return them and it will update the values either through the meta data
        /// or the last known state document
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="numOfPaths"></param>
        public void Visit(FolderCompareObject folder, int numOfPaths)
        {
            XmlDocument xmlDoc = new XmlDocument();
            PopulateFolderMetaName(folder, numOfPaths);

            for (int i = 0; i < numOfPaths; i++)
            {
                string path = Path.Combine(folder.GetSmartParentPath(i), CommonXMLConstants.MetadataPath);

                if (!File.Exists(path))
                    continue;

                CommonMethods.LoadXML(ref xmlDoc, path);
                folder = PopulateFolderWithMetaData(xmlDoc, folder, i);
            }

            AddXmlNodes(folder, numOfPaths, xmlDoc);
        }
예제 #10
0
        /// <summary>
        /// It calls ProcessFolderFinalState method and if either needLastKnownState or the method is true,
        /// it will call GenerateFolderLastKnownState method to write a last known state document
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="numOfPaths"></param>
        public void Visit(FolderCompareObject folder, int numOfPaths)
        {
            if (folder.Invalid)
                return;

            bool needLastKnownState = false;

            for (int i = 0; i < numOfPaths; i++)
            {
                _progress.Message = Path.Combine(folder.GetSmartParentPath(i), folder.Name);
                needLastKnownState = ProcessFolderFinalState(folder, i) || needLastKnownState;
            }

            if (needLastKnownState)
                GenerateFolderLastKnownState(folder, numOfPaths);

            _progress.Complete();
        }
예제 #11
0
        private void MoveFolder(FolderCompareObject folder, int numOfPaths, int srcFolderPos)
        {
            bool changed = false;

            for (int i = 0; i < numOfPaths; i++)
            {
                if (i != srcFolderPos && folder.Priority[i] != folder.Priority[srcFolderPos])
                {
                    string oldFolderName = Path.Combine(folder.GetSmartParentPath(i), folder.Name);
                    string newFolderName = Path.Combine(folder.GetSmartParentPath(i), folder.NewName);
                    string srcFolderName = Path.Combine(folder.GetSmartParentPath(srcFolderPos), folder.NewName);

                    try
                    {
                        if (Directory.Exists(oldFolderName))
                        {
                            CommonMethods.MoveFolder(oldFolderName, newFolderName); // Rename the old folder to the new name if it exists.
                            folder.FinalState[i] = FinalState.Renamed;
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_RENAMED, "Folder renamed from " + oldFolderName + " to " + newFolderName));
                        }
                        else
                        {
                            CommonMethods.CopyDirectory(srcFolderName, newFolderName); // Copy the directory from the source folder if the old folder does not exist.
                            folder.Exists[i] = true;
                            folder.CreationTimeUtc[i] = Directory.GetCreationTimeUtc(newFolderName).Ticks;
                            folder.FinalState[i] = FinalState.CreatedRenamed;
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_CREATED, "Folder copied from " + srcFolderName + " to " + newFolderName));
                        }
                        changed = true;
                    }
                    catch (MoveFolderException)
                    {
                        folder.FinalState[i] = FinalState.Error;
                        ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ERROR, "Error renaming folder from " + oldFolderName + " to " + newFolderName));
                    }
                    catch (CopyFolderException)
                    {
                        folder.FinalState[i] = FinalState.Error;
                        ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ERROR, "Error copying folder: " + srcFolderName + " to " + newFolderName));
                    }
                }
                else
                {
                    folder.FinalState[i] = FinalState.Renamed;
                    changed = true;
                }
            }
            folder.FinalState[srcFolderPos] = changed ? FinalState.Renamed : FinalState.Unchanged; // If changed is true, that means at least one file has been affected, set the FinalState to renamed. Otherwise, leave it as Unchanged.
        }
예제 #12
0
        private void DeleteFolder(FolderCompareObject folder, int numOfPaths, int srcFolderPos)
        {
            bool changed = false;

            for (int i = 0; i < numOfPaths; i++)
            {
                if (i != srcFolderPos && folder.Priority[i] != folder.Priority[srcFolderPos])
                {
                    string destFolder = Path.Combine(folder.GetSmartParentPath(i), folder.Name);

                    try
                    {
                        if (_syncConfig.ArchiveLimit > 0)
                        {
                            CommonMethods.ArchiveFolder(destFolder, _syncConfig.ArchiveName, _syncConfig.ArchiveLimit);
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ARCHIVED, "Folder archived " + destFolder));
                        }
                    }
                    catch (ArchiveFolderException)
                    {
                        folder.FinalState[i] = FinalState.Error;
                        ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ERROR, "Error archiving folder " + destFolder));
                    }

                    try
                    {
                        if (_syncConfig.Recycle)
                            CommonMethods.DeleteFolderToRecycleBin(destFolder);
                        else
                            CommonMethods.DeleteFolder(destFolder);

                        folder.Exists[i] = false;
                        folder.FinalState[i] = FinalState.Deleted;
                        changed = true; // Set it to true since the change has propaged to at least one folder

                        if (_syncConfig.Recycle)
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_DELETED, "Folder deleted to recycle bin " + destFolder));
                        else
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_DELETED, "Folder deleted " + destFolder));
                    }
                    catch (DeleteFolderException)
                    {
                        folder.FinalState[i] = FinalState.Error;
                        ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ERROR, "Error deleting folder " + destFolder));
                    }
                }
                else
                {
                    folder.FinalState[i] = folder.MetaExists[i] ? FinalState.Deleted : FinalState.Unchanged;
                    changed = true; // Set it to true since the change has propaged to at least one folder
                }

            }
            folder.FinalState[srcFolderPos] = changed ? FinalState.Deleted : FinalState.Unchanged; // Set the FinalState to deleted if changed is true, otherwise set it as Unchanged.
        }
예제 #13
0
        private void CreateFolder(FolderCompareObject folder, int numOfPaths, int srcFolderPos)
        {
            for (int i = 0; i < numOfPaths; i++)
            {
                if (i != srcFolderPos && folder.Priority[i] != folder.Priority[srcFolderPos])
                {
                    string folderToCreate = Path.Combine(folder.GetSmartParentPath(i), folder.Name);

                    if (!Directory.Exists(folderToCreate))
                    {
                        try
                        {
                            CommonMethods.CreateFolder(folderToCreate); // Create the folder since it does not exist
                            folder.Exists[i] = true; // Update the state of the folder
                            folder.CreationTimeUtc[i] = Directory.GetCreationTimeUtc(folderToCreate).Ticks;
                            folder.FinalState[i] = FinalState.Created;
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_CREATED, "Folder created " + folderToCreate));
                        }
                        catch (CreateFolderException)
                        {
                            folder.FinalState[i] = FinalState.Error;
                            ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.FSCHANGE_ERROR, "Error creating folder " + folderToCreate));
                        }
                    }
                }
                else
                {
                    folder.FinalState[i] = folder.MetaExists[i] ? FinalState.Unchanged : FinalState.Created; // Set the FinalState to unchanged if the metadata already exists, else set it to created.
                }
            }
            folder.FinalState[srcFolderPos] = folder.MetaExists[srcFolderPos] ? FinalState.Unchanged : FinalState.Created; // Set the FinalState to unchanged if the metadata exists, else set it to created.
        }
예제 #14
0
        // Based on the folder and counter , it will load the xml document and delete the folder node
        private void DeleteFolderObject(FolderCompareObject folder, int counter)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string xmlPath = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.MetadataPath);

            if (File.Exists(xmlPath))
            {
                CommonMethods.LoadXML(ref xmlDoc, xmlPath);
                XmlNode node = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");

                if (node == null)
                    return;

                node.ParentNode.RemoveChild(node);
                CommonMethods.SaveXML(ref xmlDoc, xmlPath);
            }
        }
예제 #15
0
        // Populate the folder's meta name if it exists
        private void PopulateFolderMetaName(FolderCompareObject folder, int numOfPaths)
        {
            for (int i = 0; i < numOfPaths; i++)
            {
                string currMetaData = Path.Combine(Path.Combine(folder.GetSmartParentPath(i), folder.Name), CommonXMLConstants.MetadataPath);

                if (File.Exists(currMetaData))
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    CommonMethods.LoadXML(ref xmlDoc, currMetaData);
                    XmlNode xmlNode = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + "/name");
                    if (xmlNode != null)
                        folder.MetaName = xmlNode.InnerText;
                    
                }
            }
        }
예제 #16
0
        // For any folder name in the list , create them as a node and append them to the folder node
        private void AddFolderToChild(List<string> folderName, FolderCompareObject folder, int counter, int length)
        {
            for (int i = 0; i < folderName.Count; i++)
            {
                BaseCompareObject o = folder.GetChild(folderName[i]);
                FolderCompareObject fco;

                if (o == null)
                    fco = new FolderCompareObject(folderName[i], length, folder);
                else
                    fco = (FolderCompareObject)o;

                fco.MetaExists[counter] = true;

                if (o == null)
                    folder.AddChild(fco);
            }
        }
예제 #17
0
        // Method will return any time the state of the sync progress becomes cancelled.
        private static void TraverseFolderHelper(FolderCompareObject folder, int numOfPaths, IVisitor visitor, TraverseType type, Progress syncProgress)
        {
            if (syncProgress != null && syncProgress.State == SyncState.Cancelled)
                return;

            if (type == TraverseType.Pre)
                visitor.Visit(folder, numOfPaths);

            Dictionary<string, BaseCompareObject>.ValueCollection values = folder.Contents.Values;
            foreach (BaseCompareObject o in values)
            {
                if (syncProgress != null && syncProgress.State == SyncState.Cancelled)
                    return;

                FolderCompareObject fco;
                if ((fco = o as FolderCompareObject) != null)
                    TraverseFolderHelper(fco, numOfPaths, visitor, type, syncProgress);
                else
                    visitor.Visit(o as FileCompareObject, numOfPaths);
            }

            if (type == TraverseType.Post)
                visitor.Visit(folder, numOfPaths);
        }
예제 #18
0
 // Checks if the last known state document exists and calls the AppendActionFolderLastKnownState method 
 private void GenerateFolderLastKnownState(FolderCompareObject folder, int numOfPaths)
 {
     for (int i = 0; i < numOfPaths; i++)
     {
         string parentPath = folder.GetSmartParentPath(i);
         XmlDocument xmlTodoDoc = new XmlDocument();
         string todoPath = Path.Combine(parentPath, CommonXMLConstants.LastKnownStatePath);
         CommonMethods.CreateLastKnownStateFile(parentPath);
         CommonMethods.LoadXML(ref xmlTodoDoc, todoPath);
         CommonMethods.DoFolderLastKnownCleanUp(xmlTodoDoc, folder.Name);
         AppendActionFolderLastKnownState(xmlTodoDoc, folder, CommonXMLConstants.ActionDeleted);
         CommonMethods.SaveXML(ref xmlTodoDoc, todoPath);
     }
 }
예제 #19
0
        // Deletes a folder node in the last known state file by searching for the name 
        private void DeleteFolderLastKnownState(FolderCompareObject folder, int counter)
        {
            string todoXMLPath = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.LastKnownStatePath);

            if (!File.Exists(todoXMLPath))
                return;

            XmlDocument todoXMLDoc = new XmlDocument();
            CommonMethods.LoadXML(ref todoXMLDoc, todoXMLPath);
            XmlNode folderNode = todoXMLDoc.SelectSingleNode(CommonXMLConstants.XPathLastKnownState + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");

            if (folderNode != null)
                folderNode.ParentNode.RemoveChild(folderNode);

            CommonMethods.SaveXML(ref todoXMLDoc, todoXMLPath);
        }
예제 #20
0
        // Creates a folder node in the last known state file based on the values in FolderCompareObject
        private void AppendActionFolderLastKnownState(XmlDocument xmlDoc, FolderCompareObject folder, string changeType)
        {
            string name = folder.MetaName ?? folder.Name;

            XmlText nameText = xmlDoc.CreateTextNode(name);
            XmlText action = xmlDoc.CreateTextNode(changeType);
            XmlText lastUpdatedUtcText = xmlDoc.CreateTextNode(_dateTime.ToString());

            XmlElement folderElement = xmlDoc.CreateElement(CommonXMLConstants.NodeFolder);
            XmlElement nameElement = xmlDoc.CreateElement(CommonXMLConstants.NodeName);
            XmlElement actionElement = xmlDoc.CreateElement(CommonXMLConstants.NodeAction);
            XmlElement lastUpdatedElement = xmlDoc.CreateElement(CommonXMLConstants.NodeLastUpdatedUtc);

            nameElement.AppendChild(nameText);
            actionElement.AppendChild(action);
            lastUpdatedElement.AppendChild(lastUpdatedUtcText);

            folderElement.AppendChild(nameElement);
            folderElement.AppendChild(actionElement);
            folderElement.AppendChild(lastUpdatedElement);
            XmlNode rootNode = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathLastKnownState);
            
            if(rootNode == null)
                return;
            rootNode.AppendChild(folderElement);
        }
예제 #21
0
        // Based on the folder and path , it will load the xml document in the sub folder and modify the name
        private void ModifyFolderName(FolderCompareObject folder, string subFolderPath)
        {
            string name = folder.NewName ?? folder.Name;
            string xmlPath = Path.Combine(Path.Combine(subFolderPath, name), CommonXMLConstants.MetadataPath);
            XmlDocument subFolderDoc = new XmlDocument();
            CommonMethods.LoadXML(ref subFolderDoc, xmlPath);

            XmlNode xmlNameNode = subFolderDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathName);

            if (xmlNameNode != null)
                xmlNameNode.InnerText = name;

            CommonMethods.SaveXML(ref subFolderDoc, xmlPath);
        }
예제 #22
0
        // Based on the final state of the folder , it will let the respective method handle it
        private bool ProcessFolderFinalState(FolderCompareObject folder, int counter)
        {
            FinalState?[] finalStateList = folder.FinalState;
            FinalState? changeType = finalStateList[counter];
            bool needLastKnownState = false;

            switch (changeType)
            {
                case FinalState.Created:
                    CreateFolderObject(folder, counter, false);
                    break;
                case FinalState.Deleted:
                    DeleteFolderObject(folder, counter);
                    needLastKnownState = true;
                    break;
                case FinalState.Renamed:
                    RenameFolderObject(folder, counter);
                    needLastKnownState = true;
                    break;
                case FinalState.CreatedRenamed:
                    CreateFolderObject(folder, counter, true);
                    DeleteFolderObject(folder, counter);
                    needLastKnownState = true;
                    break;
            }

            return needLastKnownState;
        }
예제 #23
0
        // For any XMLCompareObjects in the list , create them as a node and append them to the folder node
        private void AddFileToChild(List<XMLCompareObject> xmlFileList, FolderCompareObject folder, int counter, int length)
        {
            for (int i = 0; i < xmlFileList.Count; i++)
            {
                BaseCompareObject o = folder.GetChild(xmlFileList[i].Name);
                FileCompareObject fco;

                if (o == null)
                    fco = new FileCompareObject(xmlFileList[i].Name, length, folder);
                else
                    fco = (FileCompareObject)o;

                fco.MetaCreationTimeUtc[counter] = xmlFileList[i].CreatedTimeUtc;
                fco.MetaHash[counter] = xmlFileList[i].Hash;
                fco.MetaLastWriteTimeUtc[counter] = xmlFileList[i].LastModifiedTimeUtc;
                fco.MetaLength[counter] = xmlFileList[i].Size;
                fco.MetaUpdated[counter] = xmlFileList[i].LastUpdatedTimeUtc;
                fco.MetaExists[counter] = true;

                if (o == null)
                    folder.AddChild(fco);
            }
        }
예제 #24
0
        /// <summary>
        /// Processes and adds files to the tree.
        /// </summary>
        /// <param name="folder"><see cref="FolderCompareObject"/> to process and add files to.</param>
        /// <param name="numOfPaths">The total number of sync folders.</param>
        /// <param name="f">The <see cref="DirectoryInfo"/> to process and get files from.</param>
        /// <param name="index">The index indicating which sync folder it belongs to.</param>
        private void ProcessFiles(FolderCompareObject folder, int numOfPaths, DirectoryInfo f, int index)
        {
            try
            {
                FileInfo[] fileInfos = f.GetFiles();

                foreach (FileInfo info in fileInfos)
                {
                    if (_filterChain.ApplyFilter(_filter, info.FullName))
                    {
                        if (_progress != null)
                        {
                            _progress.Message = info.FullName;
                            _progress.Update();
                        }

                        BaseCompareObject o = folder.GetChild(info.Name); // Gets a child with the same name.
                        FileCompareObject fco = null;
                        bool conflict = false;

                        if (o == null) // If o is null, create a new file compare object
                            fco = new FileCompareObject(info.Name, numOfPaths, folder);
                        else
                        {
                            try
                            {
                                fco = (FileCompareObject)o; // Case o to a FileCompareObject is o is not null
                            }
                            catch (InvalidCastException)
                            // If invalid cast, it means there is a FolderCompareObject with the exact same name.
                            {
                                _typeConflicts.Add(info.FullName); // Add to to conflicts
                                conflict = true;
                                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(
                                    new LogData(LogEventType.FSCHANGE_CONFLICT,
                                                "Conflicted file detected " + info.FullName));
                            }
                        }

                        if (!conflict)
                        {
                            fco.CreationTimeUtc[index] = info.CreationTimeUtc.Ticks;
                            fco.LastWriteTimeUtc[index] = info.LastWriteTimeUtc.Ticks;
                            fco.Length[index] = info.Length;
                            fco.Exists[index] = true;

                            if (o == null)
                                folder.AddChild(fco); // Add the newly created FileCompareObject to this current folder
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to unauthorized access."));
            }
            catch (DirectoryNotFoundException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to directory not being found."));
            }
        }
예제 #25
0
        // For each list of folder names , create a node and append them to the root node
        private void AddFolderToRoot(List<string> folderName, RootCompareObject root, int counter, int length)
        {
            if (folderName.Count == 0)
                return;

            for (int i = 0; i < folderName.Count; i++)
            {
                BaseCompareObject o = root.GetChild(folderName[i]);
                FolderCompareObject fco;

                if (o == null)
                    fco = new FolderCompareObject(folderName[i], length, root);
                else
                    fco = (FolderCompareObject)o;

                fco.MetaExists[counter] = true;

                if (o == null)
                    root.AddChild(fco);
            }
        }
예제 #26
0
        /// <summary>
        /// Processes and adds folders to the tree.
        /// </summary>
        /// <param name="folder"><see cref="FolderCompareObject"/> to process and add folders to.</param>
        /// <param name="numOfPaths">The total number of sync folders.</param>
        /// <param name="f">The <see cref="DirectoryInfo"/> to process and get folders from.</param>
        /// <param name="index">The index indicating which sync folder it belongs to.</param>
        private void ProcessFolders(FolderCompareObject folder, int numOfPaths, DirectoryInfo f, int index)
        {
            try
            {
                DirectoryInfo[] infos = f.GetDirectories();

                foreach (DirectoryInfo info in infos)
                {
                    if (_filterChain.ApplyFilter(_filter, info.FullName))
                    {
                        if (_progress != null)
                        {
                            _progress.Message = info.FullName;
                            _progress.Update();
                        }

                        BaseCompareObject o = folder.GetChild(info.Name); // Gets a child with the same name.
                        FolderCompareObject fco;
                        bool conflict = false;

                        if (o == null) // If o is null, create a new folder compare object.
                            fco = new FolderCompareObject(info.Name, numOfPaths, folder);
                        // Create a new folder compare object
                        else
                        {
                            try
                            {
                                fco = (FolderCompareObject)o; // Cast o to a FolderCompareObject.
                            }
                            catch (InvalidCastException) // Happens when a file has the same name as the folder.
                            {
                                for (int i = 0; i < numOfPaths; i++)
                                {
                                    if (o.Exists[i])
                                        _typeConflicts.Add(Path.Combine(o.GetSmartParentPath(i), o.Name));
                                }
                                folder.RemoveChild(info.Name); //Remove file object
                                fco = new FolderCompareObject(info.Name, numOfPaths, folder);
                                // Create a new folder compare object
                                conflict = true;
                                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(
                                    new LogData(LogEventType.FSCHANGE_CONFLICT,
                                                "Conflicted file detected " + info.FullName));
                            }
                        }

                        fco.CreationTimeUtc[index] = info.CreationTimeUtc.Ticks;
                        fco.Exists[index] = true;

                        if (o == null || conflict)
                            folder.AddChild(fco); // Add the newly created FolderCompareObject to this current folder
                    }
                }
            }
            catch (UnauthorizedAccessException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to unauthorized access."));
            }
            catch (DirectoryNotFoundException e)
            {
                ServiceLocator.GetLogger(ServiceLocator.DEBUG_LOG).Write(e);
                ServiceLocator.GetLogger(ServiceLocator.USER_LOG).Write(new LogData(LogEventType.UNKNOWN, "Error retrieving contents of folder due to directory not being found."));
            }
        }
예제 #27
0
        // Checks the meta data by the folder name , if it exists , set it MetaExists to true.
        // If not , look up the last known state and populate the values from that document
        private FolderCompareObject PopulateFolderWithMetaData(XmlDocument xmlDoc, FolderCompareObject folder, int counter)
        {
            XmlNode node = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");
            if (node != null)
            {
                folder.MetaExists[counter] = true;
            }
            else
            {
                string path = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.LastKnownStatePath);

                if (File.Exists(path))
                {
                    XmlDocument lastKnownXmlDoc = new XmlDocument();
                    CommonMethods.LoadXML(ref lastKnownXmlDoc, path);
                    XmlNode folderNode = lastKnownXmlDoc.SelectSingleNode(CommonXMLConstants.XPathLastKnownState + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");

                    if (folderNode != null)
                    {
                        XmlNodeList nodeList = folderNode.ChildNodes;
                        for (int i = 0; i < nodeList.Count; i++)
                        {
                            XmlNode childNode = nodeList[i];

                            switch (childNode.Name)
                            {
                                case CommonXMLConstants.NodeAction:
                                    string action = childNode.InnerText;
                                    if (action.Equals("deleted"))
                                        folder.LastKnownState[counter] = LastKnownState.Deleted;
                                    else
                                        folder.LastKnownState[counter] = LastKnownState.Renamed;
                                    break;
                                case CommonXMLConstants.NodeLastUpdatedUtc:
                                    folder.MetaUpdated[counter] = long.Parse(childNode.InnerText);
                                    break;
                            }
                        }
                    }
                }
            }

            return folder;
        }
예제 #28
0
        // Based on the folder and counter , it will create a folder node in the meta data
        private void CreateFolderObject(FolderCompareObject folder, int counter, bool useNewName)
        {
            string name = useNewName ? folder.NewName : folder.Name;
            XmlDocument xmlDoc = new XmlDocument();
            string xmlPath = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.MetadataPath);
            CommonMethods.CreateFileIfNotExist(folder.GetSmartParentPath(counter));
            CommonMethods.LoadXML(ref xmlDoc, xmlPath);
            CommonMethods.DoFolderCleanUp(xmlDoc, name);
            XmlText nameText = xmlDoc.CreateTextNode(name);
            XmlText lastUpdatedUtcText = xmlDoc.CreateTextNode(_dateTime.ToString());
            XmlElement nameElement = xmlDoc.CreateElement(CommonXMLConstants.NodeName);
            XmlElement lastUpdatedElement = xmlDoc.CreateElement(CommonXMLConstants.NodeLastUpdatedUtc);
            XmlElement folderElement = xmlDoc.CreateElement(CommonXMLConstants.NodeFolder);

            nameElement.AppendChild(nameText);
            lastUpdatedElement.AppendChild(lastUpdatedUtcText);
            folderElement.AppendChild(nameElement);
            folderElement.AppendChild(lastUpdatedElement);

            XmlNode node = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr);

            if (node == null)
                return;
            node.AppendChild(folderElement);

            string subFolderXML = Path.Combine(folder.GetSmartParentPath(counter), name);
            CommonMethods.CreateFileIfNotExist(subFolderXML);
            CommonMethods.SaveXML(ref xmlDoc, xmlPath);
            ModifyFolderName(folder, folder.GetSmartParentPath(counter));
            DeleteFolderLastKnownState(folder, counter);
        }
예제 #29
0
        private string _metaName; // The name of the folder based on the metadata.

        /// <summary>
        /// Initializes a <c>FolderCompareObject</c> given the name of the file, the number of paths to synchronize, and the parent of this file.
        /// </summary>
        /// <param name="name">A <see cref="string"/> containing the name of this <c>FolderCompareObject</c>.</param>
        /// <param name="numOfPaths">An <see cref="int"/> containing the number of paths to synchronize.</param>
        /// <param name="parent">The <see cref="FolderCompareObject"/> which is the parent of this <c>FolderCompareObject</c>.</param>
        public FolderCompareObject(string name, int numOfPaths, FolderCompareObject parent)
            : base(name, numOfPaths, parent)
        {
            _contents = new Dictionary<string, BaseCompareObject>(StringComparer.OrdinalIgnoreCase);
        }
예제 #30
0
        // Based on the folder and counter , it will load the xml document and rename it
        private void RenameFolderObject(FolderCompareObject folder, int counter)
        {
            if (Directory.Exists(Path.Combine(folder.GetSmartParentPath(counter), folder.Name)))
            {
                XmlDocument xmlDoc = new XmlDocument();
                string xmlPath = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.MetadataPath);
                CommonMethods.LoadXML(ref xmlDoc, xmlPath);
                XmlNode node = xmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");

                if (node == null)
                {
                    CreateFolderObject(folder, counter, true);
                    return;
                }

                node.FirstChild.InnerText = folder.NewName;
                node.LastChild.InnerText = _dateTime.ToString();
                CommonMethods.SaveXML(ref xmlDoc, xmlPath);
            }
            else
            {
                XmlDocument newXmlDoc = new XmlDocument();
                string editOldXML = Path.Combine(Path.Combine(folder.GetSmartParentPath(counter), folder.NewName), CommonXMLConstants.MetadataPath);
                CommonMethods.CreateFileIfNotExist(Path.Combine(folder.GetSmartParentPath(counter), folder.NewName));
                CommonMethods.LoadXML(ref newXmlDoc, editOldXML);
                XmlNode xmlNameNode = newXmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathName);

                if (xmlNameNode != null)
                    xmlNameNode.InnerText = folder.NewName;

                CommonMethods.SaveXML(ref newXmlDoc, editOldXML);
                string parentXML = Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.MetadataPath);
                XmlDocument parentXmlDoc = new XmlDocument();
                CommonMethods.CreateFileIfNotExist(folder.GetSmartParentPath(counter));
                CommonMethods.LoadXML(ref parentXmlDoc, parentXML);
                XmlNode parentXmlFolderNode = parentXmlDoc.SelectSingleNode(CommonXMLConstants.XPathExpr + CommonXMLConstants.XPathFolder + "[name=" + CommonMethods.ParseXPathString(folder.Name) + "]");

                if (parentXmlFolderNode != null)
                {
                    parentXmlFolderNode.FirstChild.InnerText = folder.NewName;
                    parentXmlFolderNode.LastChild.InnerText = _dateTime.ToString();
                }

                CommonMethods.SaveXML(ref parentXmlDoc, Path.Combine(folder.GetSmartParentPath(counter), CommonXMLConstants.MetadataPath));
            }
        }