private AbstractFolderEvent CreateLocalEventBasedOnStorage(IFileSystemInfo fsObject, IMappedObject storedParent, IMappedObject storedMappedChild)
        {
            AbstractFolderEvent createdEvent = null;

            if (storedMappedChild.ParentId == storedParent.RemoteObjectId)
            {
                // Renamed, Updated or Equal
                #if __COCOA__
                if (fsObject.Name.Normalize(NormalizationForm.FormD) == storedMappedChild.Name.Normalize(NormalizationForm.FormD) && fsObject.LastWriteTimeUtc == storedMappedChild.LastLocalWriteTimeUtc)
                {
                #else
                if (fsObject.Name == storedMappedChild.Name && fsObject.LastWriteTimeUtc == storedMappedChild.LastLocalWriteTimeUtc)
                {
                #endif
                    // Equal
                    createdEvent = null;
                }
                else
                {
                    // Updated or Renamed
                    createdEvent = FileOrFolderEventFactory.CreateEvent(null, fsObject, localChange: MetaDataChangeType.CHANGED, src: this);
                }
            }
            else
            {
                // Moved
                IFileSystemInfo oldLocalPath = fsObject is IFileInfo ? (IFileSystemInfo)this.fsFactory.CreateFileInfo(this.storage.GetLocalPath(storedMappedChild)) : (IFileSystemInfo)this.fsFactory.CreateDirectoryInfo(this.storage.GetLocalPath(storedMappedChild));
                createdEvent = FileOrFolderEventFactory.CreateEvent(null, fsObject, localChange: MetaDataChangeType.MOVED, oldLocalObject: oldLocalPath, src: this);
            }

            return(createdEvent);
        }
Example #2
0
        public void InstantiateTemplate(string targetBaseDir, IParameterSet parameters = null, IVariableCollection variables = null)
        {
            if (parameters == null)
            {
                parameters = new MockParameterSet();
            }

            if (variables == null)
            {
                variables = new VariableCollection();
            }

            IRunnableProjectConfig runnableConfig = TemplateConfigTestHelpers.ConfigFromSource(_environment, SourceMountPoint);
            IFileSystemInfo        configFileInfo = TemplateConfigTestHelpers.ConfigFileSystemInfo(SourceMountPoint, _configFile);

            runnableConfig.Evaluate(parameters, variables, configFileInfo);

            MockGlobalRunSpec runSpec = new MockGlobalRunSpec();

            runSpec.RootVariableCollection = variables;
            IDirectory sourceDir = SourceMountPoint.DirectoryInfo("/");

            IOrchestrator2 basicOrchestrator         = new Core.Util.Orchestrator();
            RunnableProjectOrchestrator orchestrator = new RunnableProjectOrchestrator(basicOrchestrator);

            foreach (FileSourceMatchInfo source in runnableConfig.Sources)
            {
                TemplateConfigTestHelpers.SetupFileSourceMatchersOnGlobalRunSpec(runSpec, source);
                string targetDirForSource = Path.Combine(targetBaseDir, source.Target);
                orchestrator.Run(runSpec, sourceDir, targetDirForSource);
            }
        }
        private bool Ignore(IFileSystemInfo fileSystemInfo)
        {
            if (fileSystemInfo.Name.StartsWith(IgnorePrefix))
            {
                return(true);
            }

            if (fileSystemInfo.Name.StartsWith(IgnorePrefix))
            {
                return(true);
            }

            if (IsIgnoreSystem && fileSystemInfo.System())
            {
                return(true);
            }

            if (IsIgnoreHidden && fileSystemInfo.Hidden())
            {
                return(true);
            }

            if (IsIgnoreReadOnly && fileSystemInfo.ReadOnly())
            {
                return(true);
            }

            return(false);
        }
Example #4
0
        internal static string GetBasePath(string basePathA, IFileSystemInfo InfoA,
                                           string basePathB, IFileSystemInfo InfoB)
        {
            string nameA    = (InfoA == null ? string.Empty : InfoA.FullName);
            string nameB    = (InfoB == null ? string.Empty : InfoB.FullName);
            string basePath = string.Empty;

            if (string.IsNullOrEmpty(nameA) == false)
            {
                if (basePathA[basePathA.Length - 1] == System.IO.Path.DirectorySeparatorChar)
                {
                    basePath = nameA.Substring(basePathA.Length);
                }
                else
                {
                    basePath = nameA.Substring(basePathA.Length + 1);
                }
            }
            else
            {
                if (basePathB[basePathB.Length - 1] == System.IO.Path.DirectorySeparatorChar)
                {
                    basePath = nameB.Substring(basePathB.Length);
                }
                else
                {
                    basePath = nameB.Substring(basePathB.Length + 1);
                }
            }

            return(basePath);
        }
Example #5
0
        public IReadOnlyDictionary <string, IReadOnlyList <IFileChange2> > GetFileChanges(string targetBaseDir, IParameterSet parameters = null, IVariableCollection variables = null)
        {
            if (parameters == null)
            {
                parameters = new MockParameterSet();
            }

            if (variables == null)
            {
                variables = new VariableCollection();
            }

            IRunnableProjectConfig runnableConfig = TemplateConfigTestHelpers.ConfigFromSource(_environment, SourceMountPoint);
            IFileSystemInfo        configFileInfo = TemplateConfigTestHelpers.ConfigFileSystemInfo(SourceMountPoint, _configFile);

            runnableConfig.Evaluate(parameters, variables, configFileInfo);

            MockGlobalRunSpec runSpec   = new MockGlobalRunSpec();
            IDirectory        sourceDir = SourceMountPoint.DirectoryInfo("/");

            IOrchestrator2 basicOrchestrator         = new Core.Util.Orchestrator();
            RunnableProjectOrchestrator orchestrator = new RunnableProjectOrchestrator(basicOrchestrator);

            Dictionary <string, IReadOnlyList <IFileChange2> > changesByTarget = new Dictionary <string, IReadOnlyList <IFileChange2> >();

            foreach (FileSourceMatchInfo source in runnableConfig.Sources)
            {
                TemplateConfigTestHelpers.SetupFileSourceMatchersOnGlobalRunSpec(runSpec, source);
                string targetDirForSource            = Path.Combine(targetBaseDir, source.Target);
                IReadOnlyList <IFileChange2> changes = orchestrator.GetFileChanges(runSpec, sourceDir, targetDirForSource);
                changesByTarget[source.Target] = changes;
            }

            return(changesByTarget);
        }
        public bool TryGetTemplateFromConfig(IFileSystemInfo config, out ITemplate template)
        {
            IFile file = config as IFile;

            if (file == null)
            {
                template = null;
                return(false);
            }

            try
            {
                JObject srcObject = ReadConfigModel(file);

                template = new RunnableProjectTemplate(srcObject, this, file, RunnableProjectConfigConverter.FromJObject(srcObject));

                return(true);
            }
            catch
            {
            }

            template = null;
            return(false);
        }
 /// <summary>
 /// Solve the specified situation by using localFile and remote object.
 /// </summary>
 /// <param name="localFileSystemInfo">Local filesystem info instance.</param>
 /// <param name="remoteId">Remote identifier or object.</param>
 /// <param name="localContent">Hint if the local content has been changed.</param>
 /// <param name="remoteContent">Information if the remote content has been changed.</param>
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     if (localFileSystemInfo is IDirectoryInfo)
     {
         IDirectoryInfo localFolder    = localFileSystemInfo as IDirectoryInfo;
         IDirectoryInfo localParent    = localFolder.Parent;
         IFolder        remoteFolder   = remoteId as IFolder;
         string         remoteParentId = remoteFolder.ParentId;
         IMappedObject  mappedParent   = this.Storage.GetObjectByRemoteId(remoteParentId);
         IMappedObject  mappedObject   = this.Storage.GetObjectByRemoteId(remoteFolder.Id);
         if (localParent.Uuid == mappedParent.Guid)
         {
             // Both folders are in the same parent folder
             this.SyncNamesAndDates(localFolder, remoteFolder, mappedObject);
         }
         else
         {
             OperationsLogger.Warn(
                 string.Format(
                     "Synchronization Conflict: The local directory {0} has been moved to {1} with id {2},{4}" +
                     "but the remote folder was moved to {3}{4}You can fix this situation by moving them into the same folder",
                     localFileSystemInfo.Name,
                     localFileSystemInfo.FullName,
                     remoteFolder.Path,
                     Environment.NewLine));
             return;
         }
     }
     else if (localFileSystemInfo is IFileInfo)
     {
         IFileInfo      localFile      = localFileSystemInfo as IFileInfo;
         IDirectoryInfo localParent    = localFile.Directory;
         IDocument      remoteFile     = remoteId as IDocument;
         string         remoteParentId = remoteFile.Parents[0].Id;
         IMappedObject  mappedParent   = this.Storage.GetObjectByRemoteId(remoteParentId);
         IMappedObject  mappedObject   = this.Storage.GetObjectByRemoteId(remoteFile.Id);
         if (localParent.Uuid == mappedParent.Guid)
         {
             // Both files are in the same parent folder
             this.SyncNamesAndDates(localFile, remoteFile, mappedObject);
             return;
         }
         else
         {
             OperationsLogger.Warn(
                 string.Format(
                     "Synchronization Conflict: The local file {0} has been moved to {1} with id {2},{4}" +
                     "but the remote file was moved to {3}{4}You can fix this situation by moving them into the same folder",
                     localFileSystemInfo.Name,
                     localFileSystemInfo.FullName,
                     remoteFile.Paths[0],
                     Environment.NewLine));
             return;
         }
     }
 }
