예제 #1
0
        public override void ElementAdded(ElementAddedEventArgs e)
        {
            base.ElementAdded(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (element.IsInCircularInheritance())
            {
                ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause a circular reference.");
                current.Rollback();

                return;
            }

            List <string> superclassPropertyNames = element.Superclass.AllPropertyNames.ToList();

            List <string> nameClashes = element.Subclass
                                        .Attributes
                                        .Where(a => superclassPropertyNames.Contains(a.Name))
                                        .Select(a => a.Name)
                                        .Union(element.Subclass
                                               .LocalNavigationProperties()
                                               .Where(p => p.PropertyName != null && superclassPropertyNames.Contains(p.PropertyName))
                                               .Select(p => p.PropertyName))
                                        .ToList();

            // remove attributes in subclass that are present in superclass IF they are completely identical (except for ModelClass, of course)
            for (int i = 0; i < nameClashes.Count; i++)
            {
                ModelAttribute subclassAttribute   = element.Subclass.Attributes.First(a => a.Name == nameClashes[i]);
                ModelAttribute superclassAttribute = element.Superclass.AllAttributes.First(a => a.Name == nameClashes[i]);
                List <(string propertyName, object thisValue, object otherValue)> differences = superclassAttribute.GetDifferences(subclassAttribute);

                // ignore these differences if found
                differences.RemoveAll(x => x.propertyName == "ModelClass" ||
                                      x.propertyName == "Summary" ||
                                      x.propertyName == "Description");

                if (!differences.Any())
                {
                    element.Subclass.Attributes.Remove(element.Subclass.Attributes.Single(a => a.Name == nameClashes[i]));
                    nameClashes.RemoveAt(i--);
                }
            }

            // if any remain with the same name, it's an error
            if (nameClashes.Any())
            {
                string nameClashList = string.Join("\n   ", nameClashes);
                ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause name clashes. Resolve the following before setting the inheritance:\n   {nameClashList}");
                current.Rollback();
            }
        }
        /// <inheritdoc />
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing)
            {
                return;
            }

            if (element.Superclass.IsDeleting)
            {
                return;
            }

            ModelClass         superclass   = element.Superclass;
            ModelClass         subclass     = element.Subclass;
            List <Association> associations = store.ElementDirectory.AllElements.OfType <Association>().Where(a => a.Source == superclass || a.Target == superclass).ToList();

            if (!superclass.AllAttributes.Any() && !associations.Any())
            {
                return;
            }

            if (!subclass.IsDeleting && QuestionDisplay.Show($"Push {superclass.Name} attributes and associations down to {subclass.Name}?") == true)
            {
                superclass.PushDown(subclass);
            }
        }
예제 #3
0
        public override string GetToolTipText(DiagramItem item)
        {
            Generalization generalization = item.Shape.ModelElement as Generalization;

            return(generalization != null
                   ? $"{generalization.Subclass.Name} inherits from {generalization.Superclass.Name}"
                   : string.Empty);
        }
예제 #4
0
        public override void ElementAdded(ElementAddedEventArgs e)
        {
            base.ElementAdded(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing)
            {
                return;
            }

            if (element.IsInCircularInheritance())
            {
                ErrorDisplay.Show($"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause a circular reference.");
                current.Rollback();

                return;
            }

            List <string> superclassPropertyNames = element.Superclass
                                                    .AllAttributes
                                                    .Select(a => a.Name)
                                                    .Union(element.Superclass
                                                           .AllNavigationProperties()
                                                           .Where(x => x.PropertyName != null)
                                                           .Select(a => a.PropertyName))
                                                    .ToList();

            List <string> nameClashes = element.Subclass
                                        .Attributes
                                        .Where(a => superclassPropertyNames.Contains(a.Name))
                                        .Select(a => a.Name)
                                        .Union(element.Subclass
                                               .LocalNavigationProperties()
                                               .Where(p => p.PropertyName != null && superclassPropertyNames.Contains(p.PropertyName))
                                               .Select(p => p.PropertyName))
                                        .ToList();

            // since we created the Id property, we'll remove it. Any other clashes are up to the user to resolve.
            if (nameClashes.Contains("Id") &&
                element.Subclass.Attributes.FirstOrDefault(a => a.Name == "Id")?.IsIdentity == true &&
                element.Superclass.AllAttributes.FirstOrDefault(a => a.Name == "Id")?.IsIdentity == true)
            {
                element.Subclass.Attributes.Remove(element.Subclass.Attributes.Single(a => a.Name == "Id"));
                nameClashes.Remove("Id");
            }

            if (nameClashes.Any())
            {
                string nameClashList = string.Join("\n   ", nameClashes);
                ErrorDisplay.Show($"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause name clashes. Resolve the following before setting the inheritance:\n   {nameClashList}");
                current.Rollback();
            }
        }
        public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
        {
            base.ElementPropertyChanged(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing)
            {
                return;
            }

            switch (e.DomainProperty.Name)
            {
            case "Superclass":
            case "Subclass":
                if (!element.IsInCircularInheritance())
                {
                    current.Rollback();
                    MessageBox.Show("That inheritance link would cause a circular reference.");
                    return;
                }

                if (element.Superclass != null)
                {
                    List <string> superclassPropertyNames = element.Superclass
                                                            .AllAttributes
                                                            .Select(a => a.Name)
                                                            .Union(element.Superclass
                                                                   .AllNavigationProperties()
                                                                   .Select(a => a.PropertyName))
                                                            .ToList();

                    List <string> nameClashes = element.Subclass
                                                .Attributes
                                                .Where(a => superclassPropertyNames.Contains(a.Name))
                                                .Select(a => a.Name)
                                                .Union(element.Subclass
                                                       .LocalNavigationProperties()
                                                       .Where(p => p.PropertyName != null && superclassPropertyNames.Contains(p.PropertyName))
                                                       .Select(p => p.PropertyName))
                                                .ToList();

                    // the Add rule removes the subclass Id property if it's causing a name class, but we won't do that in the change rule

                    if (nameClashes.Any())
                    {
                        current.Rollback();
                        string nameClashList = string.Join(", ", nameClashes);
                        MessageBox.Show("That inheritance link would cause name clashes. Resolve the following before setting the inheritance: " + nameClashList);
                    }
                }
                break;
            }
        }
