Exemplo n.º 1
0
 public void SetIsSetCorrectly()
 {
     var set = ModelBuildingHelpers.BuildValidEntitySet();
     IEdmType type = set.EntityType();
     TypeSegment segment = new TypeSegment(type, set);
     segment.NavigationSource.Should().BeSameAs(set);
 }
Exemplo n.º 2
0
 public void InequalityIsCorrect()
 {
     TypeSegment typeSegment1 = new TypeSegment(HardCodedTestModel.GetPersonType(), null);
     TypeSegment typeSegment2 = new TypeSegment(HardCodedTestModel.GetDogType(), null);
     BatchSegment batchSegment = BatchSegment.Instance;
     typeSegment1.Equals(typeSegment2).Should().BeFalse();
     typeSegment1.Equals(batchSegment).Should().BeFalse();
 }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CastSegmentTemplate" /> class.
        /// </summary>
        /// <param name="typeSegment">The type segment.</param>
        public CastSegmentTemplate(TypeSegment typeSegment)
        {
            TypeSegment = typeSegment ?? throw Error.ArgumentNull(nameof(typeSegment));

            Literal = typeSegment.EdmType.AsElementType().FullTypeName();

            IsSingle = typeSegment.EdmType.TypeKind != EdmTypeKind.Collection;
        }
Exemplo n.º 4
0
        public static AndConstraint <TypeSegment> ShouldBeTypeSegment(this ODataPathSegment segment, IEdmType type)
        {
            segment.Should().BeOfType <TypeSegment>();
            TypeSegment typeSegment = segment.As <TypeSegment>();

            typeSegment.EdmType.ShouldBeEquivalentTo(type);
            return(new AndConstraint <TypeSegment>(typeSegment));
        }
Exemplo n.º 5
0
        public void SetIsSetCorrectly()
        {
            var         set     = ModelBuildingHelpers.BuildValidEntitySet();
            IEdmType    type    = set.EntityType();
            TypeSegment segment = new TypeSegment(type, set);

            segment.NavigationSource.Should().BeSameAs(set);
        }
Exemplo n.º 6
0
        public static void GetPropertyAndStructuredTypeFromPath(IEnumerable <ODataPathSegment> segments,
                                                                out IEdmProperty property, out IEdmStructuredType structuredType, out string name)
        {
            property       = null;
            structuredType = null;
            name           = String.Empty;
            string typeCast = String.Empty;

            if (segments != null)
            {
                IEnumerable <ODataPathSegment> reverseSegments = segments.Reverse();
                foreach (var segment in reverseSegments)
                {
                    NavigationPropertySegment navigationPathSegment = segment as NavigationPropertySegment;
                    if (navigationPathSegment != null)
                    {
                        property = navigationPathSegment.NavigationProperty;
                        if (structuredType == null)
                        {
                            structuredType = navigationPathSegment.NavigationProperty.ToEntityType();
                        }

                        name = navigationPathSegment.NavigationProperty.Name + typeCast;
                        return;
                    }

                    PropertySegment propertyAccessPathSegment = segment as PropertySegment;
                    if (propertyAccessPathSegment != null)
                    {
                        property = propertyAccessPathSegment.Property;
                        if (structuredType == null)
                        {
                            structuredType = GetElementType(property.Type) as IEdmStructuredType;
                        }
                        name = property.Name + typeCast;
                        return;
                    }

                    EntitySetSegment entitySetSegment = segment as EntitySetSegment;
                    if (entitySetSegment != null)
                    {
                        if (structuredType == null)
                        {
                            structuredType = entitySetSegment.EntitySet.EntityType();
                        }
                        name = entitySetSegment.EntitySet.Name + typeCast;
                        return;
                    }

                    TypeSegment typeSegment = segment as TypeSegment;
                    if (typeSegment != null)
                    {
                        structuredType = GetElementType(typeSegment.EdmType.ToEdmTypeReference(false)) as IEdmStructuredType;
                        typeCast       = "/" + structuredType;
                    }
                }
            }
        }
Exemplo n.º 7
0
        public static TypeSegment ShouldBeTypeSegment(this ODataPathSegment segment, IEdmType actualType, IEdmType expectType)
        {
            Assert.NotNull(segment);
            TypeSegment typeSegment = Assert.IsType <TypeSegment>(segment);

            Assert.Equal(typeSegment.EdmType.FullTypeName(), actualType.FullTypeName());
            Assert.Equal(typeSegment.ExpectedType.FullTypeName(), expectType.FullTypeName());
            return(typeSegment);
        }
