示例#1
0
        public ChangeScopeImpl(
            EfiTransaction efiTransaction, EditingContext editingContext, byte[] extensionToken, IChangeScopeContainer container)
        {
            _editingContext = editingContext;
            _efiTransaction = efiTransaction;
            _container      = container;

            if (extensionToken != null)
            {
                _trustedExtension = IsExtensionTrusted(extensionToken);
            }

            AddEventHandler();
        }
 /// <summary>
 ///     Note:  If createTransactionImmediately is set to true, the caller is responsible for calling CommandProcessor's FinalizeTransaction().  This is a bit wonky.  User can spin up a CommandProcessor
 ///     with this context, and then invoke that method on that command processor.
 /// </summary>
 /// <param name="editingContext"></param>
 /// <param name="originatorId"></param>
 /// <param name="transactionName"></param>
 /// <param name="artifact"></param>
 /// <param name="transactionContext"></param>
 /// <param name="createTransactionImmediately"></param>
 internal CommandProcessorContext(
     EditingContext editingContext, string originatorId, string transactionName, EFArtifact artifact,
     EfiTransactionContext transactionContext, bool createTransactionImmediately)
 {
     _editingContext = editingContext;
     _originatorId = originatorId;
     _transactionName = transactionName;
     _artifact = artifact;
     _transactionContext = transactionContext;
     if (createTransactionImmediately)
     {
         _transaction = CreateTransaction();
     }
 }
 /// <summary>
 ///     Note:  If createTransactionImmediately is set to true, the caller is responsible for calling CommandProcessor's FinalizeTransaction().  This is a bit wonky.  User can spin up a CommandProcessor
 ///     with this context, and then invoke that method on that command processor.
 /// </summary>
 /// <param name="editingContext"></param>
 /// <param name="originatorId"></param>
 /// <param name="transactionName"></param>
 /// <param name="artifact"></param>
 /// <param name="transactionContext"></param>
 /// <param name="createTransactionImmediately"></param>
 internal CommandProcessorContext(
     EditingContext editingContext, string originatorId, string transactionName, EFArtifact artifact,
     EfiTransactionContext transactionContext, bool createTransactionImmediately)
 {
     _editingContext     = editingContext;
     _originatorId       = originatorId;
     _transactionName    = transactionName;
     _artifact           = artifact;
     _transactionContext = transactionContext;
     if (createTransactionImmediately)
     {
         _transaction = CreateTransaction();
     }
 }
        public ChangeScopeImpl(
            EfiTransaction efiTransaction, EditingContext editingContext, byte[] extensionToken, IChangeScopeContainer container)
        {
            _editingContext = editingContext;
            _efiTransaction = efiTransaction;
            _container = container;

            if (extensionToken != null)
            {
                _trustedExtension = IsExtensionTrusted(extensionToken);
            }

            AddEventHandler();
        }
        public override EntityDesignerChangeScope CreateChangeScope(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("name should not be null.");
            }

            if (_scope != null)
            {
                throw new InvalidOperationException(Resources.Extensibility_StartChangeScopeFailed);
            }

            var txn = new EfiTransaction(_editingContext.GetEFArtifactService().Artifact, PROPERTY_EXTENSION_ORIGINATOR_ID, name);
            _scope = new ChangeScopeImpl(txn, _editingContext, _extensionToken, this);
            return _scope;
        }
        public override EntityDesignerChangeScope CreateChangeScope(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("name should not be null.");
            }

            if (_scope != null)
            {
                throw new InvalidOperationException(Resources.Extensibility_StartChangeScopeFailed);
            }

            var txn = new EfiTransaction(_editingContext.GetEFArtifactService().Artifact, PROPERTY_EXTENSION_ORIGINATOR_ID, name);

            _scope = new ChangeScopeImpl(txn, _editingContext, _extensionToken, this);
            return(_scope);
        }
