예제 #1
0
        protected override void OnStateChanged(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Appointment.Created _:
                break;

            case Events.Appointment.DetailsChanged changed:
                DoctorId = changed.DoctorId;
                StartUtc = changed.StartUtc;
                EndUtc   = changed.EndUtc;

                Logger.LogDebug("Appointment {Id} changed details for {Doctor}", Id, DoctorId);
                break;

            case Events.Appointment.AppointmentStarted _:
                State = AppointmentState.Started;

                Logger.LogDebug("Appointment {Id} was started", Id);
                break;

            case Events.Appointment.AppointmentEnded _:
                State = AppointmentState.Ended;

                Logger.LogDebug("Appointment {Id} was ended", Id);
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
 protected void OnValueChanged(IChangeEvent evt, object newValue)
 {
     if (m_Model is IPortModel portModel)
     {
         m_OwnerElement.CommandDispatcher.Dispatch(new UpdatePortConstantCommand(portModel, newValue));
     }
 }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.RemoteEvent"/> class.
        /// </summary>
        /// <param name="change">Change event.</param>
        public RemoteEvent(IChangeEvent change) {
            if (change == null) {
                throw new ArgumentNullException("change");
            }

            this.change = change;
        }
예제 #4
0
        public bool Project(IChangeEvent originalEvent)
        {
            switch (originalEvent)
            {
            case Events.Payment.Created e:
                this.paymentStorage.Create(e.EntityId.ToIdentifier());
                break;

            case Events.Payment.AppointmentPaymentInvoiced e:
                this.paymentStorage.Update(e.EntityId, dto =>
                {
                    dto.PaymentId      = e.EntityId;
                    dto.AppointmentId  = e.AppointmentId;
                    dto.Amount         = e.Amount;
                    dto.AmountCurrency = e.Currency;
                });
                break;

            default:
                this.logger.LogDebug($"Unknown entity type '{originalEvent.GetType().Name}'");
                return(false);
            }

            return(true);
        }
예제 #5
0
 private void RaiseCreateEvent(IChangeEvent @event)
 {
     if (this.isInstantiating)
     {
         ((IPublishingEntity)this).RaiseEvent(@event);
     }
 }
예제 #6
0
        protected override void OnStateChanged(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Person.Created _:
                break;

            case Events.Person.NameChanged changed:
                Name        = new PersonName(changed.FirstName, changed.LastName);
                DisplayName = new PersonDisplayName(changed.FirstName);
                Logger.LogDebug("Person {Id} changed name to {FirstName}, {LastName}", Id, changed.FirstName,
                                changed.LastName);
                break;

            case Events.Person.DisplayNameChanged changed:
                DisplayName = new PersonDisplayName(changed.DisplayName);
                Logger.LogDebug("Person {Id} changed display name to {DisplayName}", Id, changed.DisplayName);
                break;

            case Events.Person.EmailChanged changed:
                Email = new Email(changed.EmailAddress);
                Logger.LogDebug("Person {Id} changed email to {EmailAddress}", Id, changed.EmailAddress);
                break;

            case Events.Person.PhoneNumberChanged changed:
                Phone = new PhoneNumber(changed.PhoneNumber);
                Logger.LogDebug("Person {Id} changed phone number to {PhoneNumber}", Id, changed.PhoneNumber);
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
예제 #7
0
        public bool Project(IChangeEvent originalEvent)
        {
            switch (originalEvent)
            {
            case Events.Person.Created e:
                this.personStorage.Create(e.EntityId.ToIdentifier());
                break;

            case Events.Person.EmailChanged e:
                this.personStorage.Update(e.EntityId, dto => { dto.Email = e.EmailAddress; });
                break;

            case Events.Person.PhoneNumberChanged e:
                this.personStorage.Update(e.EntityId, dto => { dto.Phone = e.PhoneNumber; });
                break;

            case Events.Person.NameChanged e:
                this.personStorage.Update(e.EntityId, dto =>
                {
                    dto.FirstName = e.FirstName;
                    dto.LastName  = e.LastName;
                });
                break;

            case Events.Person.DisplayNameChanged e:
                this.personStorage.Update(e.EntityId, dto => { dto.DisplayName = e.DisplayName; });
                break;

            default:
                this.logger.LogDebug($"Unknown entity type '{originalEvent.GetType().Name}'");
                return(false);
            }

            return(true);
        }
예제 #8
0
 private void OnTestOnOnCallback(IChangeEvent evt)
 {
     foreach (var o in targets)
     {
         var casted = (ScriptableValueBase)o;
         casted.ForceNotifyValueChanged();
     }
 }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.RemoteEvent"/> class.
        /// </summary>
        /// <param name="change">Change event.</param>
        public RemoteEvent(IChangeEvent change)
        {
            if (change == null)
            {
                throw new ArgumentNullException("change");
            }

            this.change = change;
        }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CmisSync.Lib.Events.RemoteEvent"/> class.
        /// </summary>
        /// <param name="change">Change event.</param>
        public RemoteEvent(IChangeEvent change)
        {
            if (change == null)
            {
                throw new ArgumentNullException("The given change event must not be null");
            }

            this.change = change;
        }
예제 #11
0
 private static void ProjectEvent(IReadModelProjection projection, IChangeEvent @event,
                                  EventStreamStateChangeEvent changeEvent)
 {
     if (!projection.Project(@event))
     {
         throw new InvalidOperationException(
                   Resources.ReadModelProjector_ProjectionError.Fmt(projection.GetType().Name, changeEvent.Id,
                                                                    changeEvent.Metadata.Fqn));
     }
 }
예제 #12
0
        public static string ToData(IChangeEvent @event)
        {
            @event.GuardAgainstNull(nameof(@event));

            using (var scope = JsConfig.BeginScope())
            {
                scope.ExcludeTypeInfo = true;

                return(@event.ToJson());
            }
        }
        public bool Project(IChangeEvent originalEvent)
        {
            switch (originalEvent)
            {
            case Events.Car.Created e:
                this.carStorage.Create(e.EntityId.ToIdentifier());
                break;

            case Events.Car.ManufacturerChanged e:
                this.carStorage.Update(e.EntityId, dto =>
                {
                    dto.ManufactureYear  = e.Year;
                    dto.ManufactureMake  = e.Make;
                    dto.ManufactureModel = e.Model;
                });
                break;

            case Events.Car.OwnershipChanged e:
                this.carStorage.Update(e.EntityId, dto =>
                {
                    dto.VehicleOwnerId = e.Owner;
                    dto.ManagerIds     = new List <string> {
                        e.Owner
                    };
                });
                break;

            case Events.Car.RegistrationChanged e:
                this.carStorage.Update(e.EntityId, dto =>
                {
                    dto.LicenseJurisdiction = e.Jurisdiction;
                    dto.LicenseNumber       = e.Number;
                });
                break;

            case Events.Car.UnavailabilitySlotAdded e:
                this.unavailabilityStorage.Create(e.EntityId, dto =>
                {
                    dto.CarId             = e.CarId;
                    dto.From              = e.From;
                    dto.To                = e.To;
                    dto.CausedBy          = e.CausedBy;
                    dto.CausedByReference = e.CausedByReference;
                });
                break;

            default:
                this.recorder.TraceDebug($"Unknown entity type '{originalEvent.GetType().Name}'");
                return(false);
            }

            return(true);
        }
 protected void OnValueChanged(IChangeEvent evt, object arg3)
 {
     if (m_Model is IConstantNodeModel constantNodeModel)
     {
         if (evt != null) // Enum editor sends null
         {
             var p        = evt.GetType().GetProperty("newValue");
             var newValue = p?.GetValue(evt);
             m_OwnerElement.CommandDispatcher.Dispatch(new UpdateConstantValueCommand(constantNodeModel.Value, newValue, constantNodeModel));
         }
     }
 }
예제 #15
0
        void IPublishingEntity.RaiseEvent(IChangeEvent @event)
        {
            OnStateChanged(@event);
            var isValid = EnsureValidState();

            if (!isValid)
            {
                throw new RuleViolationException($"The entity with {Id} is in an invalid state.");
            }
            LastModifiedAtUtc = DateTime.UtcNow;
            this.events.Add(@event);
        }
예제 #16
0
        public void SetEvent(string streamName, string entityType, long version, IChangeEvent @event)
        {
            streamName.GuardAgainstNullOrEmpty(nameof(streamName));
            entityType.GuardAgainstNullOrEmpty(nameof(entityType));
            @event.GuardAgainstNull(nameof(@event));

            StreamName = streamName;
            Version    = version;
            EntityType = entityType;
            EventType  = @event.GetType().Name;
            Data       = ToData(@event);
            Metadata   = new EventMetadata(@event.GetType().AssemblyQualifiedName);
        }
예제 #17
0
        public bool Notify(IChangeEvent originalEvent)
        {
            switch (originalEvent)
            {
            case AppointmentsDomain.Events.Appointment.AppointmentEnded e:
                this.paymentsApplication.CreateInvoice(new AnonymousCaller(), e.EntityId, e.CostAmount,
                                                       e.CostCurrency);
                return(true);

            default:
                return(false);
            }
        }
        public bool Notify(IChangeEvent originalEvent)
        {
            switch (originalEvent)
            {
            case Events.Person.EmailChanged e:
                this.carsApplication.UpdateManagerEmail(new AnonymousCaller(), e.EntityId,
                                                        e.EmailAddress);
                return(true);

            default:
                return(false);
            }
        }
예제 #19
0
            /// <summary>
            /// Apply a remote change for Deleted.
            /// </summary>
            private bool ApplyRemoteChangeDelete(IChangeEvent change)
            {
                try
                {
                    ICmisObject remoteObject = session.GetObject(change.ObjectId);
                    if (null != remoteObject)
                    {
                        //  should be moveObject
                        Logger.Info("Ignore moveObject for id " + change.ObjectId);
                        return(true);
                    }
                }
                catch (CmisObjectNotFoundException)
                {
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + change.ObjectId + " : ", e);
                }
                string savedDocumentPath = database.GetRemoteFilePath(change.ObjectId); // FIXME use SyncItem to differentiate between local path and remote path

                if (null != savedDocumentPath)
                {
                    Logger.Info("Remove local document: " + savedDocumentPath);
                    if (File.Exists(savedDocumentPath))
                    {
                        File.Delete(savedDocumentPath);
                    }

                    database.RemoveFile(SyncItemFactory.CreateFromRemotePath(savedDocumentPath, repoinfo));
                    Logger.Info("Removed local document: " + savedDocumentPath);
                    return(true);
                }

                string savedFolderPath = database.GetFolderPath(change.ObjectId);

                if (null != savedFolderPath)
                {
                    Logger.Info("Remove local folder: " + savedFolderPath);
                    if (Directory.Exists(savedFolderPath))
                    {
                        Directory.Delete(savedFolderPath, true);
                        database.RemoveFolder(SyncItemFactory.CreateFromRemotePath(savedFolderPath, repoinfo));
                    }
                    Logger.Info("Removed local folder: " + savedFolderPath);
                    return(true);
                }

                return(true);
            }
예제 #20
0
        void IPublishingEntity.RaiseEvent(IChangeEvent @event, bool validate)
        {
            OnEventRaised(@event);
            if (validate)
            {
                var isValid = EnsureValidState();
                if (!isValid)
                {
                    throw new RuleViolationException($"The entity with {Id} is in an invalid state.");
                }
            }

            this.aggregateEntityEventHandler?.Invoke(@event);
            LastModifiedAtUtc = DateTime.UtcNow;
        }
        protected override void OnEventRaised(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Clinic.DoctorUnavailabilitySlotAdded added:
                ClinicId          = added.ClinicId.ToIdentifier();
                Slot              = new TimeSlot(added.From, added.To);
                CausedBy          = added.CausedBy;
                CausedByReference = added.CausedByReference;
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
예제 #22
0
        protected override void OnStateChanged(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Clinic.Created _:
                break;

            case Events.Clinic.LocationChanged changed:
                Location = new Location(changed.Country, changed.City, changed.Street);
                Logger.LogDebug("Clinic {Id} changed location to {Country}, {City}, {Street}", Id, changed.Country,
                                changed.City, changed.Street);
                break;

            case Events.Clinic.OwnershipChanged changed:
                Owner = new ClinicOwner(changed.Owner);
                Managers.Add(changed.Owner.ToIdentifier());

                Logger.LogDebug("Clinic {Id} changed ownership to {Owner}", Id, Owner);
                break;

            case Events.Clinic.RegistrationChanged changed:
                License = new ClinicLicense(changed.Jurisdiction, changed.Number);

                Logger.LogDebug("Clinic {Id} registration changed to {Jurisdiction}, {CertificateNumber}", Id,
                                changed.Jurisdiction, changed.Number);
                break;

            case Events.Clinic.DoctorUnavailabilitySlotAdded added:
                var unavailability = new UnavailabilityEntity(Logger, IdFactory);
                added.EntityId = unavailability.Id;
                unavailability.SetAggregateEventHandler(RaiseChangeEvent);
                RaiseToEntity(unavailability, @event);
                Unavailabilities.Add(unavailability);

                Logger.LogDebug("Doctor {Id} had been made unavailable from {From} until {To}", Id, added.From,
                                added.To);
                break;

            case Events.Clinic.DoctorRegisteredToClinic added:
                Doctors.Add(added.DoctorId.ToIdentifier());

                Logger.LogDebug("Doctor {Id} had been registered to clinic {Clinic}", added.DoctorId, Id);
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
예제 #23
0
        protected override void OnStateChanged(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Payment.Created _:
                break;

            case Events.Payment.AppointmentPaymentInvoiced added:
                AppointmentInvoice = new AppointmentPayment(added.AppointmentId.ToIdentifier(), added.Amount,
                                                            added.Currency);
                Logger.LogDebug("Payment {Id} added invoice for appointment {Appointment}", Id,
                                added.AppointmentId);
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
예제 #24
0
        private static void RelayEvent(IDomainEventPublisherSubscriberPair pair, IChangeEvent @event,
                                       EventStreamStateChangeEvent changeEvent)
        {
            var eventToPublish = pair.Publisher.Publish(@event);

            if (eventToPublish == null)
            {
                throw new InvalidOperationException(Resources.DomainEventNotificationProducer_PublisherError.Format(
                                                        pair.Publisher.GetType().Name,
                                                        changeEvent.Id, changeEvent.Metadata.Fqn));
            }

            if (!pair.Subscriber.Notify(eventToPublish))
            {
                throw new InvalidOperationException(Resources.DomainEventNotificationProducer_SubscriberError.Format(
                                                        pair.Subscriber.GetType().Name,
                                                        changeEvent.Id, changeEvent.Metadata.Fqn));
            }
        }
예제 #25
0
        protected override void OnStateChanged(IChangeEvent @event)
        {
            switch (@event)
            {
            case Events.Car.Created _:
                break;

            case Events.Car.ManufacturerChanged changed:
                Manufacturer = new Manufacturer(changed.Year, changed.Make, changed.Model);
                Recorder.TraceDebug("Car {Id} changed manufacturer to {Year}, {Make}, {Model}", Id, changed.Year,
                                    changed.Make, changed.Model);
                break;

            case Events.Car.OwnershipChanged changed:
                Owner    = new VehicleOwner(changed.Owner);
                Managers = new VehicleManagers();
                Managers.Add(changed.Owner.ToIdentifier());

                Recorder.TraceDebug("Car {Id} changed ownership to {Owner}", Id, Owner);
                break;

            case Events.Car.RegistrationChanged changed:
                Plate = new LicensePlate(changed.Jurisdiction, changed.Number);

                Recorder.TraceDebug("Car {Id} registration changed to {Jurisdiction}, {Number}", Id,
                                    changed.Jurisdiction, changed.Number);
                break;

            case Events.Car.UnavailabilitySlotAdded added:
                var unavailability = new UnavailabilityEntity(Recorder, IdFactory);
                added.EntityId = unavailability.Id;
                unavailability.SetAggregateEventHandler(RaiseChangeEvent);
                RaiseToEntity(unavailability, @event);
                Unavailabilities.Add(unavailability);
                Recorder.TraceDebug("Car {Id} had been made unavailable from {From} until {To}", Id, added.From,
                                    added.To);
                break;

            default:
                throw new InvalidOperationException($"Unknown event {@event.GetType()}");
            }
        }
예제 #26
0
            /// <summary>
            /// Apply a remote change for Deleted.
            /// </summary>
            private bool ApplyRemoteChangeDelete(IChangeEvent change)
            {
                try
                {
                    ICmisObject remoteObject = session.GetObject(change.ObjectId);
                    if (null != remoteObject)
                    {
                        //  should be moveObject
                        Logger.Info("Ignore moveObject for id " + change.ObjectId);
                        return true;
                    }
                }
                catch (CmisObjectNotFoundException)
                {
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + change.ObjectId + " : ", e);
                }

                string savedDocumentPath = database.GetFilePath(change.ObjectId);
                if (null != savedDocumentPath)
                {
                    Logger.Info("Remove local document: " + savedDocumentPath);
                    if(File.Exists(savedDocumentPath))
                        File.Delete(savedDocumentPath);
                    database.RemoveFile(savedDocumentPath);
                    Logger.Info("Removed local document: " + savedDocumentPath);
                    return true;
                }

                string savedFolderPath = database.GetFolderPath(change.ObjectId);
                if (null != savedFolderPath)
                {
                    Logger.Info("Remove local folder: " + savedFolderPath);
                    if(Directory.Exists(savedFolderPath)) {
                        Directory.Delete(savedFolderPath, true);
                        database.RemoveFolder(savedFolderPath);
                    }
                    Logger.Info("Removed local folder: " + savedFolderPath);
                    return true;
                }

                return true;
            }
예제 #27
0
            /// <summary>
            /// Apply a remote change for Created or Updated.
            /// </summary>
            private bool ApplyRemoteChangeUpdate(IChangeEvent change)
            {
                ICmisObject cmisObject     = null;
                IFolder     remoteFolder   = null;
                IDocument   remoteDocument = null;
                string      remotePath     = null;
                ICmisObject remoteObject   = null;
                IFolder     remoteParent   = null;

                try
                {
                    cmisObject = session.GetObject(change.ObjectId);
                }
                catch (CmisObjectNotFoundException)
                {
                    Logger.Info("Ignore the missed object for " + change.ObjectId);
                    return(true);
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + change.ObjectId + " :", e);
                    return(false);
                }

                remoteDocument = cmisObject as IDocument;
                remoteFolder   = cmisObject as IFolder;
                if (remoteDocument == null && remoteFolder == null)
                {
                    Logger.Info("Change in no sync object: " + change.ObjectId);
                    return(true);
                }
                if (remoteDocument != null)
                {
                    if (!Utils.IsFileWorthSyncing(remoteDocument.Name, repoinfo))
                    {
                        Logger.Info("Change in remote unworth syncing file: " + remoteDocument.Paths);
                        return(true);
                    }
                    if (remoteDocument.Paths.Count == 0)
                    {
                        Logger.Info("Ignore the unfiled object: " + remoteDocument.Name);
                        return(true);
                    }
                    // TODO: Support Multiple Paths
                    remotePath   = remoteDocument.Paths[0];
                    remoteParent = remoteDocument.Parents[0];
                }
                if (remoteFolder != null)
                {
                    remotePath   = remoteFolder.Path;
                    remoteParent = remoteFolder.FolderParent;
                    foreach (string name in remotePath.Split('/'))
                    {
                        if (!String.IsNullOrEmpty(name) && Utils.IsInvalidFolderName(name))
                        {
                            Logger.Info(String.Format("Change in illegal syncing path name {0}: {1}", name, remotePath));
                            return(true);
                        }
                    }
                }

                if (!remotePath.StartsWith(this.remoteFolderPath))
                {
                    Logger.Info("Change in unrelated path: " + remotePath);
                    return(true);    // The change is not under the folder we care about.
                }

                if (this.repoinfo.isPathIgnored(remotePath))
                {
                    Logger.Info("Change in ignored path: " + remotePath);
                    return(true);
                }

                string relativePath = remotePath.Substring(remoteFolderPath.Length);

                if (relativePath.Length <= 0)
                {
                    Logger.Info("Ignore change in root path: " + remotePath);
                    return(true);
                }
                if (relativePath[0] == '/')
                {
                    relativePath = relativePath.Substring(1);
                }

                try
                {
                    remoteObject = session.GetObjectByPath(remotePath);
                }
                catch (CmisObjectNotFoundException)
                {
                    Logger.Info(String.Format("Ignore remote path {0} deleted from id {1}", remotePath, cmisObject.Id));
                    return(true);
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + remotePath + " : ", e);
                    return(false);
                }

                if (remoteObject.Id != cmisObject.Id)
                {
                    Logger.Info(String.Format("Ignore remote path {0} changed from id {1} to id {2}", remotePath, cmisObject.Id, remoteObject.Id));
                    return(true);
                }

                string localPath = Path.Combine(repoinfo.TargetDirectory, relativePath).Replace('/', Path.DirectorySeparatorChar);

                if (!DownloadFolder(remoteParent, Path.GetDirectoryName(localPath)))
                {
                    Logger.Warn("Failed to download the parent folder for " + localPath);
                    return(false);
                }

                if (null != remoteDocument)
                {
                    Logger.Info(String.Format("New remote file ({0}) found.", remotePath));
                    //  check moveObject
                    string savedDocumentPath = database.GetRemoteFilePath(change.ObjectId);
                    if ((null != savedDocumentPath) && (savedDocumentPath != localPath))
                    {
                        if (File.Exists(localPath))
                        {
                            File.Delete(savedDocumentPath);
                            database.RemoveFile(SyncItemFactory.CreateFromRemotePath(savedDocumentPath, repoinfo));
                        }
                        else
                        {
                            if (File.Exists(savedDocumentPath))
                            {
                                if (!Directory.Exists(Path.GetDirectoryName(localPath)))
                                {
                                    Logger.Warn("Creating local directory: " + localPath);
                                    Directory.CreateDirectory(Path.GetDirectoryName(localPath));
                                }
                                File.Move(savedDocumentPath, localPath);
                            }
                            database.MoveFile(SyncItemFactory.CreateFromRemotePath(savedDocumentPath, repoinfo), SyncItemFactory.CreateFromLocalPath(savedDocumentPath, repoinfo));
                        }
                    }

                    return(SyncDownloadFile(remoteDocument, Path.GetDirectoryName(localPath)));
                }

                if (null != remoteFolder)
                {
                    Logger.Info(String.Format("New remote folder ({0}) found.", remotePath));
                    //  check moveObject
                    string savedFolderPath = database.GetFolderPath(change.ObjectId);
                    if ((null != savedFolderPath) && (savedFolderPath != localPath))
                    {
// TODO                        MoveFolderLocally(savedFolderPath, localPath);
                        CrawlSync(remoteFolder, localPath);
                    }
                    else
                    {
                        SyncDownloadFolder(remoteFolder, Path.GetDirectoryName(localPath));
                        CrawlSync(remoteFolder, localPath);
                    }
                }

                return(true);
            }
예제 #28
0
 protected override void OnStateChanged(IChangeEvent @event)
 {
     //Not used in testing
 }
예제 #29
0
 void IPublishedEntityEventHandler.HandleEvent(IChangeEvent @event)
 {
     OnStateChanged(@event);
 }
예제 #30
0
 protected static void RaiseToEntity(IPublishedEntityEventHandler entity, IChangeEvent @event)
 {
     entity?.HandleEvent(@event);
 }
예제 #31
0
 protected void RaiseChangeEvent(IChangeEvent @event)
 {
     ((IPublishingEntity)this).RaiseEvent(@event);
 }
예제 #32
0
 protected abstract void OnStateChanged(IChangeEvent @event);
예제 #33
0
            /// <summary>
            /// Apply a remote change for Created or Updated.
            /// </summary>
            private bool ApplyRemoteChangeUpdate(IChangeEvent change)
            {
                ICmisObject cmisObject = null;
                IFolder remoteFolder = null;
                IDocument remoteDocument = null;
                string remotePath = null;
                ICmisObject remoteObject = null;
                IFolder remoteParent = null;

                try
                {
                    cmisObject = session.GetObject(change.ObjectId);
                }
                catch(CmisObjectNotFoundException)
                {
                    Logger.Info("Ignore the missed object for " + change.ObjectId);
                    return true;
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + change.ObjectId + " :", e);
                    return false;
                }

                remoteDocument = cmisObject as IDocument;
                remoteFolder = cmisObject as IFolder;
                if (remoteDocument == null && remoteFolder == null)
                {
                    Logger.Info("Change in no sync object: " + change.ObjectId);
                    return true;
                }
                if (remoteDocument != null)
                {
                    if (!Utils.IsFileWorthSyncing(remoteDocument.Name, repoinfo))
                    {
                        Logger.Info("Change in remote unworth syncing file: " + remoteDocument.Paths);
                        return true;
                    }
                    if (remoteDocument.Paths.Count == 0)
                    {
                        Logger.Info("Ignore the unfiled object: " + remoteDocument.Name);
                        return true;
                    }
                    // TODO: Support Multiple Paths
                    remotePath = remoteDocument.Paths[0];
                    remoteParent = remoteDocument.Parents[0];
                }
                if (remoteFolder != null)
                {
                    remotePath = remoteFolder.Path;
                    remoteParent = remoteFolder.FolderParent;
                    foreach (string name in remotePath.Split('/'))
                    {
                        if (!String.IsNullOrEmpty(name) && Utils.IsInvalidFolderName(name))
                        {
                            Logger.Info(String.Format("Change in illegal syncing path name {0}: {1}", name, remotePath));
                            return true;
                        }
                    }
                }

                if (!remotePath.StartsWith(this.remoteFolderPath))
                {
                    Logger.Info("Change in unrelated path: " + remotePath);
                    return true;    // The change is not under the folder we care about.
                }

                if (this.repoinfo.isPathIgnored(remotePath))
                {
                    Logger.Info("Change in ignored path: " + remotePath);
                    return true;
                }

                string relativePath = remotePath.Substring(remoteFolderPath.Length);
                if (relativePath.Length <= 0)
                {
                    Logger.Info("Ignore change in root path: " + remotePath);
                    return true;
                }
                if (relativePath[0] == '/')
                {
                    relativePath = relativePath.Substring(1);
                }

                try
                {
                    remoteObject = session.GetObjectByPath(remotePath);
                }
                catch(CmisObjectNotFoundException)
                {
                    Logger.Info(String.Format("Ignore remote path {0} deleted from id {1}", remotePath, cmisObject.Id));
                    return true;
                }
                catch (Exception e)
                {
                    Logger.Warn("Exception when GetObject for " + remotePath + " : ", e);
                    return false;
                }

                if (remoteObject.Id != cmisObject.Id)
                {
                    Logger.Info(String.Format("Ignore remote path {0} changed from id {1} to id {2}", remotePath, cmisObject.Id, remoteObject.Id));
                    return true;
                }

                string localPath = Path.Combine(repoinfo.TargetDirectory, relativePath).Replace('/', Path.DirectorySeparatorChar);
                if (!DownloadFolder(remoteParent, Path.GetDirectoryName(localPath)))
                {
                    Logger.Warn("Failed to download the parent folder for " + localPath);
                    return false;
                }

                if (null != remoteDocument)
                {
                    Logger.Info(String.Format("New remote file ({0}) found.", remotePath));
                    //  check moveObject
                    string savedDocumentPath = database.GetFilePath(change.ObjectId);
                    if ((null != savedDocumentPath) && (savedDocumentPath != localPath))
                    {
                        if (File.Exists(localPath))
                        {
                            File.Delete(savedDocumentPath);
                            database.RemoveFile(savedDocumentPath);
                        }
                        else
                        {
                            if (File.Exists(savedDocumentPath))
                            {
                                if (!Directory.Exists(Path.GetDirectoryName(localPath)))
                                {
                                    Logger.Warn("Creating local directory: "+ localPath);
                                    Directory.CreateDirectory(Path.GetDirectoryName(localPath));
                                }
                                File.Move(savedDocumentPath, localPath);
                            }
                            database.MoveFile(savedDocumentPath, localPath);
                        }
                    }

                    return SyncDownloadFile(remoteDocument, Path.GetDirectoryName(localPath));
                }

                if (null != remoteFolder)
                {
                    Logger.Info(String.Format("New remote folder ({0}) found.", remotePath));
                    //  check moveObject
                    string savedFolderPath = database.GetFolderPath(change.ObjectId);
                    if ((null != savedFolderPath) && (savedFolderPath != localPath))
                    {
// TODO                        MoveFolderLocally(savedFolderPath, localPath);
                        CrawlSync(remoteFolder, localPath);
                    }
                    else
                    {
                        SyncDownloadFolder(remoteFolder, Path.GetDirectoryName(localPath));
                        CrawlSync(remoteFolder,localPath);
                    }
                }

                return true;
            }
