/// Ensures that DSL Diagram and Entity Diagram are in sync.
        /// This method also update the xref link between DSL Diagram and Model Diagram.
        private void ApplyLayoutInformationFromModelDiagram()
        {
            var artifact = Context.GetEFArtifactService().Artifact as EntityDesignArtifact;

            Debug.Assert(artifact != null, "Could not get the instance of EntityDesignArtifact from EditingContext.");

            if (artifact != null &&
                artifact.IsDesignerSafe)
            {
                DesignerModel.Diagram modelDiagram = null;
                if (artifact.DesignerInfo != null &&
                    artifact.DesignerInfo.Diagrams != null)
                {
                    modelDiagram = String.IsNullOrEmpty(_diagramId)
                                       ? artifact.DesignerInfo.Diagrams.FirstDiagram
                                       : artifact.DesignerInfo.Diagrams.GetDiagram(_diagramId);
                }

                // At this point DSL diagram should have been set.
                var diagram = Diagram as EntityDesignerDiagram;
                Debug.Assert(diagram != null, "Why does the DSL diagram is null?");

                if (modelDiagram != null &&
                    diagram != null)
                {
                    EntityModelToDslModelTranslatorStrategy.TranslateDiagram(diagram, modelDiagram);
                    if (CurrentDesigner != null)
                    {
                        CurrentDesigner.ZoomAtViewCenter((float)modelDiagram.ZoomLevel.Value / 100);
                    }
                }
            }
        }
Exemple #2
0
        internal static void TranslateDiagram(EntityDesignerDiagram diagram, DesignerModel.Diagram modelDiagram)
        {
            var viewModel = diagram.ModelElement;

            viewModel.ModelXRef.Add(modelDiagram, diagram, viewModel.EditingContext);

            using (var t = diagram.Store.TransactionManager.BeginTransaction("Translate diagram", true))
            {
                // list of shapes that don't have corresponding element in model and require auto-layout
                var shapesToAutoLayout = new List <ViewModelDiagram.ShapeElement>();

                // try to find object in model for each shape on a diagram
                foreach (var shapeElement in diagram.NestedChildShapes)
                {
                    var entityShape = shapeElement as EntityTypeShape;
                    if (entityShape != null &&
                        entityShape.ModelElement != null)
                    {
                        var modelEntity = viewModel.ModelXRef.GetExisting(entityShape.ModelElement) as ModelEntityType;
                        if (modelEntity != null)
                        {
                            var modelEntityTypeShape =
                                modelDiagram.EntityTypeShapes.FirstOrDefault(ets => ets.EntityType.Target == modelEntity);
                            if (modelEntityTypeShape != null)
                            {
                                viewModel.ModelXRef.Add(modelEntityTypeShape, entityShape, viewModel.EditingContext);
                                var rectangle = new ViewModelDiagram.RectangleD(
                                    modelEntityTypeShape.PointX.Value, modelEntityTypeShape.PointY.Value
                                    , modelEntityTypeShape.Width.Value, 0.0);
                                entityShape.AbsoluteBounds = rectangle;
                                entityShape.IsExpanded     = modelEntityTypeShape.IsExpanded.Value;
                                entityShape.FillColor      = modelEntityTypeShape.FillColor.Value;
                            }
                        }
                        if (viewModel.ModelXRef.GetExisting(entityShape) == null)
                        {
                            shapesToAutoLayout.Add(entityShape);
                        }
                        continue;
                    }

                    var associationConnector = shapeElement as AssociationConnector;
                    if (associationConnector != null &&
                        associationConnector.ModelElement != null)
                    {
                        var modelAssociation = viewModel.ModelXRef.GetExisting(associationConnector.ModelElement) as ModelAssociation;
                        if (modelAssociation != null)
                        {
                            var modelAssociationConnector =
                                modelDiagram.AssociationConnectors.FirstOrDefault(ac => ac.Association.Target == modelAssociation);
                            if (modelAssociationConnector != null)
                            {
                                viewModel.ModelXRef.Add(modelAssociationConnector, associationConnector, viewModel.EditingContext);
                                TranslateAssociationConnectors(associationConnector, modelAssociationConnector, shapesToAutoLayout);
                            }
                        }
                        continue;
                    }

                    var inheritanceConnector = shapeElement as InheritanceConnector;
                    if (inheritanceConnector != null &&
                        inheritanceConnector.ModelElement != null)
                    {
                        var entityTypeBase = viewModel.ModelXRef.GetExisting(inheritanceConnector.ModelElement) as EntityTypeBaseType;
                        var modelEntity    = entityTypeBase.Parent as ModelEntityType;
                        if (modelEntity != null)
                        {
                            var modelInheritanceConnector =
                                modelDiagram.InheritanceConnectors.FirstOrDefault(ic => ic.EntityType.Target == modelEntity);
                            if (modelInheritanceConnector != null)
                            {
                                viewModel.ModelXRef.Add(modelInheritanceConnector, inheritanceConnector, viewModel.EditingContext);
                                TranslateInheritanceConnectors(inheritanceConnector, modelInheritanceConnector, shapesToAutoLayout);
                            }
                        }
                        continue;
                    }
                }

                diagram.AutoLayoutDiagram(shapesToAutoLayout);

                // initiate zoom level, grid and scalar property options
                diagram.ZoomLevel          = modelDiagram.ZoomLevel.Value;
                diagram.ShowGrid           = modelDiagram.ShowGrid.Value;
                diagram.SnapToGrid         = modelDiagram.SnapToGrid.Value;
                diagram.DisplayNameAndType = modelDiagram.DisplayType.Value;
                diagram.DiagramId          = modelDiagram.Id.Value;
                diagram.Title = modelDiagram.Name.Value;

                t.Commit();
            }
        }
