예제 #1
0
        internal static void ValidateInheritanceTree(EntityModel entityModel, ValidationContext context)
        {
            context.BeginValidationGlobalStage(ValidationGlobalStage.EntityModelInheritanceTree);

            try
            {
                // get types which are on top of hierarchy, means that these types are not referenced as interfaces implementation nor as base type
                // for any other types
                var topHierarchyTypes = entityModel.TopHierarchyTypes;

                var inheritanceTrees = new Dictionary <IInterface, InheritanceTree>();

                foreach (IInterface hierarchyType in topHierarchyTypes)
                {
                    InheritanceTree inheritanceTree = hierarchyType.GetInheritanceTree();
                    inheritanceTree.RebuildTree(true);

                    if (!inheritanceTrees.ContainsKey(hierarchyType))
                    {
                        inheritanceTrees.Add(hierarchyType, inheritanceTree);
                    }

                    var duplicatedDirectInheritances = inheritanceTree.FoundDuplicatedDirectInheritances();
                    foreach (var inheritanceDetail in duplicatedDirectInheritances)
                    {
                        string duplicatedItems = string.Join(";", inheritanceDetail.Items.Select(item => string.Format("{0}:{1}", item.Interface.Name,
                                                                                                                       item.Type == InheritanceType.Direct ? "D" : "I")));

                        string error =
                            string.Format(
                                "{0} '{1}' has direct inheritance to type '{2}', but {0} '{1}' is inherited(directly:D or indirectly:I) from other types ({3}) which already inheriting type '{2}'. Please remove direct inheritance '{2}' from type '{1}'",
                                hierarchyType.TypeKind, hierarchyType.Name, inheritanceDetail.Owner.Name, duplicatedItems);

                        var inheritanceLink = InterfaceInheritInterfaces.GetLink((Interface)hierarchyType, (Interface)inheritanceDetail.Owner);

                        context.LogError(error, CODE_DUPLICATED_DIRECT_INHERITANCE, new[] { inheritanceLink });
                    }
                }

                // continue only if revious check does not log any error
                if (!context.HasViolations())
                {
                    foreach (var hierarchyType in topHierarchyTypes)
                    {
                        InheritanceTree inheritanceTree = null;
                        if (inheritanceTrees.ContainsKey(hierarchyType))
                        {
                            inheritanceTree = inheritanceTrees[hierarchyType];
                        }

                        var duplicatedPropertiesInfo =
                            PersistentTypeValidation.FindDuplicatedPropertieInInheritanceTree(hierarchyType, inheritanceTree);

                        var  duplicatedProperties = duplicatedPropertiesInfo.PropertiesWithSameType;
                        bool logAsWarning         = hierarchyType.TypeKind == PersistentTypeKind.Interface;
                        IterateThroughDuplicatedProperties(hierarchyType, duplicatedProperties, false, logAsWarning, context);

                        duplicatedProperties = duplicatedPropertiesInfo.PropertiesWithDifferentType;
                        logAsWarning         = false;
                        IterateThroughDuplicatedProperties(hierarchyType, duplicatedProperties, true, logAsWarning, context);

                        if (duplicatedPropertiesInfo.InheritancePathsCount > 1)
                        {
                            context.LogWarning(
                                string.Format(
                                    "{0} '{1}' has multiple({2}) inheritance paths, this may cause an inconsistent property types and/or attributes generated",
                                    hierarchyType.TypeKind, hierarchyType.Name,
                                    duplicatedPropertiesInfo.InheritancePathsCount),
                                "MultipleInheritancePaths", new ModelElement[] { hierarchyType as Interface });
                        }

                        if (context.CountViolations(ViolationType.Error, ViolationType.Fatal) > 0)
                        {
                            PersistentTypeValidation.ValidateProperties((PersistentType)hierarchyType, inheritanceTree, context);
                        }
                    }
                }
            }
            finally
            {
                context.EndValidationGlobalStage(ValidationGlobalStage.EntityModelInheritanceTree);
            }
        }