Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CastPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="castType">The type of the cast.</param>
        public CastPathSegment(ODataPathSegment previous, IEdmEntityType castType)
            : base(previous)
        {
            if (castType == null)
            {
                throw Error.ArgumentNull("cast");
            }

            IEdmType previousEdmType = previous.EdmType;

            if (previousEdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }

            if (previousEdmType.TypeKind == EdmTypeKind.Collection)
            {
                EdmType = castType.GetCollection();
            }
            else
            {
                EdmType = castType;
            }
            EntitySet = previous.EntitySet;
            CastType = castType;
        }
 protected override ODataPathSegment ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, string segment)
 {
     if (segment == "$count")
     {
         return new CountPathSegment();
     }
     return base.ParseAtEntityCollection(model, previous, previousEdmType, segment);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        protected ODataPathSegment(ODataPathSegment previous)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }

            Previous = previous;
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Function)
            {
                FunctionPathSegment functionSegment = (FunctionPathSegment)pathSegment;
                return KeyValuePathSegmentTemplate.TryMatch(ParameterMappings, functionSegment.Values, values);
            }

            return false;
        }
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Key)
            {
                KeyValuePathSegment keySegment = (KeyValuePathSegment)pathSegment;
                return TryMatch(ParameterMappings, keySegment.Values, values);
            }

            return false;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="action">The action being invoked.</param>
        public ActionPathSegment(ODataPathSegment previous, IEdmFunctionImport action)
            : base(previous)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            Initialize(action);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EntitySetPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="entitySet">The entity set being accessed.</param>
        public EntitySetPathSegment(ODataPathSegment previous, IEdmEntitySet entitySet)
            : base(previous)
        {
            if (entitySet == null)
            {
                throw Error.ArgumentNull("entitySet");
            }

            EdmType = entitySet.ElementType.GetCollection();
            EntitySet = entitySet;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PropertyAccessPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="property">The property being accessed by this segment.</param>
        public PropertyAccessPathSegment(ODataPathSegment previous, IEdmProperty property)
            : base(previous)
        {
            if (property == null)
            {
                throw Error.ArgumentNull("property");
            }

            EdmType = property.Type.Definition;
            Property = property;
        }
Ejemplo n.º 9
0
 protected override ODataPathSegment ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, string segment)
 {
     try
     {
         return base.ParseAtEntityCollection(model, previous, previousEdmType, segment);
     }
     catch (ODataException)
     {
         return new KeyValuePathSegment(segment);
     }
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ActionPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The previous segment in the path.</param>
        /// <param name="action">The action being invoked.</param>
        public ActionPathSegment(ODataPathSegment previous, IEdmFunctionImport action)
            : base(previous)
        {
            if (action == null)
            {
                throw Error.ArgumentNull("action");
            }

            IEdmTypeReference returnType = action.ReturnType;
            EdmType = returnType == null ? null : returnType.Definition;

            IEdmEntitySet functionEntitySet = null;
            if (action.TryGetStaticEntitySet(out functionEntitySet))
            {
                EntitySet = functionEntitySet;
            }
            Action = action;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="NavigationPathSegment" /> class.
        /// </summary>
        /// <param name="previous">The property being accessed by this segment.</param>
        /// <param name="navigationProperty">The navigation property being accessed by this segment.</param>
        public NavigationPathSegment(ODataPathSegment previous, IEdmNavigationProperty navigationProperty)
            : base(previous)
        {
            if (navigationProperty == null)
            {
                throw Error.ArgumentNull("navigation");
            }

            if (previous.EntitySet == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustHaveEntitySet);
            }

            EdmType = navigationProperty.Partner.Multiplicity() == EdmMultiplicity.Many ?
                (IEdmType)navigationProperty.ToEntityType().GetCollection() :
                (IEdmType)navigationProperty.ToEntityType();
            EntitySet = previous.EntitySet.FindNavigationTarget(navigationProperty);
            NavigationProperty = navigationProperty;
        }
        /// <summary>
        /// Parses the next OData path segment.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseNextSegment(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previous == null)
            {
                // Parse entry node
                return ParseEntrySegment(model, segment, segments);
            }
            else
            {
                // Parse non-entry node
                if (previousEdmType == null)
                {
                    throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
                }

                switch (previousEdmType.TypeKind)
                {
                    case EdmTypeKind.Collection:
                        return ParseAtCollection(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Entity:
                        return ParseAtEntity(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Complex:
                        return ParseAtComplex(model, previous, previousEdmType, segment, segments);

                    case EdmTypeKind.Primitive:
                        return ParseAtPrimitiveProperty(model, previous, previousEdmType, segment, segments);

                    default:
                        throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
                }
            }
        }
Ejemplo n.º 13
0
        /// <inheritdoc />
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Function)
            {
                FunctionPathSegment functionSegment = (FunctionPathSegment)pathSegment;
                return functionSegment.Function == Function && functionSegment.FunctionName == FunctionName;
            }

            return false;
        }