Exemple #3
0
        private static void RetrieveModelElementsFromDiagram(
            DesignerModel.Diagram diagram,
            out IList <ModelEntityType> entityTypes,
            out IList <ModelAssociation> associations)
        {
            entityTypes  = new List <ModelEntityType>();
            associations = new List <ModelAssociation>();
            var elementsToDelete = new List <EFElement>();

            foreach (var entityTypeShape in diagram.EntityTypeShapes)
            {
                if (entityTypeShape.EntityType != null &&
                    entityTypeShape.EntityType.Status == BindingStatus.Known)
                {
                    if (entityTypes.Contains(entityTypeShape.EntityType.Target))
                    {
                        elementsToDelete.Add(entityTypeShape);
                    }
                    else
                    {
                        entityTypes.Add(entityTypeShape.EntityType.Target);
                    }
                }
            }

            foreach (var associationConnector in diagram.AssociationConnectors)
            {
                if (associationConnector.Association != null &&
                    associationConnector.Association.Status == BindingStatus.Known)
                {
                    if (associations.Contains(associationConnector.Association.Target))
                    {
                        elementsToDelete.Add(associationConnector);
                    }
                    else
                    {
                        associations.Add(associationConnector.Association.Target);
                    }
                }
            }

            if (elementsToDelete.Any())
            {
                Debug.Fail(
                    string.Format(
                        CultureInfo.CurrentCulture, "Found {0} duplicate items in diagram, which will be deleted as part of loading: {1}",
                        elementsToDelete.Count, string.Join(",", elementsToDelete.Select(e => e.DisplayName))));

                if (diagram.Artifact.CanEditArtifact())
                {
                    // Don't use an EfiTransaction here, since we just want to clean up the XML and avoid triggering diagram ui deletes
                    using (var tx = diagram.Artifact.XmlModelProvider.BeginTransaction("LoadDiagram", "Remove duplicate diagram elements"))
                    {
                        foreach (var element in elementsToDelete)
                        {
                            element.Delete();
                        }

                        tx.Commit();
                    }
                }
                else
                {
                    Debug.Fail(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            "Could not delete duplicate diagram items, proceeding with load and ignoring duplicates"));
                }
            }
        }
