예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DescendantsCrawler"/> class.
        /// </summary>
        /// <param name="queue">Sync Event Queue.</param>
        /// <param name="remoteFolder">Remote folder.</param>
        /// <param name="localFolder">Local folder.</param>
        /// <param name="storage">Meta data storage.</param>
        /// <param name="filter">Aggregated filter.</param>
        /// <param name="activityListener">Activity listner.</param>
        public DescendantsCrawler(
            ISyncEventQueue queue,
            IFolder remoteFolder,
            IDirectoryInfo localFolder,
            IMetaDataStorage storage,
            IFilterAggregator filter,
            IActivityListener activityListener,
            IIgnoredEntitiesStorage ignoredStorage)
            : base(queue)
        {
            if (remoteFolder == null) {
                throw new ArgumentNullException("remoteFolder");
            }

            if (localFolder == null) {
                throw new ArgumentNullException("localFolder");
            }

            if (storage == null) {
                throw new ArgumentNullException("storage");
            }

            if (filter == null) {
                throw new ArgumentNullException("filter");
            }

            if (activityListener == null) {
                throw new ArgumentNullException("activityListener");
            }

            this.activityListener = activityListener;
            this.treebuilder = new DescendantsTreeBuilder(storage, remoteFolder, localFolder, filter, ignoredStorage);
            this.eventGenerator = new CrawlEventGenerator(storage);
            this.notifier = new CrawlEventNotifier(queue);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.Producer.Crawler.DescendantsTreeBuilder"/> class.
        /// </summary>
        /// <param name='storage'>
        /// The MetadataStorage.
        /// </param>
        /// <param name='remoteFolder'>
        /// Remote folder.
        /// </param>
        /// <param name='localFolder'>
        /// Local folder.
        /// </param>
        /// <param name='filter'>
        /// Aggregated Filters.
        /// </param>
        /// <exception cref='ArgumentNullException'>
        /// <attribution license="cc4" from="Microsoft" modified="false" /><para>The exception that is thrown when a
        /// null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument. </para>
        /// </exception>
        public DescendantsTreeBuilder(
            IMetaDataStorage storage,
            IFolder remoteFolder,
            IDirectoryInfo localFolder,
            IFilterAggregator filter,
            IIgnoredEntitiesStorage ignoredStorage)
        {
            if (remoteFolder == null) {
                throw new ArgumentNullException("remoteFolder");
            }

            if (localFolder == null) {
                throw new ArgumentNullException("localFolder");
            }

            if (storage == null) {
                throw new ArgumentNullException("storage");
            }

            if (filter == null) {
                throw new ArgumentNullException("filter");
            }

            if (ignoredStorage == null) {
                throw new ArgumentNullException("ignoredStorage");
            }

            this.storage = storage;
            this.remoteFolder = remoteFolder;
            this.localFolder = localFolder;
            this.filter = filter;
            this.matcher = new PathMatcher(localFolder.FullName, remoteFolder.Path);
            this.ignoredStorage = ignoredStorage;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.SelectiveIgnore.SelectiveIgnoreFilter"/> class.
        /// </summary>
        /// <param name="storage">Ignored entities storage.</param>
        public SelectiveIgnoreFilter(IIgnoredEntitiesStorage storage)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }

            this.storage = storage;
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EventManagerInitializer"/> class.
        /// </summary>
        /// <param name='queue'>The SyncEventQueue.</param>
        /// <param name='storage'>Storage for Metadata.</param>
        /// <param name='fileTransmissionStorage'>Storage for file transmissions.</param>
        /// <param name='ignoredStorage'>Storage for ignored entities.</param>
        /// <param name='repoInfo'>Repo info.</param>
        /// <param name='filter'>Filter aggregation.</param>
        /// <param name='activityListner'>Listener for Sync activities.</param>
        /// <param name='fsFactory'>File system factory.</param>
        /// <exception cref='ArgumentNullException'>
        /// Is thrown when an argument passed to a method is invalid because it is <see langword="null" /> .
        /// </exception>
        public EventManagerInitializer(
            ISyncEventQueue queue,
            IMetaDataStorage storage,
            IFileTransmissionStorage fileTransmissionStorage,
            IIgnoredEntitiesStorage ignoredStorage,
            RepoInfo repoInfo,
            IFilterAggregator filter,
            ActivityListenerAggregator activityListener,
            IFileSystemInfoFactory fsFactory = null) : base(queue)
        {
            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }

            if (fileTransmissionStorage == null)
            {
                throw new ArgumentNullException("fileTransmissionStorage");
            }

            if (repoInfo == null)
            {
                throw new ArgumentNullException("repoInfo");
            }

            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            if (activityListener == null)
            {
                throw new ArgumentNullException("activityListener");
            }

            if (ignoredStorage == null)
            {
                throw new ArgumentNullException("ignoredStorage", "Given storage for ignored entries is null");
            }

            if (fsFactory == null)
            {
                this.fileSystemFactory = new FileSystemInfoFactory();
            }
            else
            {
                this.fileSystemFactory = fsFactory;
            }

            this.filter                  = filter;
            this.repoInfo                = repoInfo;
            this.storage                 = storage;
            this.ignoredStorage          = ignoredStorage;
            this.fileTransmissionStorage = fileTransmissionStorage;
            this.activityListener        = activityListener;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.SelectiveIgnore.IgnoreFlagChangeDetection"/> class.
        /// </summary>
        /// <param name="ignores">Storage for ignores.</param>
        /// <param name="matcher">Path matcher.</param>
        /// <param name="queue">Sync Event Queue.</param>
        public IgnoreFlagChangeDetection(IIgnoredEntitiesStorage ignores, IPathMatcher matcher, ISyncEventQueue queue) : base(queue) {
            if (ignores == null) {
                throw new ArgumentNullException("ignores");
            }

            if (matcher == null) {
                throw new ArgumentNullException("matcher");
            }

            this.ignores = ignores;
            this.matcher = matcher;
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.SelectiveIgnore.IgnoreFlagChangeDetection"/> class.
        /// </summary>
        /// <param name="ignores">Storage for ignores.</param>
        /// <param name="matcher">Path matcher.</param>
        /// <param name="queue">Sync Event Queue.</param>
        public IgnoreFlagChangeDetection(IIgnoredEntitiesStorage ignores, IPathMatcher matcher, ISyncEventQueue queue) : base(queue)
        {
            if (ignores == null)
            {
                throw new ArgumentNullException("ignores");
            }

            if (matcher == null)
            {
                throw new ArgumentNullException("matcher");
            }

            this.ignores = ignores;
            this.matcher = matcher;
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DescendantsCrawler"/> class.
        /// </summary>
        /// <param name="queue">Sync Event Queue.</param>
        /// <param name="remoteFolder">Remote folder.</param>
        /// <param name="localFolder">Local folder.</param>
        /// <param name="storage">Meta data storage.</param>
        /// <param name="filter">Aggregated filter.</param>
        /// <param name="activityListener">Activity listner.</param>
        public DescendantsCrawler(
            ISyncEventQueue queue,
            IFolder remoteFolder,
            IDirectoryInfo localFolder,
            IMetaDataStorage storage,
            IFilterAggregator filter,
            IActivityListener activityListener,
            IIgnoredEntitiesStorage ignoredStorage)
            : base(queue)
        {
            if (remoteFolder == null)
            {
                throw new ArgumentNullException("remoteFolder");
            }

            if (localFolder == null)
            {
                throw new ArgumentNullException("localFolder");
            }

            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }

            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            if (activityListener == null)
            {
                throw new ArgumentNullException("activityListener");
            }

            this.activityListener = activityListener;
            this.treebuilder      = new DescendantsTreeBuilder(storage, remoteFolder, localFolder, filter, ignoredStorage);
            this.eventGenerator   = new CrawlEventGenerator(storage);
            this.notifier         = new CrawlEventNotifier(queue);
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.Producer.Crawler.DescendantsTreeBuilder"/> class.
        /// </summary>
        /// <param name='storage'>
        /// The MetadataStorage.
        /// </param>
        /// <param name='remoteFolder'>
        /// Remote folder.
        /// </param>
        /// <param name='localFolder'>
        /// Local folder.
        /// </param>
        /// <param name='filter'>
        /// Aggregated Filters.
        /// </param>
        /// <exception cref='ArgumentNullException'>
        /// <attribution license="cc4" from="Microsoft" modified="false" /><para>The exception that is thrown when a
        /// null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument. </para>
        /// </exception>
        public DescendantsTreeBuilder(
            IMetaDataStorage storage,
            IFolder remoteFolder,
            IDirectoryInfo localFolder,
            IFilterAggregator filter,
            IIgnoredEntitiesStorage ignoredStorage)
        {
            if (remoteFolder == null)
            {
                throw new ArgumentNullException("remoteFolder");
            }

            if (localFolder == null)
            {
                throw new ArgumentNullException("localFolder");
            }

            if (storage == null)
            {
                throw new ArgumentNullException("storage");
            }

            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            if (ignoredStorage == null)
            {
                throw new ArgumentNullException("ignoredStorage");
            }

            this.storage        = storage;
            this.remoteFolder   = remoteFolder;
            this.localFolder    = localFolder;
            this.filter         = filter;
            this.matcher        = new PathMatcher(localFolder.FullName, remoteFolder.Path);
            this.ignoredStorage = ignoredStorage;
        }
예제 #9
0
        /// <summary>
        /// Gets the remote directory tree.
        /// </summary>
        /// <returns>The remote directory tree.</returns>
        /// <param name="parent">Parent folder.</param>
        /// <param name="descendants">Descendants of remote object.</param>
        /// <param name="filter">Filter of ignored or invalid files and folder</param>
        public static IObjectTree <IFileableCmisObject> GetRemoteDirectoryTree(IFolder parent, IList <ITree <IFileableCmisObject> > descendants, IFilterAggregator filter, IIgnoredEntitiesStorage ignoredStorage, IPathMatcher matcher)
        {
            IList <IObjectTree <IFileableCmisObject> > children = new List <IObjectTree <IFileableCmisObject> >();

            if (descendants != null)
            {
                foreach (var child in descendants)
                {
                    if (child.Item is IFolder)
                    {
                        string reason;
                        var    folder = child.Item as IFolder;
                        if (!filter.FolderNamesFilter.CheckFolderName(folder.Name, out reason) && !filter.InvalidFolderNamesFilter.CheckFolderName(folder.Name, out reason))
                        {
                            if (folder.AreAllChildrenIgnored())
                            {
                                ignoredStorage.AddOrUpdateEntryAndDeleteAllChildrenFromStorage(new IgnoredEntity(folder, matcher));
                                Logger.Info(string.Format("Folder {0} with Id {1} is ignored", folder.Name, folder.Id));
                                children.Add(new ObjectTree <IFileableCmisObject> {
                                    Item     = child.Item,
                                    Children = new List <IObjectTree <IFileableCmisObject> >()
                                });
                            }
                            else
                            {
                                ignoredStorage.Remove(folder.Id);
                                children.Add(GetRemoteDirectoryTree(folder, child.Children, filter, ignoredStorage, matcher));
                            }
                        }
                        else
                        {
                            Logger.Info(reason);
                        }
                    }
                    else if (child.Item is IDocument)
                    {
                        string reason;
                        if (!filter.FileNamesFilter.CheckFile(child.Item.Name, out reason))
                        {
                            children.Add(new ObjectTree <IFileableCmisObject> {
                                Item     = child.Item,
                                Children = new List <IObjectTree <IFileableCmisObject> >()
                            });
                        }
                        else
                        {
                            Logger.Info(reason);
                        }
                    }
                }
            }

            var tree = new ObjectTree <IFileableCmisObject> {
                Item     = parent,
                Children = children
            };

            return(tree);
        }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Repository"/> class.
        /// </summary>
        /// <param name="repoInfo">Repo info.</param>
        /// <param name="activityListener">Activity listener.</param>
        /// <param name="inMemory">If set to <c>true</c> in memory.</param>
        /// <param name="queue">Event Queue.</param>
        protected Repository(RepoInfo repoInfo, ActivityListenerAggregator activityListener, bool inMemory, ICountingQueue queue) : base(repoInfo)
        {
            if (activityListener == null)
            {
                throw new ArgumentNullException("activityListener");
            }

            this.fileSystemFactory = new FileSystemInfoFactory();
            this.activityListener  = activityListener;

            this.rootFolderMonitor = new RepositoryRootDeletedDetection(this.fileSystemFactory.CreateDirectoryInfo(this.LocalPath));
            this.rootFolderMonitor.RepoRootDeleted += this.RootFolderAvailablilityChanged;

            if (!this.fileSystemFactory.CreateDirectoryInfo(this.LocalPath).IsExtendedAttributeAvailable())
            {
                throw new ExtendedAttributeException("Extended Attributes are not available on the local path: " + this.LocalPath);
            }

            this.Queue = queue;
            this.Queue.EventManager.AddEventHandler(rootFolderMonitor);
            this.Queue.EventManager.AddEventHandler(new DebugLoggingHandler());

            // Create Database connection
            this.db = new DBreezeEngine(new DBreezeConfiguration {
                DBreezeDataFolderName = inMemory ? string.Empty : repoInfo.GetDatabasePath(),
                Storage = inMemory ? DBreezeConfiguration.eStorage.MEMORY : DBreezeConfiguration.eStorage.DISK
            });

            // Create session dependencies
            this.sessionFactory = SessionFactory.NewInstance();
            this.authProvider   = AuthProviderFactory.CreateAuthProvider(repoInfo.AuthenticationType, repoInfo.Address, this.db);

            // Initialize storage
            this.storage = new MetaDataStorage(this.db, new PathMatcher(this.LocalPath, this.RepoInfo.RemotePath), inMemory);
            this.fileTransmissionStorage = new FileTransmissionStorage(this.db, RepoInfo.ChunkSize);

            // Add ignore file/folder filter
            this.ignoredFoldersFilter = new IgnoredFoldersFilter {
                IgnoredPaths = new List <string>(repoInfo.GetIgnoredPaths())
            };
            this.ignoredFileNameFilter = new IgnoredFileNamesFilter {
                Wildcards = ConfigManager.CurrentConfig.IgnoreFileNames
            };
            this.ignoredFolderNameFilter = new IgnoredFolderNameFilter {
                Wildcards = ConfigManager.CurrentConfig.IgnoreFolderNames
            };
            this.invalidFolderNameFilter = new InvalidFolderNameFilter();
            var symlinkFilter = new SymlinkFilter();

            this.filters         = new FilterAggregator(this.ignoredFileNameFilter, this.ignoredFolderNameFilter, this.invalidFolderNameFilter, this.ignoredFoldersFilter, symlinkFilter);
            this.reportingFilter = new ReportingFilter(
                this.Queue,
                this.ignoredFoldersFilter,
                this.ignoredFileNameFilter,
                this.ignoredFolderNameFilter,
                this.invalidFolderNameFilter,
                symlinkFilter);
            this.Queue.EventManager.AddEventHandler(this.reportingFilter);
            this.alreadyAddedFilter = new IgnoreAlreadyHandledFsEventsFilter(this.storage, this.fileSystemFactory);
            this.Queue.EventManager.AddEventHandler(this.alreadyAddedFilter);

            // Add handler for repo config changes
            this.Queue.EventManager.AddEventHandler(new GenericSyncEventHandler <RepoConfigChangedEvent>(0, this.RepoInfoChanged));

            // Add periodic sync procedures scheduler
            this.Scheduler = new SyncScheduler(this.Queue, repoInfo.PollInterval);
            this.Queue.EventManager.AddEventHandler(this.Scheduler);

            // Add File System Watcher
            #if __COCOA__
            this.WatcherProducer = new CmisSync.Lib.Producer.Watcher.MacWatcher(LocalPath, Queue);
            #else
            this.WatcherProducer = new NetWatcher(new FileSystemWatcher(this.LocalPath), this.Queue, this.storage);
            #endif
            this.WatcherConsumer = new WatcherConsumer(this.Queue);
            this.Queue.EventManager.AddEventHandler(this.WatcherConsumer);

            // Add transformer
            this.transformer = new ContentChangeEventTransformer(this.Queue, this.storage, this.fileSystemFactory);
            this.Queue.EventManager.AddEventHandler(this.transformer);

            // Add local fetcher
            var localFetcher = new LocalObjectFetcher(this.storage.Matcher, this.fileSystemFactory);
            this.Queue.EventManager.AddEventHandler(localFetcher);

            this.ignoredStorage = new IgnoredEntitiesStorage(new IgnoredEntitiesCollection(), this.storage);

            this.Queue.EventManager.AddEventHandler(new EventManagerInitializer(this.Queue, this.storage, this.fileTransmissionStorage, this.ignoredStorage, this.RepoInfo, this.filters, activityListener, this.fileSystemFactory));

            this.Queue.EventManager.AddEventHandler(new DelayRetryAndNextSyncEventHandler(this.Queue));

            this.connectionScheduler = new ConnectionScheduler(this.RepoInfo, this.Queue, this.sessionFactory, this.authProvider);

            this.Queue.EventManager.AddEventHandler(this.connectionScheduler);
            this.Queue.EventManager.AddEventHandler(
                new GenericSyncEventHandler <SuccessfulLoginEvent>(
                    10000,
                    delegate(ISyncEvent e) {
                this.RepoStatusFlags.Connected = true;
                this.Status = this.RepoStatusFlags.Status;

                return(false);
            }));
            this.Queue.EventManager.AddEventHandler(
                new GenericSyncEventHandler <ConfigurationNeededEvent>(
                    10000,
                    delegate(ISyncEvent e) {
                this.RepoStatusFlags.Warning = true;
                this.Status = this.RepoStatusFlags.Status;

                return(false);
            }));
            this.unsubscriber = this.Queue.CategoryCounter.Subscribe(this);
        }
        /// <summary>
        /// Gets the remote directory tree.
        /// </summary>
        /// <returns>The remote directory tree.</returns>
        /// <param name="parent">Parent folder.</param>
        /// <param name="descendants">Descendants of remote object.</param>
        /// <param name="filter">Filter of ignored or invalid files and folder</param>
        public static IObjectTree<IFileableCmisObject> GetRemoteDirectoryTree(IFolder parent, IList<ITree<IFileableCmisObject>> descendants, IFilterAggregator filter, IIgnoredEntitiesStorage ignoredStorage, IPathMatcher matcher) {
            IList<IObjectTree<IFileableCmisObject>> children = new List<IObjectTree<IFileableCmisObject>>();
            if (descendants != null) {
                foreach (var child in descendants) {
                    if (child.Item is IFolder) {
                        string reason;
                        var folder = child.Item as IFolder;
                        if (!filter.FolderNamesFilter.CheckFolderName(folder.Name, out reason) && !filter.InvalidFolderNamesFilter.CheckFolderName(folder.Name, out reason)) {
                            if (folder.AreAllChildrenIgnored()) {
                                ignoredStorage.AddOrUpdateEntryAndDeleteAllChildrenFromStorage(new IgnoredEntity(folder, matcher));
                                Logger.Info(string.Format("Folder {0} with Id {1} is ignored", folder.Name, folder.Id));
                                children.Add(new ObjectTree<IFileableCmisObject> {
                                    Item = child.Item,
                                    Children = new List<IObjectTree<IFileableCmisObject>>()
                                });
                            } else {
                                ignoredStorage.Remove(folder.Id);
                                children.Add(GetRemoteDirectoryTree(folder, child.Children, filter, ignoredStorage, matcher));
                            }
                        } else {
                            Logger.Info(reason);
                        }
                    } else if (child.Item is IDocument) {
                        string reason;
                        if (!filter.FileNamesFilter.CheckFile(child.Item.Name, out reason)) {
                            children.Add(new ObjectTree<IFileableCmisObject> {
                                Item = child.Item,
                                Children = new List<IObjectTree<IFileableCmisObject>>()
                            });
                        } else {
                            Logger.Info(reason);
                        }
                    }
                }
            }

            var tree = new ObjectTree<IFileableCmisObject> {
                Item = parent,
                Children = children
            };

            return tree;
        }