Ejemplo n.º 1
0
        /// <summary>Attempts to parse key values from the specified text.</summary>
        /// <param name='text'>Text to parse (not null).</param>
        /// <param name="allowNamedValues">Set to true if the parser should accept named values
        ///     so syntax like Name='value'. If this is false, the parsing will fail on such constructs.</param>
        /// <param name="allowNull">Set to true if the parser should accept null values.
        ///     If set to false, the parser will fail on null values.</param>
        /// <param name='instance'>After invocation, the parsed key instance.</param>
        /// <param name="enableUriTemplateParsing">Whether Uri template parsing is enabled.</param>
        /// <returns>
        /// true if the key instance was parsed; false if there was a
        /// syntactic error.
        /// </returns>
        /// <remarks>
        /// The returned instance contains only string values. To get typed values, a call to
        /// TryConvertValues is necessary.
        /// </remarks>
        private static bool TryParseFromUri(string text, bool allowNamedValues, bool allowNull, out SegmentArgumentParser instance, bool enableUriTemplateParsing)
        {
            Debug.Assert(text != null, "text != null");

            Dictionary <string, string> namedValues = null;
            List <string> positionalValues          = null;

            // parse keys just like function parameters
            ExpressionLexer          lexer      = new ExpressionLexer("(" + text + ")", true, false);
            UriQueryExpressionParser exprParser = new UriQueryExpressionParser(ODataUriParserSettings.DefaultFilterLimit /* default limit for parsing key value */, lexer);
            var tmp = (new FunctionCallParser(lexer, exprParser)).ParseArgumentListOrEntityKeyList();

            if (lexer.CurrentToken.Kind != ExpressionTokenKind.End)
            {
                instance = null;
                return(false);
            }

            if (tmp.Length == 0)
            {
                instance = Empty;
                return(true);
            }

            string valueText = null;

            foreach (FunctionParameterToken t in tmp)
            {
                valueText = null;
                LiteralToken literalToken = t.ValueToken as LiteralToken;
                if (literalToken != null)
                {
                    valueText = literalToken.OriginalText;

                    // disallow "{...}" if enableUriTemplateParsing is false (which could have been seen as valid function parameter, e.g. array notation)
                    if (!enableUriTemplateParsing && UriTemplateParser.IsValidTemplateLiteral(valueText))
                    {
                        instance = null;
                        return(false);
                    }
                }
                else
                {
                    DottedIdentifierToken dottedIdentifierToken = t.ValueToken as DottedIdentifierToken; // for enum
                    if (dottedIdentifierToken != null)
                    {
                        valueText = dottedIdentifierToken.Identifier;
                    }
                }

                if (valueText != null)
                {
                    if (t.ParameterName == null)
                    {
                        if (namedValues != null)
                        {
                            instance = null; // We cannot mix named and non-named values.
                            return(false);
                        }

                        CreateIfNull(ref positionalValues);
                        positionalValues.Add(valueText);
                    }
                    else
                    {
                        if (positionalValues != null)
                        {
                            instance = null; // We cannot mix named and non-named values.
                            return(false);
                        }

                        CreateIfNull(ref namedValues);
                        namedValues.Add(t.ParameterName, valueText);
                    }
                }
                else
                {
                    instance = null;
                    return(false);
                }
            }

            instance = new SegmentArgumentParser(namedValues, positionalValues, false, enableUriTemplateParsing);
            return(true);
        }
 /// <summary>
 /// Whether given token is valid for keyPropertyValue, allow Uri template {key} if template parsing is enabled
 /// </summary>
 /// <param name="token">The literal token to be evaluated.</param>
 /// <param name="enableUriTemplateParsing">Whether Uri template parsing is enabled.</param>
 /// <returns>Whether token is valid for keyPropertyValue.</returns>
 private static bool IsKeyValueToken(ExpressionToken token, bool enableUriTemplateParsing)
 {
     return(token.IsKeyValueToken || (enableUriTemplateParsing && UriTemplateParser.IsValidTemplateLiteral(token.Text)));
 }