internal void RecordModelChange(
     EfiChange.EfiChangeType changeType, EFObject changed,
     string property, object oldValue, object newValue)
 {
     switch (changeType)
     {
         case EfiChange.EfiChangeType.Create:
             _creates.Add(new EfiChange(changeType, changed));
             break;
         case EfiChange.EfiChangeType.Delete:
             _deletes.Add(new EfiChange(changeType, changed));
             break;
         case EfiChange.EfiChangeType.Update:
             EfiChange change = null;
             if (_updates.ContainsKey(changed))
             {
                 change = _updates[changed];
             }
             else
             {
                 change = new EfiChange(changeType, changed);
                 _updates[changed] = change;
             }
             change.RecordModelChange(property, oldValue, newValue);
             break;
     }
 }
Exemple #2
0
        internal void RecordModelChange(
            EfiChange.EfiChangeType changeType, EFObject changed,
            string property, object oldValue, object newValue)
        {
            switch (changeType)
            {
            case EfiChange.EfiChangeType.Create:
                _creates.Add(new EfiChange(changeType, changed));
                break;

            case EfiChange.EfiChangeType.Delete:
                _deletes.Add(new EfiChange(changeType, changed));
                break;

            case EfiChange.EfiChangeType.Update:
                EfiChange change = null;
                if (_updates.ContainsKey(changed))
                {
                    change = _updates[changed];
                }
                else
                {
                    change            = new EfiChange(changeType, changed);
                    _updates[changed] = change;
                }
                change.RecordModelChange(property, oldValue, newValue);
                break;
            }
        }
        internal static ModelNodeChangeType GetChangeTypeFromEfiChange(EfiChange c)
        {
            ModelNodeChangeType t;

            switch (c.Type)
            {
                case EfiChange.EfiChangeType.Create:
                    t = ModelNodeChangeType.Added;
                    break;
                case EfiChange.EfiChangeType.Delete:
                    t = ModelNodeChangeType.Deleted;
                    break;
                case EfiChange.EfiChangeType.Update:
                    t = ModelNodeChangeType.Changed;
                    break;
                default:
                    Debug.Fail("unexpected type of EfiChangeType");
                    throw new InvalidOperationException();
            }

            return t;
        }
 /// <summary>
 ///     Processes a Create or Delete change.
 /// </summary>
 /// <returns>
 ///     true if more model changes should be processed; otherwise, false;
 /// </returns>
 protected abstract bool ProcessCreateOrDeleteChange(EditingContext ctx, ModelToExplorerModelXRef xref, EfiChange change);
Exemple #5
0
 protected abstract int GetVal(EfiChange change);