Example #8
0
        public static ITemplate LoadTemplate(ITemplateInfo info)
        {
            IGenerator generator;

            if (!Components.TryGetComponent(info.GeneratorId, out generator))
            {
                return(null);
            }

            IMountPoint mountPoint;

            if (!_mountPointManager.TryDemandMountPoint(info.ConfigMountPointId, out mountPoint))
            {
                return(null);
            }

            IFileSystemInfo config = mountPoint.FileSystemInfo(info.ConfigPlace);

            ITemplate template;

            using (Timing.Over("Template from config"))
                if (generator.TryGetTemplateFromConfig(config, out template))
                {
                    return(template);
                }
                else
                {
                    //TODO: Log the failure to read the template info
                }

            return(null);
        }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId, 
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
            string oldName = (remoteId as ICmisObject).Name;

            // Rename object
            try {
                (remoteId as ICmisObject).Rename(localFileSystemInfo.Name, true);
            } catch (CmisConstraintException e) {
                if (!Utils.IsValidISO885915(localFileSystemInfo.Name)) {
                    OperationsLogger.Warn(string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name));
                    throw new InteractionNeededException(string.Format("Server denied renaming of {0}", oldName), e) {
                        Title = string.Format("Server denied renaming of {0}", oldName),
                        Description = string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name)
                    };
                }

                throw;
            } catch (CmisPermissionDeniedException) {
                OperationsLogger.Warn(string.Format("Unable to renamed remote object from {0} to {1}: Permission Denied", oldName, localFileSystemInfo.Name));
                return;
            }

            obj.Name = localFileSystemInfo.Name;
            obj.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
            this.Storage.SaveMappedObject(obj);
            this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
        }
Example #10
0
 public MergedEntry(IFileSystemInfo infoA,
                    IFileSystemInfo infoB)
     : this()
 {
     this.InfoA = infoA;
     this.InfoB = infoB;
 }
        /// <summary>
        /// Initializes a new instance of the
        /// <see cref="CmisSync.Lib.Storage.FileSystem.ReadOnlyIgnoringFileSystemInfoDecorator"/> class.
        /// </summary>
        /// <param name="info">Decorated file system info instance.</param>
        public ReadOnlyIgnoringFileSystemInfoDecorator(IFileSystemInfo info) {
            if (info == null) {
                throw new ArgumentNullException("info");
            }

            this.fileSystemInfo = info;
        }
Example #12
0
        protected PassthroughFileSystemBase(IFileSystemInfo pFileSystemInfo) : this()
        {
            FullName       = pFileSystemInfo.FullName;
            Name           = pFileSystemInfo.Name;
            FileSize       = 0;
            AllocationSize = 0;

            ReparseTag  = 0;
            IndexNumber = 0;
            HardLinks   = 0;
            EaSize      = 0;

            Attributes     = pFileSystemInfo.Attributes;
            CreationTime   = pFileSystemInfo.CreationTimeUtc;
            LastAccessTime = pFileSystemInfo.LastAccessTimeUtc;
            LastWriteTime  = pFileSystemInfo.LastWriteTimeUtc;
            ChangeTime     = LastWriteTime;

            if ((Attributes & FileAttributes.Directory) == 0)
            {
                _IsFile        = true;
                FileSize       = (pFileSystemInfo as IFileInfo).Length;
                AllocationSize = (FileSize + 4096 - 1) / 4096 * 4096;
            }
        }
Example #13
0
        internal static IReadOnlyDictionary <string, string> AugmentFileRenames(
            IEngineEnvironmentSettings environmentSettings,
            string sourceName,
            IFileSystemInfo configFile,
            string sourceDirectory,
            ref string targetDirectory,
            object resolvedNameParamValue,
            IParameterSet parameterSet,
            Dictionary <string, string> fileRenames,
            IReadOnlyList <IReplacementTokens>?symbolBasedFileRenames = null)
        {
            Dictionary <string, string> allRenames = new Dictionary <string, string>(StringComparer.Ordinal);

            IProcessor sourceRenameProcessor = SetupRenameProcessor(environmentSettings, fileRenames);
            IProcessor symbolRenameProcessor = SetupSymbolBasedRenameProcessor(environmentSettings, sourceName, ref targetDirectory, resolvedNameParamValue, parameterSet, symbolBasedFileRenames);

            IDirectory sourceBaseDirectoryInfo = configFile.Parent.Parent.DirectoryInfo(sourceDirectory.TrimEnd('/'));

            foreach (IFileSystemInfo fileSystemEntry in sourceBaseDirectoryInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories))
            {
                string sourceTemplateRelativePath = fileSystemEntry.PathRelativeTo(sourceBaseDirectoryInfo);

                // first apply the sources renames, then apply the symbol renames to that result.
                string renameFromSourcesValue = ApplyRenameProcessorToFilename(sourceRenameProcessor, sourceTemplateRelativePath);
                string renameFinalTargetValue = ApplyRenameProcessorToFilename(symbolRenameProcessor, renameFromSourcesValue);

                if (!string.Equals(sourceTemplateRelativePath, renameFinalTargetValue, StringComparison.Ordinal))
                {
                    allRenames[sourceTemplateRelativePath] = renameFinalTargetValue;
                }
            }

            return(allRenames);
        }
Example #14
0
        public static IEnumerable <IFileSystemInfo> GetThisAndParents(this IFileSystemInfo info)
        {
            if (info == null)
            {
                yield break;
            }

            yield return(info);

            if (info.Id == Guid.Empty)
            {
                yield break;
            }

            var parent = info.Parent;

            if (parent == null)
            {
                yield break;
            }

            foreach (var p in GetThisAndParents(parent))
            {
                yield return(p);
            }
        }
 public static bool IsExecutable(this IFileSystemInfo systemInfo, string accountName)
 {
     try
     {
         FileSecurity security           = GetFileSecurity(systemInfo);
         var          authorizationRules = security.GetAccessRules(true, true, typeof(NTAccount));
         foreach (AuthorizationRule rule in authorizationRules)
         {
             FileSystemAccessRule fileRule = rule as FileSystemAccessRule;
             if (fileRule != null && fileRule.IdentityReference.Value == accountName)
             {
                 if (fileRule.FileSystemRights.HasFlag(FileSystemRights.ExecuteFile) ||
                     fileRule.FileSystemRights.HasFlag(FileSystemRights.ReadAndExecute) ||
                     fileRule.FileSystemRights.HasFlag(FileSystemRights.FullControl))
                 {
                     return(true);
                 }
             }
         }
     }
     catch (Exception)
     {
         // Silently hide exception
     }
     return(false);
 }
Example #16
0
        public IFile FindBestHostTemplateConfigFile(IFileSystemInfo config)
        {
            IDictionary <string, IFile> allHostFilesForTemplate = new Dictionary <string, IFile>();

            foreach (IFile hostFile in config.Parent.EnumerateFiles($"*{HostTemplateFileConfigBaseName}", SearchOption.TopDirectoryOnly))
            {
                allHostFilesForTemplate.Add(hostFile.Name, hostFile);
            }

            string preferredHostFileName = string.Concat(_environmentSettings.Host.HostIdentifier, HostTemplateFileConfigBaseName);

            if (allHostFilesForTemplate.TryGetValue(preferredHostFileName, out IFile preferredHostFile))
            {
                return(preferredHostFile);
            }

            foreach (string fallbackHostName in _environmentSettings.Host.FallbackHostTemplateConfigNames)
            {
                string fallbackHostFileName = string.Concat(fallbackHostName, HostTemplateFileConfigBaseName);

                if (allHostFilesForTemplate.TryGetValue(fallbackHostFileName, out IFile fallbackHostFile))
                {
                    return(fallbackHostFile);
                }
            }

            return(null);
        }