Exemplo n.º 8
0
        public void InequalityIsCorrect()
        {
            TypeSegment  typeSegment1 = new TypeSegment(HardCodedTestModel.GetPersonType(), null);
            TypeSegment  typeSegment2 = new TypeSegment(HardCodedTestModel.GetDogType(), null);
            BatchSegment batchSegment = BatchSegment.Instance;

            typeSegment1.Equals(typeSegment2).Should().BeFalse();
            typeSegment1.Equals(batchSegment).Should().BeFalse();
        }
Exemplo n.º 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TypeSegmentTemplate"/> class.
        /// </summary>
        /// <param name="segment">The type cast segment.</param>
        public TypeSegmentTemplate(TypeSegment segment)
        {
            if (segment == null)
            {
                throw Error.ArgumentNull("segment");
            }

            Segment = segment;
        }
Exemplo n.º 10
0
        public void GetNavigationPropertyFromExpandPathWithTypeSegmentThrows()
        {
            var       segment   = new TypeSegment(HardCodedTestModel.GetHomeAddressType(), null);
            ODataPath odataPath = new ODataPath(segment);
            Action    uriParserHelpersAction = () => UriEdmHelpers.GetNavigationPropertyFromExpandPath(odataPath);

            uriParserHelpersAction.Throws <ODataException>(
                Strings.ExpandItemBinder_TypeSegmentNotFollowedByPath);
        }
Exemplo n.º 11
0
        public void GetMostDerivedTypeFromPathWithTypeSegmentAndInheritedTypeReturnsInheritedType()
        {
            var         segment     = new TypeSegment(HardCodedTestModel.GetHomeAddressType(), null);
            ODataPath   odataPath   = new ODataPath(segment);
            TypeSegment typeSegment = odataPath.FirstSegment as TypeSegment;
            IEdmType    type        = typeSegment.EdmType;

            var result = UriEdmHelpers.GetMostDerivedTypeFromPath(odataPath, type);

            Assert.Equal(type, result);
        }
Exemplo n.º 12
0
        public override void Handle(TypeSegment segment)
        {
            this.ThrowIfResolved();

            this.Type        = segment.EdmType;
            this.ElementType = this.GetElementType(this.Type);

            this.childSegments.Add(segment);

            this.canonicalSegments.Add(segment);
        }
Exemplo n.º 13
0
        public void GetMostDerivedTypeFromPathWithTypeSegmentAndNotInheritedTypeReturnsNotInheritedType()
        {
            var                     segment     = new TypeSegment(HardCodedTestModel.GetHomeAddressType(), null);
            ODataPath               odataPath   = new ODataPath(segment);
            IEdmEntityType          astonishing = new EdmEntityType("AwesomeNamespace", "AstonishingEntity", null, false, false);
            IEdmEntityReferenceType entityRef   = new EdmEntityReferenceType(astonishing);

            var result = UriEdmHelpers.GetMostDerivedTypeFromPath(odataPath, entityRef);

            Assert.Equal(entityRef, result);
        }
        /// <summary>
        /// Translate a TypeSegment
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        /// <returns>Defined by the implementer</returns>
        public override string Translate(TypeSegment segment)
        {
            IEdmType           type           = segment.EdmType;
            IEdmCollectionType collectionType = type as IEdmCollectionType;

            if (collectionType != null)
            {
                type = collectionType.ElementType.Definition;
            }

            return("/" + type.FullTypeName());
        }
Exemplo n.º 15
0
 /// <summary>
 /// Translate a TypeSegment
 /// </summary>
 /// <param name="segment">the segment to Translate</param>
 /// <returns>Translated WebApi path segment</returns>
 public override IEnumerable <ODataPathSegment> Translate(TypeSegment segment)
 {
     if (segment.EdmType.TypeKind == EdmTypeKind.Entity)
     {
         yield return(new CastPathSegment((IEdmEntityType)segment.EdmType));
     }
     else
     {
         yield return(new CastPathSegment(
                          (IEdmEntityType)((IEdmCollectionType)segment.EdmType).ElementType.Definition));
     }
 }
        /// <summary>
        /// Translate a TypeSegment
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        /// <returns>Defined by the implementer</returns>
        public override string Translate(TypeSegment segment)
        {
            Debug.Assert(segment != null, "segment != null");
            IEdmType           type           = segment.EdmType;
            IEdmCollectionType collectionType = type as IEdmCollectionType;

            if (collectionType != null)
            {
                type = collectionType.ElementType.Definition;
            }

            return("/" + type.ODataFullName());
        }
