/// <summary> /// Handle the specified e. /// </summary> /// <param name='e'> /// The ISyncEvent. /// </param> /// <returns> /// true if the CS Event is not valid any longer /// </returns> public override bool Handle(ISyncEvent e) { if (!(e is ContentChangeEvent)) { return(false); } var contentChangeEvent = e as ContentChangeEvent; if (contentChangeEvent.Type != DotCMIS.Enums.ChangeType.Deleted && contentChangeEvent.CmisObject == null) { try { contentChangeEvent.UpdateObject(this.session); Logger.Debug("Updated Object in contentChangeEvent" + contentChangeEvent.ToString()); } catch (CmisObjectNotFoundException) { Logger.Debug("Object with id " + contentChangeEvent.ObjectId + " has been deleted - ignore"); return(true); } catch (CmisPermissionDeniedException) { Logger.Debug("Object with id " + contentChangeEvent.ObjectId + " gives Access Denied: ACL changed - ignore"); return(true); } catch (Exception ex) { Logger.Warn("Unable to fetch object " + contentChangeEvent.ObjectId + " starting CrawlSync"); Logger.Debug(ex.StackTrace); Queue.AddEvent(new StartNextSyncEvent(true)); return(true); } } return(false); }
public override bool Handle(ISyncEvent e) { if (e is FSMovedEvent) { var movedEvent = e as FSMovedEvent; if (this.IsInsideIgnoredPath(movedEvent.OldPath) && !this.IsInsideIgnoredPath(movedEvent.LocalPath)) { this.queue.AddEvent(new FSEvent(WatcherChangeTypes.Created, movedEvent.LocalPath, movedEvent.IsDirectory)); return true; } else if (this.IsInsideIgnoredPath(movedEvent.LocalPath) && !this.IsInsideIgnoredPath(movedEvent.OldPath)) { this.queue.AddEvent(new FSEvent(WatcherChangeTypes.Deleted, movedEvent.OldPath, movedEvent.IsDirectory)); return true; } } if (e is ContentChangeEvent) { var contentChangeEvent = e as ContentChangeEvent; if (contentChangeEvent.Type != ChangeType.Deleted) { var state = IgnoredState.NOT_IGNORED; var cmisObject = contentChangeEvent.CmisObject; if (cmisObject is IFolder) { state = this.ignores.IsIgnored(cmisObject as IFolder); } else if (cmisObject is IDocument) { state = this.ignores.IsIgnored(cmisObject as IDocument); } if (state == IgnoredState.INHERITED) { this.queue.AddEvent(new ContentChangeEvent(ChangeType.Deleted, contentChangeEvent.ObjectId)); return true; } } } return false; }
/// <summary> /// Handles repository configuration change events by extracting new login informations and returns false /// </summary> /// <param name="e">The event to handle.</param> /// <returns><c>false</c></returns> public override bool Handle(ISyncEvent e) { if (e is RepoConfigChangedEvent) { var changedConfig = (e as RepoConfigChangedEvent).RepoInfo; if (changedConfig != null) { lock (this.repoInfoLock) { this.RepoInfo = changedConfig; // Reconnect this.Reconnect(); } } } else if (e is CmisConnectionExceptionEvent) { var connectionEvent = e as CmisConnectionExceptionEvent; if (this.lastSuccessfulLogin != null && connectionEvent.OccuredAt > (DateTime)this.lastSuccessfulLogin) { // Reconnect this.Reconnect(); } return(true); } return(false); }
/// <summary> /// Handle the specified e. /// </summary> /// <param name='e'> /// The ISyncEvent only handled when ContentChangeEvent /// </param> /// <returns> /// true if handled. /// </returns> /// <exception cref='InvalidOperationException'> /// Is thrown when an operation cannot be performed. /// </exception> public override bool Handle(ISyncEvent e) { if (!(e is ContentChangeEvent)) { return(false); } Logger.Debug("Handling ContentChangeEvent"); var contentChangeEvent = e as ContentChangeEvent; if (contentChangeEvent.Type != DotCMIS.Enums.ChangeType.Deleted && contentChangeEvent.CmisObject == null) { throw new InvalidOperationException("ERROR, ContentChangeEventAccumulator Missing"); } if (contentChangeEvent.Type == DotCMIS.Enums.ChangeType.Deleted) { this.HandleDeletion(contentChangeEvent); } else if (contentChangeEvent.CmisObject is IFolder) { this.HandleAsIFolder(contentChangeEvent); } else if (contentChangeEvent.CmisObject is IDocument) { this.HandleAsIDocument(contentChangeEvent); } return(true); }
/// <summary> /// Handle the specified e if FolderEvent of FileEvent. /// </summary> /// <param name='e'> /// Any ISyncEvent /// </param> /// <returns>always false</returns> public override bool Handle(ISyncEvent e) { if (e is FolderEvent) { var folderEvent = e as FolderEvent; if(folderEvent.LocalFolder != null) { return false; } if (!this.matcher.CanCreateLocalPath(folderEvent.RemoteFolder.Path)) { Logger.Debug("Dropping FolderEvent for not accessable path: " + folderEvent.RemoteFolder.Path); return true; } Logger.Debug("Fetching local object for " + folderEvent); string localPath = this.matcher.CreateLocalPath(folderEvent.RemoteFolder.Path); folderEvent.LocalFolder = this.fsFactory.CreateDirectoryInfo(localPath); } if (e is FileEvent) { var fileEvent = e as FileEvent; if (fileEvent.LocalFile != null) { return false; } if (!this.matcher.CanCreateLocalPath(fileEvent.RemoteFile.Paths[0])) { Logger.Debug("Dropping FileEvent for not accessable path: " + fileEvent.RemoteFile.Paths[0]); return true; } Logger.Debug("Fetching local object for " + fileEvent); string localPath = this.matcher.CreateLocalPath(fileEvent.RemoteFile.Paths[0]); fileEvent.LocalFile = this.fsFactory.CreateFileInfo(localPath); } return false; }
/// <summary> /// Handles File/FolderEvents. /// </summary> /// <param name="e">The event to handle.</param> /// <returns><c>false</c> on every event</returns> public override bool Handle(ISyncEvent e) { if (!this.CouldLocalObjectBeAccumulated(e as AbstractFolderEvent)) { return(false); } Logger.Debug("Handling event: " + e); var storedObject = this.GetStoredObject(e as AbstractFolderEvent); Logger.Debug(storedObject); Logger.Debug(this.GetParentId(e as AbstractFolderEvent)); if (storedObject != null) { if (storedObject.ParentId != this.GetParentId(e as AbstractFolderEvent)) { this.AccumulateEvent(e as AbstractFolderEvent, storedObject); } else if (storedObject.Name != this.GetRemoteObjectName(e as AbstractFolderEvent)) { this.AccumulateEvent(e as AbstractFolderEvent, storedObject); } } return(false); }
/// <summary> /// Handles the specified e. /// </summary> /// <param name="e">sync events</param> /// <returns>Always returns <c>false</c></returns> public override bool Handle(ISyncEvent e) { if (!(e is FileEvent || e is FolderEvent || e is CrawlRequestEvent)) { return false; } ICmisObject remote = this.GetRemoteObject(e); // already there, no need to GetObject if (remote != null) { return false; } string id; if (e is AbstractFolderEvent && (e as AbstractFolderEvent).Local == MetaDataChangeType.DELETED) { id = this.FetchIdFromStorage(e); } else { id = this.FetchIdFromExtendedAttribute(e); } if (id != null) { Logger.Debug("Fetching remote Object with id " + id); try { remote = this.session.GetObject(id, this.operationContext); Logger.Debug("Fetched object " + remote); } catch (CmisObjectNotFoundException) { Logger.Debug("Was already deleted on server, could not fetch"); return false; } this.SetRemoteObject(e, remote); } return false; }
private static void Listen(BlockingCollection <ISyncEvent> queue, SyncEventManager manager) { Logger.Debug("Starting to listen on SyncEventQueue"); while (!queue.IsCompleted) { ISyncEvent syncEvent = null; // Blocks if number.Count == 0 // IOE means that Take() was called on a completed collection. // Some other thread can call CompleteAdding after we pass the // IsCompleted check but before we call Take. // In this example, we can simply catch the exception since the // loop will break on the next iteration. try { syncEvent = queue.Take(); } catch (InvalidOperationException) { } if (syncEvent != null) { try{ manager.Handle(syncEvent); }catch (Exception e) { Logger.Error("Exception in EventHandler"); Logger.Error(e); } } } Logger.Debug("Stopping to listen on SyncEventQueue"); }
/// <summary> /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.EncapsuledEvent"/> class with an embedded event. /// </summary> /// <param name="e">An Event from another context. Must not be null</param> public EncapsuledEvent(ISyncEvent e) { if (e == null) { throw new ArgumentNullException("e", "A EncapsuledEvent needs a ISyncEvent as parameter, but null was given"); } this.Event = e; }
/// <summary> /// Handles File or FolderEvents and tries to solve the detected situation. /// </summary> /// <param name="e">FileEvent or FolderEvent</param> /// <returns><c>true</c> if the Event has been handled, otherwise <c>false</c></returns> public override bool Handle(ISyncEvent e) { if (e is AbstractFolderEvent) { var folderEvent = e as AbstractFolderEvent; try { this.DoHandle(folderEvent); } catch (RetryException retry) { Logger.Debug(string.Format("RetryException[{0}] thrown for event {1} => enqueue event", retry.Message, folderEvent.ToString())); folderEvent.RetryCount++; this.Queue.AddEvent(folderEvent); } catch (InteractionNeededException interaction) { this.Queue.AddEvent(new InteractionNeededEvent(interaction)); } catch (DotCMIS.Exceptions.CmisConnectionException) { throw; } catch (Exception ex) { Logger.Debug("Exception in SyncMechanism, requesting FullSync and rethrowing", ex); this.Queue.AddEvent(new StartNextSyncEvent(true)); throw; } return(true); } return(false); }
/// <summary> /// Handles Config changes if the poll interval has been changed. /// Resets also the timer if a full sync event has been recognized. /// </summary> /// <param name="e">Sync event.</param> /// <returns><c>false</c> on every event.</returns> public override bool Handle(ISyncEvent e) { RepoConfigChangedEvent config = e as RepoConfigChangedEvent; if (config != null) { double newInterval = config.RepoInfo.PollInterval; if (newInterval > 0 && this.interval != newInterval) { this.interval = newInterval; this.Stop(); this.timer.Interval = this.interval; this.Start(); } return(false); } StartNextSyncEvent start = e as StartNextSyncEvent; if (start != null && start.FullSyncRequested) { this.Stop(); this.Start(); } return(false); }
/// <summary> /// Handle the specified e. /// </summary> /// <param name='e'> /// The ISyncEvent. /// </param> /// <returns> /// true if the CS Event is not valid any longer /// </returns> public override bool Handle(ISyncEvent e) { if (!(e is ContentChangeEvent)) { return false; } var contentChangeEvent = e as ContentChangeEvent; if (contentChangeEvent.Type != DotCMIS.Enums.ChangeType.Deleted && contentChangeEvent.CmisObject == null) { try { contentChangeEvent.UpdateObject(this.session); Logger.Debug("Updated Object in contentChangeEvent" + contentChangeEvent.ToString()); } catch(CmisObjectNotFoundException) { Logger.Debug("Object with id " + contentChangeEvent.ObjectId + " has been deleted - ignore"); return true; } catch(CmisPermissionDeniedException) { Logger.Debug("Object with id " + contentChangeEvent.ObjectId + " gives Access Denied: ACL changed - ignore"); return true; } catch(Exception ex) { Logger.Warn("Unable to fetch object " + contentChangeEvent.ObjectId + " starting CrawlSync"); Logger.Debug(ex.StackTrace); Queue.AddEvent(new StartNextSyncEvent(true)); return true; } } return false; }
/// <summary> /// Handle the specified e. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { StartNextSyncEvent syncEvent = e as StartNextSyncEvent; if (syncEvent != null) { if (syncEvent.FullSyncRequested) { // Get last change log token on server side. string lastRemoteChangeLogTokenBeforeFullCrawlSync = this.session.Binding.GetRepositoryService().GetRepositoryInfo(this.session.RepositoryInfo.Id, null).LatestChangeLogToken; if (this.storage.ChangeLogToken == null) { syncEvent.LastTokenOnServer = lastRemoteChangeLogTokenBeforeFullCrawlSync; } // Use fallback sync algorithm return false; } else { Logger.Debug("Starting ContentChange Sync"); bool result = this.StartSync(); return result; } } // The above started full sync is finished. FullSyncCompletedEvent syncCompleted = e as FullSyncCompletedEvent; if (syncCompleted != null) { string lastTokenOnServer = syncCompleted.StartEvent.LastTokenOnServer; if (!string.IsNullOrEmpty(lastTokenOnServer)) { this.storage.ChangeLogToken = lastTokenOnServer; } } return false; }
/// <summary> /// Handles repository configuration change events by extracting new login informations and returns false /// </summary> /// <param name="e">The event to handle.</param> /// <returns>false</returns> public override bool Handle(ISyncEvent e) { if (e is RepoConfigChangedEvent) { var changedConfig = (e as RepoConfigChangedEvent).RepoInfo; if (changedConfig != null) { lock (this.repoInfoLock) { this.RepoInfo = changedConfig; this.isForbidden = false; lock (this.connectionLock) { if (this.task != null) { try { this.task.Dispose(); this.task = null; } catch (InvalidOperationException) { // Disposing the login task before it is finished is not a problem. } } this.Start(); } } } } return(false); }
public override bool Handle(ISyncEvent e) { if (e is ConfigChangedEvent) { return false; } if (!this.isRootFolderAvailable || e is FSEvent || e is AbstractFolderEvent) { var rootFolderWasAvailable = this.isRootFolderAvailable; var rootFolderExists = this.IsRootFolderAvailable(); if (!rootFolderExists) { Logger.Fatal(string.Format("Local root folder \"{0}\" is missing: All events will be ignored until the root folder is back again.", this.absolutePath)); } else if (!rootFolderWasAvailable) { Logger.Info(string.Format("Local root folder \"{0}\" is available again", this.absolutePath)); } if (rootFolderExists != rootFolderWasAvailable) { var handler = this.RepoRootDeleted; if (handler != null) { handler(this, new RootExistsEventArgs(rootFolderExists)); } } return !rootFolderExists; } else { return false; } }
/// <summary> /// Handle the specified e. /// </summary> /// <param name='e'> /// Each event will be logged /// </param> /// <returns> /// <c>false</c> /// </returns> public override bool Handle(ISyncEvent e) { if(!(e is IRemoveFromLoggingEvent)) { Logger.Debug("Incomming Event: " + e.ToString()); } return false; }
/// <exception cref="InvalidOperationException">When Listener is already stopped</exception> public void AddEvent(ISyncEvent newEvent) { if (alreadyDisposed) { throw new ObjectDisposedException("SyncEventQueue", "Called AddEvent on Disposed object"); } this.queue.Add(newEvent); }
/// <summary> /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.EncapsuledEvent"/> class with an embedded event. /// </summary> /// <param name="e">An Event from another context. Must not be null</param> public EncapsuledEvent(ISyncEvent e) { if (e == null) { throw new ArgumentNullException("A EncapsuledEvent needs a ISyncEvent as parameter, but null was given"); } this.Event = e; }
/// <summary> /// Handle the specified e. /// </summary> /// <param name='e'> /// Each event will be logged /// </param> /// <returns> /// <c>false</c> /// </returns> public override bool Handle(ISyncEvent e) { if (!(e is IRemoveFromLoggingEvent)) { Logger.Debug("Incomming Event: " + e.ToString()); } return(false); }
/// <summary> /// Handle the specified e. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { string reason; try { var nameEvent = e as IFilterableNameEvent; if (nameEvent != null && nameEvent.Name != null) { if (nameEvent.IsDirectory) { if (this.ignoredFolderNameFilter.CheckFolderName(nameEvent.Name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return(true); } } else { if (this.ignoredFileNameFilter.CheckFile(nameEvent.Name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return(true); } } } var pathEvent = e as IFilterableRemotePathEvent; if (pathEvent != null && pathEvent.RemotePath != null) { if (this.ignoredFoldersFilter.CheckPath(pathEvent.RemotePath, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return(true); } string[] folderNames = pathEvent.RemotePath.Split('/'); foreach (var name in folderNames) { if (this.invalidFolderNameFilter.CheckFolderName(name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return(true); } } } } catch (System.IO.DirectoryNotFoundException) { } catch (System.IO.FileLoadException) { } catch (System.NullReferenceException) { } return(false); }
/// <summary></summary> /// <param name="e"></param> public virtual void Handle(ISyncEvent e) { for(int i = handler.Count-1; i >= 0; i--) { var h = handler[i]; logger.Debug("Forwarding to Handler " + h); if(handler[i].Handle(e)){ return; } } }
public void AddEvent(ISyncEvent e) { if (e is ICountableEvent && (e as ICountableEvent).Category != EventCategory.NoCategory) { this.fullCounter.Increase(e as ICountableEvent); this.categoryCounter.Increase(e as ICountableEvent); } this.Queue.Enqueue(e); }
/// <summary> /// Checks is the given Event is a content change event and filters it, if it has been handled already. /// </summary> /// <param name="e">Sync event</param> /// <returns><c>true</c> if the event has been already handled, otherwise <c>false</c></returns> public override bool Handle(ISyncEvent e) { if (e is ContentChangeEvent) { ContentChangeEvent change = e as ContentChangeEvent; switch (change.Type) { case ChangeType.Created: return(this.storage.GetObjectByRemoteId(change.ObjectId) != null); case ChangeType.Deleted: return(this.storage.GetObjectByRemoteId(change.ObjectId) == null); case ChangeType.Security: goto case ChangeType.Updated; case ChangeType.Updated: var mappedObject = this.storage.GetObjectByRemoteId(change.ObjectId); if (mappedObject == null || mappedObject.LastChangeToken == null) { return(false); } else { if (change.CmisObject == null) { try { change.UpdateObject(this.session); } catch (DotCMIS.Exceptions.CmisBaseException) { return(false); } } var cmisObject = change.CmisObject; string cmisParentId = cmisObject is IFolder ? (cmisObject as IFolder).ParentId : cmisObject is IDocument ? (cmisObject as IDocument).Parents[0].Id : null; if (mappedObject.LastChangeToken == cmisObject.ChangeToken && mappedObject.ParentId == cmisParentId) { Logger.Debug(string.Format("Ignoring remote change because the ChangeToken \"{0}\" is equal to the stored one", mappedObject.LastChangeToken)); return(true); } else { return(false); } } default: return(false); } } else { return(false); } }
public override bool Handle(ISyncEvent e) { if (e is TSyncEventType) { return(Handler(e)); } else { return(false); } }
/// <summary> /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.RequestIgnoredEvent"/> class. /// </summary> /// <param name="ignoredEvent">Ignored event.</param> /// <param name="reason">Reason why it has been ignored.</param> /// <param name="source">The source which ignored the event.</param> public RequestIgnoredEvent(ISyncEvent ignoredEvent, string reason = null, SyncEventHandler source = null) { if (ignoredEvent == null) { throw new ArgumentNullException("ignoredEvent"); } if (reason == null && source == null) { throw new ArgumentNullException("There must be a reason or source given for the ignored event"); } this.IgnoredEvent = ignoredEvent; this.Reason = (reason != null) ? reason : "Event has been ignored by: " + source.ToString(); }
public void AddEvent(ISyncEvent newEvent) { lock (Events) { FSEvent fsEvent = newEvent as FSEvent; if (fsEvent != null) { Events.Add(fsEvent); } Queue.AddEvent(newEvent); } }
/// <summary> /// Handle the specified event. /// </summary> /// <param name='e'> /// Event to handle. /// </param> public void Handle(ISyncEvent e) { for (int i = this.handler.Count - 1; i >= 0; i--) { var h = this.handler[i]; if (h.Handle(e)) { if (!(e is IRemoveFromLoggingEvent)) { Logger.Debug(string.Format("Event {0} was handled by {1}", e.ToString(), h.GetType())); } return; } } }
public virtual void Handle(ISyncEvent e) { for (int i = handler.Count - 1; i >= 0; i--) { var h = handler[i]; logger.Debug("Forwarding to Handler " + h); if (handler[i].Handle(e)) { return; } } }
private bool RepoInfoChanged(ISyncEvent e) { if (e is RepoConfigChangedEvent) { this.RepoInfo = (e as RepoConfigChangedEvent).RepoInfo; return(true); } else { // This should never ever happen! return(false); } }
/// <summary></summary> /// <param name="e"></param> /// <returns></returns> public override bool Handle(ISyncEvent e) { if(!(e is FSEvent)) { return false; } FSEvent fsEvent = e as FSEvent; if (fsEvent.Type != WatcherChangeTypes.Deleted) { return false; } return true; }
private void Listen(BlockingCollection <ISyncEvent> queue, ISyncEventManager manager, WaitHandle waitHandle) { Logger.Debug("Starting to listen on SyncEventQueue"); while (!queue.IsCompleted) { ISyncEvent syncEvent = null; // Blocks if number.Count == 0 // IOE means that Take() was called on a completed collection. // Some other thread can call CompleteAdding after we pass the // IsCompleted check but before we call Take. // In this example, we can simply catch the exception since the // loop will break on the next iteration. try { syncEvent = queue.Take(); } catch (InvalidOperationException) { } if (syncEvent != null) { try { if (this.suspend) { Logger.Debug("Suspending sync"); waitHandle.WaitOne(); Logger.Debug("Continue sync"); } manager.Handle(syncEvent); } catch (CmisConnectionException connectionException) { this.AddEvent(new CmisConnectionExceptionEvent(connectionException)); } catch (Exception e) { Logger.Error(string.Format("Exception in EventHandler on Event {0}: ", syncEvent.ToString()), e); } if (syncEvent is ICountableEvent) { var category = (syncEvent as ICountableEvent).Category; if (category != EventCategory.NoCategory) { lock (this.subscriberLock) { this.fullCounter.Decrease(syncEvent as ICountableEvent); this.categoryCounter.Decrease(syncEvent as ICountableEvent); } } } } } Logger.Debug("Stopping to listen on SyncEventQueue"); }
private bool RepoInfoChanged(ISyncEvent e) { if (e is RepoConfigChangedEvent) { this.RepoInfo = (e as RepoConfigChangedEvent).RepoInfo; this.ignoredFoldersFilter.IgnoredPaths = new List <string>(this.RepoInfo.GetIgnoredPaths()); this.ignoredFileNameFilter.Wildcards = ConfigManager.CurrentConfig.IgnoreFileNames; this.ignoredFolderNameFilter.Wildcards = ConfigManager.CurrentConfig.IgnoreFolderNames; this.authProvider.DeleteAllCookies(); return(true); } return(false); }
private ICmisObject GetRemoteObject(ISyncEvent e) { if (e is FileEvent) { return((e as FileEvent).RemoteFile); } if (e is CrawlRequestEvent) { return((e as CrawlRequestEvent).RemoteFolder); } return((e as FolderEvent).RemoteFolder); }
/// <summary> /// Handle the specified Event if it is FSEvent. /// </summary> /// <param name='e'> /// The Event. /// </param> /// <returns> /// True if handled. /// </returns> public override bool Handle(ISyncEvent e) { var fsevent = e as IFSEvent; if (fsevent == null) { return false; } if (fsevent.IsDirectory) { this.HandleFolderEvents(fsevent); } else { this.HandleFileEvents(fsevent); } return true; }
/// <summary></summary> /// <param name="e"></param> /// <returns></returns> public override bool Handle(ISyncEvent e) { if (!(e is FSEvent)) { return(false); } FSEvent fsEvent = e as FSEvent; if (fsEvent.Type != WatcherChangeTypes.Deleted) { return(false); } return(true); }
/// <summary> /// Observes content change events and if they effect exiting entries, updates to storage are executed. /// If an existing entry is not ignored anymore a crawl sync is started. /// </summary> /// <param name="e">The content change events to be observed.</param> /// <returns><c>false</c> on every event</returns> public override bool Handle(ISyncEvent e) { if (e is ContentChangeEvent) { var change = e as ContentChangeEvent; if (change.Type == DotCMIS.Enums.ChangeType.Deleted) { if (this.ignores.IsIgnoredId(change.ObjectId) == IgnoredState.IGNORED) { this.ignores.Remove(change.ObjectId); this.Queue.AddEvent(new StartNextSyncEvent(true)); } return(false); } switch (this.ignores.IsIgnoredId(change.ObjectId)) { case IgnoredState.IGNORED: if (!change.CmisObject.AreAllChildrenIgnored()) { this.ignores.Remove(change.ObjectId); this.Queue.AddEvent(new StartNextSyncEvent(true)); } break; case IgnoredState.INHERITED: goto case IgnoredState.NOT_IGNORED; case IgnoredState.NOT_IGNORED: if (change.CmisObject.AreAllChildrenIgnored()) { if (change.CmisObject is IFolder) { this.ignores.AddOrUpdateEntryAndDeleteAllChildrenFromStorage(new IgnoredEntity(change.CmisObject as IFolder, this.matcher)); } else if (change.CmisObject is IDocument) { this.ignores.Add(new IgnoredEntity(change.CmisObject as IDocument, this.matcher)); } } break; } } return(false); }
/// <summary> /// Handles StartNextSync events. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { if (e is StartNextSyncEvent) { Logger.Debug("Starting DecendantsCrawlSync upon " + e); using (var activity = new ActivityListenerResource(this.activityListener)) { this.CrawlDescendants(); } this.Queue.AddEvent(new FullSyncCompletedEvent(e as StartNextSyncEvent)); return(true); } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.RequestIgnoredEvent"/> class. /// </summary> /// <param name="ignoredEvent">Ignored event.</param> /// <param name="reason">Reason why it has been ignored.</param> /// <param name="source">The source which ignored the event.</param> public RequestIgnoredEvent(ISyncEvent ignoredEvent, string reason = null, SyncEventHandler source = null) { if (ignoredEvent == null) { throw new ArgumentNullException("The ignored event cannot be null"); } if (reason == null && source == null) { throw new ArgumentNullException("There must be a reason or source given for the ignored event"); } this.IgnoredEvent = ignoredEvent; this.Reason = (reason != null) ? reason : "Event has been ignored by: " + source.ToString(); }
private void SetRemoteObject(ISyncEvent e, ICmisObject remote) { if (e is FileEvent) { (e as FileEvent).RemoteFile = remote as IDocument; } else if (e is CrawlRequestEvent) { (e as CrawlRequestEvent).RemoteFolder = remote as IFolder; } else { (e as FolderEvent).RemoteFolder = remote as IFolder; } }
/// <summary> /// Filters FSEvents if they signalize an add and are handled already. /// This occurs if the syncer creates a local object on file system. /// </summary> /// <param name="e">Sync event</param> /// <returns><c>true</c> if the storage contains an entry for this object</returns> public override bool Handle(ISyncEvent e) { if (e is IFSEvent) { var fsEvent = e as IFSEvent; IFileSystemInfo path = fsEvent.IsDirectory ? (IFileSystemInfo)this.fsFactory.CreateDirectoryInfo(fsEvent.LocalPath) : (IFileSystemInfo)this.fsFactory.CreateFileInfo(fsEvent.LocalPath); switch (fsEvent.Type) { case WatcherChangeTypes.Created: return this.storage.GetObjectByLocalPath(path) != null; case WatcherChangeTypes.Renamed: var obj = this.storage.GetObjectByLocalPath(path); if (obj != null) { if (obj.Guid != Guid.Empty) { try { Guid? guid = path.Uuid; return guid == null ? false : guid == obj.Guid; } catch (FileNotFoundException) { return true; } catch (DirectoryNotFoundException) { return true; } } else { return false; } } else { return false; } case WatcherChangeTypes.Deleted: IMappedObject o = this.storage.GetObjectByLocalPath(path); if (o == null) { return true; } else if (path.Exists) { try { Guid? uuid = path.Uuid; if (uuid != null) { return (Guid)uuid == o.Guid; } } catch (IOException) { } } return false; default: return false; } } return false; }
/// <summary> /// Handle the specified event. /// </summary> /// <param name='e'> /// Event to handle. /// </param> public void Handle(ISyncEvent e) { for (int i = this.handler.Count - 1; i >= 0; i--) { var h = this.handler[i]; if (this.handler[i].Handle(e)) { if (!(e is IRemoveFromLoggingEvent)) { Logger.Debug(string.Format("Event {0} was handled by {1}", e.ToString(), this.handler[i].GetType())); } return; } } }
/// <summary> /// Handles IFilterableRemoteObjectEvent or IFilterableLocalPathEvent if they affect an ignored folder. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { if (e is IFilterableRemoteObjectEvent) { var ev = e as IFilterableRemoteObjectEvent; if (ev.RemoteObject is IFolder) { if (this.storage.IsIgnored(ev.RemoteObject as IFolder) == IgnoredState.INHERITED) { if (e is IFilterableLocalPathEvent) { var filterablePathEvent = e as IFilterableLocalPathEvent; if (filterablePathEvent.LocalPath != null && this.storage.IsIgnoredPath(filterablePathEvent.LocalPath) == IgnoredState.NOT_IGNORED) { return(false); } } return(true); } } else if (ev.RemoteObject is IDocument) { if (this.storage.IsIgnored(ev.RemoteObject as IDocument) == IgnoredState.INHERITED) { return(true); } } } if (e is IFilterableLocalPathEvent) { var path = (e as IFilterableLocalPathEvent).LocalPath; if (path != null) { if (this.storage.IsIgnoredPath(path) == IgnoredState.INHERITED) { return(true); } } } return(false); }
/// <summary> /// Handle the specified e if AbstractFolderEvent or StartNextSyncEvent. /// </summary> /// <param name='e'> /// The ISyncEvent. /// </param> /// <returns> /// True if handled /// </returns> public override bool Handle(ISyncEvent e) { bool isEventDelayed = false; if (e is AbstractFolderEvent) { isEventDelayed = this.DelayEventIfRetryCountPositive(e as AbstractFolderEvent); } if (e is StartNextSyncEvent) { if (this.SyncHasToBeDelayed()) { this.DelayNextSyncEvent(e as StartNextSyncEvent); isEventDelayed = true; } } this.FireDelayedEventsIfQueueIsEmpty(); return isEventDelayed; }
private bool RepoInfoChanged(ISyncEvent e) { if (e is RepoConfigChangedEvent) { this.RepoInfo = (e as RepoConfigChangedEvent).RepoInfo; this.ignoredFoldersFilter.IgnoredPaths = new List <string>(this.RepoInfo.GetIgnoredPaths()); this.ignoredFileNameFilter.Wildcards = ConfigManager.CurrentConfig.IgnoreFileNames; this.ignoredFolderNameFilter.Wildcards = ConfigManager.CurrentConfig.IgnoreFolderNames; this.authProvider.DeleteAllCookies(); this.Queue.EventManager.RemoveEventHandler(this.rootFolderMonitor); this.rootFolderMonitor.RepoRootDeleted -= this.RootFolderAvailablilityChanged; this.rootFolderMonitor = new RepositoryRootDeletedDetection(this.fileSystemFactory.CreateDirectoryInfo(this.RepoInfo.LocalPath)); this.rootFolderMonitor.RepoRootDeleted += this.RootFolderAvailablilityChanged; return(true); } return(false); }
public override bool Handle(ISyncEvent e) { if (e is FSMovedEvent) { var movedEvent = e as FSMovedEvent; if (this.IsInsideIgnoredPath(movedEvent.OldPath) && !this.IsInsideIgnoredPath(movedEvent.LocalPath)) { this.queue.AddEvent(new FSEvent(WatcherChangeTypes.Created, movedEvent.LocalPath, movedEvent.IsDirectory)); return(true); } else if (this.IsInsideIgnoredPath(movedEvent.LocalPath) && !this.IsInsideIgnoredPath(movedEvent.OldPath)) { this.queue.AddEvent(new FSEvent(WatcherChangeTypes.Deleted, movedEvent.OldPath, movedEvent.IsDirectory)); return(true); } } if (e is ContentChangeEvent) { var contentChangeEvent = e as ContentChangeEvent; if (contentChangeEvent.Type != ChangeType.Deleted) { var state = IgnoredState.NOT_IGNORED; var cmisObject = contentChangeEvent.CmisObject; if (cmisObject is IFolder) { state = this.ignores.IsIgnored(cmisObject as IFolder); } else if (cmisObject is IDocument) { state = this.ignores.IsIgnored(cmisObject as IDocument); } if (state == IgnoredState.INHERITED) { this.queue.AddEvent(new ContentChangeEvent(ChangeType.Deleted, contentChangeEvent.ObjectId)); return(true); } } } return(false); }
/// <summary> /// Handles File/FolderEvents. /// </summary> /// <param name="e">The event to handle.</param> /// <returns><c>false</c> on every event</returns> public override bool Handle(ISyncEvent e) { if (!this.CouldLocalObjectBeAccumulated(e as AbstractFolderEvent)) { return false; } Logger.Debug("Handling event: " + e); var storedObject = this.GetStoredObject(e as AbstractFolderEvent); Logger.Debug(storedObject); Logger.Debug(this.GetParentId(e as AbstractFolderEvent)); if(storedObject != null) { if (storedObject.ParentId != this.GetParentId(e as AbstractFolderEvent)) { this.AccumulateEvent(e as AbstractFolderEvent, storedObject); } else if(storedObject.Name != this.GetRemoteObjectName(e as AbstractFolderEvent)) { this.AccumulateEvent(e as AbstractFolderEvent, storedObject); } } return false; }
/// <summary> /// Checks is the given Event is a content change event and filters it, if it has been handled already. /// </summary> /// <param name="e">Sync event</param> /// <returns><c>true</c> if the event has been already handled, otherwise <c>false</c></returns> public override bool Handle(ISyncEvent e) { if (e is ContentChangeEvent) { ContentChangeEvent change = e as ContentChangeEvent; switch (change.Type) { case ChangeType.Created: return this.storage.GetObjectByRemoteId(change.ObjectId) != null; case ChangeType.Deleted: return this.storage.GetObjectByRemoteId(change.ObjectId) == null; case ChangeType.Security: goto case ChangeType.Updated; case ChangeType.Updated: var mappedObject = this.storage.GetObjectByRemoteId(change.ObjectId); if (mappedObject == null || mappedObject.LastChangeToken == null) { return false; } else { if (change.CmisObject == null) { try { change.UpdateObject(this.session); } catch (DotCMIS.Exceptions.CmisBaseException) { return false; } } var cmisObject = change.CmisObject; string cmisParentId = cmisObject is IFolder ? (cmisObject as IFolder).ParentId : cmisObject is IDocument ? (cmisObject as IDocument).Parents[0].Id : null; if (mappedObject.LastChangeToken == cmisObject.ChangeToken && mappedObject.ParentId == cmisParentId) { Logger.Debug(string.Format("Ignoring remote change because the ChangeToken \"{0}\" is equal to the stored one", mappedObject.LastChangeToken)); return true; } else { return false; } } default: return false; } } else { return false; } }
/// <summary> /// Handles Config changes if the poll interval has been changed. /// Resets also the timer if a full sync event has been recognized. /// </summary> /// <param name="e">Sync event.</param> /// <returns><c>false</c> on every event.</returns> public override bool Handle(ISyncEvent e) { RepoConfigChangedEvent config = e as RepoConfigChangedEvent; if (config != null) { double newInterval = config.RepoInfo.PollInterval; if (newInterval > 0 && this.interval != newInterval) { this.interval = newInterval; this.Stop(); this.timer.Interval = this.interval; this.Start(); } return false; } StartNextSyncEvent start = e as StartNextSyncEvent; if(start != null && start.FullSyncRequested) { this.Stop(); this.Start(); } return false; }
/// <summary> /// Observes content change events and if they effect exiting entries, updates to storage are executed. /// If an existing entry is not ignored anymore a crawl sync is started. /// </summary> /// <param name="e">The content change events to be observed.</param> /// <returns><c>false</c> on every event</returns> public override bool Handle(ISyncEvent e) { if (e is ContentChangeEvent) { var change = e as ContentChangeEvent; if (change.Type == DotCMIS.Enums.ChangeType.Deleted) { if (this.ignores.IsIgnoredId(change.ObjectId) == IgnoredState.IGNORED) { this.ignores.Remove(change.ObjectId); this.Queue.AddEvent(new StartNextSyncEvent(true)); } return false; } switch (this.ignores.IsIgnoredId(change.ObjectId)) { case IgnoredState.IGNORED: if (!change.CmisObject.AreAllChildrenIgnored()) { this.ignores.Remove(change.ObjectId); this.Queue.AddEvent(new StartNextSyncEvent(true)); } break; case IgnoredState.INHERITED: goto case IgnoredState.NOT_IGNORED; case IgnoredState.NOT_IGNORED: if (change.CmisObject.AreAllChildrenIgnored()) { if (change.CmisObject is IFolder) { this.ignores.AddOrUpdateEntryAndDeleteAllChildrenFromStorage(new IgnoredEntity(change.CmisObject as IFolder, this.matcher)); } else if (change.CmisObject is IDocument) { this.ignores.Add(new IgnoredEntity(change.CmisObject as IDocument, this.matcher)); } } break; } } return false; }
private bool RepoInfoChanged(ISyncEvent e) { if (e is RepoConfigChangedEvent) { this.RepoInfo = (e as RepoConfigChangedEvent).RepoInfo; return true; } else { // This should never ever happen! return false; } }
/// <summary> /// Handle the specified e. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { string reason; try { var nameEvent = e as IFilterableNameEvent; if (nameEvent != null && nameEvent.Name != null) { if (nameEvent.IsDirectory) { if (this.ignoredFolderNameFilter.CheckFolderName(nameEvent.Name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return true; } } else { if (this.ignoredFileNameFilter.CheckFile(nameEvent.Name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return true; } } } var pathEvent = e as IFilterableRemotePathEvent; if (pathEvent != null && pathEvent.RemotePath != null) { if (this.ignoredFoldersFilter.CheckPath(pathEvent.RemotePath, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return true; } string[] folderNames = pathEvent.RemotePath.Split('/'); foreach (var name in folderNames) { if (this.invalidFolderNameFilter.CheckFolderName(name, out reason)) { this.Queue.AddEvent(new RequestIgnoredEvent(e, reason, this)); Logger.Info(reason); return true; } } } var localFolderObjectEvent = e as FolderEvent; if (localFolderObjectEvent != null) { if (this.symlinkFilter.IsSymlink(localFolderObjectEvent.LocalFolder, out reason)) { Logger.Info(reason); return true; } } var localFileObjectEvent = e as FileEvent; if (localFileObjectEvent != null) { if (this.symlinkFilter.IsSymlink(localFileObjectEvent.LocalFile, out reason)) { Logger.Info(reason); return true; } } } catch (System.IO.DirectoryNotFoundException) { } catch (System.IO.FileLoadException) { } catch (System.NullReferenceException) { } return false; }
private ICmisObject GetRemoteObject(ISyncEvent e) { if (e is FileEvent) { return (e as FileEvent).RemoteFile; } if (e is CrawlRequestEvent) { return (e as CrawlRequestEvent).RemoteFolder; } return (e as FolderEvent).RemoteFolder; }
/// <summary> /// Handles StartNextSync events. /// </summary> /// <param name="e">The event to handle.</param> /// <returns>true if handled</returns> public override bool Handle(ISyncEvent e) { if (e is StartNextSyncEvent) { try { Logger.Debug("Starting DecendantsCrawlSync upon " + e); using (var activity = new ActivityListenerResource(this.activityListener)) { this.CrawlDescendants(); } this.Queue.AddEvent(new FullSyncCompletedEvent(e as StartNextSyncEvent)); return true; } catch (InteractionNeededException interaction) { this.Queue.AddEvent(new InteractionNeededEvent(interaction)); throw; } } return false; }
private string FetchIdFromStorage(ISyncEvent e) { IFileSystemInfo path = null; if (e is FileEvent) { path = (e as FileEvent).LocalFile; } else if (e is FolderEvent) { path = (e as FolderEvent).LocalFolder; } if (path != null) { IMappedObject savedObject = this.storage.GetObjectByLocalPath(path); if (savedObject != null) { return savedObject.RemoteObjectId; } } return null; }
private string FetchIdFromExtendedAttribute(ISyncEvent e) { IFileSystemInfo path = null; if (e is FileEvent) { path = (e as FileEvent).LocalFile; } else if (e is CrawlRequestEvent) { path = (e as CrawlRequestEvent).LocalFolder; } else if (e is FolderEvent) { path = (e as FolderEvent).LocalFolder; } if (path != null && path.Exists) { Guid? uuid = null; try { uuid = path.Uuid; } catch (ExtendedAttributeException ex) { Logger.Debug("Could not read extended attributes from path, do not fetch", ex); } if (uuid != null) { var mappedObject = this.storage.GetObjectByGuid((Guid)uuid); if (mappedObject != null) { return mappedObject.RemoteObjectId; } else { Logger.Debug("Uuid found in Extended Attribute but not in DataBase, do not fetch"); } } } return null; }
/// <summary> /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.BubbledEvent"/> class with an embedded event and context /// informations of the given event. /// </summary> /// <param name="source">Context Informations of the given event</param> /// <param name="e">An Event from another context. Must not be null</param> public BubbledEvent(object source, ISyncEvent e) : base(e) { this.Source = source; }
/// <summary> /// Handles File or FolderEvents and tries to solve the detected situation. /// </summary> /// <param name="e">FileEvent or FolderEvent</param> /// <returns><c>true</c> if the Event has been handled, otherwise <c>false</c></returns> public override bool Handle(ISyncEvent e) { if (e is AbstractFolderEvent) { var folderEvent = e as AbstractFolderEvent; try { this.DoHandle(folderEvent); } catch (RetryException retry) { Logger.Debug(string.Format("RetryException[{0}] thrown for event {1} => enqueue event", retry.Message, folderEvent.ToString())); folderEvent.RetryCount++; this.Queue.AddEvent(folderEvent); } catch (InteractionNeededException interaction) { this.Queue.AddEvent(new InteractionNeededEvent(interaction)); } catch (DotCMIS.Exceptions.CmisConnectionException) { throw; } catch (Exception ex) { Logger.Debug("Exception in SyncMechanism, requesting FullSync and rethrowing", ex); this.Queue.AddEvent(new StartNextSyncEvent(true)); throw; } return true; } return false; }
/// <summary> /// This method is called, every time the config changes /// </summary> private bool RepoInfoChanged(ISyncEvent e) { if (e is RepoConfigChangedEvent) { repoinfo = (e as RepoConfigChangedEvent).RepoInfo; UpdateCmisParameters(); ForceFullSyncAtNextSync(); } return false; }
/// <exception cref="InvalidOperationException">When Listener is already stopped</exception> public void AddEvent(ISyncEvent newEvent) { if(alreadyDisposed) { throw new ObjectDisposedException("SyncEventQueue", "Called AddEvent on Disposed object"); } this.queue.Add(newEvent); }