Exemple #4
0
        private static EntityDesignerDiagram TranslateDiagramValues(EntityDesignerViewModel viewModel, DesignerModel.Diagram modelDiagram)
        {
            var diagram = viewModel.GetDiagram();

            Debug.Assert(diagram != null, "Why diagram is null?");
            if (diagram != null)
            {
                if (viewModel.ModelXRef.ContainsKey(modelDiagram) == false)
                {
                    viewModel.ModelXRef.Add(modelDiagram, diagram, viewModel.EditingContext);
                }

                using (var t = diagram.Store.TransactionManager.BeginTransaction("Translate diagram values", true))
                {
                    // set zoom level, grid and scalar property options
                    diagram.ZoomLevel          = modelDiagram.ZoomLevel.Value;
                    diagram.ShowGrid           = modelDiagram.ShowGrid.Value;
                    diagram.SnapToGrid         = modelDiagram.SnapToGrid.Value;
                    diagram.DisplayNameAndType = modelDiagram.DisplayType.Value;
                    diagram.Title     = modelDiagram.Name.Value;
                    diagram.DiagramId = modelDiagram.Id.Value;
                    t.Commit();
                }
            }
            return(diagram);
        }
Exemple #5
0
        internal override DslModeling.ModelElement TranslateModelToDslModel(EFObject modelElement, DslModeling.Partition partition)
        {
            DesignerModel.Diagram diagram = null;

            if (modelElement != null)
            {
                diagram = modelElement as DesignerModel.Diagram;
                if (diagram == null)
                {
                    throw new ArgumentException("modelElement should be a diagram");
                }
            }

            // get the service so that we can access the root of the entity model
            var service = _editingContext.GetEFArtifactService();

            if (service == null)
            {
                throw new InvalidOperationException(EntityDesignerResources.Error_NoArtifactService);
            }

            EntityDesignerViewModel entityViewModel = null;

            var entityDesignArtifact = service.Artifact as EntityDesignArtifact;

            Debug.Assert(entityDesignArtifact != null, "Artifact is not type of EntityDesignArtifact");

            if (entityDesignArtifact != null)
            {
                // Only translate the Escher Model to Dsl Model if the artifact is designer safe.
                if (entityDesignArtifact.IsDesignerSafe)
                {
                    // now get the root of the model.
                    var model = entityDesignArtifact.ConceptualModel;
                    Debug.Assert(model != null, "Could not get ConceptualModel from the artifact.");

                    if (model != null)
                    {
                        entityViewModel =
                            ModelToDesignerModelXRef.GetNewOrExisting(_editingContext, model, partition) as EntityDesignerViewModel;
                        entityViewModel.Namespace = model.Namespace.Value;

                        // If the passed-in diagram is null, retrieve the first diagram if available.
                        if (diagram == null &&
                            entityDesignArtifact.DesignerInfo() != null &&
                            entityDesignArtifact.DesignerInfo().Diagrams != null &&
                            entityDesignArtifact.DesignerInfo().Diagrams.FirstDiagram != null)
                        {
                            diagram = entityDesignArtifact.DesignerInfo().Diagrams.FirstDiagram;
                        }

                        IList <ModelEntityType>  entities;
                        IList <ModelAssociation> associations;

                        if (diagram != null)
                        {
                            RetrieveModelElementsFromDiagram(diagram, out entities, out associations);
                        }
                        else
                        {
                            entities     = model.EntityTypes().ToList();
                            associations = model.Associations().ToList();
                        }
                        TranslateEntityModel(entities, associations, entityViewModel);
                    }
                }
                else
                {
                    // return empty view model if the artifact is not designer safe so the Diagram can show safe-mode watermark
                    entityViewModel = new EntityDesignerViewModel(partition);
                    entityViewModel.EditingContext = _editingContext;
                }
            }

            return(entityViewModel);
        }