예제 #34
0
            /// <summary>
            /// Check whether a change is relevant for the current synchronized folder.
            /// </summary>
            private bool ChangeIsApplicable(IChangeEvent change)
            {
                ICmisObject cmisObject = null;
                IFolder remoteFolder = null;
                IDocument remoteDocument = null;
                IList<string> remotePaths = null;
                var changeIdForDebug = change.Properties.ContainsKey("cmis:name") ?
                    change.Properties["cmis:name"][0] : change.Properties["cmis:objectId"][0]; // TODO is it different from change.ObjectId ?

                // Get the remote changed object.
                try
                {
                    cmisObject = session.GetObject(change.ObjectId);
                }
                catch (CmisObjectNotFoundException)
                {
                    Logger.Info("Changed object has already been deleted on the server. Syncing just in case: " + changeIdForDebug);
                    // Unfortunately, in this case we can not know whether the object was relevant or not.
                    return true;
                }
                catch (CmisRuntimeException e)
                {
                    if (e.Message.Equals("Unauthorized"))
                    {
                        Logger.Info("We can not read the object id, so it is not an object we can sync anyway: " + changeIdForDebug);
                        return false;
                    }
                    else
                    {
                        Logger.Info("A CMIS exception occured when querying the change. Syncing just in case: " + changeIdForDebug + " :", e);
                        return true;
                    }
                }
                catch (Exception e)
                {
                    Logger.Warn("An exception occurred, syncing just in case: " + changeIdForDebug + " :", e);
                    return true;
                }

                // Check whether change is about a document or folder.
                remoteDocument = cmisObject as IDocument;
                remoteFolder = cmisObject as IFolder;
                if (remoteDocument == null && remoteFolder == null)
                {
                    Logger.Info("Ignore change as it is not about a document nor folder: " + changeIdForDebug);
                    return false;
                }

                // Check whether it is a document worth syncing.
                if (remoteDocument != null)
                {
                    if (!Utils.IsFileWorthSyncing(remoteDocument.Name, repoInfo))
                    {
                        Logger.Info("Ignore change as it is about a document unworth syncing: " + changeIdForDebug);
                        return false;
                    }
                    if (remoteDocument.Paths.Count == 0)
                    {
                        Logger.Info("Ignore the unfiled object: " + changeIdForDebug);
                        return false;
                    }

                    // We will check the remote document's path(s) at the end of this method.
                    remotePaths = remoteDocument.Paths;
                }

                // Check whether it is a folder worth syncing.
                if (remoteFolder != null)
                {
                    remotePaths = new List<string>();
                    remotePaths.Add(remoteFolder.Path);
                }

                // Check the object's path(s)
                foreach (string remotePath in remotePaths)
                {
                    if (PathIsApplicable(remotePath))
                    {
                        Logger.Debug("Change is applicable. Sync:" + changeIdForDebug);
                        return true;
                    }
                }

                // No path was relevant, so ignore the change.
                return false;
            }
        /// <summary>
        /// Apply a remote change for Created or Updated.
        /// <returns>Whether the change was applied successfully</returns>
        /// </summary>
        private bool ChangeIsApplicable(IChangeEvent change)
        {
            ICmisObject cmisObject = null;
                IFolder remoteFolder = null;
                IDocument remoteDocument = null;
                string remotePath = null;
                IFolder remoteParent = null;
                var changeIdForDebug = change.Properties.ContainsKey("cmis:name") ?
                    change.Properties["cmis:name"][0] : change.Properties["cmis:objectId"][0];

                // Get the remote changed object.
                try
                {
                    cmisObject = getSession().GetObject(change.ObjectId);
                }
                catch (CmisObjectNotFoundException)
                {
                    Logger.Info("Removed object, syncing might be needed: " + changeIdForDebug);
                    return true;
                }
                catch (CmisRuntimeException e)
                {
                    if (e.Message.Equals("Unauthorized"))
                    {
                        Logger.Info("We can not read the object id, so it is not an object we can sync anyway: " + changeIdForDebug);
                        return false;
                    }
                    else
                    {
                        Logger.Info("A CMIS exception occured: " + changeIdForDebug + " :", e);
                        return true;
                    }
                }
                catch (Exception e)
                {
                    Logger.Warn("An exception occurred: " + change.ObjectId + " :", e);
                    return true; // Better be on the safe side and sync.
                }

                // Check whether change is about a document or folder.
                remoteDocument = cmisObject as IDocument;
                remoteFolder = cmisObject as IFolder;
                if (remoteDocument == null && remoteFolder == null)
                {
                    Logger.Info("Ignore change as it is not about a document nor folder: " + changeIdForDebug);
                    return false;
                }

                // Check whether it is a document worth syncing.
                if (remoteDocument != null)
                {
                    if ( ! SyncUtils.IsFileWorthSyncing(remoteDocument.Name, SyncFolderInfo))
                    {
                        Logger.Info("Ignore change as it is about a document unworth syncing: " + changeIdForDebug);
                        return false;
                    }
                    if (remoteDocument.Paths.Count == 0)
                    {
                        Logger.Info("Ignore the unfiled object: " + changeIdForDebug);
                        return false;
                    }
                    // TODO: Support Multiple Paths
                    remotePath = remoteDocument.Paths[0];
                    remoteParent = remoteDocument.Parents[0];
                }

                // Check whether it is a folder worth syncing.
                if (remoteFolder != null)
                {
                    remotePath = remoteFolder.Path;
                    remoteParent = remoteFolder.FolderParent;
                    foreach (string name in remotePath.Split('/'))
                    {
                        if ( ! String.IsNullOrEmpty(name) && SyncUtils.IsInvalidFolderName(name))
                        {
                            Logger.Info(String.Format("Ignore change as it is in a path unworth syncing:  {0}: {1}", name, remotePath));
                            return false;
                        }
                    }
                }

                // Ignore the change if not in a synchronized folder.
                if ( ! remotePath.StartsWith(this.remoteFolderPath))
                {
                    Logger.Info("Ignore change as it is not in the synchronized folder's path: " + remotePath);
                    return false;
                }
                if (this.SyncFolderInfo.isPathIgnored(remotePath))
                {
                    Logger.Info("Ignore change as it is in a path configured to be ignored: " + remotePath);
                    return false;
                }
                string relativePath = remotePath.Substring(remoteFolderPath.Length);
                if (relativePath.Length <= 0)
                {
                    Logger.Info("Ignore change as it is above the synchronized folder's path:: " + remotePath);
                    return false;
                }

                Logger.Debug("Change is applicable:" + changeIdForDebug);
                return true;
        }
