Esempio n. 1
0
        /// <summary>
        /// Gets the scope required to evaluate the condition.
        /// </summary>
        /// <param name="expression">Condition expression.</param>
        /// <returns>Element attribute scope.</returns>
        private ElementAttributeScope GetRequiredScope(IConditionExpression expression)
        {
            ElementAttributeScope scope = ElementAttributeScope.Element;

            if (expression != null)
            {
                ElementAttributeExpression attributeExpression = expression as ElementAttributeExpression;
                if (attributeExpression != null)
                {
                    scope = attributeExpression.Scope;
                }
                else
                {
                    ElementAttributeScope leftScope  = GetRequiredScope(expression.Left);
                    ElementAttributeScope rightScope = GetRequiredScope(expression.Right);

                    if (leftScope > rightScope)
                    {
                        scope = leftScope;
                    }
                    else
                    {
                        scope = rightScope;
                    }
                }
            }

            return(scope);
        }
Esempio n. 2
0
 /// <summary>
 /// Creates a new element attribute expression.
 /// </summary>
 /// <param name="elementAttribute">The element attribute.</param>
 /// <param name="scope">The scope.</param>
 public ElementAttributeExpression(ElementAttributeType elementAttribute, ElementAttributeScope scope)
 {
     _elementAttributeType = elementAttribute;
     _elementScope         = scope;
 }
