Пример #1
0
        private static void AddNavigationBindings(EdmTypeMap edmMap,
                                                  NavigationSourceConfiguration navigationSourceConfiguration,
                                                  EdmNavigationSource navigationSource,
                                                  NavigationSourceLinkBuilderAnnotation linkBuilder,
                                                  Dictionary <string, EdmNavigationSource> edmNavigationSourceMap)
        {
            foreach (var binding in navigationSourceConfiguration.Bindings)
            {
                NavigationPropertyConfiguration navigationProperty = binding.NavigationProperty;
                bool isContained = navigationProperty.ContainsTarget;

                IEdmType               edmType               = edmMap.EdmTypes[navigationProperty.DeclaringType.ClrType];
                IEdmStructuredType     structuraType         = edmType as IEdmStructuredType;
                IEdmNavigationProperty edmNavigationProperty = structuraType.NavigationProperties()
                                                               .Single(np => np.Name == navigationProperty.Name);

                string bindingPath = ConvertBindingPath(edmMap, binding);
                if (!isContained)
                {
                    // calculate the binding path
                    navigationSource.AddNavigationTarget(
                        edmNavigationProperty,
                        edmNavigationSourceMap[binding.TargetNavigationSource.Name],
                        new EdmPathExpression(bindingPath));
                }

                NavigationLinkBuilder linkBuilderFunc = navigationSourceConfiguration.GetNavigationPropertyLink(navigationProperty);
                if (linkBuilderFunc != null)
                {
                    linkBuilder.AddNavigationPropertyLinkBuilder(edmNavigationProperty, linkBuilderFunc);
                }
            }
        }
        /// <summary>
        /// Create a map of string/<see cref="OpenApiSchema"/> map for a <see cref="IEdmStructuredType"/>'s all properties.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="structuredType">The Edm structured type.</param>
        /// <returns>The created map of <see cref="OpenApiSchema"/>.</returns>
        public static IDictionary <string, OpenApiSchema> CreateStructuredTypeCombinedPropertiesSchema(this ODataContext context, IEdmStructuredType structuredType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(structuredType, nameof(structuredType));

            // The name is the property name, the value is a Schema Object describing the allowed values of the property.
            IDictionary <string, OpenApiSchema> properties = new Dictionary <string, OpenApiSchema>();

            // structure properties
            foreach (var property in structuredType.StructuralProperties())
            {
                // OpenApiSchema propertySchema = property.Type.CreateSchema();
                // propertySchema.Default = property.DefaultValueString != null ? new OpenApiString(property.DefaultValueString) : null;
                if (property.Type.FullName() != structuredType.FullTypeName() &&
                    property.Type.FullName() != $"Collection({structuredType.FullTypeName()})")
                {
                    properties.Add(property.Name, context.CreatePropertySchema(property));
                }
            }

            // navigation properties
            foreach (var property in structuredType.NavigationProperties())
            {
                if (property.Type.FullName() != structuredType.FullTypeName() &&
                    property.Type.FullName() != $"Collection({structuredType.FullTypeName()})")
                {
                    OpenApiSchema propertySchema = context.CreateEdmTypeSchema(property.Type);
                    properties.Add(property.Name, propertySchema);
                }
            }

            return(properties);
        }
        public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmStructuredType structuredType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(structuredType, nameof(structuredType));

            NavigationRestrictionsType navigation = context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);

            if (navigation != null && !navigation.IsNavigable)
            {
                return(null);
            }

            IList <IOpenApiAny> selectItems = new List <IOpenApiAny>();

            foreach (var property in structuredType.StructuralProperties())
            {
                selectItems.Add(new OpenApiString(property.Name));
            }

            foreach (var property in structuredType.NavigationProperties())
            {
                if (navigation != null && navigation.IsRestrictedProperty(property.Name))
                {
                    continue;
                }

                selectItems.Add(new OpenApiString(property.Name));
            }

            return(new OpenApiParameter
            {
                Name = "$select",
                In = ParameterLocation.Query,
                Description = "Select properties to be returned",
                Schema = new OpenApiSchema
                {
                    Type = "array",
                    UniqueItems = true,
                    Items = new OpenApiSchema
                    {
                        Type = "string",
                        Enum = selectItems
                    }
                },
                Style = ParameterStyle.Form,
                Explode = false
            });
        }
        public static OpenApiParameter CreateExpand(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmStructuredType structuredType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(target, nameof(target));
            Utils.CheckArgumentNull(structuredType, nameof(structuredType));

            ExpandRestrictionsType expand = context.Model.GetRecord <ExpandRestrictionsType>(target, CapabilitiesConstants.ExpandRestrictions);

            if (expand != null && !expand.IsExpandable)
            {
                return(null);
            }

            IList <IOpenApiAny> expandItems = new List <IOpenApiAny>
            {
                new OpenApiString("*")
            };

            foreach (var property in structuredType.NavigationProperties())
            {
                if (expand != null && expand.IsNonExpandableProperty(property.Name))
                {
                    continue;
                }

                expandItems.Add(new OpenApiString(property.Name));
            }

            return(new OpenApiParameter
            {
                Name = "$expand",
                In = ParameterLocation.Query,
                Description = "Expand related entities",
                Schema = new OpenApiSchema
                {
                    Type = "array",
                    UniqueItems = true,
                    Items = new OpenApiSchema
                    {
                        Type = "string",
                        Enum = expandItems
                    }
                },
                Style = ParameterStyle.Form,
                Explode = false
            });
        }