示例#7
0
        private static EfiChangeGroup ProcessDesignerChange(XmlTransactionEventArgs xmlTransactionEventArgs, EfiTransaction efiTransaction)
        {
            // if the transaction has one of our transactions in the UserState, then
            // this will not be null
            var changeGroup = efiTransaction.ChangeGroup;

            // Here, we need to call RecordModelChange for each change that occurred in the XmlTransaction
            // Since the XmlTransaction started in our model, the model already reflects these changes.
            foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes())
            {
                Debug.Assert(xmlChange.Node != null);

                if (xmlChange.Node.NodeType == XmlNodeType.Element ||
                    xmlChange.Node.NodeType == XmlNodeType.Attribute ||
                    xmlChange.Node.NodeType == XmlNodeType.Document)
                {
                    var efObject = ModelItemAnnotation.GetModelItem(xmlChange.Node);
                    if (efObject != null)
                    {
                        if (xmlChange.Node.NodeType == XmlNodeType.Element &&
                            xmlChange.Action == XObjectChange.Value)
                        {
                            var nodeValueChange = xmlChange as IXmlNodeValueChange;
                            Debug.Assert(
                                nodeValueChange != null &&
                                string.IsNullOrEmpty(nodeValueChange.OldValue) &&
                                string.IsNullOrEmpty(nodeValueChange.NewValue));

                            // at times (like when the last child is removed), the XLinq tree will
                            // collapse whitespace nodes and we will get 'set value' on the
                            // preceeding element, we can ignore these
                            continue;
                        }

                        string oldValue = null;
                        string newValue = null;
                        string property = null;
                        GetOldAndNewValues(xmlChange, out property, out oldValue, out newValue);

                        changeGroup.RecordModelChange(GetChangeType(xmlChange), efObject, property, oldValue, newValue);
                    }
                }
            }

            return(changeGroup);
        }
示例#8
0
        private EfiChangeGroup ProcessUndoRedoChanges(XmlTransactionEventArgs xmlTransactionEventArgs)
        {
            using (var tx = new EfiTransaction(this, EfiTransactionOriginator.UndoRedoOriginatorId, xmlTransactionEventArgs.Transaction))
            {
                var changeGroup             = tx.ChangeGroup;
                var undoChanges             = new List <ExternalXMLModelChange>();
                var containersToRenormalize = new List <EFContainer>();
                var bindingsForRebind       = new List <ItemBinding>();
                var namespaces = GetNamespaces();

                // filter the changes received from XmlEditor and resolve changed EFObjects and their parents
                foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes())
                {
                    // determine how to process this edit
                    if (xmlChange.Node.NodeType == XmlNodeType.Element ||
                        xmlChange.Node.NodeType == XmlNodeType.Attribute ||
                        xmlChange.Node.NodeType == XmlNodeType.Document)
                    {
                        if (xmlChange.Node.NodeType == XmlNodeType.Element &&
                            xmlChange.Action == XObjectChange.Value)
                        {
                            var nodeValueChange = xmlChange as IXmlNodeValueChange;
                            Debug.Assert(
                                nodeValueChange != null &&
                                string.IsNullOrEmpty(nodeValueChange.OldValue) &&
                                string.IsNullOrEmpty(nodeValueChange.NewValue));

                            // in cases where we are undoing the addition of all children to an element A, the Xml Model
                            // will forcibly add an empty string to the element A so that a "short" end tag "/>" is not created
                            // in this case, the change we will receive is a set value change on an element; we ignore this
                        }
                        else
                        {
                            var emc = new ExternalXMLModelChange(xmlChange, ExpectEFObjectForXObject);
                            if (emc.IsAnnotationChange(namespaces))
                            {
                                continue;
                            }

                            undoChanges.Add(emc);
                        }
                    }
                }

                // go through the undo changes and make changes to the model
                foreach (var undoModelChange in undoChanges)
                {
                    // Should ignore other artifact changes.
                    if (undoModelChange.ChangedEFObject.Artifact != this)
                    {
                        continue;
                    }

                    if (undoModelChange.Action == XObjectChange.Remove)
                    {
                        ProcessExternalRemoveChange(changeGroup, bindingsForRebind, undoModelChange);
                    }
                    else
                    {
                        ProcessExternalAddOrUpdateChange(changeGroup, containersToRenormalize, undoModelChange);
                    }
                }

                // because of the order in which elements were possibly added, certain ItemBindings were not resolved;
                // therefore we have to step through the normalized EFElements again and normalize/resolve so their child
                // ItemBindings will get resolved.
                foreach (var container in containersToRenormalize)
                {
                    XmlModelHelper.NormalizeAndResolve(container);
                }
                XmlModelHelper.RebindItemBindings(bindingsForRebind);

#if DEBUG
                var visitor = GetVerifyModelIntegrityVisitor();
                visitor.Traverse(this);

                if (visitor.ErrorCount > 0)
                {
                    Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):");
                    Debug.WriteLine(visitor.AllSerializedErrors);
                    Debug.Assert(
                        false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details.");
                }
#endif
                return(changeGroup);
            }
        }
        internal EfiTransaction CreateTransaction()
        {
            Debug.Assert(!HasOpenTransaction, "We are opening a second transaction for this Context.");

            return _transaction = new EfiTransaction(Artifact, _originatorId, _transactionName, _transactionContext);
        }