Esempio n. 3
0
        /// <summary>
        /// Parses and expression to an expression tree.
        /// </summary>
        /// <param name="expression">Condition expression text.</param>
        /// <returns>A condition expression instance.</returns>
        public IConditionExpression Parse(string expression)
        {
            const int            DefaultExpressionLength = 128;
            IConditionExpression conditionExpression     = null;

            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            else if (expression.Trim().Length == 0)
            {
                throw new ArgumentException("expression");
            }

            List <IConditionExpression> nodes = new List <IConditionExpression>();

            StringReader reader = new StringReader(expression);

            StringBuilder expressionBuilder = new StringBuilder(DefaultExpressionLength);

            bool inString    = false;
            bool inAttribute = false;
            int  depth       = 0;

            int data = reader.Read();

            while (data > 0)
            {
                char ch     = (char)data;
                char nextCh = (char)reader.Peek();

                if (inString && ch != '\'')
                {
                    expressionBuilder.Append(ch);
                }
                else
                {
                    switch (ch)
                    {
                    case ' ':
                    case '\t':
                    case '\r':
                    case '\n':
                        // Eat whitespace
                        break;

                    case ExpressionPrefix:
                        CheckForInvalidOperator(expression, expressionBuilder);
                        if (nextCh == ExpressionStart)
                        {
                            inAttribute = true;
                            reader.Read();
                        }
                        break;

                    case '=':
                        if (nextCh == '=')
                        {
                            nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Equal));
                            reader.Read();
                        }
                        else if (nextCh == '~')
                        {
                            nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Matches));
                            reader.Read();
                        }
                        break;

                    case '!':
                        if (nextCh == '=')
                        {
                            nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.NotEqual));
                            reader.Read();
                        }
                        else
                        {
                            expressionBuilder.Append(ch);
                        }
                        break;

                    case ':':
                        nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Contains));
                        reader.Read();
                        break;

                    case 'O':
                        if (nextCh == 'r' && !inAttribute && !inString)
                        {
                            nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.Or));
                            reader.Read();
                        }
                        else
                        {
                            expressionBuilder.Append(ch);
                        }
                        break;

                    case 'A':
                        if (nextCh == 'n' && !inAttribute && !inString)
                        {
                            reader.Read();
                            nextCh = (char)reader.Peek();
                            if (nextCh == 'd')
                            {
                                nodes.Add(new OperatorExpressionPlaceholder(BinaryExpressionOperator.And));
                                reader.Read();
                            }
                        }
                        else
                        {
                            expressionBuilder.Append(ch);
                        }
                        break;

                    case ExpressionEnd:
                        if (inAttribute)
                        {
                            string attribute = expressionBuilder.ToString();
                            expressionBuilder = new StringBuilder(DefaultExpressionLength);
                            ElementAttributeScope elementScope = ElementAttributeScope.Element;
                            bool isFileExpression = false;

                            int separatorIndex = attribute.LastIndexOf(ScopeSeparator);
                            if (separatorIndex > 0)
                            {
                                try
                                {
                                    string attributeScope = attribute.Substring(0, separatorIndex);
                                    attribute = attribute.Substring(separatorIndex + 1);

                                    if (attributeScope == FileAttributeScope)
                                    {
                                        isFileExpression = true;
                                    }
                                    else
                                    {
                                        elementScope = (ElementAttributeScope)
                                                       Enum.Parse(typeof(ElementAttributeScope), attributeScope);
                                    }
                                }
                                catch (ArgumentException ex)
                                {
                                    OnInvalidExpression(expression, "Unknown attribute scope: {0}", ex.Message);
                                }
                            }

                            if (isFileExpression)
                            {
                                FileAttributeType fileAttribute = FileAttributeType.None;

                                try
                                {
                                    fileAttribute = (FileAttributeType)
                                                    Enum.Parse(typeof(FileAttributeType), attribute);
                                }
                                catch (ArgumentException ex)
                                {
                                    OnInvalidExpression(expression, "Unknown attribute: {0}", ex.Message);
                                }

                                FileAttributeExpression attributeExpresion = new FileAttributeExpression(
                                    fileAttribute);
                                nodes.Add(attributeExpresion);
                            }
                            else
                            {
                                ElementAttributeType elementAttribute = ElementAttributeType.None;

                                try
                                {
                                    elementAttribute = (ElementAttributeType)
                                                       Enum.Parse(typeof(ElementAttributeType), attribute);
                                }
                                catch (ArgumentException ex)
                                {
                                    OnInvalidExpression(expression, "Unknown attribute: {0}", ex.Message);
                                }

                                ElementAttributeExpression attributeExpresion = new ElementAttributeExpression(
                                    elementAttribute, elementScope);
                                nodes.Add(attributeExpresion);
                            }

                            inAttribute = false;
                        }
                        else if (expressionBuilder.Length > 0 && nodes.Count > 0)
                        {
                            IConditionExpression innerExpression = nodes[nodes.Count - 1];
                            nodes.RemoveAt(nodes.Count - 1);

                            string unaryOperatorString = expressionBuilder.ToString().Trim();
                            expressionBuilder = new StringBuilder(DefaultExpressionLength);

                            UnaryExpressionOperator?unaryOperator = null;

                            if (unaryOperatorString == "!")
                            {
                                unaryOperator = UnaryExpressionOperator.Negate;
                            }
                            else
                            {
                                OnInvalidExpression(expression,
                                                    "Invalid operator {0}", unaryOperatorString);
                            }

                            UnaryOperatorExpression unaryOperatorExpression = new UnaryOperatorExpression(
                                unaryOperator.Value, innerExpression);

                            nodes.Add(unaryOperatorExpression);
                            depth--;
                        }
                        else
                        {
                            depth--;
                        }
                        break;

                    case ExpressionStart:
                        IConditionExpression nestedExpression       = null;
                        StringBuilder        childExpressionBuilder = new StringBuilder(DefaultExpressionLength);
                        data   = reader.Read();
                        ch     = (char)data;
                        nextCh = (char)reader.Peek();
                        depth++;
                        while (data > 0)
                        {
                            if (ch == ExpressionPrefix && nextCh == ExpressionStart)
                            {
                                inAttribute = true;
                                childExpressionBuilder.Append(ExpressionPrefix);
                                data = reader.Read();
                                childExpressionBuilder.Append(ExpressionStart);
                            }
                            else if (ch == ExpressionStart && !inAttribute)
                            {
                                depth++;
                                childExpressionBuilder.Append(ExpressionStart);
                            }
                            else if (nextCh == ExpressionEnd)
                            {
                                childExpressionBuilder.Append(ch);

                                if (inAttribute || depth > 1)
                                {
                                    if (inAttribute)
                                    {
                                        inAttribute = false;
                                    }
                                    else if (depth > 1)
                                    {
                                        depth--;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                childExpressionBuilder.Append(ch);
                            }

                            data   = reader.Read();
                            ch     = (char)data;
                            nextCh = (char)reader.Peek();
                        }

                        try
                        {
                            nestedExpression = Parse(childExpressionBuilder.ToString());
                        }
                        catch (ArgumentException)
                        {
                            OnInvalidExpression(expression);
                        }
                        nodes.Add(nestedExpression);
                        break;

                    case '\'':
                        if (inString)
                        {
                            if (nextCh == '\'')
                            {
                                expressionBuilder.Append(ch);
                                reader.Read();
                            }
                            else
                            {
                                string str = expressionBuilder.ToString();
                                expressionBuilder = new StringBuilder(DefaultExpressionLength);
                                StringExpression stringExpression = new StringExpression(str);
                                nodes.Add(stringExpression);
                                inString = false;
                            }
                        }
                        else
                        {
                            CheckForInvalidOperator(expression, expressionBuilder);
                            inString = true;
                        }

                        break;

                    default:
                        expressionBuilder.Append(ch);
                        break;
                    }
                }

                data = reader.Read();
            }

            if (inString)
            {
                OnInvalidExpression(expression, "Expected '");
            }
            else if (inAttribute || depth > 0)
            {
                OnInvalidExpression(expression, "Expected )");
            }
            else if (depth < 0)
            {
                OnInvalidExpression(expression, "Unmatched )");
            }

            //
            // Assembly the flat list of expressions and expression placeholders into an
            // expression tree.
            //
            conditionExpression = AssembleExpressionTree(nodes.AsReadOnly(), expression);

            return(conditionExpression);
        }
 /// <summary>
 /// Creates a new element attribute expression.
 /// </summary>
 /// <param name="elementAttribute">The element attribute.</param>
 /// <param name="scope">The scope.</param>
 public ElementAttributeExpression(ElementAttributeType elementAttribute, ElementAttributeScope scope)
 {
     _elementAttributeType = elementAttribute;
     _elementScope = scope;
 }
Esempio n. 5
0
 /// <summary>
 /// Creates a new ElementFilter.
 /// </summary>
 /// <param name="conditionExpression">The condition expression.</param>
 public ElementFilter(string conditionExpression)
 {
     _conditionExpression = ConditionExpressionParser.Instance.Parse(conditionExpression);
     _requiredScope       = GetRequiredScope(_conditionExpression);
 }
Esempio n. 6
0
 /// <summary>
 /// Creates a new ElementFilter.
 /// </summary>
 /// <param name="conditionExpression">The condition expression.</param>
 public ElementFilter(string conditionExpression)
 {
     _conditionExpression = ConditionExpressionParser.Instance.Parse(conditionExpression);
     _requiredScope = GetRequiredScope(_conditionExpression);
 }