Exemplo n.º 1
0
 public SynchronizationContext(Synchronization synchronization, SynchronizationDirection direction, ChangePropagationMode changePropagation)
     : base(synchronization)
 {
     Direction         = direction;
     ChangePropagation = changePropagation;
     Inconsistencies   = new ObservableSet <IInconsistency>();
 }
Exemplo n.º 2
0
        protected void PerformNoChangePropagation(TLeft left, TRight right, SynchronizationDirection direction, ISynchronizationContext context)
        {
            switch (direction)
            {
            case SynchronizationDirection.CheckOnly:
                var leftValue  = leftGetter(left);
                var rightValue = rightGetter(right);
                if (!EqualityComparer <TValue> .Default.Equals(leftValue, rightValue))
                {
                    context.Inconsistencies.Add(new PropertyInequality <TLeft, TRight, TValue>(left, leftSetter, leftValue, right, rightSetter, rightValue));
                }
                break;

            case SynchronizationDirection.LeftToRight:
            case SynchronizationDirection.LeftToRightForced:
                rightSetter(right, leftGetter(left));
                break;

            case SynchronizationDirection.LeftWins:
                var val1 = leftGetter(left);
                if (val1 != null)
                {
                    rightSetter(right, val1);
                }
                else
                {
                    leftSetter(left, rightGetter(right));
                }
                break;

            case SynchronizationDirection.RightToLeft:
            case SynchronizationDirection.RightToLeftForced:
                leftSetter(left, rightGetter(right));
                break;

            case SynchronizationDirection.RightWins:
                var val2 = rightGetter(right);
                if (val2 != null)
                {
                    leftSetter(left, val2);
                }
                else
                {
                    rightSetter(right, leftGetter(left));
                }
                break;

            default:
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 3
0
            public Dependency(ISynchronizationJob <TLeft, TRight> inner, SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, INotifyValue <bool> tracker)
            {
                Inner       = inner;
                Computation = computation;
                Direction   = direction;
                Tracker     = tracker;

                if (tracker.Value)
                {
                    Current = Inner.Perform(Computation, Direction, Computation.SynchronizationContext);
                }

                Tracker.ValueChanged += Tracker_ValueChanged;
            }
Exemplo n.º 4
0
        protected void PerformNoChangePropagation(TLeft left, TRight right, SynchronizationDirection direction)
        {
            switch (direction)
            {
            case SynchronizationDirection.LeftToRight:
            case SynchronizationDirection.LeftToRightForced:
                rightSetter(right, leftGetter(left));
                break;

            case SynchronizationDirection.LeftWins:
                var val1 = leftGetter(left);
                if (val1 != null)
                {
                    rightSetter(right, val1);
                }
                else
                {
                    leftSetter(left, rightGetter(right));
                }
                break;

            case SynchronizationDirection.RightToLeft:
            case SynchronizationDirection.RightToLeftForced:
                leftSetter(left, rightGetter(right));
                break;

            case SynchronizationDirection.RightWins:
                var val2 = rightGetter(right);
                if (val2 != null)
                {
                    leftSetter(left, val2);
                }
                else
                {
                    rightSetter(right, leftGetter(left));
                }
                break;

            default:
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 5
0
 public virtual IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
 {
     if (direction.IsRightToLeft())
     {
         return(Perform(computation.Opposite.Input, computation.Input, context));
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 6
0
        public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
        {
            var left  = computation.Input;
            var right = computation.Opposite.Input;

            switch (context.ChangePropagation)
            {
            case NMF.Transformations.ChangePropagationMode.None:
                PerformNoChangePropagation(left, right, direction);
                return(null);

            case NMF.Transformations.ChangePropagationMode.OneWay:
                return(PerformOneWay(left, right, context));

            case NMF.Transformations.ChangePropagationMode.TwoWay:
                return(PerformTwoWay(left, right, context));

            default:
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 7
0
        public ISynchronizationContext Synchronize <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation)
            where TLeft : class
            where TRight : class
        {
            if (startRule == null)
            {
                throw new ArgumentNullException("startRule");
            }

            Initialize();

            var context = new SynchronizationContext(this, direction, changePropagation);

            switch (direction)
            {
            case SynchronizationDirection.LeftToRight:
            case SynchronizationDirection.LeftToRightForced:
            case SynchronizationDirection.LeftWins:
                var c1 = TransformationRunner.Transform(new object[] { left }, right != null ? new Axiom(right) : null, startRule.LeftToRight, context);
                right = c1.Output as TRight;
                break;

            case SynchronizationDirection.RightToLeft:
            case SynchronizationDirection.RightToLeftForced:
            case SynchronizationDirection.RightWins:
                var c2 = TransformationRunner.Transform(new object[] { right }, left != null ? new Axiom(left) : null, startRule.RightToLeft, context);
                left = c2.Output as TLeft;
                break;

            case SynchronizationDirection.CheckOnly:
                if (left == null)
                {
                    throw new ArgumentException("Passed model must not be null when running in check-only mode", nameof(left));
                }
                if (right == null)
                {
                    throw new ArgumentException("Passed model must not be null when running in check-only mode", nameof(right));
                }
                TransformationRunner.Transform(new object[] { left }, new Axiom(right), startRule.LeftToRight, context);
                break;

            default:
                throw new ArgumentOutOfRangeException("direction");
            }
            return(context);
        }
Exemplo n.º 8
0
        public ISynchronizationContext Synchronize <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation)
            where TLeft : class
            where TRight : class
        {
            if (startRule == null)
            {
                throw new ArgumentNullException("startRule");
            }

            Initialize();

            var context = new SynchronizationContext(this, direction, changePropagation);

            switch (direction)
            {
            case SynchronizationDirection.LeftToRight:
            case SynchronizationDirection.LeftToRightForced:
            case SynchronizationDirection.LeftWins:
                var c1 = TransformationRunner.Transform(new object[] { left }, new object[] { right }, startRule.LeftToRight, context);
                right = c1.Output as TRight;
                break;

            case SynchronizationDirection.RightToLeft:
            case SynchronizationDirection.RightToLeftForced:
            case SynchronizationDirection.RightWins:
                var c2 = TransformationRunner.Transform(new object[] { right }, new object[] { left }, startRule.RightToLeft, context);
                left = c2.Output as TLeft;
                break;

            default:
                throw new ArgumentOutOfRangeException("direction");
            }
            return(context);
        }
Exemplo n.º 9
0
        internal void Synchronize(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
        {
            var dependencies = computation.Dependencies;

            foreach (var job in SynchronizationJobs.Where(j => !j.IsEarly))
            {
                var dependency = job.Perform(computation, direction, context);
                if (dependency != null)
                {
                    dependencies.Add(dependency);
                }
            }
        }
        private void CallRTLTransformationForInput(SynchronizationComputation <TRight, TLeft> syncComputation, SynchronizationDirection direction, TDepRight input, TDepLeft context, Action <TLeft, TDepLeft> leftSetter, Action <TRight, TDepRight> rightSetter)
        {
            var left = syncComputation.Opposite.Input;

            if (input != null)
            {
                if (leftSetter == null)
                {
                    return;
                }
                var comp = syncComputation.TransformationContext.CallTransformation(childRule.RightToLeft, new object[] { input }, new object[] { context });
                if (comp == null)
                {
                    return;
                }
                if (!comp.IsDelayed)
                {
                    leftSetter(left, comp.Output as TDepLeft);
                }
                else
                {
                    comp.OutputInitialized += (o, e) => leftSetter(left, comp.Output as TDepLeft);
                };
            }
            else
            {
                if (direction == SynchronizationDirection.RightWins)
                {
                    CallLTRTransformationForInput(syncComputation.Opposite, SynchronizationDirection.RightWins, context, input, leftSetter, rightSetter);
                }
                else if (direction == SynchronizationDirection.RightToLeftForced)
                {
                    if (leftSetter == null)
                    {
                        return;
                    }
                    leftSetter(left, null);
                }
            }
        }
Exemplo n.º 11
0
 public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
 {
     if (Action != null)
     {
         return(Action(computation.Input, computation.Opposite.Input, direction, context));
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 12
0
 public SynchronizationContext(Synchronization synchronization, SynchronizationDirection direction, ChangePropagationMode changePropagation)
     : base(synchronization)
 {
     this.direction = direction;
     this.changePropagation = changePropagation;
 }
Exemplo n.º 13
0
 public SynchronizationContext(Synchronization synchronization, SynchronizationDirection direction, ChangePropagationMode changePropagation)
     : base(synchronization)
 {
     this.direction         = direction;
     this.changePropagation = changePropagation;
 }
Exemplo n.º 14
0
 public static bool IsRightToLeft(this SynchronizationDirection direction)
 {
     return(direction == SynchronizationDirection.RightToLeft || direction == SynchronizationDirection.RightToLeftForced || direction == SynchronizationDirection.RightWins);
 }
Exemplo n.º 15
0
 public static bool IsLeftToRight(this SynchronizationDirection direction)
 {
     return(direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins);
 }
Exemplo n.º 16
0
        public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
        {
            switch (context.ChangePropagation)
            {
            case ChangePropagationMode.None:
                return(null);

            case ChangePropagationMode.OneWay:
                if (direction != SynchronizationDirection.LeftToRight && direction != SynchronizationDirection.LeftToRightForced && direction != SynchronizationDirection.LeftWins)
                {
                    return(null);
                }
                break;

            case ChangePropagationMode.TwoWay:
                break;

            default:
                throw new InvalidOperationException("The change propagation mode is invalid.");
            }

            var instantiationMonitor = Predicate.Observe(computation.Input);
            var monitor = new Monitor(instantiationMonitor, computation);

            monitor.StartMonitoring();
            return(monitor);
        }
Exemplo n.º 17
0
        internal void CallRTLTransformationForInput(SynchronizationComputation <TRight, TLeft> syncComputation, SynchronizationDirection direction, TDepRight input, TDepLeft context, Action <TLeft, TDepLeft> leftSetter, Action <TRight, TDepRight> rightSetter)
        {
            if (direction == SynchronizationDirection.CheckOnly)
            {
                // two-way change propagation is handled through dependency
                if (syncComputation.SynchronizationContext.ChangePropagation == ChangePropagationMode.None)
                {
                    Match(syncComputation.Opposite, leftGetter(syncComputation.Opposite.Input), input);
                }
                return;
            }
            var left = syncComputation.Opposite.Input;

            if (input != null)
            {
                if (leftSetter == null)
                {
                    return;
                }
                var comp = syncComputation.TransformationContext.CallTransformation(childRule.RightToLeft, new object[] { input }, new object[] { context });
                if (comp == null)
                {
                    return;
                }
                if (!comp.IsDelayed)
                {
                    leftSetter(left, comp.Output as TDepLeft);
                }
                else
                {
                    comp.OutputInitialized += (o, e) => leftSetter(left, comp.Output as TDepLeft);
                };
            }
            else
            {
                if (direction == SynchronizationDirection.RightWins)
                {
                    CallLTRTransformationForInput(syncComputation.Opposite, SynchronizationDirection.RightWins, context, input, leftSetter, rightSetter);
                }
                else if (direction == SynchronizationDirection.RightToLeftForced)
                {
                    if (leftSetter == null)
                    {
                        return;
                    }
                    leftSetter(left, null);
                }
            }
        }
Exemplo n.º 18
0
        public ISynchronizationContext SynchronizeMany <TLeft, TRight>(SynchronizationRule <TLeft, TRight> startRule, ICollection <TLeft> lefts, ICollection <TRight> rights, SynchronizationDirection direction, ChangePropagationMode changePropagation)
            where TLeft : class
            where TRight : class
        {
            if (startRule == null)
            {
                throw new ArgumentNullException("startRule");
            }

            var context = new SynchronizationContext(this, direction, changePropagation);

            switch (direction)
            {
            case SynchronizationDirection.LeftToRight:
                var c1 = TransformationRunner.TransformMany(lefts.Select(l => new object[] { l }), rights, startRule.LeftToRight, context);
                rights.Clear();
                rights.AddRange(c1.Select(c => c.Output as TRight));
                break;

            case SynchronizationDirection.RightToLeft:
                var c2 = TransformationRunner.TransformMany(rights.Select(r => new object[] { r }), lefts, startRule.RightToLeft, context);
                lefts.Clear();
                lefts.AddRange(c2.Select(c => c.Output as TLeft));
                break;

            default:
                throw new ArgumentOutOfRangeException("direction");
            }
            return(context);
        }
Exemplo n.º 19
0
 public IDisposable Perform(SynchronizationComputation <TLeft, TRight> computation, SynchronizationDirection direction, ISynchronizationContext context)
 {
     return(new Dependency(Inner, computation, direction, CreateTracker(computation)));
 }
Exemplo n.º 20
0
 public ISynchronizationContext Synchronize <TLeft, TRight>(ref TLeft left, ref TRight right, SynchronizationDirection direction, ChangePropagationMode changePropagation)
     where TLeft : class
     where TRight : class
 {
     return(Synchronize <TLeft, TRight>(GetSynchronizationRuleForSignature(typeof(TLeft), typeof(TRight)) as SynchronizationRule <TLeft, TRight>, ref left, ref right, direction, changePropagation));
 }
Exemplo n.º 21
0
        private void TestFsm2Pn(SynchronizationDirection direction, ChangePropagationMode changePropagartion, bool initializeFsm, bool initializePn)
        {
            Assert.IsTrue(initializeFsm | initializePn);

            var fsm = this.fsm;
            var pn  = this.pn;

            if (initializeFsm)
            {
                FillStateMachine();
            }
            if (initializePn)
            {
                FillPetriNet();
            }

            fsm2pn.Initialize();

            var context = fsm2pn.Synchronize(fsm2pn.SynchronizationRule <FSM2PN.AutomataToNet>(), ref fsm, ref pn, direction, changePropagartion);

            var isLeftToRight = direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins;
            var isForced      = direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.RightToLeftForced;
            var isJoined      = direction == SynchronizationDirection.LeftWins || direction == SynchronizationDirection.RightWins;

            Fsm.State s1;
            Pn.Place  p1;

            if (initializeFsm && initializePn)
            {
                if (isForced)
                {
                    if (isLeftToRight)
                    {
                        s1 = AssertOriginalFsm(fsm, context);
                    }
                    else
                    {
                        s1 = AssertPetriNetLikeFsm(fsm, context);
                    }
                }
                else if (isJoined || !isLeftToRight)
                {
                    s1 = AssertJoinedFsm(fsm, context);
                }
                else
                {
                    s1 = AssertOriginalFsm(fsm, context);
                }
            }
            else if (!initializeFsm)
            {
                if (!isLeftToRight || isJoined)
                {
                    s1 = AssertPetriNetLikeFsm(fsm, context);
                }
                else
                {
                    s1 = AssertEmptyFsm(fsm);
                }
            }
            else if (!initializePn)
            {
                if (isForced && !isLeftToRight)
                {
                    s1 = AssertEmptyFsm(fsm);
                }
                else
                {
                    s1 = AssertOriginalFsm(fsm, context);
                }
            }
            else
            {
                s1 = null;
                Assert.Fail();
            }

            if (initializeFsm && initializePn)
            {
                if (isForced)
                {
                    if (!isLeftToRight)
                    {
                        p1 = AssertOriginalPetriNet(pn, context, s1);
                    }
                    else
                    {
                        p1 = AssertFsmLikePetriNet(pn, context, s1);
                    }
                }
                else if (isJoined || isLeftToRight)
                {
                    p1 = AssertJoinedPetriNet(pn, context, s1);
                }
                else
                {
                    p1 = AssertOriginalPetriNet(pn, context, s1);
                }
            }
            else if (!initializePn)
            {
                if (isLeftToRight || isJoined)
                {
                    p1 = AssertFsmLikePetriNet(pn, context, s1);
                }
                else
                {
                    p1 = AssertEmptyPetriNet(pn);
                }
            }
            else if (!initializeFsm)
            {
                if (isForced && isLeftToRight)
                {
                    p1 = AssertEmptyPetriNet(pn);
                }
                else
                {
                    p1 = AssertOriginalPetriNet(pn, context, s1);
                }
            }
            else
            {
                p1 = null;
                Assert.Fail();
            }

            if (changePropagartion == ChangePropagationMode.TwoWay ||
                (changePropagartion == ChangePropagationMode.OneWay && isLeftToRight))
            {
                AssertOneWayUpdatesFsmToPetriNet(s1, p1);
            }

            if (changePropagartion == ChangePropagationMode.TwoWay ||
                (changePropagartion == ChangePropagationMode.OneWay && !isLeftToRight))
            {
                AssertOneWayUpdatesPetriNetToFsm(p1, s1);
            }
        }
Exemplo n.º 22
0
        private void TestFsm2Pn(SynchronizationDirection direction, ChangePropagationMode changePropagartion, bool initializeFsm, bool initializePn)
        {
            Assert.IsTrue(initializeFsm | initializePn);

            var fsm = this.fsm;
            var pn = this.pn;

            if (initializeFsm) FillStateMachine();
            if (initializePn) FillPetriNet();

            fsm2pn.Initialize();

            var context = fsm2pn.Synchronize(fsm2pn.SynchronizationRule<FSM2PN.AutomataToNet>(), ref fsm, ref pn, direction, changePropagartion);
            var isLeftToRight = direction == SynchronizationDirection.LeftToRight || direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.LeftWins;
            var isForced = direction == SynchronizationDirection.LeftToRightForced || direction == SynchronizationDirection.RightToLeftForced;
            var isJoined = direction == SynchronizationDirection.LeftWins || direction == SynchronizationDirection.RightWins;

            Fsm.State s1;
            Pn.Place p1;

            if (initializeFsm && initializePn)
            {
                if (isForced)
                {
                    if (isLeftToRight)
                    {
                        s1 = AssertOriginalFsm(fsm, context);
                    }
                    else
                    {
                        s1 = AssertPetriNetLikeFsm(fsm, context);
                    }
                }
                else if (isJoined || !isLeftToRight)
                {
                    s1 = AssertJoinedFsm(fsm, context);
                }
                else
                {
                    s1 = AssertOriginalFsm(fsm, context);
                }
            }
            else if (!initializeFsm)
            {
                if (!isLeftToRight || isJoined)
                {
                    s1 = AssertPetriNetLikeFsm(fsm, context);
                }
                else
                {
                    s1 = AssertEmptyFsm(fsm);
                }
            }
            else if (!initializePn)
            {
                if (isForced && !isLeftToRight)
                {
                    s1 = AssertEmptyFsm(fsm);
                }
                else
                {
                    s1 = AssertOriginalFsm(fsm, context);
                }
            }
            else
            {
                s1 = null;
                Assert.Fail();
            }

            if (initializeFsm && initializePn)
            {
                if (isForced)
                {
                    if (!isLeftToRight)
                    {
                        p1 = AssertOriginalPetriNet(pn, context, s1);
                    }
                    else
                    {
                        p1 = AssertFsmLikePetriNet(pn, context, s1);
                    }
                }
                else if (isJoined || isLeftToRight)
                {
                    p1 = AssertJoinedPetriNet(pn, context, s1);
                }
                else
                {
                    p1 = AssertOriginalPetriNet(pn, context, s1);
                }
            }
            else if (!initializePn)
            {
                if (isLeftToRight || isJoined)
                {
                    p1 = AssertFsmLikePetriNet(pn, context, s1);
                }
                else
                {
                    p1 = AssertEmptyPetriNet(pn);
                }
            }
            else if (!initializeFsm)
            {
                if (isForced && isLeftToRight)
                {
                    p1 = AssertEmptyPetriNet(pn);
                }
                else
                {
                    p1 = AssertOriginalPetriNet(pn, context, s1);
                }
            }
            else
            {
                p1 = null;
                Assert.Fail();
            }

            if (changePropagartion == ChangePropagationMode.TwoWay ||
                (changePropagartion == ChangePropagationMode.OneWay && isLeftToRight))
            {
                AssertOneWayUpdatesFsmToPetriNet(s1, p1);
            }

            if (changePropagartion == ChangePropagationMode.TwoWay ||
                (changePropagartion == ChangePropagationMode.OneWay && !isLeftToRight))
            {
                AssertOneWayUpdatesPetriNetToFsm(p1, s1);
            }
        }