示例#10
0
        private void PostProcessUpdate(CommandProcessorContext cpc, EfiTransaction tx, bool artifactInitiallyDirty)
        {
            var setUndoScope = false;

            try
            {
                // process those checks that need to run in the originating xact
                while (cpc.IntegrityChecks.Count > 0)
                {
                    // peek for the next check and invoke it, don't dequeue it so we
                    // won't add dupes and recurse forever
                    var check = cpc.IntegrityChecks.Peek();
                    check.Invoke();

                    // now pop it off the queue
                    cpc.IntegrityChecks.Dequeue();
                }

                if (cpc.EditingContext.ParentUndoUnitStarted == false)
                {
                    cpc.EditingContext.ParentUndoUnitStarted = true;
                    cpc.Artifact.XmlModelProvider.BeginUndoScope(cpc.EfiTransaction.Name);
                    setUndoScope = true;
                }

                if (_shouldNotifyObservers)
                {
                    cpc.Artifact.ModelManager.BeforeCommitChangeGroups(cpc);
                }

                // Do not mark the artifact as clean if the artifact was initially dirty before commands
                // were executed... otherwise we may lose information like diagram layout and configurations.
                // Also, translation rules can perform immediate changes to configurations which will dirty the artifact
                // but are not recorded through the enqueued commands. So we should not set the artifact to clean in this case.
                tx.Commit(!artifactInitiallyDirty);
                cpc.DisposeTransaction();

#if DEBUG
                var visitor = cpc.Artifact.GetVerifyModelIntegrityVisitor(true, true, true, true, true);
                visitor.Traverse(cpc.Artifact);

                if (visitor.ErrorCount > 0)
                {
                    Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):");
                    Debug.WriteLine(visitor.AllSerializedErrors);
                    Debug.Assert(
                        false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details.");
                }
#endif

                if (_shouldNotifyObservers)
                {
                    cpc.Artifact.ModelManager.RouteChangeGroups();
                }
                else
                {
                    // Changegroups have been recorded in the model manager;
                    // if we don't clear them they will be routed on the next observable transaction.
                    cpc.Artifact.ModelManager.ClearChangeGroups();
                }
            }
            finally
            {
                if (setUndoScope)
                {
                    cpc.Artifact.XmlModelProvider.EndUndoScope();
                    cpc.EditingContext.ParentUndoUnitStarted = false;
                }
            }
        }
        private void PostProcessUpdate(CommandProcessorContext cpc, EfiTransaction tx, bool artifactInitiallyDirty)
        {
            var setUndoScope = false;
            try
            {
                // process those checks that need to run in the originating xact
                while (cpc.IntegrityChecks.Count > 0)
                {
                    // peek for the next check and invoke it, don't dequeue it so we
                    // won't add dupes and recurse forever
                    var check = cpc.IntegrityChecks.Peek();
                    check.Invoke();

                    // now pop it off the queue
                    cpc.IntegrityChecks.Dequeue();
                }

                if (cpc.EditingContext.ParentUndoUnitStarted == false)
                {
                    cpc.EditingContext.ParentUndoUnitStarted = true;
                    cpc.Artifact.XmlModelProvider.BeginUndoScope(cpc.EfiTransaction.Name);
                    setUndoScope = true;
                }

                if (_shouldNotifyObservers)
                {
                    cpc.Artifact.ModelManager.BeforeCommitChangeGroups(cpc);
                }

                // Do not mark the artifact as clean if the artifact was initially dirty before commands
                // were executed... otherwise we may lose information like diagram layout and configurations.
                // Also, translation rules can perform immediate changes to configurations which will dirty the artifact
                // but are not recorded through the enqueued commands. So we should not set the artifact to clean in this case.
                tx.Commit(!artifactInitiallyDirty);
                cpc.DisposeTransaction();

#if DEBUG
                var visitor = cpc.Artifact.GetVerifyModelIntegrityVisitor(true, true, true, true, true);
                visitor.Traverse(cpc.Artifact);

                if (visitor.ErrorCount > 0)
                {
                    Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):");
                    Debug.WriteLine(visitor.AllSerializedErrors);
                    Debug.Assert(
                        false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details.");
                }
#endif

                if (_shouldNotifyObservers)
                {
                    cpc.Artifact.ModelManager.RouteChangeGroups();
                }
                else
                {
                    // Changegroups have been recorded in the model manager;
                    // if we don't clear them they will be routed on the next observable transaction.
                    cpc.Artifact.ModelManager.ClearChangeGroups();
                }
            }
            finally
            {
                if (setUndoScope)
                {
                    cpc.Artifact.XmlModelProvider.EndUndoScope();
                    cpc.EditingContext.ParentUndoUnitStarted = false;
                }
            }
        }
        internal EfiTransaction CreateTransaction()
        {
            Debug.Assert(!HasOpenTransaction, "We are opening a second transaction for this Context.");

            return(_transaction = new EfiTransaction(Artifact, _originatorId, _transactionName, _transactionContext));
        }
