protected override void InvokeInternal(CommandProcessorContext cpc) { if (_diagram != null) { // Add diagram id information in the transaction context. // This is to ensure the diagram objects are created correctly. if (cpc.EfiTransaction.GetContextValue <DiagramContextItem>(EfiTransactionOriginator.TransactionOriginatorDiagramId) == null) { cpc.EfiTransaction.AddContextValue( EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(_diagram.Id.Value)); } } var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // check if entity is in the model _createdEntity = artifact.ArtifactSet.LookupSymbol(_clipboardEntity.NormalizedName) as EntityType; if (_diagram != null && _createdEntity != null && _createdEntity is ConceptualEntityType) { if (_createdEntity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == _diagram.Id.Value) == 0) { // CreateEntityTypeShapeAndConnectorsInDiagram method will check if the shape for the entity-type has been created; // and it will not create one if the shape already exists in the diagram. // Also, VerifyDiagramModelIntegrityVisitor will assert if there are duplicate diagram shapes (shapes that point to the same model element) // every-time a command transaction is committed. So adding another check to do the same thing here is redundant. CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, _createdEntity as ConceptualEntityType, _clipboardEntity.EntityTypeShapeFillColor, false); return; } } CreateEntityCopyInModel(cpc); }
internal static void StaticInvoke(CommandProcessorContext cpc, EntityTypeShape entityTypeShape) { var viewModel = entityTypeShape.GetRootViewModel(); Debug.Assert(viewModel != null, "Unable to find root view model from entity-type-shape:" + entityTypeShape.AccessibleName); if (viewModel != null) { var entityType = viewModel.ModelXRef.GetExisting(entityTypeShape.ModelElement) as EntityType; var diagram = viewModel.ModelXRef.GetExisting(entityTypeShape.Diagram) as Diagram; Debug.Assert(entityType != null && diagram != null); if (entityType != null && diagram != null) { var cmd = new CreateEntityTypeShapeCommand(diagram, entityType); CommandProcessor.InvokeSingleCommand(cpc, cmd); var modelEntityShape = cmd.EntityTypeShape; Debug.Assert(modelEntityShape != null); viewModel.ModelXRef.Add(modelEntityShape, entityTypeShape, viewModel.EditingContext); } } }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, Color entityTypeShapeFillColor, bool createRelatedEntityTypeShapes) { // if the entity type shape has been created, return immediately. if (entity == null || entity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == diagram.Id.Value) > 0) { return; } var createEntityTypeShapecommand = new CreateEntityTypeShapeCommand(diagram, entity, entityTypeShapeFillColor); createEntityTypeShapecommand.PostInvokeEvent += (o, eventsArgs) => { if (createEntityTypeShapecommand.EntityTypeShape != null) { var relatedEntityTypesNotInDiagram = new List <EntityType>(); var entityTypesInDiagram = new HashSet <EntityType>(diagram.EntityTypeShapes.Select(ets => ets.EntityType.Target)); // add inheritance connector if the base type exists in the diagram. if (entity.SafeBaseType != null) { if (entityTypesInDiagram.Contains(entity.SafeBaseType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, entity)); } else { relatedEntityTypesNotInDiagram.Add(entity.SafeBaseType); } } // add the inheritance connector if the derived type exist in the diagram. foreach (var derivedEntityType in entity.ResolvableDirectDerivedTypes) { if (entityTypesInDiagram.Contains(derivedEntityType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, derivedEntityType)); } else { relatedEntityTypesNotInDiagram.Add(derivedEntityType); } } // Find all associations which the entity type participates. var participatingAssociations = Association.GetAssociationsForEntityType(entity); foreach (var association in participatingAssociations) { var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList(); var entityTypesNotInDiagram = entityTypesInAssociation.Except(entityTypesInDiagram).ToList(); if (entityTypesNotInDiagram.Count == 0) { CommandProcessor.InvokeSingleCommand(cpc, new CreateAssociationConnectorCommand(diagram, association)); } relatedEntityTypesNotInDiagram.AddRange(entityTypesNotInDiagram); } if (createRelatedEntityTypeShapes) { foreach (var entityType in relatedEntityTypesNotInDiagram) { // we only want to bring entity-type directly related to the entity-type, so set createRelatedEntityTypeShapes flag to false. CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entityType as ConceptualEntityType, entityTypeShapeFillColor, false); } } } }; CommandProcessor.InvokeSingleCommand(cpc, createEntityTypeShapecommand); }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_diagram != null) { // Add diagram id information in the transaction context. // This is to ensure the diagram objects are created correctly. if (cpc.EfiTransaction.GetContextValue <DiagramContextItem>(EfiTransactionOriginator.TransactionOriginatorDiagramId) == null) { cpc.EfiTransaction.AddContextValue( EfiTransactionOriginator.TransactionOriginatorDiagramId, new DiagramContextItem(_diagram.Id.Value)); } } var service = cpc.EditingContext.GetEFArtifactService(); var artifact = service.Artifact; // the model that we want to add the entity to var model = ModelHelper.GetEntityModel(artifact, _modelSpace); var entitiesMap = new Dictionary <EntityTypeClipboardFormat, EntityType>(_clipboardEntities.ClipboardEntities.Count); // create copies of EntityTypes foreach (var clipboardEntity in _clipboardEntities.ClipboardEntities) { var cmd = new CopyEntityCommand(_diagram, clipboardEntity, _modelSpace); CommandProcessor.InvokeSingleCommand(cpc, cmd); entitiesMap.Add(clipboardEntity, cmd.EntityType); } // create copies of associations foreach (var clipboardAssociation in _clipboardEntities.ClipboardAssociations) { // Check if the association is in the Artifact/model. if (_diagram != null) { // Get the association by name. var association = artifact.ArtifactSet.LookupSymbol(clipboardAssociation.NormalizedName) as Association; if (association != null) { var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList(); // Check whether the associated entity-types are created in the previous step. // When the user copy and paste an association and the associated entities in the same diagram, // we need to create a new copy of the association in the model. Without the check below, the code will determine that there is no need // to create the copy since the association exist in the model. if (entityTypesInAssociation.Except(entitiesMap.Values).Count() == 0) { // At this point we know that the association that is referred in clipboard exists in the current model. // Next we will check whether this association is represented in diagram or not. // if not, create a new association connector in the diagram. if (association.GetAntiDependenciesOfType <AssociationConnector>() .Count(ac => ac.Diagram.Id == _diagram.Id.Value) == 0) { // AssociationConnector is created by creating EntityTypeShapes that associationEnd refer to. foreach (var associationEnd in association.AssociationEnds()) { var entityType = associationEnd.Type.SafeTarget as ConceptualEntityType; Debug.Assert( entityType != null, "In: CopyEntitiesCommand's InvokeInternal, associationEnd's Type property should be typeof ConceptualEntityType"); if (entityType != null) { // CreateEntityTypeShapeAndConnectorsInDiagram method will check if the shape for the entity-type has been created; // and it will not create one if the shape already exists in the diagram. // Also, VerifyDiagramModelIntegrityVisitor will assert if there are duplicate diagram shapes (shapes that point to the same model element) // every-time a command transaction is committed. So adding another check to do the same thing here is redundant. CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, entityType, false); } } } continue; } } } CopyAssociation(cpc, model, clipboardAssociation, entitiesMap); } // create copies of inheritances foreach (var inheritance in _clipboardEntities.ClipboardInheritances) { if (_diagram != null) { // Check if the underlying entity types are in the artifact/model to do that we need to: // - Get the Entity-Types by name. // - Check whether the entity-types match what were created in copy entities steps. var derivedEntity = artifact.ArtifactSet.LookupSymbol(inheritance.Key.NormalizedName) as EntityType; var baseEntity = artifact.ArtifactSet.LookupSymbol(inheritance.Value.NormalizedName) as EntityType; if (derivedEntity != null && baseEntity != null) { if (entitiesMap.Values.Contains(derivedEntity) && entitiesMap.Values.Contains(baseEntity)) { // check if the underlying entity-types are not in the diagram. // InheritanceConnector are created by ensuring both EntityTypeShapes are created. if (derivedEntity.GetAntiDependenciesOfType <EntityTypeShape>().Count(ets => ets.Diagram.Id == _diagram.Id.Value) == 0 && baseEntity.GetAntiDependenciesOfType <EntityTypeShape>() .Count(ets2 => ets2.Diagram.Id == _diagram.Id.Value) == 0) { // CreateEntityTypeShapeAndConnectorsInDiagram method will check if the shape for the entity-type has been created; // and it will not create one if the shape already exists in the diagram. // Also, VerifyDiagramModelIntegrityVisitor will assert if there are duplicate diagram shapes (shapes that point to the same model element) // every-time a command transaction is committed. So adding another check to do the same thing here is redundant. CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, derivedEntity as ConceptualEntityType, false); CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, baseEntity as ConceptualEntityType, false); } continue; } } } CopyInheritance(cpc, inheritance, entitiesMap); } }
private static void InjectEntityTypeShapeCommand( CommandProcessorContext commandProcessorContext, HashSet<ShapeChangeInformation> shapeChangeInfoSet, Diagram diagram, ConceptualEntityType entityType, XObjectChange changeAction) { // First check to see if there is already a change in the original transaction // for the EntityTypeShape that matches the one that we're getting var shapeChangeInfoToQuery = new ShapeChangeInformation { ChangeType = changeAction, ModelEFObject = entityType, DiagramId = diagram.Id.Value }; var shapeChangeInfoExists = shapeChangeInfoSet.Contains(shapeChangeInfoToQuery); // We only want to create model diagram if the transaction is originated from this diagram. if (changeAction == XObjectChange.Add) { // We only want to inject the entity-type-shape if the transaction is originated from the passed in diagram. if (commandProcessorContext != null && commandProcessorContext.EfiTransaction != null) { var contextItem = commandProcessorContext.EfiTransaction.GetContextValue<DiagramContextItem>( EfiTransactionOriginator.TransactionOriginatorDiagramId); if (contextItem != null && contextItem.DiagramId == diagram.Id.Value) { // look in the dictionary for an 'add' to an EntityTypeShape that points to this modelobject. if (shapeChangeInfoExists == false) { var cmd = new CreateEntityTypeShapeCommand(diagram, entityType); CommandProcessor.InvokeSingleCommand(commandProcessorContext, cmd); } // We have the ability to create an EntityType and an Inheritance in one transaction, so we need // to check for it here. if (entityType.BaseType.Target != null) { InjectInheritanceConnectorCommand( commandProcessorContext, shapeChangeInfoSet, diagram, entityType.BaseType, changeAction); } } } } else if (changeAction == XObjectChange.Remove && shapeChangeInfoExists == false) { // this is happening before the transaction is taking place so we are free to look up anti-dependencies // on this delete foreach ( var entityTypeShape in entityType.GetAntiDependenciesOfType<EntityTypeShape>() .Where(ets => ets.Diagram != null && ets.Diagram.Id == diagram.Id.Value)) { if (entityTypeShape != null) { var deleteEntityTypeShapeCommand = entityTypeShape.GetDeleteCommand(); CommandProcessor.InvokeSingleCommand(commandProcessorContext, deleteEntityTypeShapeCommand); } } } }
protected override void InvokeInternal(CommandProcessorContext cpc) { if (_efElements != null) { foreach (var efElement in _efElements) { // -------------------------------------------------------------------------------- // | EF Element Type | Diagram shape type | // -------------------------------------------------------------------------------- // | Conceptual Entity Type Entity Type Shape | // | Association Association Connector | // | Association Set Association Connector | // | Entity Set Entity Type Shapes for all ET in the set | // | Property Property's entity type shape | // -------------------------------------------------------------------------------- var entityType = efElement as ConceptualEntityType; var association = efElement as Association; var entitySet = efElement as EntitySet; var associationSet = efElement as AssociationSet; if (efElement is Property) { entityType = efElement.GetParentOfType(typeof(ConceptualEntityType)) as ConceptualEntityType; } if (associationSet != null && associationSet.Association.Status == BindingStatus.Known) { association = associationSet.Association.Target; } if (entityType != null) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, entityType, _createRelatedEntities); } else if (association != null) { Debug.Assert( association.AssociationEnds().Count == 2, "Received incorrect number of AssociationEnds (" + association.AssociationEnds().Count + ") for Association " + association.ToPrettyString() + " should be 2."); var assocEnds = association.AssociationEnds(); var assocEnd1 = assocEnds[0]; var assocEnd2 = assocEnds[1]; if (assocEnd1.Type.Status == BindingStatus.Known && assocEnd2.Type.Status == BindingStatus.Known) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, assocEnd1.Type.Target as ConceptualEntityType, _createRelatedEntities); // Check whether the association is self association or not. // If it is a self association, then we can skip creating the shape for the second associationEnd's entity type // since both association-ends point to the same entity type. if (assocEnd1.Type.Target != assocEnd2.Type.Target) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, assocEnd2.Type.Target as ConceptualEntityType, _createRelatedEntities); } } } else if (entitySet != null) { foreach (var et in entitySet.GetEntityTypesInTheSet()) { CreateEntityTypeShapeCommand.CreateEntityTypeShapeAndConnectorsInDiagram( cpc, _diagram, et as ConceptualEntityType, _createRelatedEntities); } } else { Debug.Fail("Unable to create diagram shape for EFElement with type:" + efElement.GetType().Name); } } } }
internal static void CreateEntityTypeShapeAndConnectorsInDiagram( CommandProcessorContext cpc, Diagram diagram, ConceptualEntityType entity, Color entityTypeShapeFillColor, bool createRelatedEntityTypeShapes) { // if the entity type shape has been created, return immediately. if (entity == null || entity.GetAntiDependenciesOfType<EntityTypeShape>().Count(ets => ets.Diagram.Id == diagram.Id.Value) > 0) { return; } var createEntityTypeShapecommand = new CreateEntityTypeShapeCommand(diagram, entity, entityTypeShapeFillColor); createEntityTypeShapecommand.PostInvokeEvent += (o, eventsArgs) => { if (createEntityTypeShapecommand.EntityTypeShape != null) { var relatedEntityTypesNotInDiagram = new List<EntityType>(); var entityTypesInDiagram = new HashSet<EntityType>(diagram.EntityTypeShapes.Select(ets => ets.EntityType.Target)); // add inheritance connector if the base type exists in the diagram. if (entity.SafeBaseType != null) { if (entityTypesInDiagram.Contains(entity.SafeBaseType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, entity)); } else { relatedEntityTypesNotInDiagram.Add(entity.SafeBaseType); } } // add the inheritance connector if the derived type exist in the diagram. foreach (var derivedEntityType in entity.ResolvableDirectDerivedTypes) { if (entityTypesInDiagram.Contains(derivedEntityType)) { CommandProcessor.InvokeSingleCommand(cpc, new CreateInheritanceConnectorCommand(diagram, derivedEntityType)); } else { relatedEntityTypesNotInDiagram.Add(derivedEntityType); } } // Find all associations which the entity type participates. var participatingAssociations = Association.GetAssociationsForEntityType(entity); foreach (var association in participatingAssociations) { var entityTypesInAssociation = association.AssociationEnds().Select(ae => ae.Type.Target).ToList(); var entityTypesNotInDiagram = entityTypesInAssociation.Except(entityTypesInDiagram).ToList(); if (entityTypesNotInDiagram.Count == 0) { CommandProcessor.InvokeSingleCommand(cpc, new CreateAssociationConnectorCommand(diagram, association)); } relatedEntityTypesNotInDiagram.AddRange(entityTypesNotInDiagram); } if (createRelatedEntityTypeShapes) { foreach (var entityType in relatedEntityTypesNotInDiagram) { // we only want to bring entity-type directly related to the entity-type, so set createRelatedEntityTypeShapes flag to false. CreateEntityTypeShapeAndConnectorsInDiagram( cpc, diagram, entityType as ConceptualEntityType, entityTypeShapeFillColor, false); } } } }; CommandProcessor.InvokeSingleCommand(cpc, createEntityTypeShapecommand); }