Ejemplo n.º 14
0
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
 {
     return pathSegment.SegmentKind == ODataSegmentKinds.Value;
 }
        /// <summary>
        /// Parses the next OData path segment following an entity.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntity(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, string segment)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }
            IEdmEntityType previousType = previousEdmType as IEdmEntityType;

            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityType, previousEdmType);
            }

            if (segment == ODataSegmentKinds.Links)
            {
                return(new LinksPathSegment());
            }

            // first look for navigation properties
            IEdmNavigationProperty navigation = previousType.NavigationProperties().SingleOrDefault(np => np.Name == segment);

            if (navigation != null)
            {
                return(new NavigationPathSegment(navigation));
            }

            // next look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);

            if (property != null)
            {
                return(new PropertyAccessPathSegment(property));
            }

            // next look for type casts
            IEdmEntityType castType = model.FindDeclaredType(segment) as IEdmEntityType;

            if (castType != null)
            {
                if (!castType.IsOrInheritsFrom(previousType) && !previousType.IsOrInheritsFrom(castType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousType));
                }
                return(new CastPathSegment(castType));
            }

            // finally look for bindable procedures
            IEdmEntityContainer container = ExtractEntityContainer(model);
            IEdmFunctionImport  procedure = container.FunctionImports().FindBindableAction(previousType, segment);

            if (procedure != null)
            {
                return(new ActionPathSegment(procedure));
            }

            // Treating as an open property
            return(new UnresolvedPathSegment(segment));
        }
        /// <summary>
        /// Parses the next OData path segment following an entity.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntity(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }
            IEdmEntityType previousType = previousEdmType as IEdmEntityType;
            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityType, previousEdmType);
            }

            if (segment == ODataSegmentKinds.Links)
            {
                return new LinksPathSegment();
            }

            // first look for navigation properties
            IEdmNavigationProperty navigation = previousType.NavigationProperties().SingleOrDefault(np => np.Name == segment);
            if (navigation != null)
            {
                return new NavigationPathSegment(navigation);
            }

            // next look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);
            if (property != null)
            {
                return new PropertyAccessPathSegment(property);
            }

            // next look for type casts
            IEdmEntityType castType = model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                if (!castType.IsOrInheritsFrom(previousType) && !previousType.IsOrInheritsFrom(castType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousType));
                }
                return new CastPathSegment(castType);
            }

            // finally look for bindable procedures
            IEdmEntityContainer container = ExtractEntityContainer(model);
            IEdmActionImport action = container.FindAction(segment, previousType);
            if (action != null)
            {
                return new ActionPathSegment(action);
            }

            // Try to match this to a function call
            FunctionPathSegment pathSegment = TryMatchFunctionCall(segment, segments, model, bindingType: previousType);
            if (pathSegment != null)
            {
                return pathSegment;
            }

            // Treating as an open property
            return new UnresolvedPathSegment(segment);
        }
        /// <summary>
        /// Parses the next OData path segment following an entity collection.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previousEdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }
            IEdmCollectionType collectionType = previousEdmType as IEdmCollectionType;
            if (collectionType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previousEdmType);
            }
            IEdmEntityType elementType = collectionType.ElementType.Definition as IEdmEntityType;
            if (elementType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previousEdmType);
            }

            // look for keys first.
            if (segment.StartsWith("(", StringComparison.Ordinal) && segment.EndsWith(")", StringComparison.Ordinal))
            {
                Contract.Assert(segment.Length >= 2);
                string value = segment.Substring(1, segment.Length - 2);
                return new KeyValuePathSegment(value);
            }

            // next look for casts
            IEdmEntityType castType = model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                IEdmType previousElementType = collectionType.ElementType.Definition;
                if (!castType.IsOrInheritsFrom(previousElementType) && !previousElementType.IsOrInheritsFrom(castType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousElementType));
                }
                return new CastPathSegment(castType);
            }

            // now look for bindable actions
            IEdmEntityContainer container = ExtractEntityContainer(model);
            IEdmActionImport action = container.FindAction(segment, collectionType);
            if (action != null)
            {
                return new ActionPathSegment(action);
            }

            // Try to match this to a function call
            FunctionPathSegment pathSegment = TryMatchFunctionCall(segment, segments, model, bindingType: collectionType);
            if (pathSegment != null)
            {
                return pathSegment;
            }

            throw new ODataException(Error.Format(SRResources.NoActionFoundForCollection, segment, collectionType.ElementType));
        }