Exemplo n.º 17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CastSegmentTemplate" /> class.
        /// </summary>
        /// <param name="castType">The cast Edm type.</param>
        /// <param name="expectedType">The expected Edm type.</param>
        /// <param name="navigationSource">The target navigation source. it could be null.</param>
        public CastSegmentTemplate(IEdmType castType, IEdmType expectedType, IEdmNavigationSource navigationSource)
        {
            if (castType == null)
            {
                throw Error.ArgumentNull(nameof(castType));
            }

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

            TypeSegment = new TypeSegment(castType, expectedType, navigationSource);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Follow an ODataPath from to get the most derived type
        /// </summary>
        /// <param name="path">the path to follow</param>
        /// <param name="startingType">the starting type before beginning to walk the path.</param>
        /// <returns>the most derived type in the path.</returns>
        public static IEdmType GetMostDerivedTypeFromPath(ODataPath path, IEdmType startingType)
        {
            IEdmType currentType = startingType;

            foreach (ODataPathSegment currentSegment in path)
            {
                TypeSegment typeSegment = currentSegment as TypeSegment;
                if (typeSegment != null && typeSegment.EdmType.IsOrInheritsFrom(currentType))
                {
                    currentType = typeSegment.EdmType;
                }
            }

            return(currentType);
        }
Exemplo n.º 19
0
        private static void Test(IEdmModel model)
        {
            IEdmEntityType order       = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Order");
            IEdmEntityType customer    = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Customer");
            IEdmEntityType vipCustomer = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "VipCustomer");

            IEdmNavigationProperty navProp     = order.FindProperty("Customer") as IEdmNavigationProperty;
            IEdmEntitySet          customers   = model.EntityContainer.FindEntitySet("Customers");
            IEdmEntitySet          orders      = model.EntityContainer.FindEntitySet("Orders");
            ODataPathSegment       navSegment  = new NavigationPropertySegment(navProp, orders);
            ODataPathSegment       typeSegment = new TypeSegment(vipCustomer, customer, customers);

            // this throw: The last segment, and only the last segment, must be a navigation property in $expand.
            // ODataExpandPath path = new ODataExpandPath(navSegment, typeSegment);
        }
