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); }
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); }
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); }
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)); }
internal EfiChangeGroup(EfiTransaction tx) { _tx = tx; }
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; }
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; } }