/// <summary> /// Parses the key value literal. /// </summary> /// <param name="lexer">The lexer positioned on the key value.</param> /// <returns>The literal query token.</returns> private static LiteralQueryToken ParseKeyValueLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); LiteralQueryToken result = UriQueryExpressionParser.TryParseLiteral(lexer); if (result == null) { throw new ODataException(Strings.UriQueryPathParser_InvalidKeyValueLiteral(lexer.CurrentToken.Text)); } return(result); }
/// <summary> /// Parses a <paramref name="orderBy "/> clause on the given <paramref name="elementType"/>, binding /// the text into semantic nodes using the provided model. /// </summary> /// <param name="orderBy">String representation of the orderby expression.</param> /// <param name="elementType">Type that the orderby clause refers to.</param> /// <param name="entitySet">EntitySet that the elements beign filtered are from.</param> /// <returns>A <see cref="OrderByClause"/> representing the metadata bound orderby expression.</returns> private OrderByClause ParseOrderByImplementation(string orderBy, IEdmType elementType, IEdmEntitySet entitySet) { ExceptionUtils.CheckArgumentNotNull(this.configuration.Model, "model"); ExceptionUtils.CheckArgumentNotNull(elementType, "elementType"); ExceptionUtils.CheckArgumentNotNull(orderBy, "orderBy"); // Get the syntactic representation of the filter expression UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(this.Settings.OrderByLimit); var orderByQueryTokens = expressionParser.ParseOrderBy(orderBy); // Bind it to metadata BindingState state = new BindingState(this.configuration); state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(elementType.ToTypeReference(), entitySet); state.RangeVariables.Push(state.ImplicitRangeVariable); MetadataBinder binder = new MetadataBinder(state); OrderByBinder orderByBinder = new OrderByBinder(binder.Bind); OrderByClause orderByClause = orderByBinder.BindOrderBy(state, orderByQueryTokens); return(orderByClause); }
/// <summary> /// Parses a <paramref name="filter"/> clause on the given <paramref name="elementType"/>, binding /// the text into semantic nodes using the provided. /// </summary> /// <param name="filter">String representation of the filter expression.</param> /// <param name="elementType">Type that the filter clause refers to.</param> /// <param name="entitySet">EntitySet that the elements beign filtered are from.</param> /// <returns>A <see cref="FilterClause"/> representing the metadata bound filter expression.</returns> private FilterClause ParseFilterImplementation(string filter, IEdmType elementType, IEdmEntitySet entitySet) { ExceptionUtils.CheckArgumentNotNull(this.configuration, "this.configuration"); ExceptionUtils.CheckArgumentNotNull(elementType, "elementType"); ExceptionUtils.CheckArgumentNotNull(filter, "filter"); // Get the syntactic representation of the filter expression UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(this.Settings.FilterLimit); QueryToken filterToken = expressionParser.ParseFilter(filter); // Bind it to metadata BindingState state = new BindingState(this.configuration); state.ImplicitRangeVariable = NodeFactory.CreateImplicitRangeVariable(elementType.ToTypeReference(), entitySet); state.RangeVariables.Push(state.ImplicitRangeVariable); MetadataBinder binder = new MetadataBinder(state); FilterBinder filterBinder = new FilterBinder(binder.Bind, state); FilterClause boundNode = filterBinder.BindFilter(filterToken); return(boundNode); }
/// <summary> /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="SyntacticTree"/> /// describing the query specified by the uri. /// </summary> /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param> /// <param name="serviceBaseUri">The base URI of the service.</param> /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param> /// <returns>A new instance of <see cref="SyntacticTree"/> which represents the query specified in the <paramref name="queryUri"/>.</returns> public static SyntacticTree ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth) { ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri"); if (!queryUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(queryUri), "queryUri"); } ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri"); if (!serviceBaseUri.IsAbsoluteUri) { throw new ArgumentException(Strings.SyntacticTree_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri"); } if (maxDepth <= 0) { throw new ArgumentException(Strings.SyntacticTree_MaxDepthInvalid, "maxDepth"); } UriPathParser pathParser = new UriPathParser(maxDepth); var path = pathParser.ParsePathIntoSegments(queryUri, serviceBaseUri); List <CustomQueryOptionToken> queryOptions = UriUtils.ParseQueryOptions(queryUri); QueryToken filter = null; string filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption); if (filterQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); filter = expressionParser.ParseFilter(filterQuery); } IEnumerable <OrderByToken> orderByTokens = null; string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption); if (orderByQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); orderByTokens = expressionParser.ParseOrderBy(orderByQuery); } SelectToken select = null; string selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption); if (selectQuery != null) { ISelectExpandTermParser selectParser = SelectExpandTermParserFactory.Create(selectQuery); select = selectParser.ParseSelect(); } ExpandToken expand = null; string expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption); if (expandQuery != null) { ISelectExpandTermParser expandParser = SelectExpandTermParserFactory.Create(expandQuery); expand = expandParser.ParseExpand(); } int? skip = null; string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption); if (skipQuery != null) { int skipValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue)) { throw new ODataException(Strings.SyntacticTree_InvalidSkipQueryOptionValue(skipQuery)); } skip = skipValue; } int? top = null; string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption); if (topQuery != null) { int topValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue)) { throw new ODataException(Strings.SyntacticTree_InvalidTopQueryOptionValue(topQuery)); } top = topValue; } string inlineCountQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.InlineCountQueryOption); InlineCountKind?inlineCount = QueryTokenUtils.ParseInlineCountKind(inlineCountQuery); string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption); return(new SyntacticTree( path, filter, orderByTokens, select, expand, skip, top, inlineCount, format, queryOptions.Count == 0 ? null : new ReadOnlyCollection <CustomQueryOptionToken>(queryOptions))); }
/// <summary> /// Parses the <paramref name="queryUri"/> and returns a new instance of <see cref="QueryDescriptorQueryToken"/> /// describing the query specified by the uri. /// </summary> /// <param name="queryUri">The absolute URI which holds the query to parse. This must be a path relative to the <paramref name="serviceBaseUri"/>.</param> /// <param name="serviceBaseUri">The base URI of the service.</param> /// <param name="maxDepth">The maximum depth of any single query part. Security setting to guard against DoS attacks causing stack overflows and such.</param> /// <returns>A new instance of <see cref="QueryDescriptorQueryToken"/> which represents the query specified in the <paramref name="queryUri"/>.</returns> public static QueryDescriptorQueryToken ParseUri(Uri queryUri, Uri serviceBaseUri, int maxDepth) { ExceptionUtils.CheckArgumentNotNull(queryUri, "queryUri"); if (!queryUri.IsAbsoluteUri) { throw new ArgumentException(Strings.QueryDescriptorQueryToken_UriMustBeAbsolute(queryUri), "queryUri"); } ExceptionUtils.CheckArgumentNotNull(serviceBaseUri, "serviceBaseUri"); if (!serviceBaseUri.IsAbsoluteUri) { throw new ArgumentException(Strings.QueryDescriptorQueryToken_UriMustBeAbsolute(serviceBaseUri), "serviceBaseUri"); } if (maxDepth <= 0) { throw new ArgumentException(Strings.QueryDescriptorQueryToken_MaxDepthInvalid, "maxDepth"); } UriQueryPathParser pathParser = new UriQueryPathParser(maxDepth); QueryToken path = pathParser.ParseUri(queryUri, serviceBaseUri); List<QueryOptionQueryToken> queryOptions = UriUtils.ParseQueryOptions(queryUri); QueryToken filter = null; string filterQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FilterQueryOption); if (filterQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); filter = expressionParser.ParseFilter(filterQuery); } IEnumerable<OrderByQueryToken> orderByTokens = null; string orderByQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.OrderByQueryOption); if (orderByQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); orderByTokens = expressionParser.ParseOrderBy(orderByQuery); } SelectQueryToken select = null; string selectQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SelectQueryOption); if (selectQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); select = expressionParser.ParseSelect(selectQuery); } ExpandQueryToken expand = null; string expandQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.ExpandQueryOption); if (expandQuery != null) { UriQueryExpressionParser expressionParser = new UriQueryExpressionParser(maxDepth); expand = expressionParser.ParseExpand(expandQuery); } int? skip = null; string skipQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.SkipQueryOption); if (skipQuery != null) { int skipValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(skipQuery, out skipValue)) { throw new ODataException(Strings.QueryDescriptorQueryToken_InvalidSkipQueryOptionValue(skipQuery)); } skip = skipValue; } int? top = null; string topQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.TopQueryOption); if (topQuery != null) { int topValue; if (!UriPrimitiveTypeParser.TryUriStringToNonNegativeInteger(topQuery, out topValue)) { throw new ODataException(Strings.QueryDescriptorQueryToken_InvalidTopQueryOptionValue(topQuery)); } top = topValue; } string inlineCountQuery = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.InlineCountQueryOption); InlineCountKind? inlineCount = QueryTokenUtils.ParseInlineCountKind(inlineCountQuery); string format = queryOptions.GetQueryOptionValueAndRemove(UriQueryConstants.FormatQueryOption); return new QueryDescriptorQueryToken( path, filter, orderByTokens, select, expand, skip, top, inlineCount, format, queryOptions.Count == 0 ? null : new ReadOnlyCollection<QueryOptionQueryToken>(queryOptions)); }
/// <summary> /// Build the list of expand options /// Depends on whether options are allowed or not. /// </summary> /// <param name="isInnerTerm">is this an inner expand term</param> /// <param name="pathToken">the current level token, as a PathToken</param> /// <returns>An expand term token based on the path token, and all available expand options.</returns> internal override ExpandTermToken BuildExpandTermToken(bool isInnerTerm, PathSegmentToken pathToken) { DebugUtils.CheckNoExternalCallers(); QueryToken filterOption = null; OrderByToken orderByOption = null; long? topOption = null; long? skipOption = null; InlineCountKind?inlineCountOption = null; SelectToken selectOption = null; ExpandToken expandOption = null; if (this.Lexer.CurrentToken.Kind == ExpressionTokenKind.OpenParen) { // could have a filter, orderby, etc. or another select and expand. while (this.Lexer.PeekNextToken().Kind != ExpressionTokenKind.CloseParen) { switch (this.Lexer.NextToken().Text) { case ExpressionConstants.QueryOptionFilter: { // advance to the equal sign this.Lexer.NextToken(); string filterText = this.ReadQueryOption(); UriQueryExpressionParser filterParser = new UriQueryExpressionParser(this.MaxDepth); filterOption = filterParser.ParseFilter(filterText); break; } case ExpressionConstants.QueryOptionOrderby: { // advance to the equal sign this.Lexer.NextToken(); string orderByText = this.ReadQueryOption(); UriQueryExpressionParser orderbyParser = new UriQueryExpressionParser(this.MaxDepth); orderByOption = orderbyParser.ParseOrderBy(orderByText).Single(); break; } case ExpressionConstants.QueryOptionTop: { // advance to the equal sign this.Lexer.NextToken(); string topText = this.ReadQueryOption(); // TryParse requires a non-nullable long. long top; if (!long.TryParse(topText, out top)) { throw new ODataException(ODataErrorStrings.UriSelectParser_InvalidTopOption(topText)); } topOption = top; break; } case ExpressionConstants.QueryOptionSkip: { // advance to the equal sign this.Lexer.NextToken(); string skipText = this.ReadQueryOption(); // TryParse requires a non-nullable long. long skip; if (!long.TryParse(skipText, out skip)) { throw new ODataException(ODataErrorStrings.UriSelectParser_InvalidSkipOption(skipText)); } skipOption = skip; break; } case ExpressionConstants.QueryOptionInlineCount: { // advance to the equal sign this.Lexer.NextToken(); string inlineCountText = this.ReadQueryOption(); switch (inlineCountText) { case ExpressionConstants.InlineCountNone: { inlineCountOption = InlineCountKind.None; break; } case ExpressionConstants.InlineCountAllPages: { inlineCountOption = InlineCountKind.AllPages; break; } default: { throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(this.Lexer.ExpressionText)); } } break; } case ExpressionConstants.QueryOptionSelect: { // advance to the equal sign this.Lexer.NextToken(); selectOption = this.ParseSelect(); break; } case ExpressionConstants.QueryOptionExpand: { // advance to the equal sign this.Lexer.NextToken(); expandOption = this.ParseExpand(); break; } default: { throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(this.Lexer.ExpressionText)); } } } } else if (this.IsNotEndOfTerm(isInnerTerm)) { throw new ODataException(ODataErrorStrings.UriSelectParser_TermIsNotValid(this.Lexer.ExpressionText)); } return(new ExpandTermToken(pathToken, filterOption, orderByOption, topOption, skipOption, inlineCountOption, selectOption, expandOption)); }