Exemplo n.º 20
0
        public void TryMatch_ReturnsTrue()
        {
            // Arrange
            EdmEntityType       entityType = new EdmEntityType("NS", "entity");
            TypeSegmentTemplate template   = new TypeSegmentTemplate(new TypeSegment(entityType, null));
            TypeSegment         segment    = new TypeSegment(entityType, null);

            // Act
            Dictionary <string, object> values = new Dictionary <string, object>();
            bool result = template.TryMatch(segment, values);

            // Assert
            Assert.True(result);
            Assert.Empty(values);
        }
        public void Translate_TypeSegment_To_CastPathSegment_Works()
        {
            // Arrange
            IEdmEntitySet entityset = _model.FindDeclaredEntitySet("RoutingCustomers");
            IEdmEntityType entityType = _model.FindDeclaredType("System.Web.OData.Routing.RoutingCustomer") as IEdmEntityType;
            TypeSegment segment = new TypeSegment(entityType, entityset);

            // Act
            IEnumerable<ODataPathSegment> segments = _translator.Translate(segment);

            // Assert
            ODataPathSegment pathSegment = Assert.Single(segments);
            CastPathSegment castPathSegment = Assert.IsType<CastPathSegment>(pathSegment);
            Assert.Same(entityType, castPathSegment.CastType);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Handle a TypeSegment, we use "cast" for type segment.
        /// </summary>
        /// <param name="segment">the segment to handle</param>
        public override void Handle(TypeSegment segment)
        {
            Contract.Assert(segment != null);
            _navigationSource = segment.NavigationSource;

            // Uri literal does not use the collection type.
            IEdmType elementType = segment.EdmType;

            if (segment.EdmType.TypeKind == EdmTypeKind.Collection)
            {
                elementType = ((IEdmCollectionType)segment.EdmType).ElementType.Definition;
            }

            _pathUriLiteral.Add(elementType.FullTypeName());
        }
Exemplo n.º 23
0
        public void TryMatch_ReturnsFalse()
        {
            // Arrange
            EdmEntityType entityType1 = new EdmEntityType("NS", "entity1");
            EdmEntityType entityType2 = new EdmEntityType("NS", "entity2");

            TypeSegmentTemplate template = new TypeSegmentTemplate(new TypeSegment(entityType1, null));
            TypeSegment         segment  = new TypeSegment(entityType2, null);

            // Act
            Dictionary <string, object> values = new Dictionary <string, object>();
            bool result = template.TryMatch(segment, values);

            // Assert
            Assert.False(result);
        }
Exemplo n.º 24
0
        public void Translate_TypeSegment_To_CastPathSegment_Works()
        {
            // Arrange
            IEdmEntitySet  entityset  = _model.FindDeclaredEntitySet("RoutingCustomers");
            IEdmEntityType entityType = _model.FindDeclaredType("System.Web.OData.Routing.RoutingCustomer") as IEdmEntityType;
            TypeSegment    segment    = new TypeSegment(entityType, entityset);

            // Act
            IEnumerable <ODataPathSegment> segments = _translator.Translate(segment);

            // Assert
            ODataPathSegment pathSegment     = Assert.Single(segments);
            CastPathSegment  castPathSegment = Assert.IsType <CastPathSegment>(pathSegment);

            Assert.Same(entityType, castPathSegment.CastType);
        }
Exemplo n.º 25
0
        public static string ToUriLiteral(this TypeSegment segment)
        {
            if (segment == null)
            {
                throw Error.ArgumentNull("segment");
            }

            IEdmType elementType = segment.EdmType;

            if (segment.EdmType.TypeKind == EdmTypeKind.Collection)
            {
                elementType = ((IEdmCollectionType)segment.EdmType).ElementType.Definition;
            }

            return(elementType.FullTypeName());
        }
Exemplo n.º 26
0
        /// <summary>
        /// Handle a TypeSegment, we use "cast" for type segment.
        /// </summary>
        /// <param name="segment">the segment to handle</param>
        public override void Handle(TypeSegment segment)
        {
            _navigationSource = segment.NavigationSource;

            _pathTemplate.Add(ODataSegmentKinds.Cast); // cast

            // Uri literal does not use the collection type.
            IEdmType elementType = segment.EdmType;

            if (segment.EdmType.TypeKind == EdmTypeKind.Collection)
            {
                elementType = ((IEdmCollectionType)segment.EdmType).ElementType.Definition;
            }

            _pathUriLiteral.Add(elementType.FullTypeName());
        }
        public void TranslateCastSegmentTemplate_ReturnsODataTypeSegment()
        {
            // Arrange
            EdmEntityType                 baseType = new EdmEntityType("NS", "base");
            EdmEntityType                 subType  = new EdmEntityType("NS", "sub", baseType);
            CastSegmentTemplate           template = new CastSegmentTemplate(subType, baseType, null);
            ODataTemplateTranslateContext context  = new ODataTemplateTranslateContext();

            // Act
            ODataPathSegment actual = template.Translate(context);

            // Assert
            Assert.NotNull(actual);
            TypeSegment typeSegment = Assert.IsType <TypeSegment>(actual);

            Assert.Same(subType, typeSegment.EdmType);
        }
Exemplo n.º 28
0
        public void ODataPathSegmentHandler_Handles_TypeCastSegment()
        {
            // Arrange
            ODataPathSegmentHandler handler = new ODataPathSegmentHandler();

            EdmEntityType      customer        = new EdmEntityType("NS", "Customer");
            EdmEntityType      vipCustomer     = new EdmEntityType("NS", "VipCustomer", customer);
            EdmEntityContainer entityContainer = new EdmEntityContainer("NS", "Default");
            EdmEntitySet       customers       = entityContainer.AddEntitySet("Customers", customer);
            TypeSegment        segment         = new TypeSegment(vipCustomer, customer, customers);

            // Act
            handler.Handle(segment);

            // Assert
            Assert.Equal("NS.VipCustomer", handler.PathLiteral);
            Assert.Same(customers, handler.NavigationSource);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Translate a TypeSegment
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        /// <returns>Translated WebApi path segment</returns>
        public override IEnumerable <ODataPathSegment> Translate(TypeSegment segment)
        {
            IEdmType elementType = segment.EdmType;

            if (segment.EdmType.TypeKind == EdmTypeKind.Collection)
            {
                elementType = ((IEdmCollectionType)segment.EdmType).ElementType.Definition;
            }

            if (elementType.TypeKind == EdmTypeKind.Entity)
            {
                yield return(new CastPathSegment((IEdmEntityType)elementType));
            }
            else if (elementType.TypeKind == EdmTypeKind.Complex)
            {
                yield return(new ComplexCastPathSegment((IEdmComplexType)elementType));
            }
        }
Exemplo n.º 30
0
        /// <summary>
        /// Translate TypeSegment to linq expression.
        /// </summary>
        /// <param name="segment">The TypeSegment</param>
        /// <returns>The linq expression</returns>
        public override Expression Translate(TypeSegment segment)
        {
            if (this.LastQueryTarget.IsEntitySet)
            {
                Type baseType     = EdmClrTypeUtils.GetInstanceType(this.LastQueryTarget.ElementType.FullTypeName());
                Type instanceType = EdmClrTypeUtils.GetInstanceType(((IEdmCollectionType)segment.EdmType).ElementType);

                // A set return now is a IEnumable, try to convert to IQueryable.
                this.ResultExpression = Expression.Call(typeof(Queryable), AsQueryableMethod, new Type[] { baseType }, this.ResultExpression);

                // Convert to .Where(it=> it is Type)
                ParameterExpression parameter = Expression.Parameter(baseType, "it");
                Expression          body      = Expression.TypeIs(parameter, instanceType);
                this.ResultExpression = Expression.Call(typeof(Queryable), WhereMethodName, new Type[] { baseType }, this.ResultExpression, Expression.Quote(Expression.Lambda(body, parameter)));
                this.ResultExpression = Expression.Call(typeof(Queryable), CastMethodName, new[] { instanceType }, this.ResultExpression);
            }
            else if (this.LastQueryTarget.TypeKind == EdmTypeKind.Entity)
            {
                Type instanceType = EdmClrTypeUtils.GetInstanceType(segment.EdmType.FullTypeName());
                this.ResultExpression = Expression.Convert(this.ResultExpression, instanceType);
            }
            else if (this.LastQueryTarget.Property != null)
            {
                if (this.LastQueryTarget.TypeKind == EdmTypeKind.Complex)
                {
                    Type instanceType = EdmClrTypeUtils.GetInstanceType(segment.EdmType.FullTypeName());
                    this.ResultExpression = Expression.Convert(this.ResultExpression, instanceType);
                }
                else
                {
                    // This code should not be hit. It should be prevented by UriParser.
                    throw new ApplicationException(
                              string.Format("PropertySegment with TypeKind '{0}' following by TypeSegment is invalid", this.LastQueryTarget.TypeKind));
                }
            }
            else
            {
                throw Utility.BuildException(HttpStatusCode.NotImplemented, "Unsupported URI segment before TypeSegment", null);
            }

            this.LastProcessedSegment = segment;
            return(this.ResultExpression);
        }
Exemplo n.º 31
0
        public void ODataPathSegmentToTemplateHandler_Handles_TypeCast()
        {
            // Arrange
            ODataPathSegmentToTemplateHandler handler = new ODataPathSegmentToTemplateHandler(null);

            EdmEntityType      customer        = new EdmEntityType("NS", "Customer");
            EdmEntityType      vipCustomer     = new EdmEntityType("NS", "VipCustomer", customer);
            EdmEntityContainer entityContainer = new EdmEntityContainer("NS", "Default");
            EdmEntitySet       customers       = entityContainer.AddEntitySet("Customers", customer);
            TypeSegment        segment         = new TypeSegment(vipCustomer, customer, customers);

            // Act
            handler.Handle(segment);

            // Assert
            ODataSegmentTemplate segmentTemplate = Assert.Single(handler.Templates);

            Assert.IsType <CastSegmentTemplate>(segmentTemplate);
        }
Exemplo n.º 32
0
        /// <summary>
        /// Follow an ODataPath from an Expand to get the Final Nav Prop
        /// </summary>
        /// <param name="path">the path to follow</param>
        /// <returns>the navigation property at the end of that path.</returns>
        /// <exception cref="ODataException">Throws if the last segment in the path is not a nav prop.</exception>
        public static IEdmNavigationProperty GetNavigationPropertyFromExpandPath(ODataPath path)
        {
            NavigationPropertySegment navPropSegment = null;

            foreach (ODataPathSegment currentSegment in path)
            {
                TypeSegment typeSegment = currentSegment as TypeSegment;
                navPropSegment = currentSegment as NavigationPropertySegment;
                if (typeSegment == null && navPropSegment == null)
                {
                    throw new ODataException(OData.Core.Strings.ExpandItemBinder_TypeSegmentNotFollowedByPath);
                }
            }

            if (navPropSegment == null)
            {
                throw new ODataException(OData.Core.Strings.ExpandItemBinder_TypeSegmentNotFollowedByPath);
            }
            else
            {
                return(navPropSegment.NavigationProperty);
            }
        }
        public void GetFirstNonTypeCastSegment_WorksForSelectPathWithFirstNonTypeSegmentAtLast()
        {
            // Arrange
            EdmEntityType          entityType = new EdmEntityType("NS", "Customer");
            IEdmStructuralProperty property   = entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.String);

            ODataPathSegment firstTypeSegment     = new TypeSegment(entityType, null);
            ODataPathSegment secondTypeSegment    = new TypeSegment(entityType, null);
            ODataPathSegment firstPropertySegment = new PropertySegment(property);
            ODataSelectPath  selectPath           = new ODataSelectPath(
                firstTypeSegment,
                secondTypeSegment,
                firstPropertySegment);

            // Act
            IList <ODataPathSegment> remainingSegments;
            ODataPathSegment         firstNonTypeSegment = selectPath.GetFirstNonTypeCastSegment(out remainingSegments);

            // Assert
            Assert.NotNull(firstNonTypeSegment);
            Assert.Same(firstPropertySegment, firstNonTypeSegment);

            Assert.Null(remainingSegments);
        }
Exemplo n.º 34
0
 public void TypeSetCorrectly()
 {
     IEdmType type = ModelBuildingHelpers.BuildValidEntityType();
     TypeSegment segment = new TypeSegment(type, null);
     segment.EdmType.Should().BeSameAs(type);
 }
Exemplo n.º 35
0
 /// <summary>
 /// Handle a TypeSegment
 /// </summary>
 /// <param name="segment">the segment to Handle</param>
 public virtual void Handle(TypeSegment segment)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 36
0
 public void EqualityIsCorrect()
 {
     TypeSegment typeSegment1 = new TypeSegment(HardCodedTestModel.GetPersonType(), null);
     TypeSegment typeSegment2 = new TypeSegment(HardCodedTestModel.GetPersonType(), null);
     typeSegment1.Equals(typeSegment2).Should().BeTrue();
 }
Exemplo n.º 37
0
 public void SelectComplexCollectionPropertyWithCast()
 {
     var selectItem = ParseSingleSelectForPerson("PreviousAddresses/Fully.Qualified.Namespace.HomeAddress");
     ODataPathSegment[] segments = new ODataPathSegment[2];
     segments[0] = new PropertySegment(HardCodedTestModel.GetPersonPreviousAddressesProp());
     segments[1] = new TypeSegment(HardCodedTestModel.GetHomeAddressType(), null);
     selectItem.ShouldBePathSelectionItem(new ODataPath(segments));
 }
Exemplo n.º 38
0
        /// <summary>
        /// Binds the paths from the request's $select query option to the sets/types/properties from the metadata provider of the service.
        /// </summary>
        /// <param name="requestDescription">The request description.</param>
        /// <param name="dataService">The data service.</param>
        /// <param name="selectQueryOption">The raw value of the $select query option.</param>
        /// <returns>The bound select segments.</returns>
        internal static IList<IList<SelectItem>> BindSelectSegments(RequestDescription requestDescription, IDataService dataService, string selectQueryOption)
        {
            Debug.Assert(requestDescription != null, "requestDescription != null");
            Debug.Assert(dataService != null, "dataService != null");

            if (string.IsNullOrEmpty(selectQueryOption))
            {
                return new List<IList<SelectItem>>();
            }

            // Throw if $select requests have been disabled by the user
            Debug.Assert(dataService.Configuration != null, "dataService.Configuration != null");
            if (!dataService.Configuration.DataServiceBehavior.AcceptProjectionRequests)
            {
                throw DataServiceException.CreateBadRequestError(Strings.DataServiceConfiguration_ProjectionsNotAccepted);
            }

            IList<IList<string>> selectPathsAsText = SplitSelect(selectQueryOption, dataService.Provider);
            Debug.Assert(selectPathsAsText != null, "selectPathsAsText != null");

            List<IList<SelectItem>> boundSegments = new List<IList<SelectItem>>(selectPathsAsText.Count);
            if (selectPathsAsText.Count == 0)
            {
                return boundSegments;
            }

            ValidateSelectIsAllowedForRequest(requestDescription);

            MetadataProviderEdmModel metadataProviderEdmModel = dataService.Provider.GetMetadataProviderEdmModel();

            for (int i = selectPathsAsText.Count - 1; i >= 0; i--)
            {
                IList<string> path = selectPathsAsText[i];
                List<SelectItem> boundSegmentPath = new List<SelectItem>(path.Count);
                boundSegments.Add(boundSegmentPath);

                ResourceType targetResourceType = requestDescription.TargetResourceType;
                ResourceSetWrapper targetResourceSet = requestDescription.TargetResourceSet;

                // if we get to here, we're building a partial selection
                List<TypeSegment> typeSegments = new List<TypeSegment>();
                bool previousSegmentIsTypeSegment = false;
                for (int j = 0; j < path.Count; j++)
                {
                    string pathSegment = path[j];
                    bool lastPathSegment = (j == path.Count - 1);

                    // '*' is special, it means "Project all immediate properties on this level."
                    if (pathSegment == "*")
                    {
                        Debug.Assert(lastPathSegment, "A wildcard select segment must be the last one. This should have been checked already when splitting appart the paths.");
                        boundSegmentPath.Add(CreateWildcardSelection());
                        continue;
                    }

                    bool nameIsContainerQualified;
                    string nameFromContainerQualifiedName = dataService.Provider.GetNameFromContainerQualifiedName(pathSegment, out nameIsContainerQualified);
                    if (nameFromContainerQualifiedName == "*")
                    {
                        Debug.Assert(lastPathSegment, "A wildcard select segment must be the last one.  This should have been checked already when splitting appart the paths.");
                        Debug.Assert(nameIsContainerQualified, "nameIsContainerQualified == true");
                        boundSegmentPath.Add(CreateContainerQualifiedWildcardSelection(metadataProviderEdmModel));
                        continue;
                    }

                    ResourceProperty property = targetResourceType.TryResolvePropertyName(pathSegment);
                    if (property == null)
                    {
                        ResourceType resolvedResourceType = WebUtil.ResolveTypeIdentifier(dataService.Provider, pathSegment, targetResourceType, previousSegmentIsTypeSegment);
                        if (resolvedResourceType != null)
                        {
                            previousSegmentIsTypeSegment = true;
                            if (lastPathSegment)
                            {
                                throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryParametersPathCannotEndInTypeIdentifier(XmlConstants.HttpQueryStringSelect, resolvedResourceType.FullName));
                            }

                            targetResourceType = resolvedResourceType;

                            // Whenever we encounter the type segment, we need to only verify that the MPV is set to 3.0 or higher.
                            // There is no need to check for request DSV, request MinDSV or request MaxDSV since there are no protocol changes in
                            // the payload for uri's with type identifier.
                            requestDescription.VerifyProtocolVersion(VersionUtil.Version3Dot0, dataService);

                            IEdmSchemaType edmType = metadataProviderEdmModel.EnsureSchemaType(targetResourceType);
                            TypeSegment typeSegment = new TypeSegment(edmType);
                            typeSegments.Add(typeSegment);
                            continue;
                        }

                        previousSegmentIsTypeSegment = false;

                        // If the currentResourceType is an open type, we require the service action name to be fully qualified or else we treat it as an open property name.
                        if (!targetResourceType.IsOpenType || nameIsContainerQualified)
                        {
                            // Note that if the service does not implement IDataServiceActionProvider and the MaxProtocolVersion < V3, 
                            // GetActionsBoundToAnyTypeInResourceSet() would simply return an empty ServiceOperationWrapper collection.
                            Debug.Assert(dataService.ActionProvider != null, "dataService.ActionProvider != null");
                            IEnumerable<OperationWrapper> allOperationsInSet = dataService.ActionProvider.GetActionsBoundToAnyTypeInResourceSet(targetResourceSet);
                            List<OperationWrapper> selectedServiceActions = allOperationsInSet.Where(o => o.Name == nameFromContainerQualifiedName).ToList();

                            if (selectedServiceActions.Count > 0)
                            {
                                if (!lastPathSegment)
                                {
                                    throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_ServiceActionMustBeLastSegmentInSelect(pathSegment));
                                }

                                boundSegmentPath.Add(CreateOperationSelection(metadataProviderEdmModel, selectedServiceActions, typeSegments));
                                continue;
                            }
                        }

                        if (!targetResourceType.IsOpenType)
                        {
                            throw DataServiceException.CreateSyntaxError(Strings.RequestUriProcessor_PropertyNotFound(targetResourceType.FullName, pathSegment));
                        }

                        if (!lastPathSegment)
                        {
                            // Open navigation properties are not supported on OpenTypes.
                            throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(pathSegment));
                        }

                        boundSegmentPath.Add(CreateOpenPropertySelection(pathSegment, typeSegments));
                    }
                    else
                    {
                        previousSegmentIsTypeSegment = false;

                        ValidateSelectedProperty(targetResourceType, property, lastPathSegment);

                        boundSegmentPath.Add(CreatePropertySelection(metadataProviderEdmModel, targetResourceType, property, typeSegments));

                        if (property.TypeKind == ResourceTypeKind.EntityType)
                        {
                            targetResourceSet = dataService.Provider.GetResourceSet(targetResourceSet, targetResourceType, property);
                            targetResourceType = property.ResourceType;
                        }
                    }
                }

                // Note that this check is also covering cases where a type segment is followed by a wildcard.
                if (previousSegmentIsTypeSegment)
                {
                    throw DataServiceException.CreateBadRequestError(Strings.RequestQueryProcessor_QueryParametersPathCannotEndInTypeIdentifier(XmlConstants.HttpQueryStringSelect, targetResourceType.FullName));
                }
            }

            return boundSegments;
        }