예제 #36
0
        private void Sync() {
            // Get last change log token on server side.
            this.session.Binding.GetRepositoryService().GetRepositoryInfos(null);    // refresh
            string lastTokenOnServer = this.session.Binding.GetRepositoryService().GetRepositoryInfo(this.session.RepositoryInfo.Id, null).LatestChangeLogToken;

            // Get last change token that had been saved on client side.
            string lastTokenOnClient = this.storage.ChangeLogToken;

            if (lastTokenOnClient == null) {
                // Token is null, which means no content change sync has ever happened yet, so just sync everything from remote.
                // Force full sync
                var fullsyncevent = new StartNextSyncEvent(true);
                Queue.AddEvent(fullsyncevent);
                return;
            }

            do {
                // Check which files/folders have changed.
                IChangeEvents changes = this.session.GetContentChanges(lastTokenOnClient, this.isPropertyChangesSupported, this.maxNumberOfContentChanges);

                // Replicate each change to the local side.
                bool first = true;
                foreach (IChangeEvent change in changes.ChangeEventList) {
                    // ignore first event when lists overlapp
                    if (first) {
                        first = false;
                        if (this.lastChange != null &&
                           (this.lastChange.ChangeType == DotCMIS.Enums.ChangeType.Created
                         || this.lastChange.ChangeType == DotCMIS.Enums.ChangeType.Deleted)) {
                            if (change != null && change.ChangeType == this.lastChange.ChangeType && change.ObjectId == this.lastChange.ObjectId) {
                                continue;
                            }
                        }
                    }

                    this.lastChange = change;

                    Queue.AddEvent(new ContentChangeEvent(change.ChangeType, change.ObjectId));
                }

                // Save change log token locally.
                if (changes.HasMoreItems == true) {
                    lastTokenOnClient = changes.LatestChangeLogToken;
                } else {
                    lastTokenOnClient = lastTokenOnServer;
                }

                this.storage.ChangeLogToken = lastTokenOnClient;

                // refresh
                this.session.Binding.GetRepositoryService().GetRepositoryInfos(null);
                lastTokenOnServer = this.session.Binding.GetRepositoryService().GetRepositoryInfo(this.session.RepositoryInfo.Id, null).LatestChangeLogToken;
            } while (!lastTokenOnServer.Equals(lastTokenOnClient));
        }