Example #17
0
 /// <summary>
 /// Solve the specified situation by using localFile and remote object.
 /// </summary>
 /// <param name="localFileSystemInfo">Local filesystem info instance.</param>
 /// <param name="remoteId">Remote identifier or object.</param>
 /// <param name="localContent">Hint if the local content has been changed.</param>
 /// <param name="remoteContent">Information if the remote content has been changed.</param>
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     if (localFileSystemInfo is IDirectoryInfo)
     {
         IDirectoryInfo localFolder    = localFileSystemInfo as IDirectoryInfo;
         IDirectoryInfo localParent    = localFolder.Parent;
         IFolder        remoteFolder   = remoteId as IFolder;
         string         remoteParentId = remoteFolder.ParentId;
         IMappedObject  mappedParent   = this.Storage.GetObjectByRemoteId(remoteFolder.ParentId);
         IMappedObject  mappedObject   = this.Storage.GetObjectByRemoteId(remoteFolder.Id);
         if (localParent.Uuid == mappedParent.Guid)
         {
             // Both folders are in the same parent folder
             this.SyncNamesAndDates(localFolder, remoteFolder, mappedObject);
         }
         else
         {
             throw new NotImplementedException();
         }
     }
     else
     {
         throw new NotImplementedException();
     }
 }
 private static FileSecurity GetFileSecurity(IFileSystemInfo systemInfo)
 {
     return(new FileSecurity(systemInfo.FullName,
                             AccessControlSections.Owner |
                             AccessControlSections.Group |
                             AccessControlSections.Access));
 }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
            var localParent = localFileSystemInfo is IFileInfo ? (localFileSystemInfo as IFileInfo).Directory : (localFileSystemInfo as IDirectoryInfo).Parent;
            var mappedLocalParent = this.Storage.GetObjectByGuid((Guid)localParent.Uuid);
            var remoteObject = remoteId as IFileableCmisObject;
            var targetId = mappedLocalParent.RemoteObjectId;
            var src = this.Session.GetObject(obj.ParentId);
            var target = this.Session.GetObject(targetId);
            try {
                OperationsLogger.Info(string.Format("Moving remote object {2} from folder {0} to folder {1}", src.Name, target.Name, remoteId.Id));
                remoteObject = remoteObject.Move(src, target);
            } catch (CmisPermissionDeniedException) {
                OperationsLogger.Info(string.Format("Moving remote object failed {0}: Permission Denied", localFileSystemInfo.FullName));
                return;
            }

            obj.ParentId = targetId;
            obj.Ignored = remoteObject.AreAllChildrenIgnored();
            this.Storage.SaveMappedObject(obj);

            if (obj.Name != localFileSystemInfo.Name) {
                this.renameChangeSolver.Solve(localFileSystemInfo, remoteObject, localContent, remoteContent);
            } else {
                this.changeChangeSolver.Solve(localFileSystemInfo, remoteObject, localContent, remoteContent);
            }
        }
 private void AddDeletedObjectsToMergableEvents(
     List <IMappedObject> storedObjectList,
     Dictionary <string, Tuple <AbstractFolderEvent, AbstractFolderEvent> > eventMap,
     bool areLocalEvents)
 {
     foreach (var deleted in storedObjectList)
     {
         string          path     = this.storage.GetLocalPath(deleted);
         IFileSystemInfo info     = deleted.Type == MappedObjectType.File ? (IFileSystemInfo)this.fsFactory.CreateFileInfo(path) : (IFileSystemInfo)this.fsFactory.CreateDirectoryInfo(path);
         var             newEvent = FileOrFolderEventFactory.CreateEvent(
             null,
             info,
             areLocalEvents ? MetaDataChangeType.NONE : MetaDataChangeType.DELETED,
             areLocalEvents ? MetaDataChangeType.DELETED : MetaDataChangeType.NONE,
             areLocalEvents ? this.storage.GetRemotePath(deleted) : null,
             areLocalEvents ? null : info,
             src: this);
         if (!eventMap.ContainsKey(deleted.RemoteObjectId))
         {
             eventMap[deleted.RemoteObjectId] = new Tuple <AbstractFolderEvent, AbstractFolderEvent>(
                 areLocalEvents ? newEvent : null,
                 areLocalEvents ? null : newEvent);
         }
         else
         {
             eventMap[deleted.RemoteObjectId] = new Tuple <AbstractFolderEvent, AbstractFolderEvent>(
                 areLocalEvents ? newEvent : eventMap[deleted.RemoteObjectId].Item1,
                 areLocalEvents ? eventMap[deleted.RemoteObjectId].Item2 : newEvent);
         }
     }
 }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
            var localParent = localFileSystemInfo is IFileInfo ? (localFileSystemInfo as IFileInfo).Directory : (localFileSystemInfo as IDirectoryInfo).Parent;
            var mappedLocalParent = this.Storage.GetObjectByGuid((Guid)localParent.Uuid);
            var remoteObject = remoteId as IFileableCmisObject;
            var targetId = mappedLocalParent.RemoteObjectId;
            var src = this.Session.GetObject(obj.ParentId);
            var target = this.Session.GetObject(targetId);
            try {
                OperationsLogger.Info(string.Format("Moving remote object {2} from folder {0} to folder {1}", src.Name, target.Name, remoteId.Id));
                remoteObject = remoteObject.Move(src, target);
            } catch (CmisPermissionDeniedException) {
                OperationsLogger.Info(string.Format("Moving remote object failed {0}: Permission Denied", localFileSystemInfo.FullName));
                return;
            }

            obj.ParentId = targetId;
            this.Storage.SaveMappedObject(obj);

            if (obj.Name != localFileSystemInfo.Name) {
                this.renameChangeSolver.Solve(localFileSystemInfo, remoteObject, localContent, remoteContent);
            } else {
                this.changeChangeSolver.Solve(localFileSystemInfo, remoteObject, localContent, remoteContent);
            }
        }
Example #22
0
        /// <summary>
        /// Solves the situation by deleting the corresponding remote object.
        /// </summary>
        /// <param name="localFile">Local file.</param>
        /// <param name="remoteId">Remote identifier or object.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFile,
            IObjectId remoteId,
            ContentChangeType localContent  = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            var mappedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);

            if (mappedObject.LastChangeToken != (remoteId as ICmisObject).ChangeToken)
            {
                throw new ArgumentException("Remote object has been changed since last sync => force crawl sync");
            }

            bool hasBeenDeleted = this.TryDeleteObjectOnServer(remoteId, mappedObject.Type);

            if (hasBeenDeleted)
            {
                this.Storage.RemoveObject(mappedObject);
                OperationsLogger.Info(string.Format("Deleted the corresponding remote object {0} of locally deleted object {1}", remoteId.Id, mappedObject.Name));
            }
            else
            {
                OperationsLogger.Warn(string.Format("Permission denied while trying to Delete the locally deleted object {0} on the server.", mappedObject.Name));
            }
        }
        private static void AddToDirectory(IDirectoryInfo directory, IFileSystemInfo child)
        {
            var children = (List <IFileSystemInfo>)directory.EnumerateFileSystemInfos();
            int index    = children.BinarySearch(child, Comparer <IFileSystemInfo> .Create((x, y) => string.Compare(x.FullName, y.FullName, StringComparison.OrdinalIgnoreCase)));

            if (index >= 0)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Item with name {0} already exists in folder {1}", child.FullName, directory.FullName));
            }

            if (child.TraverseBreadthFirst(f => (f as IDirectoryInfo)?.EnumerateFileSystemInfos()).Contains(directory))
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Circular dependency. Item {0} is a parent of {1} already", child.FullName, directory.FullName));
            }

            var directoryChild = child as IDirectoryInfo;

            if (directoryChild != null)
            {
                var oldParent = (List <IFileSystemInfo>)directoryChild.Parent?.EnumerateFileSystemInfos();
                oldParent?.Remove(directoryChild);
                directoryChild.Parent.Returns(directory);
            }
            else
            {
                var fileChild = (IFileInfo)child;
                var oldParent = (List <IFileSystemInfo>)fileChild.Directory?.EnumerateFileSystemInfos();
                oldParent?.Remove(fileChild);
                fileChild.Directory.Returns(directory);
            }

            children.Insert(~index, child);
        }
Example #24
0
        private void InitItem(IFileSystemInfo fileInfo, IWorkspaceItem parent, WebWorkspaceItemHandler handler)
        {
            if (fileInfo.Name.StartsWith("."))
            {
                if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
                {
                    excludedDirs.Add(fileInfo.FullName + "\\");
                }

                return;
            }

            var item = new WorkspaceItem(fileInfo, this, parent);

            if (fileInfo is IDirectoryInfo dirInfo)
            {
                item.Type = WorkspaceItemType.Directory;
                foreach (var info in dirInfo.EnumerateFileSystemInfos())
                {
                    InitItem(info, item, handler);
                }
            }
            else if (item.Type == WorkspaceItemType.Bibliography)
            {
                Bibliography.Parse(item);
            }

            parent.Children.Add(item);
        }
        public static IFileSystemInfo FromIndentedString(IFileSystem fileSystem, string rootPath, string indentedString)
        {
            string[]    lines         = indentedString.Split('\r', '\n');
            Stack <int> folderIndents = new Stack <int>();

            folderIndents.Push(-1);
            IDirectoryInfo root      = Create(fileSystem, rootPath);
            IDirectoryInfo directory = root;

            foreach (string line in lines.Where(l => !string.IsNullOrWhiteSpace(l)))
            {
                int    indent   = GetIndent(line);
                string name     = line.Trim();
                bool   isFolder = IsFolder(name);

                if (isFolder)
                {
                    // Find a folder for current item
                    while (indent <= folderIndents.Peek())
                    {
                        folderIndents.Pop();
                        directory = directory.Parent;
                    }

                    string         path  = Path.Combine(directory.FullName, name.Substring(1, name.Length - 2));
                    IDirectoryInfo child = Create(fileSystem, path);

                    AddToDirectory(directory, child);

                    folderIndents.Push(indent);
                    directory = child;
                }
                else
                {
                    // Find a folder for current item
                    while (indent <= folderIndents.Peek())
                    {
                        folderIndents.Pop();
                        directory = directory.Parent;
                    }

                    string          path  = Path.Combine(directory.FullName, name);
                    IFileSystemInfo child = FileInfoStubFactory.Create(fileSystem, path);

                    AddToDirectory(directory, child);
                }
            }

            var children = (List <IFileSystemInfo>)root.EnumerateFileSystemInfos();

            if (children.Count != 1)
            {
                return(root);
            }

            var result = children.First();

            children.Remove(result);
            return(result);
        }