示例#13
0
 internal EfiChangeGroup(EfiTransaction tx)
 {
     _tx = tx;
 }
示例#14
0
        private static EfiChangeGroup ProcessDesignerChange(XmlTransactionEventArgs xmlTransactionEventArgs, EfiTransaction efiTransaction)
        {
            // if the transaction has one of our transactions in the UserState, then 
            // this will not be null
            var changeGroup = efiTransaction.ChangeGroup;

            // Here, we need to call RecordModelChange for each change that occurred in the XmlTransaction
            // Since the XmlTransaction started in our model, the model already reflects these changes.
            foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes())
            {
                Debug.Assert(xmlChange.Node != null);

                if (xmlChange.Node.NodeType == XmlNodeType.Element
                    || xmlChange.Node.NodeType == XmlNodeType.Attribute
                    || xmlChange.Node.NodeType == XmlNodeType.Document)
                {
                    var efObject = ModelItemAnnotation.GetModelItem(xmlChange.Node);
                    if (efObject != null)
                    {
                        if (xmlChange.Node.NodeType == XmlNodeType.Element
                            && xmlChange.Action == XObjectChange.Value)
                        {
                            var nodeValueChange = xmlChange as IXmlNodeValueChange;
                            Debug.Assert(
                                nodeValueChange != null
                                && string.IsNullOrEmpty(nodeValueChange.OldValue)
                                && string.IsNullOrEmpty(nodeValueChange.NewValue));

                            // at times (like when the last child is removed), the XLinq tree will 
                            // collapse whitespace nodes and we will get 'set value' on the 
                            // preceeding element, we can ignore these
                            continue;
                        }

                        string oldValue = null;
                        string newValue = null;
                        string property = null;
                        GetOldAndNewValues(xmlChange, out property, out oldValue, out newValue);

                        changeGroup.RecordModelChange(GetChangeType(xmlChange), efObject, property, oldValue, newValue);
                    }
                }
            }

            return changeGroup;
        }
