示例#1
0
        private void VerifyFindDerivedType(IEnumerable <XElement> sourceCsdls, IEdmModel testModel)
        {
            Func <IEdmStructuredType, string> getFullName = (type) =>
            {
                return(type as IEdmComplexType != null ? ((IEdmComplexType)type).FullName() : type as IEdmEntityType != null ? ((IEdmEntityType)type).FullName() : null);
            };

            Func <IEdmStructuredType, string> getNamespace = (type) =>
            {
                return(type as IEdmComplexType != null ? ((IEdmComplexType)type).Namespace : type as IEdmEntityType != null ? ((IEdmEntityType)type).Namespace : null);
            };

            Action <IEdmStructuredType, string> checkFindAllDerivedFunction = (structuredType, structuralTypeElementName) =>
            {
                var expectedResults = EdmLibCsdlContentGenerator.GetDerivedTypes(sourceCsdls, structuralTypeElementName, getFullName(structuredType));
                var actualResults   = testModel.FindAllDerivedTypes(structuredType).Select(n => getFullName(n));
                Assert.IsTrue(expectedResults.Count() == actualResults.Count() && !expectedResults.Except(actualResults).Any(),
                              "FindAllDerivedTypes returns unexpected results.");
            };

            Action <IEdmStructuredType, string> checkFindDirectlyDerivedFunction = (structuredType, structuralTypeElementName) =>
            {
                var expectedResults = EdmLibCsdlContentGenerator.GetDirectlyDerivedTypes(sourceCsdls, structuralTypeElementName, getFullName(structuredType));
                var actualResults   = testModel.FindDirectlyDerivedTypes(structuredType).Select(n => getFullName(n));

                Assert.IsTrue(expectedResults.Count() == actualResults.Count() && !expectedResults.Except(actualResults).Any(),
                              "FindDirectlyDerivedTypes returns unexpected results.");
            };

            IEnumerable <EdmError> edmErrors;

            testModel.Validate(out edmErrors);

            var structuredTypes = testModel.SchemaElements.OfType <IEdmStructuredType>();

            foreach (var structuredType in structuredTypes)
            {
                if (edmErrors.Any(n => n.ErrorCode == EdmErrorCode.BadCyclicEntity && n.ErrorMessage.Contains(getFullName(structuredType))))
                {
                    Assert.IsTrue(0 == testModel.FindDirectlyDerivedTypes(structuredType).Count(), "FindDirectlyDerivedTypes returns unexpected results.");
                    Assert.IsTrue(0 == testModel.FindAllDerivedTypes(structuredType).Count(), "FindAllDerivedTypes returns unexpected results.");
                }
                else
                {
                    if (structuredType is IEdmEntityType)
                    {
                        checkFindDirectlyDerivedFunction(structuredType, "EntityType");
                        checkFindAllDerivedFunction(structuredType, "EntityType");
                    }
                    else if (structuredType is IEdmComplexType)
                    {
                        checkFindDirectlyDerivedFunction(structuredType, "ComplexType");
                        checkFindAllDerivedFunction(structuredType, "ComplexType");
                    }
                }
            }
        }
        public void FullTest()
        {
            IEdmModel model = NewModel();
            // Find a type (complex or entity or enum).
            var orderType = model.FindDeclaredType("Sample.NS.Order");

            TestContext.WriteLine("{0} type '{1}' found.", orderType.TypeKind, orderType.FullName());
            var addressType = model.FindDeclaredType("Sample.NS.Address");

            TestContext.WriteLine("{0} type '{1}' found.", addressType.TypeKind, addressType);
            // Find derived type of some type.
            var workAddressType = model.FindAllDerivedTypes((IEdmStructuredType)addressType).Single();

            TestContext.WriteLine("Type '{0}' is the derived from '{1}'.", ((IEdmSchemaType)workAddressType).Name, addressType.Name);
            // Find an operation.
            var rateAction = model.FindDeclaredOperations("Sample.NS.Rate").Single();

            TestContext.WriteLine("{0} '{1}' found.", rateAction.SchemaElementKind, rateAction.Name);
            // Find an operation import.
            var mostValuableFunctionImport = model.FindDeclaredOperationImports("MostValuable").Single();

            TestContext.WriteLine("{0} '{1}' found.", mostValuableFunctionImport.ContainerElementKind, mostValuableFunctionImport.Name);
            // Find an annotation and get its value.
            var customerSet        = model.FindDeclaredEntitySet("Customers");
            var maxCountAnnotation = model.FindDeclaredVocabularyAnnotations(customerSet).Single();
            var maxCountValue      = ((IEdmIntegerValue)maxCountAnnotation.Value).Value;

            TestContext.WriteLine("'{0}' = '{1}' on '{2}'", maxCountAnnotation.Term.Name, maxCountValue, ((IEdmEntitySet)maxCountAnnotation.Target).Name);
        }
        internal EntitySetInfo(IEdmModel edmModel, IEdmEntitySet edmEntitySet, ITypeResolver typeResolver)
        {
            Contract.Assert(edmModel != null);
            Contract.Assert(edmEntitySet != null);
            Contract.Assert(typeResolver != null);

            Name = edmEntitySet.Name;
            ElementType = new EntityTypeInfo(edmModel, edmEntitySet.ElementType, typeResolver);
            var entityTypes = new List<EntityTypeInfo>(3) { ElementType };

            // Create an EntityTypeInfo for any derived types in the model
            foreach (var edmDerivedType in edmModel.FindAllDerivedTypes(edmEntitySet.ElementType).OfType<IEdmEntityType>())
            {
                entityTypes.Add(new EntityTypeInfo(edmModel, edmDerivedType, typeResolver));
            }

            // Connect any derived types with their base class
            for (int i = 1; i < entityTypes.Count; ++i)
            {
                var baseEdmEntityType = entityTypes[i].EdmEntityType.BaseEntityType();
                if (baseEdmEntityType != null)
                {
                    var baseEntityTypeInfo = entityTypes.First(entityTypeInfo => entityTypeInfo.EdmEntityType == baseEdmEntityType);
                    if (baseEntityTypeInfo != null)
                    {
                        entityTypes[i].BaseTypeInfo = baseEntityTypeInfo;
                    }
                }
            }

            EntityTypes = entityTypes;
        }