Exemple #6
0
        /// <summary>
        ///     This method loads the DSL view model with the items in the artifact's C-Model.
        /// </summary>
        internal void ReloadModel(EntityDesignerViewModel viewModel)
        {
            var diagram = viewModel.GetDiagram();

            if (diagram == null)
            {
                // empty DSL diagram
                return;
            }

            // get our artifact
            var artifact = EditingContextManager.GetArtifact(viewModel.EditingContext) as EntityDesignArtifact;

            Debug.Assert(artifact != null);

            var serializationResult = new SerializationResult();

            var serializationContext = new SerializationContext(GetDirectory(viewModel.Store), artifact.Uri.LocalPath, serializationResult);
            var transactionContext   = new TransactionContext();

            transactionContext.Add(SerializationContext.TransactionContextKey, serializationContext);

            var workaroundFixSerializationTransactionValue = false;

            if (viewModel.Store.PropertyBag.ContainsKey("WorkaroundFixSerializationTransaction"))
            {
                workaroundFixSerializationTransactionValue = (bool)viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"];
            }

            try
            {
                // To fix performance issue during reload, we turn-off layout during "serialization".
                viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"] = true;

                using (var t = viewModel.Store.TransactionManager.BeginTransaction("ReloadModel", true, transactionContext))
                {
                    if (artifact.ConceptualModel() == null)
                    {
                        return;
                    }

                    DesignerModel.Diagram diagramModel = null;

                    // If DiagramId is not string empty, try to get the diagram from the artifact.
                    // There is a situation where we could not find the diagram given an ID (for example: EDMX Model's Diagram that is created by VS before SQL 11;
                    // In that case, we assign temporary ID to the diagram and a new ID will be generated every time the model is reloaded.)
                    // We could safely choose the first diagram since multiple diagrams feature didn't exist in VS prior to SQL11 release.
                    if (!string.IsNullOrEmpty(diagram.DiagramId))
                    {
                        diagramModel = artifact.DesignerInfo.Diagrams.GetDiagram(diagram.DiagramId);
                    }

                    if (diagramModel == null)
                    {
                        diagramModel = artifact.DesignerInfo.Diagrams.FirstDiagram;
                    }

                    if (diagramModel != null)
                    {
                        // Re-establish the xref between Escher conceptual model and DSL root model.
                        // and between Escher Diagram model and DSL diagram model.

                        Debug.Assert(viewModel.ModelXRef != null, "Why ModelXRef is null?");
                        if (viewModel.ModelXRef != null)
                        {
                            viewModel.ModelXRef.Add(artifact.ConceptualModel(), viewModel, viewModel.EditingContext);
                            viewModel.ModelXRef.Add(diagramModel, diagram, viewModel.EditingContext);
                            ModelTranslatorContextItem.GetEntityModelTranslator(viewModel.EditingContext)
                            .TranslateModelToDslModel(diagramModel, viewModel.Partition);
                        }
                    }

                    if (t.IsActive)
                    {
                        t.Commit();
                    }
                }
            }
            finally
            {
                viewModel.Store.PropertyBag["WorkaroundFixSerializationTransaction"] = workaroundFixSerializationTransactionValue;
            }
        }
