protected override void InvokeInternal(CommandProcessorContext cpc) { if (!string.IsNullOrEmpty(Role) && !string.Equals(End.Role.Value, Role, StringComparison.Ordinal)) { // TODO: should this command be enqueued in the command processor? RenameCommand c = new EntityDesignRenameCommand(End, Role, true); CommandProcessor.InvokeSingleCommand(cpc, c); // bug 563525: we need to update EndProperties within AssociationSetMappings if the AssociationEnd changes. // we update the "Role" of an AssociationSetEnd in the RenameCommand but the SingleItemBinding that we have to update // that is bound to the AssociationSetEnd is unique to this situation; it is not technically a "refactor rename". var associationSetEnd = End.GetAntiDependenciesOfType <AssociationSetEnd>().FirstOrDefault(); if (associationSetEnd != null) { // we need to renormalize the associationSetEnd, since the role name will have changed. XmlModelHelper.NormalizeAndResolve(associationSetEnd); var endPropertiesInAssocSetMappings = associationSetEnd.GetAntiDependenciesOfType <EndProperty>(); foreach (var endProperty in endPropertiesInAssocSetMappings) { endProperty.Name.SetRefName(associationSetEnd); CheckArtifactBindings.ScheduleBindingsForRebind(cpc, new HashSet <ItemBinding> { endProperty.Name }); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (!string.IsNullOrEmpty(Role) && !string.Equals(End.Role.Value, Role, StringComparison.Ordinal)) { // TODO: should this command be enqueued in the command processor? RenameCommand c = new EntityDesignRenameCommand(End, Role, true); CommandProcessor.InvokeSingleCommand(cpc, c); // bug 563525: we need to update EndProperties within AssociationSetMappings if the AssociationEnd changes. // we update the "Role" of an AssociationSetEnd in the RenameCommand but the SingleItemBinding that we have to update // that is bound to the AssociationSetEnd is unique to this situation; it is not technically a "refactor rename". var associationSetEnd = End.GetAntiDependenciesOfType<AssociationSetEnd>().FirstOrDefault(); if (associationSetEnd != null) { // we need to renormalize the associationSetEnd, since the role name will have changed. XmlModelHelper.NormalizeAndResolve(associationSetEnd); var endPropertiesInAssocSetMappings = associationSetEnd.GetAntiDependenciesOfType<EndProperty>(); foreach (var endProperty in endPropertiesInAssocSetMappings) { endProperty.Name.SetRefName(associationSetEnd); CheckArtifactBindings.ScheduleBindingsForRebind(cpc, new HashSet<ItemBinding> { endProperty.Name }); } } } }
internal override void Invoke(CommandProcessorContext cpc) { var viewModel = _entityType.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from entity type: " + _entityType.Name); if (viewModel != null) { var entityType = viewModel.ModelXRef.GetExisting(_entityType) as Model.Entity.EntityType; Debug.Assert(entityType != null); Command c = new EntityDesignRenameCommand(entityType, _entityType.Name, true); var cp = new CommandProcessor(cpc, c); cp.Invoke(); } }
internal override void Invoke(CommandProcessorContext cpc) { var viewModel = _property.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from property: " + _property.Name); if (viewModel != null) { var property = viewModel.ModelXRef.GetExisting(_property) as Model.Entity.Property; Debug.Assert(property != null); Command c = new EntityDesignRenameCommand(property, _property.Name, true); var cp = new CommandProcessor(cpc, c); cp.Invoke(); } }
private void RenameEntitySet(CommandProcessorContext cpc) { var entity = Element as EntityType; Debug.Assert(entity != null, "Element for rename was not EntityType"); // rename EntitySet only if the entity has no base type if (entity != null) { var cet = entity as ConceptualEntityType; if (cet != null && cet.HasResolvableBaseType) { return; } } if (entity.EntitySet != null) { var entitySetName = entity.EntitySet.LocalName.Value; // check if EntitySet name is of auto-generated form (which differs depending on // the setting of the pluralization flag) var autoEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, entity.LocalName.Value); if (entitySetName.StartsWith(autoEntitySetName, StringComparison.CurrentCulture)) { // the actual EntitySet name may differ from the auto-generated name by an integer suffix // if there were clashes with existing EntitySet names - so check this here var suffix = entitySetName.Substring(autoEntitySetName.Length); int i; if (suffix.Length == 0 || int.TryParse(suffix, out i)) { var proposedEntitySetName = ModelHelper.ConstructProposedEntitySetName(entity.Artifact, NewName); var newEntitySetName = ModelHelper.GetUniqueName( typeof(EntitySet), (entity.EntityModel.EntityContainer), proposedEntitySetName); RenameCommand cmd = new EntityDesignRenameCommand(entity.EntitySet, newEntitySetName, UniquenessIsCaseSensitive); CommandProcessor.InvokeSingleCommand(cpc, cmd); } } } }
protected override void OnApplyChanges() { // SCCI operation, check out any file that need to be changed. // If failed to check out any file or user cancelled check out, return. var filesToCheckOut = new List<String>(GetListOfFilesToCheckOut()); if (!EnsureFileCheckOut(filesToCheckOut)) { return; } // Set up linked undo var linkedUndoManager = ServiceProvider.GetService(typeof(SVsLinkedUndoTransactionManager)) as IVsLinkedUndoTransactionManager; var completedLinkedUndo = false; try { var hr = linkedUndoManager.OpenLinkedUndo(ApplyChangesUndoScope, UndoDescription); if (hr == VSConstants.S_OK) { var linkedUndoHr = 0; // Remember what are invisible editors we open, we will release them explicitly // after apply changes are done. var invisibleEditors = new List<IVsInvisibleEditor>(); try { var changeCount = FileChanges.Count; string errorMessage = null; string fileName = null; try { for (var changeIndex = 0; changeIndex < changeCount && !IsCancelled && !ErrorOccurred; changeIndex++) { var fileChange = FileChanges[changeIndex]; if (fileChange.IsFileModified) { // When apply change to a file, if that file is not in RDT, it will open that file in invisible editor. fileName = fileChange.FileName; var textBuffer = GetTextBufferForFile(fileName, invisibleEditors); if (textBuffer != null) { ApplyChangesToOneFile(fileChange, textBuffer, false, null); } } } // Execute the rename command to update the CSDL model var artifact = _objectToRename.Artifact as EntityDesignArtifact; Debug.Assert(artifact != null, "Object being refactored does not have an EntityDesignArtifact parent."); if (artifact != null) { var renameCommand = new EntityDesignRenameCommand(_objectToRename, _newName, false); var cpc = new CommandProcessorContext( artifact.EditingContext, "EFRefactoringOperation->OnApplyChanges", Resources.Tx_RefactorRenameCommand); CommandProcessor.InvokeSingleCommand(cpc, renameCommand); } } catch (IOException) { errorMessage = string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, fileName); } catch (InvalidOperationException) { errorMessage = string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, fileName); } if (errorMessage != null) { // Any error occur, abort the transaction. linkedUndoManager.AbortLinkedUndo(); OnError(errorMessage); } else { // Succeed, close linked undo and submit the transaction. // This operation will automatically save any dirty file. linkedUndoHr = linkedUndoManager.CloseLinkedUndo(); if (linkedUndoHr != VSConstants.S_OK) { linkedUndoManager.AbortLinkedUndo(); } } completedLinkedUndo = true; } finally { var editorCount = invisibleEditors.Count; for (var editorIndex = 0; editorIndex < editorCount; editorIndex++) { // Close invisible editor from RDT var invisibleEditor = invisibleEditors[editorIndex]; if (invisibleEditor != null) { Marshal.ReleaseComObject(invisibleEditor); } } } } else { OnError(string.Format(CultureInfo.CurrentCulture, Resources.Error_FailedApplyChangeToFile, string.Empty)); } } finally { if (completedLinkedUndo == false) { linkedUndoManager.AbortLinkedUndo(); } } }
public void Simple_Association() { UITestRunner.Execute(TestContext.TestName, () => { const string typePrefix = "Simple_Association"; const string testName = "UndoRedo." + typePrefix; ExecuteUndoRedoTest( testName, "BlankModel.edmx", (commandProcessorContext, artifact) => { const string entity1TypeName = typePrefix + "_EntityType1"; const string entity2TypeName = typePrefix + "_EntityType2"; const string association1TypeName = typePrefix + "_Association1"; const string association2TypeName = typePrefix + "_Association2"; var dte = VsIdeTestHostContext.Dte; // Note: we cannot populate these EFObjects as soon as we create them. Since we are undoing/redoing, // we will create new instances and need to discover them "on-demand" ConceptualEntityType entityType1; ConceptualEntityType entityType2; // CREATE TWO ENTITIES CreateDefaultEntityType(commandProcessorContext, entity1TypeName, typePrefix + "_EntitySet1"); CreateDefaultEntityType(commandProcessorContext, entity2TypeName, typePrefix + "_EntitySet2"); entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName); entityType2 = artifact.GetFreshConceptualEntity(entity2TypeName); Assert.IsNotNull(entityType1); Assert.IsNotNull(entityType2); // CREATE ASSOCIATION new CommandProcessor( commandProcessorContext, new CreateConceptualAssociationCommand( association1TypeName, entityType1, "*", "Entity2", entityType2, "1", "Entity1", uniquifyNames: false, createForeignKeyProperties: false)).Invoke(); Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName), "Association not created."); // Undo Redo "Create Association1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNull(artifact.GetFreshAssociation(association1TypeName)); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNotNull( artifact.GetFreshAssociation(association1TypeName), "Association should not have disappeared."); // DELETE ASSOCIATION new CommandProcessor( commandProcessorContext, artifact.GetFreshAssociation(association1TypeName).GetDeleteCommand()).Invoke(); Assert.AreEqual(0, artifact.ConceptualModel().AssociationCount, "No associations expected."); // Undo Redo "Delete Association1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName)); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.AreEqual(0, artifact.ConceptualModel().AssociationCount, "No associations expected."); // Undo "Delete Association1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNotNull( artifact.GetFreshAssociation(association1TypeName), "Association not re-created after Undo."); // CREATE ANOTHER ASSOCIATION 2 (we'll make it a self-association for good measure) entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName); entityType2 = artifact.GetFreshConceptualEntity(entity1TypeName); new CommandProcessor( commandProcessorContext, new CreateConceptualAssociationCommand( association2TypeName, entityType1, "*", "Entity1_1", entityType1, "1", "Entity1_2", uniquifyNames: false, createForeignKeyProperties: false)).Invoke(); Assert.IsNotNull(artifact.GetFreshAssociation(association2TypeName), "Association not created."); // Undo Redo "Create Association2" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNull(artifact.GetFreshAssociation(association2TypeName)); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNotNull( artifact.GetFreshAssociation(association2TypeName), "Association should not have disappeared."); // CHANGE MULTIPLICITY var association1End1 = artifact.GetFreshAssociationEnd(association1TypeName, 0); Assert.AreEqual("*", association1End1.Multiplicity.Value); new CommandProcessor( commandProcessorContext, new ChangeAssociationEndCommand(association1End1, "1", null)).Invoke(); Assert.AreEqual("1", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value); //Undo Redo "Change Association1 End1 Multiplicity: * --> 1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.AreEqual("*", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.AreEqual("1", artifact.GetFreshAssociationEnd(association1TypeName, 0).Multiplicity.Value); // CHANGE ROLE var association2End1 = artifact.GetFreshAssociationEnd(association2TypeName, 0); Assert.AreEqual("Simple_Association_EntityType1", association2End1.Role.Value); new CommandProcessor( commandProcessorContext, new ChangeAssociationEndCommand(association2End1, association2End1.Multiplicity.Value, "Entity2")) .Invoke(); Assert.AreEqual("Entity2", artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value); // Undo Redo "Change Association2 End2 Role: Entity1 --> Entity2" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.AreEqual( "Simple_Association_EntityType1", artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.AreEqual("Entity2", artifact.GetFreshAssociationEnd(association2TypeName, 0).Role.Value); // CHANGE NAVIGATION PROPERTY NAME entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName); var entityType1NavProp1 = entityType1.NavigationProperties().Single(np => np.LocalName.Value == "Entity2"); new CommandProcessor( commandProcessorContext, new EntityDesignRenameCommand(entityType1NavProp1, "Entity2_1", false)).Invoke(); Assert.IsNotNull( entityType1.NavigationProperties().SingleOrDefault(np => np.LocalName.Value == "Entity2_1")); // Undo Redo "Rename EntityType1 NavigationProperty1: Entity2 --> Entity2_1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNotNull( artifact.GetFreshConceptualEntity(entity1TypeName) .NavigationProperties() .SingleOrDefault(np => np.LocalName.Value == "Entity2")); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNotNull( artifact.GetFreshConceptualEntity(entity1TypeName) .NavigationProperties() .SingleOrDefault(np => np.LocalName.Value == "Entity2_1")); // RENAME ENTITYSET (changes AssociationSetEnds) Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet .RefName); entityType1 = artifact.GetFreshConceptualEntity(entity1TypeName); var entityType1Set = (ConceptualEntitySet)entityType1.EntitySet; RenameCommand renameEt1set = new EntityDesignRenameCommand(entityType1Set, "Entity1Set_1", false); new CommandProcessor( commandProcessorContext, new EntityDesignRenameCommand(entityType1Set, "Entity1Set_1", false)).Invoke(); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet .RefName); // Undo Redo"Rename EntityType1 EntitySet: Entity1Set --> Entity1Set_1" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Simple_Association_EntitySet1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet .RefName); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association1TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[0].EntitySet .RefName); Assert.AreEqual( "Entity1Set_1", artifact.GetFreshAssociation(association2TypeName).AssociationSet.AssociationSetEnds()[1].EntitySet .RefName); // RENAME ASSOCIATION new CommandProcessor( commandProcessorContext, new EntityDesignRenameCommand( artifact.GetFreshAssociation(association2TypeName), "Entity1Entity1_new", false)).Invoke(); Assert.IsNotNull(artifact.GetFreshAssociation("Entity1Entity1_new")); // Undo Redo "Rename Association2" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNotNull(artifact.GetFreshAssociation(association2TypeName)); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNotNull(artifact.GetFreshAssociation("Entity1Entity1_new")); // RENAME ASSOCIATION new CommandProcessor( commandProcessorContext, new EntityDesignRenameCommand( artifact.GetFreshAssociation(association1TypeName), "Entity2Entity1_newSet", false)).Invoke(); Assert.IsNull(artifact.GetFreshAssociation(association1TypeName)); Assert.IsNotNull(artifact.GetFreshAssociation("Entity2Entity1_newSet")); // Undo Redo "Rename Association1 Set" dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), UndoCommand); Assert.IsNotNull(artifact.GetFreshAssociation(association1TypeName)); Assert.IsNull(artifact.GetFreshAssociation("Entity2Entity1_newSet")); dte.ExecuteCommandForOpenDocument(artifact.LocalPath(), RedoCommand); Assert.IsNull(artifact.GetFreshAssociation(association1TypeName)); Assert.IsNotNull(artifact.GetFreshAssociation("Entity2Entity1_newSet")); }); }); }