예제 #6
0
        /// <inheritdoc />
        public override void ElementDeleting(ElementDeletingEventArgs e)
        {
            base.ElementDeleting(e);

            Generalization element = (Generalization)e.ModelElement;
            Store          store   = element.Store;
            Transaction    current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (element.Superclass.IsDeleting)
            {
                return;
            }

            ModelClass subclass   = element.Subclass;
            ModelClass superclass = element.Superclass;

            List <Association> associations = superclass.AllNavigationProperties()
                                              .Select(n => n.AssociationObject)
                                              .Distinct()
                                              .ToList();

            if (!superclass.AllAttributes.Any() && !associations.Any())
            {
                return;
            }

            if (!subclass.IsDeleting && BooleanQuestionDisplay.Show(store, $"Push {superclass.Name} attributes and associations down to {subclass.Name}?") == true)
            {
                superclass.PushDown(subclass);
            }
        }
예제 #7
0
        public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
        {
            base.ElementPropertyChanged(e);

            Generalization element = (Generalization)e.ModelElement;

            if (element.IsDeleted)
            {
                return;
            }

            Store       store   = element.Store;
            Transaction current = store.TransactionManager.CurrentTransaction;

            if (current.IsSerializing || ModelRoot.BatchUpdating)
            {
                return;
            }

            if (Equals(e.NewValue, e.OldValue))
            {
                return;
            }

            switch (e.DomainProperty.Name)
            {
            case "Superclass":
            case "Subclass":

                if (element.Subclass.IsPropertyBag && !element.Superclass.IsPropertyBag)
                {
                    ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: Since {element.Subclass.Name} is a property bag, it can't inherit from {element.Superclass.Name}, which is not a property bag.");
                    current.Rollback();

                    return;
                }

                if (!element.IsInCircularInheritance())
                {
                    ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause a circular reference.");
                    current.Rollback();

                    return;
                }

                if (element.Superclass != null)
                {
                    List <string> superclassPropertyNames = element.Superclass
                                                            .AllAttributes
                                                            .Select(a => a.Name)
                                                            .Union(element.Superclass
                                                                   .AllNavigationProperties()
                                                                   .Select(a => a.PropertyName))
                                                            .ToList();

                    List <string> nameClashes = element.Subclass
                                                .Attributes
                                                .Where(a => superclassPropertyNames.Contains(a.Name))
                                                .Select(a => a.Name)
                                                .Union(element.Subclass
                                                       .LocalNavigationProperties()
                                                       .Where(p => p.PropertyName != null && superclassPropertyNames.Contains(p.PropertyName))
                                                       .Select(p => p.PropertyName))
                                                .ToList();

                    // the Add rule removes the subclass Id property if it's causing a name class, but we won't do that in the change rule

                    if (nameClashes.Any())
                    {
                        string nameClashList = string.Join("\n   ", nameClashes);
                        ErrorDisplay.Show(store, $"{element.Subclass.Name} -> {element.Superclass.Name}: That inheritance link would cause name clashes. Resolve the following before setting the inheritance:\n   " + nameClashList);
                        current.Rollback();
                    }
                }

                break;
            }
        }