示例#15
0
        private EfiChangeGroup ProcessUndoRedoChanges(XmlTransactionEventArgs xmlTransactionEventArgs)
        {
            using (var tx = new EfiTransaction(this, EfiTransactionOriginator.UndoRedoOriginatorId, xmlTransactionEventArgs.Transaction))
            {
                var changeGroup = tx.ChangeGroup;
                var undoChanges = new List<ExternalXMLModelChange>();
                var containersToRenormalize = new List<EFContainer>();
                var bindingsForRebind = new List<ItemBinding>();
                var namespaces = GetNamespaces();

                // filter the changes received from XmlEditor and resolve changed EFObjects and their parents
                foreach (var xmlChange in xmlTransactionEventArgs.Transaction.Changes())
                {
                    // determine how to process this edit
                    if (xmlChange.Node.NodeType == XmlNodeType.Element
                        || xmlChange.Node.NodeType == XmlNodeType.Attribute
                        || xmlChange.Node.NodeType == XmlNodeType.Document)
                    {
                        if (xmlChange.Node.NodeType == XmlNodeType.Element
                            && xmlChange.Action == XObjectChange.Value)
                        {
                            var nodeValueChange = xmlChange as IXmlNodeValueChange;
                            Debug.Assert(
                                nodeValueChange != null
                                && string.IsNullOrEmpty(nodeValueChange.OldValue)
                                && string.IsNullOrEmpty(nodeValueChange.NewValue));

                            // in cases where we are undoing the addition of all children to an element A, the Xml Model
                            // will forcibly add an empty string to the element A so that a "short" end tag "/>" is not created
                            // in this case, the change we will receive is a set value change on an element; we ignore this
                        }
                        else
                        {
                            var emc = new ExternalXMLModelChange(xmlChange, ExpectEFObjectForXObject);
                            if (emc.IsAnnotationChange(namespaces))
                            {
                                continue;
                            }

                            undoChanges.Add(emc);
                        }
                    }
                }

                // go through the undo changes and make changes to the model
                foreach (var undoModelChange in undoChanges)
                {
                    // Should ignore other artifact changes.
                    if (undoModelChange.ChangedEFObject.Artifact != this)
                    {
                        continue;
                    }

                    if (undoModelChange.Action == XObjectChange.Remove)
                    {
                        ProcessExternalRemoveChange(changeGroup, bindingsForRebind, undoModelChange);
                    }
                    else
                    {
                        ProcessExternalAddOrUpdateChange(changeGroup, containersToRenormalize, undoModelChange);
                    }
                }

                // because of the order in which elements were possibly added, certain ItemBindings were not resolved;
                // therefore we have to step through the normalized EFElements again and normalize/resolve so their child
                // ItemBindings will get resolved.
                foreach (var container in containersToRenormalize)
                {
                    XmlModelHelper.NormalizeAndResolve(container);
                }
                XmlModelHelper.RebindItemBindings(bindingsForRebind);

#if DEBUG
                var visitor = GetVerifyModelIntegrityVisitor();
                visitor.Traverse(this);

                if (visitor.ErrorCount > 0)
                {
                    Debug.WriteLine("Model Integrity Verifier found " + visitor.ErrorCount + " error(s):");
                    Debug.WriteLine(visitor.AllSerializedErrors);
                    Debug.Assert(
                        false, "Model Integrity Verifier found " + visitor.ErrorCount + " error(s). See the Debug console for details.");
                }
#endif
                return changeGroup;
            }
        }