예제 #37
0
            /// <summary>
            /// Apply a remote change.
            /// </summary>
            private void ApplyRemoteChange(IChangeEvent change)
            {
                Logger.Info("Sync | Change type:" + change.ChangeType.ToString() + " id:" + change.ObjectId + " properties:" + change.Properties);
                IFolder remoteFolder;
                IDocument remoteDocument;
                switch (change.ChangeType)
                {
                    // Case when an object has been created or updated.
                    case ChangeType.Created:
                    case ChangeType.Updated:
                        ICmisObject cmisObject = session.GetObject(change.ObjectId);
                        if (null != (remoteDocument = cmisObject as IDocument))
                        {
                            string remoteDocumentPath = remoteDocument.Paths.First();
                            if (!remoteDocumentPath.StartsWith(remoteFolderPath))
                            {
                                Logger.Info("Sync | Change in unrelated document: " + remoteDocumentPath);
                                break; // The change is not under the folder we care about.
                            }
                            string relativePath = remoteDocumentPath.Substring(remoteFolderPath.Length + 1);
                            string relativeFolderPath = Path.GetDirectoryName(relativePath);
                            relativeFolderPath = relativeFolderPath.Replace('/', '\\'); // TODO OS-specific separator
                            string localFolderPath = Path.Combine(repoinfo.TargetDirectory, relativeFolderPath);
                            DownloadFile(remoteDocument, localFolderPath);
                        }
                        else if (null != (remoteFolder = cmisObject as IFolder))
                        {
                            string localFolder = Path.Combine(repoinfo.TargetDirectory, remoteFolder.Path);
                            if(!this.repoinfo.isPathIgnored(remoteFolder.Path))
                                RecursiveFolderCopy(remoteFolder, localFolder);
                        }
                        break;

                    // Case when an object has been deleted.
                    case ChangeType.Deleted:
                        cmisObject = session.GetObject(change.ObjectId);
                        if (null != (remoteDocument = cmisObject as IDocument))
                        {
                            string remoteDocumentPath = remoteDocument.Paths.First();
                            if (!remoteDocumentPath.StartsWith(remoteFolderPath))
                            {
                                Logger.Info("Sync | Change in unrelated document: " + remoteDocumentPath);
                                break; // The change is not under the folder we care about.
                            }
                            string relativePath = remoteDocumentPath.Substring(remoteFolderPath.Length + 1);
                            string relativeFolderPath = Path.GetDirectoryName(relativePath);
                            relativeFolderPath = relativeFolderPath.Replace('/', '\\'); // TODO OS-specific separator
                            string localFolderPath = Path.Combine(repoinfo.TargetDirectory, relativeFolderPath);
                            // TODO DeleteFile(localFolderPath); // Delete on filesystem and in database
                        }
                        else if (null != (remoteFolder = cmisObject as IFolder))
                        {
                            string localFolder = Path.Combine(repoinfo.TargetDirectory, remoteFolder.Path);
                            if(!this.repoinfo.isPathIgnored(remoteFolder.Path))
                                RemoveFolderLocally(localFolder); // Remove from filesystem and database.
                        }
                        break;

                    // Case when access control or security policy has changed.
                    case ChangeType.Security:
                        // TODO
                        break;
                }
            }