001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.language.simple.ast;
018
019import org.apache.camel.Exchange;
020import org.apache.camel.Expression;
021import org.apache.camel.Predicate;
022import org.apache.camel.builder.PredicateBuilder;
023import org.apache.camel.language.simple.types.LogicalOperatorType;
024import org.apache.camel.language.simple.types.SimpleParserException;
025import org.apache.camel.language.simple.types.SimpleToken;
026import org.apache.camel.util.ExpressionToPredicateAdapter;
027import org.apache.camel.util.ObjectHelper;
028
029/**
030 * Represents a logical expression in the AST
031 */
032public class LogicalExpression extends BaseSimpleNode {
033
034    private LogicalOperatorType operator;
035    private SimpleNode left;
036    private SimpleNode right;
037
038    public LogicalExpression(SimpleToken token) {
039        super(token);
040        operator = LogicalOperatorType.asOperator(token.getText());
041    }
042
043    @Override
044    public String toString() {
045        return left + " " + token.getText() + " " + right;
046    }
047
048    public boolean acceptLeftNode(SimpleNode lef) {
049        this.left = lef;
050        return true;
051    }
052
053    public boolean acceptRightNode(SimpleNode right) {
054        this.right = right;
055        return true;
056    }
057
058    public LogicalOperatorType getOperator() {
059        return operator;
060    }
061
062    @Override
063    public Expression createExpression(String expression) {
064        ObjectHelper.notNull(left, "left node", this);
065        ObjectHelper.notNull(right, "right node", this);
066
067        final Expression leftExp = left.createExpression(expression);
068        final Expression rightExp = right.createExpression(expression);
069
070        if (operator == LogicalOperatorType.AND) {
071            return createAndExpression(leftExp, rightExp);
072        } else if (operator == LogicalOperatorType.OR) {
073            return createOrExpression(leftExp, rightExp);
074        }
075
076        throw new SimpleParserException("Unknown logical operator " + operator, token.getIndex());
077    }
078
079    private Expression createAndExpression(final Expression leftExp, final Expression rightExp) {
080        return new Expression() {
081            @Override
082            public <T> T evaluate(Exchange exchange, Class<T> type) {
083                Predicate predicate = ExpressionToPredicateAdapter.toPredicate(leftExp);
084                predicate = PredicateBuilder.and(predicate, ExpressionToPredicateAdapter.toPredicate(rightExp));
085
086                boolean answer = predicate.matches(exchange);
087                return exchange.getContext().getTypeConverter().convertTo(type, answer);
088            }
089
090            @Override
091            public String toString() {
092                return left + " " + token.getText() + " " + right;
093            }
094        };
095    }
096
097    private Expression createOrExpression(final Expression leftExp, final Expression rightExp) {
098        return new Expression() {
099            @Override
100            public <T> T evaluate(Exchange exchange, Class<T> type) {
101                Predicate predicate = ExpressionToPredicateAdapter.toPredicate(leftExp);
102                predicate = PredicateBuilder.or(predicate, ExpressionToPredicateAdapter.toPredicate(rightExp));
103
104                boolean answer = predicate.matches(exchange);
105                return exchange.getContext().getTypeConverter().convertTo(type, answer);
106            }
107
108            @Override
109            public String toString() {
110                return left + " " + token.getText() + " " + right;
111            }
112        };
113    }
114
115}