Пример #5
0
        /// <summary>
        /// Gets the selected navigation properties for the current node.
        /// </summary>
        /// <param name="structuredType">The current structured type.</param>
        /// <returns>The set of selected navigation properties.</returns>
        internal IEnumerable <IEdmNavigationProperty> GetSelectedNavigationProperties(IEdmStructuredType structuredType)
        {
            if (this.selectionType == SelectionType.Empty)
            {
                return(EmptyNavigationProperties);
            }

            // We cannot determine the selected navigation properties without the user model. This means we won't be computing the missing navigation properties.
            // For reading we will report what's on the wire and for writing we just write what the user explicitly told us to write.
            if (structuredType == null)
            {
                return(EmptyNavigationProperties);
            }

            if (this.selectionType == SelectionType.EntireSubtree || this.hasWildcard ||
                (this.selectedProperties.Count() == 0 && this.children.Values.All(n => n.isExpandedNavigationProperty)))
            {
                return(structuredType.NavigationProperties());
            }

            // Find all the selected navigation properties
            // NOTE: the assumption is that the number of selected properties usually is a lot smaller
            //       than the number of all properties on the type and that FindProperty for each selected
            //       property is faster than iterating through all the properties on the type.
            Debug.Assert(this.selectedProperties != null, "selectedProperties != null");
            IEnumerable <string> navigationPropertyNames = this.selectedProperties;

            if (this.children != null)
            {
                navigationPropertyNames = this.children.Keys.Concat(navigationPropertyNames);
            }

            IEnumerable <IEdmNavigationProperty> selectedNavigationProperties = navigationPropertyNames
                                                                                .Select(structuredType.FindProperty)
                                                                                .OfType <IEdmNavigationProperty>();

            // gather up the selected navigations from any child nodes that have type segments matching the current type and append them.
            foreach (SelectedPropertiesNode typeSegmentChild in this.GetMatchingTypeSegments(structuredType))
            {
                selectedNavigationProperties = selectedNavigationProperties.Concat(typeSegmentChild.GetSelectedNavigationProperties(structuredType));
            }

            // ensure no duplicates are returned.
            return(selectedNavigationProperties.Distinct());
        }
        private static ODataPathSegment CreatePropertySegment(ODataPathSegment previous, ODataTemplateTranslateContext context)
        {
            if (previous == null)
            {
                return(null);
            }

            IEdmStructuredType previewEdmType = previous.EdmType as IEdmStructuredType;

            if (previewEdmType == null)
            {
                return(null);
            }

            if (!context.RouteValues.TryGetValue("property", out object value))
            {
                return(null);
            }

            string propertyName = value as string;
            IEdmStructuralProperty edmProperty = previewEdmType.StructuralProperties().FirstOrDefault(p => p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase));

            if (edmProperty != null)
            {
                return(new PropertySegment(edmProperty));
            }

            IEdmNavigationProperty navProperty = previewEdmType.NavigationProperties().FirstOrDefault(p => p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase));

            if (navProperty != null)
            {
                // TODO: shall we calculate the navigation source for navigation segment?
                return(new NavigationPropertySegment(navProperty, null));
            }

            return(null);
        }