示例#4
0
        public override string GetDerivedEntityTypeExactName(string collectionName, string entityTypeName)
        {
            IEdmEntityType entityType;

            if (TryGetEntitySet(collectionName, out var entitySet))
            {
                entityType = (_model.FindAllDerivedTypes(entitySet.EntityType())
                              .BestMatch(x => (x as IEdmEntityType).Name, entityTypeName, NameMatchResolver)) as IEdmEntityType;
                if (entityType != null)
                {
                    return(entityType.Name);
                }
            }
            else if (TryGetSingleton(collectionName, out var singleton))
            {
                entityType = (_model.FindDirectlyDerivedTypes(singleton.EntityType())
                              .BestMatch(x => (x as IEdmEntityType).Name, entityTypeName, NameMatchResolver)) as IEdmEntityType;
                if (entityType != null)
                {
                    return(entityType.Name);
                }
            }
            else if (TryGetEntityType(entityTypeName, out entityType))
            {
                return(entityType.Name);
            }

            throw new UnresolvableObjectException(entityTypeName, $"Entity type [{entityTypeName}] not found");
        }
示例#5
0
        public override string GetDerivedEntityTypeExactName(string collectionName, string entityTypeName)
        {
            IEdmEntitySet  entitySet;
            IEdmSingleton  singleton;
            IEdmEntityType entityType;

            if (TryGetEntitySet(collectionName, out entitySet))
            {
                entityType = (_model.FindAllDerivedTypes(entitySet.EntityType())
                              .BestMatch(x => (x as IEdmEntityType).Name, entityTypeName, _session.Pluralizer)) as IEdmEntityType;
                if (entityType != null)
                {
                    return(entityType.Name);
                }
            }
            else if (TryGetSingleton(collectionName, out singleton))
            {
                entityType = (_model.FindDirectlyDerivedTypes(singleton.EntityType())
                              .BestMatch(x => (x as IEdmEntityType).Name, entityTypeName, _session.Pluralizer)) as IEdmEntityType;
                if (entityType != null)
                {
                    return(entityType.Name);
                }
            }
            else if (TryGetEntityType(entityTypeName, out entityType))
            {
                return(entityType.Name);
            }

            throw new UnresolvableObjectException(entityTypeName, string.Format("Entity type [{0}] not found", entityTypeName));
        }
