internal static InheritanceTree Create(IInterface treeRoot) { List <InheritanceNode> treeRootChilds = new List <InheritanceNode>(); InheritanceTree inheritanceTree = new InheritanceTree(treeRoot, treeRootChilds); return(inheritanceTree); }
private void Build(IModelRoot modelRoot) { var inheritanceTrees = InheritanceTreeCache.Get(modelRoot.TopHierarchyTypes.ToArray()); foreach (var tree in inheritanceTrees) { if (!tree.TreeRebuilded) { tree.RebuildTree(true); } } var mergePaths = InheritanceTree.MergePaths(inheritanceTrees); var dependencyImplementationFlatList = InheritanceTree.GetDependencyImplementationFlatList(mergePaths); foreach (var @interface in dependencyImplementationFlatList) { IPropertiesBuilder propertiesBuilder = PropertiesBuilder.Build(@interface); lock (sync) { propertiesBuilders.Add(@interface, propertiesBuilder); } } // process rest types (e.g. with no inheritance defined) foreach (var @interface in modelRoot.PersistentTypes.Except(dependencyImplementationFlatList)) { IPropertiesBuilder propertiesBuilder = PropertiesBuilder.Build(@interface); lock (sync) { propertiesBuilders.Add(@interface, propertiesBuilder); } } }
internal InheritancePath(InheritanceTree treeNode, IEnumerable <InheritanceNode> nodes) { this.pathNodes = new List <InheritanceNode>(nodes) { treeNode }; this.id = Guid.NewGuid(); }
internal static void ValidateProperties <T>(T persistentType, InheritanceTree inheritanceTree, ValidationContext context) where T : PersistentType { if (persistentType is IInterface) { // validate 'IsInheritedProperty' properties, each property marked with this must have property with same name in its inheritance tree path IEnumerable <IPropertyBase> properties = persistentType.AllProperties.Where(property => property.IsInherited); if (properties.Count() > 0) { IInterface @interface = (IInterface)persistentType; if (inheritanceTree == null) { inheritanceTree = @interface.GetInheritanceTree(); inheritanceTree.RebuildTree(true); } foreach (var property in properties) { bool foundProperty = false; inheritanceTree.IterateTree(false, delegate(GenericTreeIterationArgs <InheritanceNode> args) { IInterface currentType = args.Current.Interface; foundProperty = currentType != persistentType && currentType.AllProperties.Any(item => Util.StringEqual(item.Name, property.Name, true) && item.PropertyKind == property.PropertyKind); args.Cancel = foundProperty; }); if (!foundProperty) { context.LogError( string.Format( ERROR_INVALID_IS_INHERITED_PROPERTY, persistentType.TypeKind, persistentType.Name, property.PropertyKind, property.Name), CODE_INVALID_IS_INHERITED_PROPERTY, new[] { property as ModelElement }); } } } } ValidateOrmAttributes(persistentType, context); }
private void Prepare() { thisInterface = persistentType as IInterface; if (thisInterface == null) { return; } //inheritanceTree = thisInterface.GetInheritanceTree(); inheritanceTree = InheritanceTreeCache.Get(thisInterface); if (!inheritanceTree.TreeRebuilded) { inheritanceTree.RebuildTree(); } allInheritanceTypes = inheritanceTree.GetFlatList(InheritanceListMode.WholeTree); PrepareTypeAttributes(); PrepareProperties(); PreparePropertiesTypeAttributes(); }
internal static DuplicatedPropertiesInfo FindDuplicatedPropertieInInheritanceTree(IInterface thisInterface, InheritanceTree inheritanceTree) { if (inheritanceTree == null) { inheritanceTree = thisInterface.GetInheritanceTree(); inheritanceTree.RebuildTree(true); } var inheritanceTreeList = inheritanceTree.GetFlatList(InheritanceListMode.WholeTree).Select(node => node.Interface); List <IPropertyBase> scalarPropertiesWithDifferentType = new List <IPropertyBase>(); List <IPropertyBase> scalarPropertiesWithSameType = new List <IPropertyBase>(); List <IPropertyBase> structurePropertiesWithDifferentType = new List <IPropertyBase>(); List <IPropertyBase> structurePropertiesWithSameType = new List <IPropertyBase>(); List <IPropertyBase> navigationPropertiesWithDifferentType = new List <IPropertyBase>(); List <IPropertyBase> navigationPropertiesWithSameType = new List <IPropertyBase>(); // iterate scalar properties foreach (var scalarProperty in thisInterface.GetScalarProperties()) { if (scalarProperty.IsInherited) { continue; } var query = from childInterface in inheritanceTreeList let childScalarProperties = childInterface.Properties.Where(item => item.PropertyKind == PropertyKind.Scalar).Cast <IScalarProperty>() where childScalarProperties.Any(childScalarProperty => Util.StringEqual(childScalarProperty.Name, scalarProperty.Name, true)) select new { PropertiesWithDifferentType = childScalarProperties .Where(childScalarProperty => !childScalarProperty.Type.EqualsTo(scalarProperty.Type)), PropertiesWithSameType = childScalarProperties .Where(childScalarProperty => childScalarProperty.Type.EqualsTo(scalarProperty.Type)) }; scalarPropertiesWithDifferentType.AddRange( query.SelectMany(arg => arg.PropertiesWithDifferentType).Cast <IPropertyBase>().ToList()); scalarPropertiesWithSameType.AddRange( query.SelectMany(arg => arg.PropertiesWithSameType).Cast <IPropertyBase>().ToList()); } // iterate structures properties foreach (var structureProperty in thisInterface.GetStructureProperties()) { if (structureProperty.IsInherited) { continue; } var query = from childInterface in inheritanceTreeList let childStructureProperties = childInterface.Properties.Where(item => item.PropertyKind == PropertyKind.Structure).Cast <IStructureProperty>() where childStructureProperties.Any(childStructureProperty => Util.StringEqual(childStructureProperty.Name, structureProperty.Name, true)) select new { PropertiesWithDifferentType = childStructureProperties .Where(childScalarProperty => childScalarProperty.TypeOf != structureProperty.TypeOf), PropertiesWithSameType = childStructureProperties .Where(childScalarProperty => childScalarProperty.TypeOf == structureProperty.TypeOf) }; structurePropertiesWithDifferentType.AddRange( query.SelectMany(arg => arg.PropertiesWithDifferentType).Cast <IPropertyBase>().ToList()); structurePropertiesWithSameType.AddRange( query.SelectMany(arg => arg.PropertiesWithSameType).Cast <IPropertyBase>().ToList()); } // iterate navigation properties foreach (var navigationProperty in thisInterface.NavigationProperties) { if (navigationProperty.IsInherited) { continue; } var query = from childInterface in inheritanceTreeList let childNavigationProperties = childInterface.NavigationProperties where childNavigationProperties.Any(childStructureProperty => Util.StringEqual(childStructureProperty.Name, navigationProperty.Name, true)) select new { PropertiesWithDifferentType = childNavigationProperties .Where(childScalarProperty => !childScalarProperty.PersistentTypeHasAssociations.EqualAssociationLinkTo(navigationProperty.PersistentTypeHasAssociations)), PropertiesWithSameType = childNavigationProperties .Where(childScalarProperty => childScalarProperty.PersistentTypeHasAssociations.EqualAssociationLinkTo(navigationProperty.PersistentTypeHasAssociations)) }; navigationPropertiesWithDifferentType.AddRange( query.SelectMany(arg => arg.PropertiesWithDifferentType).Cast <IPropertyBase>().ToList()); navigationPropertiesWithSameType.AddRange( query.SelectMany(arg => arg.PropertiesWithSameType).Cast <IPropertyBase>().ToList()); } var propertiesWithDifferentType = scalarPropertiesWithDifferentType.Concat(structurePropertiesWithDifferentType).Concat( navigationPropertiesWithDifferentType); var propertiesWithSameType = scalarPropertiesWithSameType.Concat(structurePropertiesWithSameType).Concat( navigationPropertiesWithSameType); int inheritancePathsCount = inheritanceTree.GetUniquePathsSuperRoots().Count(); DuplicatedPropertiesInfo info = new DuplicatedPropertiesInfo(propertiesWithDifferentType, propertiesWithSameType, inheritancePathsCount); return(info); }
public InheritanceTree GetInheritanceTree() { return(InheritanceTree.Create(this)); }
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); } }