Пример #7
0
        private void Initialize(SelectExpandClause selectExpandClause, IEdmStructuredType structuredType, IEdmModel model, bool expandedReference)
        {
            if (structuredType == null)
            {
                throw Error.ArgumentNull("structuredType");
            }

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

            // So far, it includes all properties of primitive, enum and collection of them
            HashSet <IEdmStructuralProperty> allStructuralProperties = new HashSet <IEdmStructuralProperty>();

            IEdmEntityType entityType = structuredType as IEdmEntityType;

            if (expandedReference)
            {
                SelectAllDynamicProperties = false;
                if (entityType != null)
                {
                    // only need to include the key properties.
                    SelectedStructuralProperties = new HashSet <IEdmStructuralProperty>(entityType.Key());
                }
            }
            else
            {
                // So far, it includes all properties of complex and collection of complex
                HashSet <IEdmStructuralProperty> allComplexStructuralProperties = new HashSet <IEdmStructuralProperty>();
                GetStructuralProperties(structuredType, allStructuralProperties, allComplexStructuralProperties);

                // So far, it includes all navigation properties
                HashSet <IEdmNavigationProperty> allNavigationProperties;
                HashSet <IEdmAction>             allActions;
                HashSet <IEdmFunction>           allFunctions;
                IEnumerable <SelectItem>         selectItems = new List <SelectItem>();

                if (entityType != null)
                {
                    allNavigationProperties = new HashSet <IEdmNavigationProperty>(entityType.NavigationProperties());
                    allActions   = new HashSet <IEdmAction>(model.GetAvailableActions(entityType));
                    allFunctions = new HashSet <IEdmFunction>(model.GetAvailableFunctions(entityType));
                }
                else if (structuredType != null)
                {
                    allNavigationProperties = new HashSet <IEdmNavigationProperty>(structuredType.NavigationProperties());

                    // Currently, the library does not support for bounded operations on complex type.
                    allActions   = new HashSet <IEdmAction>();
                    allFunctions = new HashSet <IEdmFunction>();
                }
                else
                {
                    allNavigationProperties = new HashSet <IEdmNavigationProperty>();
                    allActions   = new HashSet <IEdmAction>();
                    allFunctions = new HashSet <IEdmFunction>();
                }

                if (selectExpandClause == null)
                {
                    SelectedStructuralProperties = allStructuralProperties;
                    SelectedComplexProperties    = allComplexStructuralProperties;
                    SelectedNavigationProperties = allNavigationProperties;
                    SelectedActions            = allActions;
                    SelectedFunctions          = allFunctions;
                    SelectAllDynamicProperties = true;
                }
                else
                {
                    if (selectExpandClause.AllSelected)
                    {
                        SelectedStructuralProperties = allStructuralProperties;
                        SelectedComplexProperties    = allComplexStructuralProperties;
                        SelectedNavigationProperties = allNavigationProperties;
                        SelectedActions            = allActions;
                        SelectedFunctions          = allFunctions;
                        SelectAllDynamicProperties = true;
                    }
                    else
                    {
                        // Explicitly set SelectAllDynamicProperties as false, while the BuildSelections method will set it as true
                        // if it meets the select all condition.
                        SelectAllDynamicProperties = false;
                        BuildSelections(selectExpandClause, allStructuralProperties, allComplexStructuralProperties, allNavigationProperties, allActions, allFunctions);
                    }

                    selectItems = selectExpandClause.SelectedItems;
                }

                BuildExpansions(selectItems, allNavigationProperties);

                // remove expanded navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ExpandedProperties.Keys);

                // remove referenced navigation properties from the selected navigation properties.
                SelectedNavigationProperties.ExceptWith(ReferencedNavigationProperties);
            }
        }