Example #26
0
        private static AppConfiguration Load(IFileSystemInfo info)
        {
            var file = ResolveFile(info);

            var tempFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                using (var destination = new FileStream(tempFile, FileMode.Create, FileAccess.ReadWrite))
                    using (var source = file.OpenRead())
                    {
                        source.CopyTo(destination);
                    }

                var configuration = Manager.OpenMappedExeConfiguration(new ExeConfigurationFileMap {
                    ExeConfigFilename = tempFile
                }, ConfigurationUserLevel.None);
                return((AppConfiguration)configuration.GetSection(AppConfiguration.SectionName));
            }
            finally
            {
                if (File.Exists(tempFile))
                {
                    File.Delete(tempFile);
                }
            }
        }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var    obj     = this.Storage.GetObjectByRemoteId(remoteId.Id);
            string oldName = (remoteId as ICmisObject).Name;

            // Rename object
            try {
                (remoteId as ICmisObject).Rename(localFileSystemInfo.Name, true);
            } catch (CmisConstraintException e) {
                if (!Utils.IsValidISO885915(localFileSystemInfo.Name))
                {
                    OperationsLogger.Warn(string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name));
                    throw new InteractionNeededException(string.Format("Server denied renaming of {0}", oldName), e)
                          {
                              Title       = string.Format("Server denied renaming of {0}", oldName),
                              Description = string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name)
                          };
                }

                throw;
            } catch (CmisPermissionDeniedException) {
                OperationsLogger.Warn(string.Format("Unable to renamed remote object from {0} to {1}: Permission Denied", oldName, localFileSystemInfo.Name));
                return;
            }

            obj.Name    = localFileSystemInfo.Name;
            obj.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
            this.Storage.SaveMappedObject(obj);
            this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
        }
Example #28
0
        private static string GetFullName(IReadOnlyCollection <string> path, IFileSystemInfo item, bool relative)
        {
            if (!relative)
            {
                if (item is IFullName fullName)
                {
                    return(fullName.FullName);
                }
            }

            if (path == null)
            {
                return("/");
            }

            StringBuilder sb = new StringBuilder();

            sb.Append('/');
            foreach (var part in path)
            {
                sb.Append(part);
                sb.Append('/');
            }

            sb.Append(item?.Name);
            return(sb.ToString());
        }
Example #29
0
        protected Guid WriteOrUseUuidIfSupported(IFileSystemInfo info)
        {
            Guid uuid = Guid.Empty;

            if (info.IsExtendedAttributeAvailable())
            {
                try {
                    Guid?localUuid = info.Uuid;
                    if (localUuid == null || this.Storage.GetObjectByGuid((Guid)localUuid) != null)
                    {
                        uuid = Guid.NewGuid();
                        try {
                            info.Uuid = uuid;
                        } catch (RestoreModificationDateException restoreException) {
                            Logger.Debug("Could not retore the last modification date of " + info.FullName, restoreException);
                        }
                    }
                    else
                    {
                        uuid = localUuid ?? Guid.NewGuid();
                    }
                } catch (ExtendedAttributeException ex) {
                    throw new RetryException(ex.Message, ex);
                }
            }

            return(uuid);
        }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var savedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
            string newPath = remoteId is IFolder ? this.Storage.Matcher.CreateLocalPath(remoteId as IFolder) : this.Storage.Matcher.CreateLocalPath(remoteId as IDocument);
            if (remoteId is IFolder) {
                IDirectoryInfo dirInfo = localFileSystemInfo as IDirectoryInfo;
                string oldPath = dirInfo.FullName;
                if (!dirInfo.FullName.Equals(newPath)) {
                    dirInfo.MoveTo(newPath);
                    OperationsLogger.Info(string.Format("Moved local folder {0} to {1}", oldPath, newPath));
                } else {
                    return;
                }
            } else if (remoteId is IDocument) {
                IFileInfo fileInfo = localFileSystemInfo as IFileInfo;
                string oldPath = fileInfo.FullName;
                fileInfo.MoveTo(newPath);
                OperationsLogger.Info(string.Format("Moved local file {0} to {1}", oldPath, newPath));
            }

            savedObject.Name = (remoteId as ICmisObject).Name;
            savedObject.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
            savedObject.ParentId = remoteId is IFolder ? (remoteId as IFolder).ParentId : (remoteId as IDocument).Parents[0].Id;
            this.Storage.SaveMappedObject(savedObject);

            this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
        }
        public bool TryGetTemplateFromConfigInfo(IFileSystemInfo templateFileConfig, out ITemplate template, IFileSystemInfo localeFileConfig = null, IFile hostTemplateConfigFile = null, string baselineName = null)
        {
            IFile templateFile = templateFileConfig as IFile;

            if (templateFile == null)
            {
                template = null;
                return(false);
            }

            IFile localeFile         = localeFileConfig as IFile;
            ITemplateEngineHost host = templateFileConfig.MountPoint.EnvironmentSettings.Host;

            try
            {
                JObject baseSrcObject = ReadJObjectFromIFile(templateFile);
                JObject srcObject     = MergeAdditionalConfiguration(baseSrcObject, templateFileConfig);

                JObject localeSourceObject = null;
                if (localeFile != null)
                {
                    localeSourceObject = ReadJObjectFromIFile(localeFile);
                }

                ISimpleConfigModifiers configModifiers = new SimpleConfigModifiers()
                {
                    BaselineName = baselineName
                };
                SimpleConfigModel templateModel = SimpleConfigModel.FromJObject(templateFile.MountPoint.EnvironmentSettings, srcObject, configModifiers, localeSourceObject);

                if (!PerformTemplateValidation(templateModel, templateFile, host))
                {
                    template = null;
                    return(false);
                }

                if (!CheckGeneratorVersionRequiredByTemplate(templateModel.GeneratorVersions))
                {   // template isn't compatible with this generator version
                    template = null;
                    return(false);
                }

                RunnableProjectTemplate runnableProjectTemplate = new RunnableProjectTemplate(srcObject, this, templateFile, templateModel, null, hostTemplateConfigFile);
                if (!AreAllTemplatePathsValid(templateModel, runnableProjectTemplate))
                {
                    template = null;
                    return(false);
                }

                template = runnableProjectTemplate;
                return(true);
            }
            catch (Exception ex)
            {
                host.LogMessage($"Error reading template from file: {templateFile.FullPath} | Error = {ex.Message}");
            }

            template = null;
            return(false);
        }
Example #32
0
        public bool TryGetTemplateFromConfigInfo(IFileSystemInfo config, out ITemplate template, IFileSystemInfo localeConfig = null, IFile hostTemplateConfigFile = null)
        {
            IFile file = config as IFile;

            if (file == null)
            {
                template = null;
                return(false);
            }

            IFile localeFile = localeConfig as IFile;

            try
            {
                JObject srcObject = ReadJObjectFromIFile(file);

                JObject localeSourceObject = null;
                if (localeFile != null)
                {
                    localeSourceObject = ReadJObjectFromIFile(localeFile);
                }

                SimpleConfigModel templateModel = SimpleConfigModel.FromJObject(file.MountPoint.EnvironmentSettings, srcObject, localeSourceObject);
                template = new RunnableProjectTemplate(srcObject, this, file, templateModel, null, hostTemplateConfigFile);
                return(true);
            }
            catch (Exception ex)
            {
                ITemplateEngineHost host = config.MountPoint.EnvironmentSettings.Host;
                host.LogMessage($"Error reading template from file: {file.FullPath} | Error = {ex.ToString()}");
            }

            template = null;
            return(false);
        }
        // Checks the primarySource for additional configuration files.
        // If found, merges them all together.
        // Returns the merged JObject (or the original if there was nothing to merge).
        // Additional files must be in the same dir as the template file.
        private JObject MergeAdditionalConfiguration(JObject primarySource, IFileSystemInfo primarySourceConfig)
        {
            IReadOnlyList <string> otherFiles = primarySource.ArrayAsStrings(AdditionalConfigFilesIndicator);

            if (!otherFiles.Any())
            {
                return(primarySource);
            }

            JObject combinedSource = (JObject)primarySource.DeepClone();

            foreach (string partialConfigFileName in otherFiles)
            {
                if (!partialConfigFileName.EndsWith("." + TemplateConfigFileName))
                {
                    throw new TemplateAuthoringException($"Split configuration error with file [{partialConfigFileName}]. Additional configuration file names must end with '.{TemplateConfigFileName}'.", partialConfigFileName);
                }

                IFile partialConfigFile = primarySourceConfig.Parent.EnumerateFiles(partialConfigFileName, SearchOption.TopDirectoryOnly).FirstOrDefault(x => string.Equals(x.Name, partialConfigFileName));

                if (partialConfigFile == null)
                {
                    throw new TemplateAuthoringException($"Split configuration file [{partialConfigFileName}] could not be found.", partialConfigFileName);
                }

                JObject partialConfigJson = ReadJObjectFromIFile(partialConfigFile);
                combinedSource.Merge(partialConfigJson);
            }

            return(combinedSource);
        }
        public IFile FindBestHostTemplateConfigFile(IFileSystemInfo config)
        {
            IDictionary <string, IFile> dictionary = new Dictionary <string, IFile>();

            foreach (var item in config.Parent.EnumerateFiles("*" + HostTemplateFileConfigBaseName, SearchOption.TopDirectoryOnly))
            {
                dictionary.Add(item.Name, item);
            }

            var key = EnvironmentSettings.Host.HostIdentifier + HostTemplateFileConfigBaseName;

            if (dictionary.TryGetValue(key, out var value))
            {
                return(value);
            }

            foreach (var fallbackHostTemplateConfigName in EnvironmentSettings.Host.FallbackHostTemplateConfigNames)
            {
                var key2 = fallbackHostTemplateConfigName + HostTemplateFileConfigBaseName;
                if (dictionary.TryGetValue(key2, out var value2))
                {
                    return(value2);
                }
            }

            return(null);
        }
 /// <summary>
 /// Gets the remote identifier by trying to read the Uuid of the given directory. If this fails or returns null,
 /// the local path is used to request the remote object id from the storage.
 /// </summary>
 /// <returns>The stored remote identifier, or null if there is no entry found.</returns>
 /// <param name="storage">Meta data storage instance.</param>
 /// <param name="info">File system item info.</param>
 public static string GetRemoteId(this IMetaDataStorage storage, IFileSystemInfo info) {
     IMappedObject mappedObject = storage.GetObject(info);
     if (mappedObject != null) {
         return mappedObject.RemoteObjectId;
     } else {
         return null;
     }
 }
 /// <summary>
 /// Does nothing
 /// </summary>
 /// <param name='localFile'>
 /// Local file.
 /// </param>
 /// <param name='remoteId'>
 /// Remote identifier.
 /// </param>
 /// <param name="localContent">Hint if the local content has been changed.</param>
 /// <param name="remoteContent">Information if the remote content has been changed.</param>
 public virtual void Solve(
     IFileSystemInfo localFile,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     // No Operation Needed
 }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            if (localFileSystemInfo is IFileInfo && remoteId is IDocument) {
                var localFile = localFileSystemInfo as IFileInfo;
                var remoteDocument = remoteId as IDocument;

                var mappedObject = this.Storage.GetObject(localFile);
                if (mappedObject == null) {
                    throw new ArgumentException(string.Format("Could not find db entry for {0} => invoke crawl sync", localFileSystemInfo.FullName));
                }

                if (mappedObject.LastChangeToken != (remoteId as ICmisObjectProperties).ChangeToken) {
                    throw new ArgumentException(string.Format("remote {1} {0} has also been changed since last sync => invoke crawl sync", remoteId.Id, remoteId is IDocument ? "document" : "folder"));
                }

                if (localFile != null && localFile.IsContentChangedTo(mappedObject, scanOnlyIfModificationDateDiffers: true)) {
                    Logger.Debug(string.Format("\"{0}\" is different from {1}", localFile.FullName, mappedObject.ToString()));
                    OperationsLogger.Debug(string.Format("Local file \"{0}\" has been changed", localFile.FullName));
                    try {
                        var transmission = this.transmissionManager.CreateTransmission(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.FullName);
                        mappedObject.LastChecksum = this.UploadFileWithPWC(localFile, ref remoteDocument, transmission);
                        mappedObject.ChecksumAlgorithmName = "SHA-1";
                        if (remoteDocument.Id != mappedObject.RemoteObjectId) {
                            this.TransmissionStorage.RemoveObjectByRemoteObjectId(mappedObject.RemoteObjectId);
                            mappedObject.RemoteObjectId = remoteDocument.Id;
                        }
                    } catch (Exception ex) {
                        if (ex.InnerException is CmisPermissionDeniedException) {
                            OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: PermissionDenied", localFile.FullName));
                            return;
                        } else if (ex.InnerException is CmisStorageException) {
                            OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: StorageException", localFile.FullName), ex);
                            return;
                        }

                        throw;
                    }

                    mappedObject.LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate;
                    mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc;
                    mappedObject.LastContentSize = localFile.Length;

                    OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName));
                }

                mappedObject.LastChangeToken = remoteDocument.ChangeToken;
                mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc;
                this.Storage.SaveMappedObject(mappedObject);
            } else {
                this.folderOrFileContentUnchangedSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
            }

            return;
        }