Exemple #6
0
 public EfiChangeStableSortItem(EfiChange change, int position)
 {
     _change   = change;
     _position = position;
 }
        protected override bool ProcessCreateOrDeleteChange(EditingContext ctx, ModelToExplorerModelXRef xref, EfiChange change)
        {
            var artifact = change.Changed as EFArtifact;

            var conceptualModel = change.Changed as ConceptualEntityModel;
            var storageModel = change.Changed as StorageEntityModel;
            var mappingModel = change.Changed as MappingModel;
            if (null != artifact
                ||
                null != conceptualModel
                ||
                null != storageModel
                ||
                null != mappingModel)
            {
                // reset the search results - they will no longer be valid
                // once the view model is recalculated below
                var explorerSearchResults = ExplorerSearchResults.GetExplorerSearchResults(ctx);
                explorerSearchResults.Reset();

                // reload the UI - the ExplorerViewModelChanged will be fired
                // allowing the frame to rebind
                CreateViewModel(ctx);

                // don't process any more
                return false;
            }

            var efElement = change.Changed as EFElement;
            // ExplorerViewModelHelper only needs to process EFElement changes
            // (others are DefaultableValue and SingleItemBinding - but
            // ExplorerViewModel does not currently need to map these latter)
            if (null != efElement)
            {
                var parent = efElement.Parent as EFElement;
                Debug.Assert(
                    null != parent,
                    "received changed element of type " + change.Changed.GetType().FullName + " with non-EFElement parent of type "
                    + (efElement.Parent == null ? "NULL" : efElement.Parent.GetType().FullName));
                if (null != parent)
                {
                    // special case changing of an entity's key
                    // If we are creating/deleting a Key PropertyRef then we need
                    // to update the underlying ExplorerProperty
                    var propRef = efElement as PropertyRef;
                    var keyElement = efElement as Key;
                    if (propRef != null)
                    {
                        keyElement = propRef.GetParentOfType(typeof(Key)) as Key;
                        if (keyElement != null
                            && null != propRef.Name
                            && null != propRef.Name.Target)
                        {
                            ExplorerEFElement explorerProp =
                                xref.GetExisting(propRef.Name.Target) as ExplorerProperty;
                            if (null != explorerProp)
                            {
                                explorerProp.OnModelPropertyChanged(ExplorerEFElement.IsKeyPropertyID);
                            }
                        }
                    }
                    else if (keyElement != null)
                    {
                        // key must be a child of an entity
                        var et = parent as EntityType;
                        if (et != null)
                        {
                            // the key is being created or completely removed, so sync up every property
                            foreach (var prop in et.Properties())
                            {
                                ExplorerEFElement explorerProp = xref.GetExisting(prop) as ExplorerProperty;
                                if (null != explorerProp)
                                {
                                    explorerProp.OnModelPropertyChanged(ExplorerEFElement.IsKeyPropertyID);
                                }
                            }
                        }
                    }
                    else
                    {
                        // find Explorer node which maps to the model's parent
                        // this can be null is the ViewModel does not map the
                        // parent object
                        if (typeof(FunctionImport) == efElement.GetType())
                        {
                            // the FunctionImport Explorer Parent node has been decided to be the ConceptualEntityModel ExplorerEFElement
                            // rather than the ConceptualEntityContainer one which we would more naturally use to match the model setup
                            parent = parent.Parent as EFElement;
                        }
                        var explorerParentItem = xref.GetExisting(parent);
                        if (null != explorerParentItem)
                        {
                            // now find the Explorer node which should be the new/deleted ViewModel element's parent
                            // (may not be the same as above due to Explorer ghost nodes)
                            explorerParentItem = explorerParentItem.GetParentNodeForElement(efElement);

                            if (EfiChange.EfiChangeType.Create == change.Type)
                            {
                                // It's possible that between the Create of a parent and its child
                                // the Children property is called on the parent which loads the
                                // child into the parent, even though the child is being added with 
                                // change.Type = Create. For safety, we should remove the existing
                                // child (if it exists) so as to ensure any changes in the child change 
                                // are reflected.
                                var explorerEFElement = xref.GetExisting(efElement);
                                if (explorerEFElement != null)
                                {
                                    explorerParentItem.RemoveChildIfLoaded(efElement);
                                }
                                explorerParentItem.InsertChildIfLoaded(efElement);
                            }
                            else
                            {
                                explorerParentItem.RemoveChildIfLoaded(efElement);
                            }
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        ///     Updates corresponding view model item.
        ///     For simplicity each change updates all item values.
        /// </summary>
        private void OnEFObjectUpdated(EfiChange change, ModelToDesignerModelXRefItem xref)
        {
            Debug.Assert(change.Changed != null);
            var efObject = change.Changed;

            // Updating a base type is a special case, because it really means creating or deleting an inheritance connector
            var baseType = efObject as EntityTypeBaseType;
            if (baseType != null)
            {
                if (xref.ContainsKey(baseType.Parent))
                {
                    // always recreate inheritance
                    OnEFObjectDeleted(baseType, xref);
                    if (xref.ContainsKey(baseType.Parent))
                    {
                        ModelTranslatorContextItem.GetEntityModelTranslator(EditingContext).SynchronizeSingleDslModelElement(this, efObject);
                    }
                }
                return;
            }

            // for AssociationEnd we want to update parent Association
            var associationEnd = efObject as AssociationEnd;
            if (associationEnd != null)
            {
                efObject = associationEnd.Parent;
            }

            // regardless the change always update whole element (it shouldn't be too big overhead)
            OnEFObjectCreatedOrUpdated(efObject, xref);
        }
            protected override int GetVal(EfiChange change)
            {
                // we always order deletes before creates before updates.
                if (change.Type == EfiChange.EfiChangeType.Update)
                {
                    return 100;
                }
                else if (change.Type == EfiChange.EfiChangeType.Delete)
                {
                    return -1;
                }
                else
                {
                    Debug.Assert(change.Type == EfiChange.EfiChangeType.Create);

                    var entityType = change.Changed as Model.Entity.EntityType;
                    if (entityType != null)
                    {
                        return 1;
                    }

                    var association = change.Changed as Model.Entity.Association;
                    if (association != null)
                    {
                        return 2;
                    }

                    var prop = change.Changed as Model.Entity.Property;
                    if (prop != null)
                    {
                        return 3;
                    }

                    var propertyRef = change.Changed as PropertyRef;
                    if (propertyRef != null)
                    {
                        return 4;
                    }

                    var key = change.Changed as Key;
                    if (key != null)
                    {
                        return 5;
                    }

                    var ets = change.Changed as ModelDesigner.EntityTypeShape;
                    if (ets != null)
                    {
                        return 6;
                    }

                    var ac = change.Changed as ModelDesigner.AssociationConnector;
                    if (ac != null)
                    {
                        return 7;
                    }

                    var ic = change.Changed as ModelDesigner.InheritanceConnector;
                    if (ic != null)
                    {
                        return 8;
                    }

                    return 9;
                }
            }
        /// <summary>
        ///     Project the Diagram Model changes to DSL Model Elements.
        ///     Note that this is only to ensure that DSL Model Elements are in sync with the diagram model.
        /// </summary>
        private void ProcessSingleDiagramModelChange(EfiChange change, HashSet<EFObject> extraElementsToProcess)
        {
            var diagramObject = change.Changed as ModelDiagram.BaseDiagramObject;
            var xref = ModelXRef;

            // Ignore if the change is not model diagram object or diagram object does not below to this view model diagram.
            if (diagramObject == null
                || diagramObject.Diagram == null
                || diagramObject.Diagram.Id != DiagramId)
            {
                return;
            }

            if (change.Type == EfiChange.EfiChangeType.Create)
            {
                EFObject efObject = null;

                var entityTypeShape = change.Changed as ModelDesigner.EntityTypeShape;
                var inheritanceConnector = change.Changed as ModelDesigner.InheritanceConnector;
                var associationConnector = change.Changed as ModelDesigner.AssociationConnector;

                if (entityTypeShape != null)
                {
                    // There is a code above that will Debug.Fail if the object in extraElementsToProcess is not ConceptualEntityType
                    Model.Entity.EntityType et = entityTypeShape.EntityType.Target as ConceptualEntityType;
                    if (et != null)
                    {
                        extraElementsToProcess.Add(et);
                        efObject = et;
                    }
                }
                else if (inheritanceConnector != null)
                {
                    var et = inheritanceConnector.EntityType.Target as ConceptualEntityType;
                    if (et != null)
                    {
                        efObject = et.BaseType;
                    }
                }
                else if (associationConnector != null)
                {
                    efObject = associationConnector.Association.Target;
                }

                if (efObject != null)
                {
                    OnEFObjectCreatedOrUpdated(efObject, xref);
                }
            }
            else if (change.Type == EfiChange.EfiChangeType.Delete)
            {
                var entityTypeShape = change.Changed as ModelDesigner.EntityTypeShape;
                var inheritanceConnector = change.Changed as ModelDesigner.InheritanceConnector;
                var associationConnector = change.Changed as ModelDesigner.AssociationConnector;

                EFObject efObject = null;
                if (entityTypeShape != null)
                {
                    efObject = entityTypeShape.EntityType.Target;
                }
                else if (inheritanceConnector != null)
                {
                    var et = inheritanceConnector.EntityType.Target as ConceptualEntityType;
                    if (et != null)
                    {
                        efObject = et.BaseType;
                    }
                }
                else if (associationConnector != null)
                {
                    efObject = associationConnector.Association.Target;
                }

                if (efObject != null)
                {
                    OnEFObjectDeleted(efObject, xref);
                }
            }
        }
        private bool ProcessSingleModelChange(EfiChange change)
        {
            var xref = ModelXRef;

            if ((change.Type == EfiChange.EfiChangeType.Create ||
                 change.Type == EfiChange.EfiChangeType.Delete)
                && (change.Changed is EFArtifact ||
                 change.Changed is ConceptualEntityModel))
            {
                // the artifact or model has changed on us, reload the whole thing
                ClearAndReloadDiagram();
                return true;
            }
            else
            {
                try
                {
                    switch (change.Type)
                    {
                        case EfiChange.EfiChangeType.Update:
                            OnEFObjectUpdated(change, xref);
                            break;

                        case EfiChange.EfiChangeType.Create:
                            // Adding association, entity-type or inheritance is no longer translate to the addition of the corresponding DSL model elements.
                            // We only add the DSL model elements if Escher model diagrams are added (InheritanceConnector etc.)
                            if (!(change.Changed is Model.Entity.Association
                                  || change.Changed is ConceptualEntityType
                                  || change.Changed is EntityTypeBaseType))
                            {
                                OnEFObjectUpdated(change, xref);
                            }
                            break;

                        case EfiChange.EfiChangeType.Delete:
                            OnEFObjectDeleted(change.Changed, xref);
                            break;

                        default:
                            Debug.Assert(false, "Unknown change type.");
                            break;
                    }

                    // If Entity-type's base type has changed, invalidate the shape so the base type name in the shape can be updated.
                    var baseType = change.Changed as EntityTypeBaseType;
                    if (baseType != null)
                    {
                        Debug.Assert(baseType.Parent != null, "EntityTypeBaseType's Parent should not be null.");
                        if (baseType.Parent != null)
                        {
                            var entityType = ModelXRef.GetExisting(baseType.Parent) as EntityType;
                            // the entity type is null if it is not in the diagram.
                            if (entityType != null)
                            {
                                var ets = PresentationViewsSubject.GetPresentation(entityType).FirstOrDefault() as EntityTypeShape;
                                Debug.Assert(ets != null, "The shape for entity-type : " + entityType.Name + " is not available.");
                                if (ets != null)
                                {
                                    ets.Invalidate();
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.Fail("Exception caught while processing changes to the designer", e.Message);
                    ClearAndReloadDiagram();
                    return true;
                }
            }

            return false;
        }