Exemplo n.º 39
0
 public void TargetEdmTypeIsTargetType()
 {
     TypeSegment typeSegment = new TypeSegment(HardCodedTestModel.GetPersonType(), null);
     typeSegment.TargetEdmType.Should().BeSameAs(HardCodedTestModel.GetPersonType());
 }
Exemplo n.º 40
0
        public override void Handle(TypeSegment segment)
        {
            this.ThrowIfResolved();

            this.Type = segment.EdmType;
            this.ElementType = this.GetElementType(this.Type);

            this.childSegments.Add(segment);

            this.canonicalSegments.Add(segment);
        }
Exemplo n.º 41
0
        private void AddTypeCastsIfNecessary()
        {
            IEdmEntityType owningType = null;
            List<ODataPathSegment> newSegments = new List<ODataPathSegment>();
            foreach (ODataPathSegment segment in _segments)
            {
                NavigationPropertySegment navProp = segment as NavigationPropertySegment;
                if (navProp != null && owningType != null &&
                    owningType.FindProperty(navProp.NavigationProperty.Name) == null)
                {
                    // need a type cast
                    TypeSegment typeCast = new TypeSegment(
                        navProp.NavigationProperty.DeclaringType,
                        navigationSource: null);
                    newSegments.Add(typeCast);
                }

                newSegments.Add(segment);
                IEdmEntityType targetEntityType = GetTargetEntityType(segment);
                if (targetEntityType != null)
                {
                    owningType = targetEntityType;
                }
            }

            _segments = newSegments;
        }