Exemple #7
0
        private static void InjectInheritanceConnectorCommand(
            CommandProcessorContext commandProcessorContext, HashSet <ShapeChangeInformation> shapeChangeInfoSet,
            Diagram diagram, EntityTypeBaseType baseType, XObjectChange changeAction)
        {
            // First check to see if there is already a change in the original transaction
            // for the InheritanceConnector that matches the one that we're getting
            var shapeChangeInfoToQuery = new ShapeChangeInformation
            {
                ChangeType    = changeAction,
                ModelEFObject = baseType.OwnerEntityType,
                DiagramId     = diagram.Id.Value
            };

            var shapeChangeInfoExists = shapeChangeInfoSet.Contains(shapeChangeInfoToQuery);

            if (changeAction == XObjectChange.Add &&
                shapeChangeInfoExists == false)
            {
                var participatingEntityTypes = new List <EntityType>();

                var derivedEntityType = baseType.Parent as EntityType;
                Debug.Assert(derivedEntityType != null, "Where is the parent EntityType of this BaseType attribute?");

                if (derivedEntityType != null)
                {
                    // The inheritance connector is added if
                    // - the participating entities exists in the diagram.
                    // or
                    // - the participating entities will be added in the current transaction.
                    participatingEntityTypes.Add(derivedEntityType);
                    participatingEntityTypes.Add(((ConceptualEntityType)derivedEntityType).BaseType.Target);

                    foreach (var entityType in participatingEntityTypes)
                    {
                        if (diagram.EntityTypeShapes.Where(ets => ets.EntityType.Target == entityType).Any() ||
                            shapeChangeInfoSet.Where(
                                sc =>
                                sc.DiagramId == diagram.Id.Value && sc.ModelEFObject == entityType && sc.ChangeType == XObjectChange.Add)
                            .Any())
                        {
                            continue;
                        }
                        // If it reach this point, that means that we should not add inheritance connector in the diagram.
                        return;
                    }
                    var cmd = new CreateInheritanceConnectorCommand(diagram, derivedEntityType);
                    CommandProcessor.InvokeSingleCommand(commandProcessorContext, cmd);
                }
            }
            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
                var owningEntityType = baseType.Parent as EntityType;
                if (owningEntityType != null)
                {
                    foreach (
                        var inheritanceConnector in
                        owningEntityType.GetAntiDependenciesOfType <InheritanceConnector>()
                        .Where(ic => ic.Diagram != null && ic.Diagram.Id == diagram.Id.Value))
                    {
                        if (inheritanceConnector != null)
                        {
                            var deleteInheritanceConnectorCommand = inheritanceConnector.GetDeleteCommand();
                            CommandProcessor.InvokeSingleCommand(commandProcessorContext, deleteInheritanceConnectorCommand);
                        }
                    }
                }
            }
        }
Exemple #8
0
        private static void InjectAssociationConnectorCommand(
            CommandProcessorContext commandProcessorContext, HashSet <ShapeChangeInformation> shapeChangeInfoSet, Diagram diagram,
            Association association, XObjectChange changeAction)
        {
            // First check to see if there is already a change in the original transaction
            // for the AssociationConnector that matches the one that we're getting
            var shapeChangeInfoToQuery = new ShapeChangeInformation
            {
                ChangeType    = changeAction,
                ModelEFObject = association,
                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 &&
                shapeChangeInfoExists == false)
            {
                // The association connector is added if
                // - the participating entities are in the diagram.
                // or
                // - the participating entities will be added in the current transaction.
                foreach (var end in association.AssociationEnds())
                {
                    if (end.Type != null &&
                        end.Type.Target != null)
                    {
                        if (diagram.EntityTypeShapes.Where(ets => ets.EntityType.Target == end.Type.Target).Any() ||
                            shapeChangeInfoSet.Where(
                                sc =>
                                sc.DiagramId == diagram.Id.Value && sc.ModelEFObject == end.Type.Target &&
                                sc.ChangeType == XObjectChange.Add).Any())
                        {
                            continue;
                        }
                    }
                    // If it reach this point, that means that we should not add association connector in the diagram.
                    return;
                }
                var cmd = new CreateAssociationConnectorCommand(diagram, association);
                CommandProcessor.InvokeSingleCommand(commandProcessorContext, cmd);
            }
            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 associationConnector in
                    association.GetAntiDependenciesOfType <AssociationConnector>()
                    .Where(ac => ac.Diagram != null && ac.Diagram.Id == diagram.Id.Value))
                {
                    if (associationConnector != null)
                    {
                        var deleteAssociationConnectorCommand = associationConnector.GetDeleteCommand();
                        CommandProcessor.InvokeSingleCommand(commandProcessorContext, deleteAssociationConnectorCommand);
                    }
                }
            }
        }
Exemple #9
0
 internal void AddDiagram(Diagram diagram)
 {
     _diagrams.Add(diagram);
 }
Exemple #10
0
        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);
                    }
                }
            }
        }