Ejemplo n.º 18
0
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Cast)
            {
                CastPathSegment castSegment = (CastPathSegment)pathSegment;
                return castSegment.CastType == CastType
                    && castSegment.CastTypeName == CastTypeName;
            }

            return false;
        }
Ejemplo n.º 19
0
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Navigation)
            {
                NavigationPathSegment navigationSegment = (NavigationPathSegment)pathSegment;
                return navigationSegment.NavigationProperty == NavigationProperty
                    && navigationSegment.NavigationPropertyName == NavigationPropertyName;
            }

            return false;
        }
Ejemplo n.º 20
0
 /// <inheritdoc/>
 public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
 {
     return false;
 }
Ejemplo n.º 21
0
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.EntitySet)
            {
                EntitySetPathSegment entitySetSegment = (EntitySetPathSegment)pathSegment;
                return entitySetSegment.EntitySet == EntitySet && entitySetSegment.EntitySetName == EntitySetName;
            }

            return false;
        }
        /// <summary>
        /// Parses the next OData path segment following a collection.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtCollection(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previousEdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }

            IEdmCollectionType collection = previousEdmType as IEdmCollectionType;
            if (collection == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeCollectionType, previousEdmType);
            }

            switch (collection.ElementType.Definition.TypeKind)
            {
                case EdmTypeKind.Entity:
                    return ParseAtEntityCollection(model, previous, previousEdmType, segment, segments);

                default:
                    throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Parses the first OData segment following the service base URI.
        /// </summary>
        /// <param name="root">The service base path segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseEntrySegment(ODataPathSegment root, string segment)
        {
            if (root == null)
            {
                throw Error.ArgumentNull("root");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (segment == ODataSegmentKinds.Metadata)
            {
                return new MetadataPathSegment(root);
            }
            if (segment == ODataSegmentKinds.Batch)
            {
                return new BatchPathSegment(root);
            }

            IEdmEntitySet entitySet = Container.FindEntitySet(segment);
            if (entitySet != null)
            {
                return new EntitySetPathSegment(root, entitySet);
            }

            IEdmFunctionImport function = Container.FunctionImports().SingleOrDefault(fi => fi.Name == segment && fi.IsBindable == false);
            if (function != null)
            {
                return new ActionPathSegment(root, function);
            }

            // segment does not match the model
            return null;
        }
        /// <summary>
        /// Parses the next OData path segment following a complex-typed segment.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtComplex(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            IEdmComplexType previousType = previousEdmType as IEdmComplexType;
            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeComplexType, previousEdmType);
            }

            // look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);
            if (property != null)
            {
                return new PropertyAccessPathSegment(property);
            }

            // Treating as an open property
            return new UnresolvedPathSegment(segment);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Parses the next OData path segment following an entity collection.
        /// </summary>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntityCollection(ODataPathSegment previous, string segment)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (previous.EdmType == null)
            {
                throw Error.InvalidOperation(SRResources.PreviousSegmentEdmTypeCannotBeNull);
            }
            IEdmCollectionType collectionType = previous.EdmType as IEdmCollectionType;
            if (collectionType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previous.EdmType);
            }
            IEdmEntityType elementType = collectionType.ElementType.Definition as IEdmEntityType;
            if (elementType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityCollectionType, previous.EdmType);
            }

            // look for keys first.
            if (segment.StartsWith("(", StringComparison.Ordinal) && segment.EndsWith(")", StringComparison.Ordinal))
            {
                Contract.Assert(segment.Length >= 2);
                string value = segment.Substring(1, segment.Length - 2);
                return new KeyValuePathSegment(previous, value);
            }

            // next look for casts
            IEdmEntityType castType = Model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                IEdmType previousElementType = collectionType.ElementType.Definition;
                if (!castType.IsOrInheritsFrom(previousElementType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousElementType));
                }
                return new CastPathSegment(previous, castType);
            }

            // now look for bindable actions
            IEdmFunctionImport procedure = Container.FunctionImports().FindBindableAction(collectionType, segment);
            if (procedure != null)
            {
                return new ActionPathSegment(previous, procedure);
            }

            throw new ODataException(Error.Format(SRResources.NoActionFoundForCollection, segment, collectionType.ElementType));
        }
        /// <summary>
        /// Parses the next OData path segment following a primitive property.
        /// </summary>
        /// <param name="model">The model to use for path parsing.</param>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="previousEdmType">The EDM type of the OData path up to the previous segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <param name="segments">The queue of pending segments.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtPrimitiveProperty(IEdmModel model, ODataPathSegment previous,
            IEdmType previousEdmType, string segment, Queue<string> segments)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (segments == null)
            {
                throw Error.ArgumentNull("segments");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }

            if (segment == ODataSegmentKinds.Value)
            {
                return new ValuePathSegment();
            }

            throw new ODataException(Error.Format(SRResources.InvalidPathSegment, segment, previous));
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Parses the next OData path segment following an entity.
        /// </summary>
        /// <param name="previous">The previous path segment.</param>
        /// <param name="segment">The value of the segment to parse.</param>
        /// <returns>A parsed representation of the segment.</returns>
        protected virtual ODataPathSegment ParseAtEntity(ODataPathSegment previous, string segment)
        {
            if (previous == null)
            {
                throw Error.ArgumentNull("previous");
            }
            if (String.IsNullOrEmpty(segment))
            {
                throw Error.Argument(SRResources.SegmentNullOrEmpty);
            }
            IEdmEntityType previousType = previous.EdmType as IEdmEntityType;
            if (previousType == null)
            {
                throw Error.Argument(SRResources.PreviousSegmentMustBeEntityType, previous.EdmType);
            }

            if (segment == ODataSegmentKinds.Links)
            {
                return new LinksPathSegment(previous);
            }

            // first look for navigation properties
            IEdmNavigationProperty navigation = previousType.NavigationProperties().SingleOrDefault(np => np.Name == segment);
            if (navigation != null)
            {
                return new NavigationPathSegment(previous, navigation);
            }

            // next look for properties
            IEdmProperty property = previousType.Properties().SingleOrDefault(p => p.Name == segment);
            if (property != null)
            {
                return new PropertyAccessPathSegment(previous, property);
            }

            // next look for type casts
            IEdmEntityType castType = Model.FindDeclaredType(segment) as IEdmEntityType;
            if (castType != null)
            {
                if (!castType.IsOrInheritsFrom(previousType))
                {
                    throw new ODataException(Error.Format(SRResources.InvalidCastInPath, castType, previousType));
                }
                return new CastPathSegment(previous, castType);
            }

            // finally look for bindable procedures
            IEdmFunctionImport procedure = Container.FunctionImports().FindBindableAction(previousType, segment);
            if (procedure != null)
            {
                return new ActionPathSegment(previous, procedure);
            }

            // Treating as an open property
            return new UnresolvedPathSegment(previous, segment);
        }
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Property)
            {
                PropertyAccessPathSegment propertySegment = (PropertyAccessPathSegment)pathSegment;
                return propertySegment.Property == Property && propertySegment.PropertyName == PropertyName;
            }

            return false;
        }
Ejemplo n.º 29
0
        /// <inheritdoc/>
        public override bool TryMatch(ODataPathSegment pathSegment, IDictionary<string, object> values)
        {
            if (pathSegment.SegmentKind == ODataSegmentKinds.Action)
            {
                ActionPathSegment actionSegment = (ActionPathSegment)pathSegment;
                return actionSegment.Action == Action && actionSegment.ActionName == ActionName;
            }

            return false;
        }