Exemplo n.º 42
0
        private void ProcessTokenAsPath(NonSystemToken tokenIn)
        {
            Debug.Assert(tokenIn != null, "tokenIn != null");

            List<ODataPathSegment> pathSoFar = new List<ODataPathSegment>();
            IEdmStructuredType currentLevelType = this.edmType;

            // first, walk through all type segments in a row, converting them from tokens into segments.
            if (tokenIn.IsNamespaceOrContainerQualified())
            {
                PathSegmentToken firstNonTypeToken;
                pathSoFar.AddRange(SelectExpandPathBinder.FollowTypeSegments(tokenIn, this.model, this.maxDepth, this.resolver, ref currentLevelType, out firstNonTypeToken));
                Debug.Assert(firstNonTypeToken != null, "Did not get last token.");
                tokenIn = firstNonTypeToken as NonSystemToken;
                if (tokenIn == null)
                {
                    throw new ODataException(ODataErrorStrings.SelectPropertyVisitor_SystemTokenInSelect(firstNonTypeToken.Identifier));
                }  
            }

            // next, create a segment for the first non-type segment in the path.
            ODataPathSegment lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(tokenIn, this.model, currentLevelType, resolver);

            // next, create an ODataPath and add the segments to it.
            if (lastSegment != null)
            {
                pathSoFar.Add(lastSegment);

                bool hasCollectionInPath = false;

                // try create a complex type property path.
                while (true)
                {
                    // no need to go on if the current property is not of complex type or collection of complex type.
                    currentLevelType = lastSegment.EdmType as IEdmStructuredType;
                    var collectionType = lastSegment.EdmType as IEdmCollectionType;
                    if ((currentLevelType == null || currentLevelType.TypeKind != EdmTypeKind.Complex) 
                        && (collectionType == null || collectionType.ElementType.TypeKind() != EdmTypeKind.Complex))
                    {
                        break;
                    }

                    NonSystemToken nextToken = tokenIn.NextToken as NonSystemToken;
                    if (nextToken == null)
                    {
                        break;
                    }

                    lastSegment = null;

                    // This means last segment a collection of complex type,
                    // current segment can only be type cast and cannot be proprty name.
                    if (currentLevelType == null)
                    {
                        currentLevelType = collectionType.ElementType.Definition as IEdmStructuredType;
                        hasCollectionInPath = true;
                    }
                    else if (!hasCollectionInPath)
                    {
                        // If there is no collection type in the path yet, will try to bind property for the next token
                        // first try bind the segment as property.
                        lastSegment = SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(nextToken, this.model,
                            currentLevelType, resolver);
                    }

                    // then try bind the segment as type cast.
                    if (lastSegment == null)
                    {
                        IEdmStructuredType typeFromNextToken = UriEdmHelpers.FindTypeFromModel(this.model, nextToken.Identifier, this.resolver) as IEdmStructuredType;

                        if (typeFromNextToken.IsOrInheritsFrom(currentLevelType))
                        {
                            lastSegment = new TypeSegment(typeFromNextToken, /*entitySet*/null);
                        }
                    }

                    // type cast failed too.
                    if (lastSegment == null)
                    {
                        break;
                    }

                    // try move to and add next path segment.
                    tokenIn = nextToken;
                    pathSoFar.Add(lastSegment);
                }
            }

            ODataSelectPath selectedPath = new ODataSelectPath(pathSoFar);

            var selectionItem = new PathSelectItem(selectedPath);

            // non-navigation cases do not allow further segments in $select.
            if (tokenIn.NextToken != null)
            {
                throw new ODataException(ODataErrorStrings.SelectBinder_MultiLevelPathInSelect);
            }

            // if the selected item is a nav prop, then see if its already there before we add it.
            NavigationPropertySegment trailingNavPropSegment = selectionItem.SelectedPath.LastSegment as NavigationPropertySegment;
            if (trailingNavPropSegment != null)
            {
                if (this.expandClauseToDecorate.SelectedItems.Any(x => x is PathSelectItem &&
                    ((PathSelectItem)x).SelectedPath.Equals(selectedPath)))
                {
                    return;
                }
            }

            this.expandClauseToDecorate.AddToSelectedItems(selectionItem);         
        }