Example #38
0
 public bool IsSymlink(IFileSystemInfo fsInfo, out string reason) {
     reason = string.Empty;
     if (fsInfo.Exists && fsInfo.IsSymlink) {
         reason = string.Format("{0} is a symbolic link", fsInfo.FullName);
         return true;
     } else {
         return false;
     }
 }
 private void MoveTo(IFileSystemInfo localFsInfo, string oldPath, string newPath) {
     if (localFsInfo is IFileInfo) {
         (localFsInfo as IFileInfo).MoveTo(newPath);
         OperationsLogger.Info(string.Format("Moved local file {0} to {1}", oldPath, newPath));
     } else {
         (localFsInfo as IDirectoryInfo).MoveTo(newPath);
         OperationsLogger.Info(string.Format("Moved local folder {0} to {1}", oldPath, newPath));
     }
 }
 /// <summary>
 /// Solve the specified situation by using localFile and remote object.
 /// </summary>
 /// <param name="localFile">Local file.</param>
 /// <param name="remoteId">Remote identifier or object.</param>
 /// <param name="localContent">Hint if the local content has been changed.</param>
 /// <param name="remoteContent">Information if the remote content has been changed.</param>
 public override void Solve(
     IFileSystemInfo localFile,
     IObjectId remoteId,
     ContentChangeType localContent = ContentChangeType.NONE,
     ContentChangeType remoteContent = ContentChangeType.NONE)
 {
     var mappedObject = this.Storage.GetObjectByLocalPath(localFile);
     this.Storage.RemoveObject(mappedObject);
 }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var savedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
            Guid? newParentUuid = localFileSystemInfo is IFileInfo ? (localFileSystemInfo as IFileInfo).Directory.Uuid : (localFileSystemInfo as IDirectoryInfo).Parent.Uuid;
            string newParentId = this.Storage.GetObjectByGuid((Guid)newParentUuid).RemoteObjectId;
            savedObject.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
            if (localFileSystemInfo.Name == (remoteId as ICmisObject).Name) {
                // Both names are equal => only move to new remote parent
                try {
                    (remoteId as IFileableCmisObject).Move(this.Session.GetObject(savedObject.ParentId), this.Session.GetObject(newParentId));
                } catch (CmisPermissionDeniedException) {
                    OperationsLogger.Info(string.Format("Permission Denied: Cannot move remote object {0} from {1} to {2}", remoteId.Id, savedObject.ParentId, newParentId));
                    return;
                }

                savedObject.Name = localFileSystemInfo.Name;
                savedObject.ParentId = newParentId;
                this.Storage.SaveMappedObject(savedObject);
                this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
            } else {
                // Names are different to each other
                if (localFileSystemInfo.Name == savedObject.Name) {
                    // Remote rename and local move => Move remote and rename locally => change change solver
                    try {
                        remoteId = (remoteId as IFileableCmisObject).Move(this.Session.GetObject(savedObject.ParentId), this.Session.GetObject(newParentId));
                    } catch (CmisPermissionDeniedException) {
                        OperationsLogger.Info(string.Format("Permission Denied: Cannot move remote object {0} from {1} to {2}", remoteId.Id, savedObject.ParentId, newParentId));
                        return;
                    }

                    var localParentPath = localFileSystemInfo is IFileInfo ? (localFileSystemInfo as IFileInfo).Directory.FullName : (localFileSystemInfo as IDirectoryInfo).Parent.FullName;
                    string newPath = Path.Combine(localParentPath, (remoteId as ICmisObject).Name);
                    this.MoveTo(localFileSystemInfo, localFileSystemInfo.FullName, newPath);
                    savedObject.Name = localFileSystemInfo.Name;
                    savedObject.ParentId = newParentId;
                    this.Storage.SaveMappedObject(savedObject);
                    this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
                } else {
                    // Both sides have been renamed => Move remote => rename rename solver
                    try {
                        (remoteId as IFileableCmisObject).Move(this.Session.GetObject(savedObject.ParentId), this.Session.GetObject(newParentId));
                    } catch (CmisPermissionDeniedException) {
                        OperationsLogger.Info(string.Format("Permission Denied: Cannot move remote object {0} from {1} to {2}", remoteId.Id, savedObject.ParentId, newParentId));
                        return;
                    }

                    savedObject.ParentId = newParentId;
                    this.Storage.SaveMappedObject(savedObject);
                    this.renameRenameSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
                }
            }
        }
        /// <summary>
        /// Renames the specified localFile to the name of the given remoteId object by using the storage, localFile and remoteId.
        /// </summary>
        /// <param name="localFile">Local file or folder. It is the source file/folder reference, which should be renamed.</param>
        /// <param name="remoteId">Remote identifier. Should be an instance of IFolder or IDocument.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFile,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            IMappedObject obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
            if (remoteId is IFolder) {
                // Rename local folder
                IFolder remoteFolder = remoteId as IFolder;
                IDirectoryInfo dirInfo = localFile as IDirectoryInfo;
                string oldPath = dirInfo.FullName;
                try {
                    dirInfo.MoveTo(Path.Combine(dirInfo.Parent.FullName, remoteFolder.Name));
                    obj.Name = remoteFolder.Name;
                } catch (IOException) {
                    if (dirInfo.Name.Equals(remoteFolder.Name, StringComparison.OrdinalIgnoreCase)) {
                        obj.Name = dirInfo.Name;
                    } else {
                        throw;
                    }
                }

                if (remoteFolder.LastModificationDate != null) {
                    dirInfo.LastWriteTimeUtc = (DateTime)remoteFolder.LastModificationDate;
                }

                obj.LastChangeToken = remoteFolder.ChangeToken;
                obj.LastRemoteWriteTimeUtc = remoteFolder.LastModificationDate;
                obj.LastLocalWriteTimeUtc = dirInfo.LastWriteTimeUtc;
                obj.Ignored = remoteFolder.AreAllChildrenIgnored();
                this.Storage.SaveMappedObject(obj);
                OperationsLogger.Info(string.Format("Renamed local folder {0} to {1}", oldPath, remoteFolder.Name));
            } else if(remoteId is IDocument) {
                // Rename local file
                IDocument remoteDocument = remoteId as IDocument;
                IFileInfo fileInfo = localFile as IFileInfo;
                string oldPath = fileInfo.FullName;
                fileInfo.MoveTo(Path.Combine(fileInfo.Directory.FullName, remoteDocument.Name));
                if (remoteDocument.LastModificationDate != null) {
                    fileInfo.LastWriteTimeUtc = (DateTime)remoteDocument.LastModificationDate;
                }

                obj.Name = remoteDocument.Name;
                obj.LastChangeToken = remoteContent == ContentChangeType.NONE ? remoteDocument.ChangeToken : obj.LastChangeToken;
                obj.LastRemoteWriteTimeUtc = remoteContent == ContentChangeType.NONE ? remoteDocument.LastModificationDate : obj.LastRemoteWriteTimeUtc;
                obj.LastLocalWriteTimeUtc = fileInfo.LastWriteTimeUtc;
                this.Storage.SaveMappedObject(obj);
                OperationsLogger.Info(string.Format("Renamed local file {0} to {1}", oldPath, remoteDocument.Name));
                if (remoteContent != ContentChangeType.NONE) {
                    throw new ArgumentException("Remote documents content is also changed => force crawl sync.");
                }
            } else {
                throw new ArgumentException("Given remote Id is not an IFolder nor an IDocument instance");
            }
        }
 /// <summary>
 /// Solve the specified situation by using the storage and remote object id to remove existing db entries and forces a crawl sync by throwing an IOException.
 /// </summary>
 /// <param name="localFile">Deleted Local filesystem info instance.</param>
 /// <param name="remoteId">Remote identifier or object.</param>
 /// <param name="localContent">Hint if the local content has been changed. Is not used by this solver.</param>
 /// <param name="remoteContent">Information if the remote content has been changed. Is not used by this solver.</param>
 public override void Solve(
     IFileSystemInfo localFile,
     IObjectId remoteId,
     ContentChangeType localContent = ContentChangeType.NONE,
     ContentChangeType remoteContent = ContentChangeType.NONE)
 {
     var mappedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
     this.Storage.RemoveObject(mappedObject);
     throw new IOException(
         string.Format(
         "Local deleted {0} is renamed or moved remotely => invoking crawl sync to download them again",
         mappedObject.Type == MappedObjectType.File ? "file" : "directory"));
 }
 /// <summary>
 /// Solve the specified situation by using localFile and remote object.
 /// </summary>
 /// <param name="localFileSystemInfo">Local filesystem info instance.</param>
 /// <param name="remoteId">Remote identifier or object.</param>
 /// <param name="localContent">Hint if the local content has been changed.</param>
 /// <param name="remoteContent">Information if the remote content has been changed.</param>
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     if (localFileSystemInfo is IDirectoryInfo) {
         IDirectoryInfo localFolder = localFileSystemInfo as IDirectoryInfo;
         IDirectoryInfo localParent = localFolder.Parent;
         IFolder remoteFolder = remoteId as IFolder;
         string remoteParentId = remoteFolder.ParentId;
         IMappedObject mappedParent = this.Storage.GetObjectByRemoteId(remoteParentId);
         IMappedObject mappedObject = this.Storage.GetObjectByRemoteId(remoteFolder.Id);
         if (localParent.Uuid == mappedParent.Guid) {
             // Both folders are in the same parent folder
             this.SyncNamesAndDates(localFolder, remoteFolder, mappedObject);
         } else {
             OperationsLogger.Warn(
                 string.Format(
                 "Synchronization Conflict: The local directory {0} has been moved to {1} with id {2},{4}" +
                 "but the remote folder was moved to {3}{4}You can fix this situation by moving them into the same folder",
                 localFileSystemInfo.Name,
                 localFileSystemInfo.FullName,
                 remoteFolder.Path,
                 Environment.NewLine));
             return;
         }
     } else if (localFileSystemInfo is IFileInfo) {
         IFileInfo localFile = localFileSystemInfo as IFileInfo;
         IDirectoryInfo localParent = localFile.Directory;
         IDocument remoteFile = remoteId as IDocument;
         string remoteParentId = remoteFile.Parents[0].Id;
         IMappedObject mappedParent = this.Storage.GetObjectByRemoteId(remoteParentId);
         IMappedObject mappedObject = this.Storage.GetObjectByRemoteId(remoteFile.Id);
         if (localParent.Uuid == mappedParent.Guid) {
             // Both files are in the same parent folder
             this.SyncNamesAndDates(localFile, remoteFile, mappedObject);
             return;
         } else {
             OperationsLogger.Warn(
                 string.Format(
                 "Synchronization Conflict: The local file {0} has been moved to {1} with id {2},{4}" +
                 "but the remote file was moved to {3}{4}You can fix this situation by moving them into the same folder",
                 localFileSystemInfo.Name,
                 localFileSystemInfo.FullName,
                 remoteFile.Paths[0],
                 Environment.NewLine));
             return;
         }
     }
 }
 /// <summary>
 /// Creates the event.
 /// </summary>
 /// <returns>The event.</returns>
 /// <param name="isFile">If set to <c>true</c> is file.</param>
 /// <param name="remoteObject">Remote object.</param>
 /// <param name="localObject">Local object.</param>
 /// <param name="remoteChange">Remote change.</param>
 /// <param name="localChange">Local change.</param>
 /// <param name="oldRemotePath">Old remote path.</param>
 /// <param name="oldLocalObject">Old local object.</param>
 /// <param name="src">Source of the creation.</param>
 public static AbstractFolderEvent CreateEvent(
     bool isFile,
     IFileableCmisObject remoteObject = null,
     IFileSystemInfo localObject = null,
     MetaDataChangeType remoteChange = MetaDataChangeType.NONE,
     MetaDataChangeType localChange = MetaDataChangeType.NONE,
     string oldRemotePath = null,
     IFileSystemInfo oldLocalObject = null,
     object src = null) {
     if (localChange != MetaDataChangeType.MOVED &&
         remoteChange != MetaDataChangeType.MOVED) {
         if (isFile) {
             return new FileEvent(
                 localObject as IFileInfo,
                 remoteObject as IDocument) {
                 Local = localChange,
                 Remote = remoteChange
             };
         } else {
             return new FolderEvent(
                 localObject as IDirectoryInfo,
                 remoteObject as IFolder,
                 src) {
                 Local = localChange,
                 Remote = remoteChange
             };
         }
     } else {
         if (isFile) {
             return new FileMovedEvent(
                 oldLocalObject as IFileInfo,
                 localObject as IFileInfo,
                 oldRemotePath,
                 remoteObject as IDocument) {
                 Local = localChange,
                 Remote = remoteChange
             };
         } else {
             return new FolderMovedEvent(
                 oldLocalObject as IDirectoryInfo,
                 localObject as IDirectoryInfo,
                 oldRemotePath,
                 remoteObject as IFolder,
                 src) {
                 Local = localChange,
                 Remote = remoteChange
             };
         }
     }
 }
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     // User Interaction needed or the content will be downloaded on next sync.
     // Possibilities:
     // - Download new remote content (default, because no user interaction is needed and it is simple to solve)
     // - Remove remote element
     // - Ignore until situation is cleared
     OperationsLogger.Warn(string.Format("The remote object {0} of the corresponding locally deleted element has been changed => Downloading the remote changes", remoteId.Id));
     this.Storage.RemoveObject(this.Storage.GetObjectByRemoteId(remoteId.Id));
     throw new ArgumentException("Remote object has been changed while the object was deleted locally => force crawl sync");
 }
        /// <summary>
        /// Solve the specified situation by using the session, storage, localFile and remoteId.
        /// If a folder is affected, simply update the local change time of the corresponding local folder.
        /// If it is a file and the changeToken is not equal to the saved, the new content is downloaded.
        /// </summary>
        /// <param name="localFile">Local file.</param>
        /// <param name="remoteId">Remote identifier.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFile,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            IMappedObject obj = this.Storage.GetObjectByRemoteId(remoteId.Id);
            if (remoteId is IFolder) {
                var remoteFolder = remoteId as IFolder;
                DateTime? lastModified = remoteFolder.LastModificationDate;
                obj.LastChangeToken = remoteFolder.ChangeToken;
                if (lastModified != null) {
                    try {
                        localFile.LastWriteTimeUtc = (DateTime)lastModified;
                    } catch(IOException e) {
                        Logger.Debug("Couldn't set the server side modification date", e);
                    }

                    obj.Ignored = remoteFolder.AreAllChildrenIgnored();
                    obj.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc;
                }
            } else if (remoteId is IDocument) {
                var remoteDocument = remoteId as IDocument;
                DateTime? lastModified = remoteDocument.LastModificationDate;
                if ((lastModified != null && lastModified != obj.LastRemoteWriteTimeUtc) || obj.LastChangeToken != remoteDocument.ChangeToken) {
                    if (remoteContent != ContentChangeType.NONE) {
                        if (obj.LastLocalWriteTimeUtc != localFile.LastWriteTimeUtc) {
                            throw new ArgumentException("The local file has been changed since last write => aborting update");
                        }

                        obj.LastChecksum = DownloadChanges(localFile as IFileInfo, remoteDocument, obj, this.fsFactory, this.transmissonManager, Logger);
                    }

                    obj.LastRemoteWriteTimeUtc = remoteDocument.LastModificationDate;
                    if (remoteDocument.LastModificationDate != null) {
                        localFile.LastWriteTimeUtc = (DateTime)remoteDocument.LastModificationDate;
                    }

                    obj.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc;
                    obj.LastContentSize = remoteDocument.ContentStreamLength ?? 0;
                }

                obj.LastChangeToken = remoteDocument.ChangeToken;
                obj.LastRemoteWriteTimeUtc = lastModified;
            }

            this.Storage.SaveMappedObject(obj);
        }
        public static IMappedObject GetObject(this IMetaDataStorage storage, IFileSystemInfo info) {
            IMappedObject mappedObject = null;
            try {
                Guid? guid = info.Uuid;
                if (guid != null) {
                    mappedObject = storage.GetObjectByGuid((Guid)guid);
                }
            } catch (Exception) {
            }

            if (mappedObject == null) {
                mappedObject = storage.GetObjectByLocalPath(info);
            }

            return mappedObject;
        }
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     // Rename local object and call change/change solver
     var savedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
     string oldPath = localFileSystemInfo.FullName;
     string parentPath = localFileSystemInfo is IFileInfo ? (localFileSystemInfo as IFileInfo).Directory.FullName : (localFileSystemInfo as IDirectoryInfo).Parent.FullName;
     string newPath = Path.Combine(parentPath, (remoteId as ICmisObject).Name);
     this.MoveTo(localFileSystemInfo, oldPath, newPath);
     savedObject.Name = (remoteId as ICmisObject).Name;
     savedObject.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
     this.Storage.SaveMappedObject(savedObject);
     this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
 }
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     var mappedObject = this.Storage.GetObjectByGuid((Guid)localFileSystemInfo.Uuid);
     this.Storage.RemoveObject(mappedObject);
     if (localFileSystemInfo is IFileInfo) {
         this.secondSolver.Solve(localFileSystemInfo, null, ContentChangeType.CREATED, ContentChangeType.NONE);
     } else if (localFileSystemInfo is IDirectoryInfo) {
         this.secondSolver.Solve(localFileSystemInfo, null, ContentChangeType.NONE, ContentChangeType.NONE);
         var dir = localFileSystemInfo as IDirectoryInfo;
         if (dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0) {
             throw new IOException(string.Format("There are unsynced files in local folder {0} => starting crawl sync", dir.FullName));
         }
     }
 }
 /// <summary>
 /// Creates the event.
 /// </summary>
 /// <returns>The event.</returns>
 /// <param name="remoteObject">Remote object.</param>
 /// <param name="localObject">Local object.</param>
 /// <param name="remoteChange">Remote change.</param>
 /// <param name="localChange">Local change.</param>
 /// <param name="oldRemotePath">Old remote path.</param>
 /// <param name="oldLocalObject">Old local object.</param>
 /// <param name="src">Source of the creation.</param>
 public static AbstractFolderEvent CreateEvent(
     IFileableCmisObject remoteObject = null,
     IFileSystemInfo localObject = null,
     MetaDataChangeType remoteChange = MetaDataChangeType.NONE,
     MetaDataChangeType localChange = MetaDataChangeType.NONE,
     string oldRemotePath = null,
     IFileSystemInfo oldLocalObject = null,
     object src = null) {
     return CreateEvent(
         remoteObject is IDocument || localObject is IFileInfo,
         remoteObject,
         localObject,
         remoteChange,
         localChange,
         oldRemotePath,
         oldLocalObject,
         src);
 }
        /// <summary>
        /// Deletes the given localFileInfo on file system and removes the stored object from storage.
        /// </summary>
        /// <param name="localFileInfo">Local file info.</param>
        /// <param name="remoteId">Remote identifier.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFileInfo,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            if (localFileInfo is IDirectoryInfo) {
                if (!this.DeleteLocalObjectIfHasBeenSyncedBefore(localFileInfo)) {
                    this.Storage.RemoveObject(this.Storage.GetObjectByLocalPath(localFileInfo));
                    throw new IOException(string.Format("Not all local objects under {0} have been synced yet", localFileInfo.FullName));
                } else {
                    this.Storage.RemoveObject(this.Storage.GetObjectByLocalPath(localFileInfo));
                }
            } else if (localFileInfo is IFileInfo) {
                var file = localFileInfo as IFileInfo;
                file.Refresh();
                var mappedFile = this.Storage.GetObjectByLocalPath(file);
                if (file.Exists) {
                    if (mappedFile != null && file.LastWriteTimeUtc.Equals(mappedFile.LastLocalWriteTimeUtc)) {
                        file.Delete();
                        OperationsLogger.Info(string.Format("Deleted local file {0} because the mapped remote object {0} has been deleted", file.FullName, mappedFile.RemoteObjectId));
                    } else {
                        file.Uuid = null;
                        if (mappedFile == null) {
                            return;
                        }

                        OperationsLogger.Info(string.Format("Deletion of local file {0} skipped because of not yet uploaded changes", file.FullName));
                    }
                } else {
                    if (mappedFile == null) {
                        return;
                    } else {
                        OperationsLogger.Info(string.Format("Deletion of local file {0} skipped because it has already been deleted", file.FullName));
                    }
                }

                this.Storage.RemoveObject(this.Storage.GetObjectByLocalPath(localFileInfo));
                file.Refresh();
                if (file.Exists) {
                    throw new IOException(string.Format("Deletion of local file {0} skipped because of not yet uploaded changes", localFileInfo.FullName));
                }
            }
        }
        /// <summary>
        /// Solves the situation by deleting the corresponding remote object.
        /// </summary>
        /// <param name="localFile">Local file.</param>
        /// <param name="remoteId">Remote identifier or object.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFile,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            var mappedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
            if (mappedObject.LastChangeToken != (remoteId as ICmisObject).ChangeToken) {
                throw new ArgumentException("Remote object has been changed since last sync => force crawl sync");
            }

            bool hasBeenDeleted = this.TryDeleteObjectOnServer(remoteId, mappedObject.Type);
            if (hasBeenDeleted) {
                this.Storage.RemoveObject(mappedObject);
                OperationsLogger.Info(string.Format("Deleted the corresponding remote object {0} of locally deleted object {1}", remoteId.Id, mappedObject.Name));
            } else {
                OperationsLogger.Warn(string.Format("Permission denied while trying to Delete the locally deleted object {0} on the server.", mappedObject.Name));
            }
        }
        /// <summary>
        /// Solve the specified situation by using the session, storage, localFile and remoteId.
        /// Moves the local file/folder to the new location.
        /// </summary>
        /// <param name="localFile">Old local file/folder.</param>
        /// <param name="remoteId">Remote identifier.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFile,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            // Move local object
            var savedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
            string newPath = remoteId is IFolder ? this.Storage.Matcher.CreateLocalPath(remoteId as IFolder) : this.Storage.Matcher.CreateLocalPath(remoteId as IDocument);
            if (remoteId is IFolder) {
                IDirectoryInfo dirInfo = localFile as IDirectoryInfo;
                string oldPath = dirInfo.FullName;
                if (!dirInfo.FullName.Equals(newPath)) {
                    dirInfo.MoveTo(newPath);
                    dirInfo.LastWriteTimeUtc = (remoteId as IFolder).LastModificationDate != null ? (DateTime)(remoteId as IFolder).LastModificationDate : dirInfo.LastWriteTimeUtc;
                    OperationsLogger.Info(string.Format("Moved local folder {0} to {1}", oldPath, newPath));
                } else {
                    return;
                }
            } else if (remoteId is IDocument) {
                IFileInfo fileInfo = localFile as IFileInfo;
                string oldPath = fileInfo.FullName;
                fileInfo.MoveTo(newPath);
                fileInfo.LastWriteTimeUtc = (remoteId as IDocument).LastModificationDate != null ? (DateTime)(remoteId as IDocument).LastModificationDate : fileInfo.LastWriteTimeUtc;
                OperationsLogger.Info(string.Format("Moved local file {0} to {1}", oldPath, newPath));
            }

            savedObject.Name = (remoteId as ICmisObject).Name;
            savedObject.ParentId = remoteId is IFolder ? (remoteId as IFolder).ParentId : (remoteId as IDocument).Parents[0].Id;
            savedObject.LastChangeToken = (remoteId is IDocument && remoteContent != ContentChangeType.NONE) ? savedObject.LastChangeToken : remoteId is ICmisObject ? (remoteId as ICmisObject).ChangeToken : null;
            savedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc;
            savedObject.LastRemoteWriteTimeUtc = (remoteId is IDocument && remoteContent != ContentChangeType.NONE) ? savedObject.LastRemoteWriteTimeUtc : (remoteId as ICmisObject).LastModificationDate;
            savedObject.Ignored = (remoteId as ICmisObject).AreAllChildrenIgnored();
            this.Storage.SaveMappedObject(savedObject);
            if (remoteId is IDocument && remoteContent != ContentChangeType.NONE) {
                throw new ArgumentException("Remote content has also been changed => force crawl sync.");
            }
        }
 private AbstractFolderEvent GenerateCreatedEvent(IFileSystemInfo fsInfo) {
     return FileOrFolderEventFactory.CreateEvent(null, fsInfo, localChange: MetaDataChangeType.CREATED, src: this);
 }
        private AbstractFolderEvent CreateLocalEventBasedOnStorage(IFileSystemInfo fsObject, IMappedObject storedParent, IMappedObject storedMappedChild) {
            AbstractFolderEvent createdEvent = null;
            if (storedParent == null) {
                throw new ArgumentNullException("storedParent", "stored parent is null. Stored child: " + storedMappedChild.ToString() + Environment.NewLine + "local object is: " + fsObject.FullName);
            }

            if (storedMappedChild.ParentId == storedParent.RemoteObjectId) {
                // Renamed, Updated or Equal
                #if __COCOA__
                if (fsObject.Name.Normalize(NormalizationForm.FormD) == storedMappedChild.Name.Normalize(NormalizationForm.FormD) && fsObject.LastWriteTimeUtc == storedMappedChild.LastLocalWriteTimeUtc) {
                #else
                if (fsObject.Name == storedMappedChild.Name &&
                    fsObject.LastWriteTimeUtc == storedMappedChild.LastLocalWriteTimeUtc &&
                    fsObject.ReadOnly == storedMappedChild.IsReadOnly) {
                #endif
                    // Equal
                    createdEvent = null;
                } else {
                    // Updated or Renamed
                    createdEvent = FileOrFolderEventFactory.CreateEvent(null, fsObject, localChange: MetaDataChangeType.CHANGED, src: this);
                }
            } else {
                // Moved
                IFileSystemInfo oldLocalPath = fsObject is IFileInfo ? (IFileSystemInfo)this.fsFactory.CreateFileInfo(this.storage.GetLocalPath(storedMappedChild)) : (IFileSystemInfo)this.fsFactory.CreateDirectoryInfo(this.storage.GetLocalPath(storedMappedChild));
                createdEvent = FileOrFolderEventFactory.CreateEvent(null, fsObject, localChange: MetaDataChangeType.MOVED, oldLocalObject: oldLocalPath, src: this);
            }

            return createdEvent;
        }

        private IMappedObject FindStoredObjectByFileSystemInfo(List<IMappedObject> storedObjects, IFileSystemInfo fsInfo) {
            Guid? childGuid = fsInfo.Uuid;
            if (childGuid != null) {
               return storedObjects.Find(o => o.Guid == (Guid)childGuid);
            }

            return null;
        }
    }
        /// <summary>
        /// Solve the specified situation by taking renaming the local or remote object to the name of the last changed object.
        /// </summary>
        /// <param name="localFileSystemInfo">Local file system info.</param>
        /// <param name="remoteId">Remote object.</param>
        /// <param name="localContent">Hint if the local content has been changed.</param>
        /// <param name="remoteContent">Information if the remote content has been changed.</param>
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            if (localFileSystemInfo is IDirectoryInfo) {
                var localFolder = localFileSystemInfo as IDirectoryInfo;
                var remoteFolder = remoteId as IFolder;
                var mappedObject = this.Storage.GetObjectByRemoteId(remoteFolder.Id);
                if (localFolder.Name.Equals(remoteFolder.Name)) {
                    mappedObject.Name = localFolder.Name;
                } else if (localFolder.LastWriteTimeUtc.CompareTo((DateTime)remoteFolder.LastModificationDate) > 0) {
                    string oldName = remoteFolder.Name;
                    try {
                        remoteFolder.Rename(localFolder.Name, true);
                    } catch (CmisConstraintException e) {
                        if (!Utils.IsValidISO885915(localFolder.Name)) {
                            OperationsLogger.Warn(string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFolder.Name));
                            throw new InteractionNeededException(string.Format("Server denied renaming of {0}", oldName), e) {
                                Title = string.Format("Server denied renaming of {0}", oldName),
                                Description = string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFolder.Name)
                            };
                        }

                        throw;
                    }

                    mappedObject.Name = remoteFolder.Name;
                    OperationsLogger.Info(string.Format("Renamed remote folder {0} with id {2} to {1}", oldName, remoteFolder.Id, remoteFolder.Name));
                } else {
                    string oldName = localFolder.Name;
                    localFolder.MoveTo(Path.Combine(localFolder.Parent.FullName, remoteFolder.Name));
                    mappedObject.Name = remoteFolder.Name;
                    OperationsLogger.Info(string.Format("Renamed local folder {0} to {1}", Path.Combine(localFolder.Parent.FullName, oldName), remoteFolder.Name));
                }

                mappedObject.LastLocalWriteTimeUtc = localFolder.LastWriteTimeUtc;
                mappedObject.LastRemoteWriteTimeUtc = (DateTime)remoteFolder.LastModificationDate;
                mappedObject.LastChangeToken = remoteFolder.ChangeToken;
                mappedObject.Ignored = remoteFolder.AreAllChildrenIgnored();
                this.Storage.SaveMappedObject(mappedObject);
            } else if (localFileSystemInfo is IFileInfo) {
                var localFile = localFileSystemInfo as IFileInfo;
                var remoteFile = remoteId as IDocument;
                var mappedObject = this.Storage.GetObjectByRemoteId(remoteFile.Id);
                if (localFile.Name.Equals(remoteFile.Name)) {
                    mappedObject.Name = localFile.Name;
                    this.Storage.SaveMappedObject(mappedObject);
                    this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
                } else {
                    string desc = string.Format(
                        "The local file {0} has been locally renamed from {1} to {2} and remotely to {3}. " +
                        "Fix this conflict by renaming the remote file to {2} or the local file to {3}.",
                        localFile.FullName,
                        mappedObject.Name,
                        localFile.Name,
                        remoteFile.Name);
                    OperationsLogger.Warn("Synchronization Conflict: " + desc);
                    throw new InteractionNeededException("Synchronization Conflict") {
                        Title = "Synchronization Conflict",
                        Description = desc
                    };
                }
            }
        }
        public override void Solve(
            IFileSystemInfo localFileSystemInfo,
            IObjectId remoteId,
            ContentChangeType localContent,
            ContentChangeType remoteContent)
        {
            var savedObject = this.Storage.GetObjectByRemoteId(remoteId.Id);
            string oldPath = localFileSystemInfo.FullName;
            string oldName = (remoteId as ICmisObject).Name;
            if ((remoteId as ICmisObject).Name != savedObject.Name) {
                // Both are renamed and remote is also moved => move & rename/rename
                string newPath = remoteId is IFolder ? this.Storage.Matcher.CreateLocalPath(remoteId as IFolder) : this.Storage.Matcher.CreateLocalPath(remoteId as IDocument);
                if ((remoteId as ICmisObject).Name == localFileSystemInfo.Name) {
                    // Move local object to new name, bacause it is the same => only change/change solver is needed
                    this.MoveTo(localFileSystemInfo, oldPath, newPath);
                    savedObject.Name = localFileSystemInfo.Name;
                    savedObject.ParentId = remoteId is IFolder ? (remoteId as IFolder).ParentId : (remoteId as IDocument).Parents[0].Id;
                    this.Storage.SaveMappedObject(savedObject);
                    this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
                } else {
                    // Only move local object to new folder but keep the old name => both names are different => rename/rename solver needed
                    newPath = newPath.TrimEnd(Path.DirectorySeparatorChar);
                    newPath = newPath.Substring(0, newPath.Length - (remoteId as ICmisObject).Name.Length) + oldName;
                    this.MoveTo(localFileSystemInfo, oldPath, newPath);
                    savedObject.ParentId = remoteId is IFolder ? (remoteId as IFolder).ParentId : (remoteId as IDocument).Parents[0].Id;
                    this.Storage.SaveMappedObject(savedObject);
                    this.renameRenameSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
                }
            } else {
                // Local rename and remote move => move locally and rename remote => change/change
                try {
                    // rename remote file
                    (remoteId as ICmisObject).Rename(localFileSystemInfo.Name, true);
                    OperationsLogger.Info(string.Format("Renamed remote object {0} from {1} to {2}", remoteId.Id, oldName, localFileSystemInfo.Name));
                    savedObject.Name = (remoteId as ICmisObject).Name;
                } catch (CmisConstraintException e) {
                    if (!Utils.IsValidISO885915(localFileSystemInfo.Name)) {
                        OperationsLogger.Warn(string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name));
                        throw new InteractionNeededException(string.Format("Server denied renaming of {0}", oldName), e) {
                            Title = string.Format("Server denied renaming of {0}", oldName),
                            Description = string.Format("Server denied to rename {0} to {1}, perhaps because it contains UTF-8 characters", oldName, localFileSystemInfo.Name)
                        };
                    }

                    throw;
                } catch (CmisPermissionDeniedException) {
                    OperationsLogger.Info(string.Format("Permission Denied: Cannot rename remote object ({1}): {0}", (remoteId as ICmisObject).Name, remoteId.Id));
                    return;
                }

                string newPath = remoteId is IFolder ? this.Storage.Matcher.CreateLocalPath(remoteId as IFolder) : this.Storage.Matcher.CreateLocalPath(remoteId as IDocument);
                // move local object to same directory as the remote object is
                this.MoveTo(localFileSystemInfo, oldPath, newPath);

                savedObject.ParentId = remoteId is IFolder ? (remoteId as IFolder).ParentId : (remoteId as IDocument).Parents[0].Id;
                this.Storage.SaveMappedObject(savedObject);

                // Synchronize the rest with the change change solver
                this.changeChangeSolver.Solve(localFileSystemInfo, remoteId, localContent, remoteContent);
            }
        }
 public void CallEnsureThatLocalFileNameContainsLegalCharacters(IFileSystemInfo fileInfo, CmisConstraintException e) {
     this.EnsureThatLocalFileNameContainsLegalCharacters(fileInfo, e);
 }
 public override void Solve(
     IFileSystemInfo localFileSystemInfo,
     IObjectId remoteId,
     ContentChangeType localContent,
     ContentChangeType remoteContent)
 {
     throw new NotImplementedException();
 }