示例#6
0
        internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal <IEdmEntityType> visited, IEdmModel context)
        {
            if (visited.Add(source))
            {
                if (source.IsOrInheritsFrom(target))
                {
                    return(true);
                }

                foreach (IEdmNavigationProperty navProp in source.NavigationProperties())
                {
                    if (navProp.ContainsTarget && TypeIndirectlyContainsTarget(navProp.ToEntityType(), target, visited, context))
                    {
                        return(true);
                    }
                }

                foreach (IEdmStructuredType derived in context.FindAllDerivedTypes(source))
                {
                    IEdmEntityType derivedEntity = derived as IEdmEntityType;
                    if (derivedEntity != null && TypeIndirectlyContainsTarget(derivedEntity, target, visited, context))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
示例#7
0
        private static bool HasAutoExpandProperty(this IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty pathProperty, ISet <IEdmStructuredType> visited)
        {
            if (visited.Contains(structuredType))
            {
                return(false);
            }
            visited.Add(structuredType);

            List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>();

            structuredTypes.Add(structuredType);
            structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType));

            foreach (IEdmStructuredType edmStructuredType in structuredTypes)
            {
                // for top type, let's retrieve its properties and the properties from base type of top type if has.
                // for derived type, let's retrieve the declared properties.
                IEnumerable <IEdmProperty> properties = edmStructuredType == structuredType
                        ? edmStructuredType.Properties()
                        : edmStructuredType.DeclaredProperties;

                foreach (IEdmProperty property in properties)
                {
                    switch (property.PropertyKind)
                    {
                    case EdmPropertyKind.Structural:
                        IEdmStructuralProperty structuralProperty = (IEdmStructuralProperty)property;
                        IEdmTypeReference      typeRef            = property.Type.GetElementTypeOrSelf();
                        if (typeRef.IsComplex() && edmModel.CanExpand(typeRef.AsComplex().ComplexDefinition(), structuralProperty))
                        {
                            IEdmStructuredType subStrucutredType = typeRef.AsStructured().StructuredDefinition();
                            if (edmModel.HasAutoExpandProperty(subStrucutredType, structuralProperty, visited))
                            {
                                return(true);
                            }
                        }
                        break;

                    case EdmPropertyKind.Navigation:
                        IEdmNavigationProperty navigationProperty = (IEdmNavigationProperty)property;
                        if (IsAutoExpand(navigationProperty, pathProperty, edmStructuredType, edmModel))
                        {
                            return(true);    // find an auto-expand navigation property path
                        }
                        break;
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Find the given type in a structured type inheritance, include itself.
        /// </summary>
        /// <param name="structuralType">The starting structural type.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="typeName">The searching type name.</param>
        /// <returns>The found type.</returns>
        public static IEdmStructuredType FindTypeInInheritance(this IEdmStructuredType structuralType, IEdmModel model, string typeName)
        {
            IEdmStructuredType baseType = structuralType;

            while (baseType != null)
            {
                if (GetName(baseType) == typeName)
                {
                    return(baseType);
                }

                baseType = baseType.BaseType;
            }

            return(model.FindAllDerivedTypes(structuralType).FirstOrDefault(c => GetName(c) == typeName));
        }
示例#9
0
        /// <summary>
        /// Gets the auto select paths.
        /// </summary>
        /// <param name="edmModel">The Edm model.</param>
        /// <param name="structuredType">The Edm structured type.</param>
        /// <param name="pathProperty">The property from path, it can be null.</param>
        /// <param name="querySettings">The query settings.</param>
        /// <returns>The auto select paths.</returns>
        public static IList <SelectModelPath> GetAutoSelectPaths(this IEdmModel edmModel, IEdmStructuredType structuredType,
                                                                 IEdmProperty pathProperty, ModelBoundQuerySettings querySettings = null)
        {
            if (edmModel == null)
            {
                throw Error.ArgumentNull(nameof(edmModel));
            }

            if (structuredType == null)
            {
                throw Error.ArgumentNull(nameof(structuredType));
            }

            List <SelectModelPath> autoSelectProperties = new List <SelectModelPath>();

            List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>();

            structuredTypes.Add(structuredType);
            structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType));

            foreach (IEdmStructuredType edmStructuredType in structuredTypes)
            {
                // for top type, let's retrieve its properties and the properties from base type of top type if has.
                // for derived type, let's retrieve the declared properties.
                IEnumerable <IEdmStructuralProperty> properties = (edmStructuredType == structuredType) ?
                                                                  edmStructuredType.StructuralProperties() :
                                                                  properties = edmStructuredType.DeclaredStructuralProperties();

                foreach (IEdmStructuralProperty property in properties)
                {
                    if (IsAutoSelect(property, pathProperty, edmStructuredType, edmModel, querySettings))
                    {
                        if (edmStructuredType == structuredType)
                        {
                            autoSelectProperties.Add(new SelectModelPath(new[] { property }));
                        }
                        else
                        {
                            autoSelectProperties.Add(new SelectModelPath(new IEdmElement[] { edmStructuredType, property }));
                        }
                    }
                }
            }

            return(autoSelectProperties);
        }
示例#10
0
        /// <summary>
        /// Find the given type in a structured type inheritance, include itself.
        /// </summary>
        /// <param name="structuralType">The starting structural type.</param>
        /// <param name="model">The Edm model.</param>
        /// <param name="typeName">The searching type name.</param>
        /// <param name="caseInsensitive">If true, performs case insensitive search</param>
        /// <returns>The found type.</returns>
        public static IEdmStructuredType FindTypeInInheritance(this IEdmStructuredType structuralType, IEdmModel model, string typeName, bool caseInsensitive = false)
        {
            StringComparison   typeStringComparison = caseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
            IEdmStructuredType baseType             = structuralType;

            while (baseType != null)
            {
                if (GetName(baseType).Equals(typeName, typeStringComparison))
                {
                    return(baseType);
                }

                baseType = baseType.BaseType;
            }

            return(model.FindAllDerivedTypes(structuralType).FirstOrDefault(c => GetName(c).Equals(typeName, typeStringComparison)));
        }
示例#11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NavigationSourceLinkBuilderAnnotation"/> class.
        /// </summary>
        /// <param name="navigationSource">The navigation source for which the link builder is being constructed.</param>
        /// <param name="model">The EDM model that this navigation source belongs to.</param>
        /// <remarks>This constructor creates a link builder that generates URL's that follow OData conventions for the given navigation source.</remarks>
        public NavigationSourceLinkBuilderAnnotation(IEdmNavigationSource navigationSource, IEdmModel model)
        {
            if (navigationSource == null)
            {
                throw Error.ArgumentNull("navigationSource");
            }

            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            IEdmEntityType elementType = navigationSource.EntityType();
            IEnumerable <IEdmEntityType> derivedTypes = model.FindAllDerivedTypes(elementType).Cast <IEdmEntityType>();

            // Add navigation link builders for all navigation properties of entity.
            foreach (IEdmNavigationProperty navigationProperty in elementType.NavigationProperties())
            {
                Func <EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                    (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: false);
                AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
            }

            // Add navigation link builders for all navigation properties in derived types.
            bool derivedTypesDefineNavigationProperty = false;

            foreach (IEdmEntityType derivedEntityType in derivedTypes)
            {
                foreach (IEdmNavigationProperty navigationProperty in derivedEntityType.DeclaredNavigationProperties())
                {
                    derivedTypesDefineNavigationProperty = true;
                    Func <EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                        (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: true);
                    AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
                }
            }

            _navigationSourceName = navigationSource.Name;

            Func <EntityInstanceContext, Uri> selfLinkFactory =
                (entityInstanceContext) => entityInstanceContext.GenerateSelfLink(includeCast: derivedTypesDefineNavigationProperty);

            _idLinkBuilder = new SelfLinkBuilder <Uri>(selfLinkFactory, followsConventions: true);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EntitySetLinkBuilderAnnotation"/> class.
        /// </summary>
        /// <param name="entitySet">The entity set for which the link builder is being constructed.</param>
        /// <param name="model">The EDM model that this entity set belongs to.</param>
        /// <remarks>This constructor creates a link builder that generates URL's that follow OData conventions for the given entity set.</remarks>
        public EntitySetLinkBuilderAnnotation(IEdmEntitySet entitySet, IEdmModel model)
        {
            if (entitySet == null)
            {
                throw Error.ArgumentNull("entitySet");
            }
            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            IEdmEntityType elementType = entitySet.ElementType;
            IEnumerable <IEdmEntityType> derivedTypes = model.FindAllDerivedTypes(elementType).Cast <IEdmEntityType>();
            bool derivedTypesDefineNavigationProperty = false;

            // Add navigation link builders for all navigation properties of entity.
            foreach (IEdmNavigationProperty navigationProperty in elementType.NavigationProperties())
            {
                Func <EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                    (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: false);
                AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
            }

            // Add navigation link builders for all navigation properties in derived types.
            foreach (IEdmEntityType derivedEntityType in derivedTypes)
            {
                foreach (IEdmNavigationProperty navigationProperty in derivedEntityType.DeclaredNavigationProperties())
                {
                    derivedTypesDefineNavigationProperty = true;
                    Func <EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                        (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: true);
                    AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
                }
            }

            _entitySetName       = entitySet.Name;
            _feedSelfLinkBuilder = (feedContext) => feedContext.GenerateFeedSelfLink();

            Func <EntityInstanceContext, string> selfLinkFactory =
                (entityInstanceContext) => entityInstanceContext.GenerateSelfLink(includeCast: derivedTypesDefineNavigationProperty);

            _idLinkBuilder = new SelfLinkBuilder <string>(selfLinkFactory, followsConventions: true);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NavigationSourceLinkBuilderAnnotation"/> class.
        /// </summary>
        /// <param name="navigationSource">The navigation source for which the link builder is being constructed.</param>
        /// <param name="model">The EDM model that this navigation source belongs to.</param>
        /// <remarks>This constructor creates a link builder that generates URL's that follow OData conventions for the given navigation source.</remarks>
        public NavigationSourceLinkBuilderAnnotation(IEdmNavigationSource navigationSource, IEdmModel model)
        {
            if (navigationSource == null)
            {
                throw Error.ArgumentNull("navigationSource");
            }

            if (model == null)
            {
                throw Error.ArgumentNull("model");
            }

            IEdmEntityType elementType = navigationSource.EntityType();
            IEnumerable<IEdmEntityType> derivedTypes = model.FindAllDerivedTypes(elementType).Cast<IEdmEntityType>();

            // Add navigation link builders for all navigation properties of entity.
            foreach (IEdmNavigationProperty navigationProperty in elementType.NavigationProperties())
            {
                Func<EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                    (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: false);
                AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
            }

            // Add navigation link builders for all navigation properties in derived types.
            bool derivedTypesDefineNavigationProperty = false;
            foreach (IEdmEntityType derivedEntityType in derivedTypes)
            {
                foreach (IEdmNavigationProperty navigationProperty in derivedEntityType.DeclaredNavigationProperties())
                {
                    derivedTypesDefineNavigationProperty = true;
                    Func<EntityInstanceContext, IEdmNavigationProperty, Uri> navigationLinkFactory =
                    (entityInstanceContext, navProperty) => entityInstanceContext.GenerateNavigationPropertyLink(navProperty, includeCast: true);
                    AddNavigationPropertyLinkBuilder(navigationProperty, new NavigationLinkBuilder(navigationLinkFactory, followsConventions: true));
                }
            }

            _navigationSourceName = navigationSource.Name;
            _feedSelfLinkBuilder = (feedContext) => feedContext.GenerateFeedSelfLink();

            Func<EntityInstanceContext, string> selfLinkFactory =
                (entityInstanceContext) => entityInstanceContext.GenerateSelfLink(includeCast: derivedTypesDefineNavigationProperty);
            _idLinkBuilder = new SelfLinkBuilder<string>(selfLinkFactory, followsConventions: true);
        }
示例#14
0
        internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal <IEdmEntityType> visited, IEdmModel context)
        {
            bool flag;

            if (visited.Add(source))
            {
                if (!source.IsOrInheritsFrom(target))
                {
                    foreach (IEdmNavigationProperty edmNavigationProperty in source.NavigationProperties())
                    {
                        if (!edmNavigationProperty.ContainsTarget || !ValidationHelper.TypeIndirectlyContainsTarget(edmNavigationProperty.ToEntityType(), target, visited, context))
                        {
                            continue;
                        }
                        flag = true;
                        return(flag);
                    }
                    IEnumerator <IEdmStructuredType> enumerator = context.FindAllDerivedTypes(source).GetEnumerator();
                    using (enumerator)
                    {
                        while (enumerator.MoveNext())
                        {
                            IEdmStructuredType current       = enumerator.Current;
                            IEdmEntityType     edmEntityType = current as IEdmEntityType;
                            if (edmEntityType == null || !ValidationHelper.TypeIndirectlyContainsTarget(edmEntityType, target, visited, context))
                            {
                                continue;
                            }
                            flag = true;
                            return(flag);
                        }
                        return(false);
                    }
                    return(flag);
                }
                else
                {
                    return(true);
                }
            }
            return(false);
        }
示例#15
0
        public override string GetDerivedEntityTypeExactName(string collectionName, string entityTypeName)
        {
            IEdmEntitySet  entitySet;
            IEdmEntityType entityType;

            if (TryGetEntitySet(collectionName, out entitySet))
            {
                entityType = (_model.FindAllDerivedTypes(entitySet.ElementType)
                              .BestMatch(x => (x as IEdmEntityType).Name, entityTypeName, _session.Settings.NameMatchResolver) as IEdmEntityType);
                if (entityType != null)
                {
                    return(entityType.Name);
                }
            }
            else if (TryGetEntityType(entityTypeName, out entityType))
            {
                return(entityType.Name);
            }

            throw new UnresolvableObjectException(entityTypeName, string.Format("Entity type [{0}] not found", entityTypeName));
        }
示例#16
0
        /// <summary>
        /// Tests whether there are auto select properties.
        /// So far, we only test one depth for auto select, shall we go through the deeper depth?
        /// </summary>
        /// <param name="edmModel">The Edm model.</param>
        /// <param name="structuredType">The type from value or from path.</param>
        /// <param name="property">The property from path, it can be null.</param>
        /// <returns>true if the structured type has auto select properties; otherwise false.</returns>
        public static bool HasAutoSelectProperty(this IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty property)
        {
            if (edmModel == null)
            {
                throw Error.ArgumentNull(nameof(edmModel));
            }

            if (structuredType == null)
            {
                throw Error.ArgumentNull(nameof(structuredType));
            }

            List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>();

            structuredTypes.Add(structuredType);
            structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType));

            foreach (IEdmStructuredType edmStructuredType in structuredTypes)
            {
                // for top type, let's retrieve its properties and the properties from base type of top type if has.
                // for derived type, let's retrieve the declared properties.
                IEnumerable <IEdmStructuralProperty> properties = edmStructuredType == structuredType
                        ? edmStructuredType.StructuralProperties()
                        : edmStructuredType.DeclaredStructuralProperties();

                foreach (IEdmStructuralProperty subProperty in properties)
                {
                    if (IsAutoSelect(subProperty, property, edmStructuredType, edmModel))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Function to find the name of the type/class being used by identifier that is the last item in the path collection.
        /// This function can make recursive calls
        /// </summary>
        /// <param name="definition"><see cref="IEdmType"/> that has properties to be searched into</param>
        /// <param name="searchPath">List of string that shows the depth of the search into the definition from the odataPath type definition</param>
        /// <param name="searchingParent">Denotes whether we are searching for the property in parent classes</param>
        /// <returns>pair of Edm type name and whether type is found as navigation property</returns>
        public (IEdmType type, bool isNavigationProperty) SearchForEdmType(IEdmType definition, ICollection <string> searchPath, bool searchingParent = false)
        {
            // if the type is a collection, use the type of the element of the collection
            var elementDefinition = GetEdmElementType(definition);

            // we are at the root of the search so just return the definition of the root item
            if (searchPath.Count <= 1)
            {
                return(elementDefinition, false);
            }

            // Find all derived types. This is required in cases where the path refers to a parent class,
            // but the searched propery belongs to the child class.
            // Example: "post/attachments" path refers to attachments as "Attachment", but one can have a "FileAttachment"
            // in post. "ContentBytes", which exists only on the derived class, doesn't show up if looked in "Attachment".
            // We are also checking if we are searching parent classes at the moment for inherited properties. If that is the case,
            // we don't go to derived types, because that would cause searching for properties in sibling classes.
            // It can cause infinite loop if the property is not found, because we have a way of both going up and down in the
            // class hierarchy.
            IEnumerable <IEdmStructuredType> derivedTypes = null;

            if (!searchingParent && elementDefinition is IEdmStructuredType structuredTypeDefinition)
            {
                derivedTypes = Model?.FindAllDerivedTypes(structuredTypeDefinition);
            }

            // the second element in the path is the property we are searching for
            var searchIdentifier = searchPath.ElementAt(1);

            // Loop through the properties of the entity if is structured
            if (elementDefinition is IEdmStructuredType structuredType)
            {
                foreach (var property in structuredType.DeclaredProperties)
                {
                    if (property.Name.Equals(searchIdentifier, StringComparison.OrdinalIgnoreCase))
                    {
                        elementDefinition = GetEdmElementType(property.Type.Definition);

                        // check if we need to search deeper to search the properties of a nested item
                        if (searchPath.Count > 2)
                        {
                            // get rid of the root item and do a deeper search
                            var subList = searchPath.Where(x => !x.Equals(searchPath.First(), StringComparison.OrdinalIgnoreCase)).ToList();
                            return(SearchForEdmType(property.Type.Definition, subList));
                        }
                        else
                        {
                            return(elementDefinition, property.PropertyKind == EdmPropertyKind.Navigation);
                        }
                    }
                }

                // search in derived types
                if (derivedTypes is object)
                {
                    foreach (var derivedType in derivedTypes)
                    {
                        var(result, isNavigationProperty) = SearchForEdmType(derivedType, searchPath);
                        if (result != null)
                        {
                            return(result, isNavigationProperty);
                        }
                    }
                }

                // check properties of the base type as it may be inherited
                return(SearchForEdmType(structuredType.BaseType, searchPath, searchingParent: true));
            }

            // search failed so return null type
            return(null, false);
        }
示例#18
0
        internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal<IEdmEntityType> visited, IEdmModel context)
        {
            if (visited.Add(source))
            {
                if (source.IsOrInheritsFrom(target))
                {
                    return true;
                }

                foreach (IEdmNavigationProperty navProp in source.NavigationProperties())
                {
                    if (navProp.ContainsTarget && TypeIndirectlyContainsTarget(navProp.ToEntityType(), target, visited, context))
                    {
                        return true;
                    }
                }

                foreach (IEdmStructuredType derived in context.FindAllDerivedTypes(source))
                {
                    IEdmEntityType derivedEntity = derived as IEdmEntityType;
                    if (derivedEntity != null && TypeIndirectlyContainsTarget(derivedEntity, target, visited, context))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
 public static IEnumerable <IEdmStructuredType> DerivedTypes(this IEdmStructuredType structuralType, IEdmModel model)
 {
     return(model.FindAllDerivedTypes(structuralType));
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        public bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // use the cached
            Debug.Assert(context.Singleton != null);
            Debug.Assert(context.Action != null);
            ActionModel action = context.Action;

            string    singletonName = context.Singleton.Name;
            string    prefix        = context.Prefix;
            IEdmModel model         = context.Model;

            string actionMethodName = action.ActionMethod.Name;

            if (IsSupportedActionName(actionMethodName, singletonName))
            {
                ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton));
                action.AddSelector(context.Prefix, context.Model, template);

                // processed
                return(true);
            }

            // type cast
            // Get{SingletonName}From{EntityTypeName} or GetFrom{EntityTypeName}
            int index = actionMethodName.IndexOf("From", StringComparison.Ordinal);

            if (index == -1)
            {
                return(false);
            }

            string actionPrefix = actionMethodName.Substring(0, index);

            if (IsSupportedActionName(actionPrefix, singletonName))
            {
                IEdmEntityType entityType   = context.Singleton.EntityType();
                string         castTypeName = actionMethodName.Substring(index + 4);

                // Shall we cast to base type and the type itself? I think yes.
                IEdmEntityType baseType = entityType;
                while (baseType != null)
                {
                    if (baseType.Name == castTypeName)
                    {
                        ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton),
                                                                           new CastSegmentTemplate(baseType));
                        action.AddSelector(context.Prefix, context.Model, template);

                        return(true);
                    }

                    baseType = baseType.BaseEntityType();
                }

                // shall we cast to derived type
                IEdmEntityType castType = model.FindAllDerivedTypes(entityType).OfType <IEdmEntityType>().FirstOrDefault(c => c.Name == castTypeName);
                if (castType != null)
                {
                    ODataPathTemplate template = new ODataPathTemplate(new SingletonSegmentTemplate(context.Singleton),
                                                                       new CastSegmentTemplate(castType));
                    action.AddSelector(context.Prefix, context.Model, template);

                    return(true);
                }
            }

            return(false);
        }
示例#21
0
        private static void GetAutoExpandPaths(this IEdmModel edmModel, IEdmStructuredType structuredType, IEdmProperty pathProperty,
                                               Stack <IEdmElement> nodes, ISet <IEdmStructuredType> visited, IList <ExpandModelPath> results,
                                               bool isSelectPresent = false, ModelBoundQuerySettings querySettings = null)
        {
            if (visited.Contains(structuredType))
            {
                return;
            }
            visited.Add(structuredType);

            List <IEdmStructuredType> structuredTypes = new List <IEdmStructuredType>();

            structuredTypes.Add(structuredType);
            structuredTypes.AddRange(edmModel.FindAllDerivedTypes(structuredType));

            foreach (IEdmStructuredType edmStructuredType in structuredTypes)
            {
                IEnumerable <IEdmProperty> properties;

                if (edmStructuredType == structuredType)
                {
                    // for base type, let's retrieve its properties and the properties from base type of base type if have.
                    properties = edmStructuredType.Properties();
                }
                else
                {
                    // for derived type, let's retrieve the declared properties.
                    properties = edmStructuredType.DeclaredProperties;
                    nodes.Push(edmStructuredType); // add a type cast for derived type
                }

                foreach (IEdmProperty property in properties)
                {
                    switch (property.PropertyKind)
                    {
                    case EdmPropertyKind.Structural:
                        IEdmStructuralProperty structuralProperty = (IEdmStructuralProperty)property;
                        IEdmTypeReference      typeRef            = property.Type.GetElementTypeOrSelf();
                        if (typeRef.IsComplex() && edmModel.CanExpand(typeRef.AsComplex().ComplexDefinition(), structuralProperty))
                        {
                            IEdmStructuredType subStructuredType = typeRef.AsStructured().StructuredDefinition();

                            nodes.Push(structuralProperty);

                            edmModel.GetAutoExpandPaths(subStructuredType, structuralProperty, nodes, visited, results, isSelectPresent, querySettings);

                            nodes.Pop();
                        }
                        break;

                    case EdmPropertyKind.Navigation:
                        IEdmNavigationProperty navigationProperty = (IEdmNavigationProperty)property;
                        if (IsAutoExpand(navigationProperty, pathProperty, edmStructuredType, edmModel, isSelectPresent, querySettings))
                        {
                            nodes.Push(navigationProperty);
                            results.Add(new ExpandModelPath(nodes.Reverse()));     // found  an auto-expand navigation property path
                            nodes.Pop();
                        }
                        break;
                    }
                }

                if (edmStructuredType != structuredType)
                {
                    nodes.Pop(); // pop the type cast for derived type
                }
            }
        }
示例#22
0
		internal static bool TypeIndirectlyContainsTarget(IEdmEntityType source, IEdmEntityType target, HashSetInternal<IEdmEntityType> visited, IEdmModel context)
		{
			bool flag;
			if (visited.Add(source))
			{
				if (!source.IsOrInheritsFrom(target))
				{
					foreach (IEdmNavigationProperty edmNavigationProperty in source.NavigationProperties())
					{
						if (!edmNavigationProperty.ContainsTarget || !ValidationHelper.TypeIndirectlyContainsTarget(edmNavigationProperty.ToEntityType(), target, visited, context))
						{
							continue;
						}
						flag = true;
						return flag;
					}
					IEnumerator<IEdmStructuredType> enumerator = context.FindAllDerivedTypes(source).GetEnumerator();
					using (enumerator)
					{
						while (enumerator.MoveNext())
						{
							IEdmStructuredType current = enumerator.Current;
							IEdmEntityType edmEntityType = current as IEdmEntityType;
							if (edmEntityType == null || !ValidationHelper.TypeIndirectlyContainsTarget(edmEntityType, target, visited, context))
							{
								continue;
							}
							flag = true;
							return flag;
						}
						return false;
					}
					return flag;
				}
				else
				{
					return true;
				}
			}
			return false;
		}
        /// <summary>
        /// Create OData type cast paths.
        /// </summary>
        /// <param name="currentPath">The current OData path.</param>
        /// <param name="convertSettings">The settings for the current conversion.</param>
        /// <param name="structuredType">The type that is being inherited from to which this method will add downcast path segments.</param>
        /// <param name="annotable">The annotable navigation source to read cast annotations from.</param>
        /// <param name="targetsMany">Whether the annotable navigation source targets many entities.</param>
        private void CreateTypeCastPaths(ODataPath currentPath, OpenApiConvertSettings convertSettings, IEdmStructuredType structuredType, IEdmVocabularyAnnotatable annotable, bool targetsMany)
        {
            if (currentPath == null)
            {
                throw Error.ArgumentNull(nameof(currentPath));
            }
            if (convertSettings == null)
            {
                throw Error.ArgumentNull(nameof(convertSettings));
            }
            if (structuredType == null)
            {
                throw Error.ArgumentNull(nameof(structuredType));
            }
            if (annotable == null)
            {
                throw Error.ArgumentNull(nameof(annotable));
            }
            if (!convertSettings.EnableODataTypeCast)
            {
                return;
            }

            var annotedTypeNames = GetDerivedTypeConstaintTypeNames(annotable);

            if (!annotedTypeNames.Any() && convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments)
            {
                return;                                                                                                  // we don't want to generate any downcast path item if there is no type cast annotation.
            }
            var annotedTypeNamesSet = new HashSet <string>(annotedTypeNames, StringComparer.OrdinalIgnoreCase);

            bool filter(IEdmStructuredType x) =>
            convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments && annotedTypeNames.Contains(x.FullTypeName()) ||
            !convertSettings.RequireDerivedTypesConstraintForODataTypeCastSegments && (
                !annotedTypeNames.Any() ||
                annotedTypeNames.Contains(x.FullTypeName())
                );

            var targetTypes = _model
                              .FindAllDerivedTypes(structuredType)
                              .Where(x => (x.TypeKind == EdmTypeKind.Entity || x.TypeKind == EdmTypeKind.Complex) && filter(x))
                              .OfType <IEdmStructuredType>()
                              .ToArray();

            foreach (var targetType in targetTypes)
            {
                var castPath          = currentPath.Clone();
                var targetTypeSegment = new ODataTypeCastSegment(targetType);

                castPath.Push(targetTypeSegment);
                AppendPath(castPath);
                if (targetsMany)
                {
                    CreateCountPath(castPath, convertSettings);
                }
                else
                {
                    if (convertSettings.ExpandDerivedTypesNavigationProperties)
                    {
                        foreach (var declaredNavigationProperty in targetType.DeclaredNavigationProperties())
                        {
                            RetrieveNavigationPropertyPaths(declaredNavigationProperty, null, castPath, convertSettings);
                        }
                    }
                }
            }
        }