Search in sources :

Example 1 with FormulaFunction

use of org.activityinfo.model.formula.functions.FormulaFunction in project activityinfo by bedatadriven.

the class XPathBuilder method appendTo.

private void appendTo(FormulaNode formulaNode, StringBuilder xpath) {
    if (formulaNode instanceof ConstantNode) {
        ConstantNode constantNode = (ConstantNode) formulaNode;
        FieldValue value = constantNode.getValue();
        if (value instanceof BooleanFieldValue) {
            BooleanFieldValue booleanFieldValue = (BooleanFieldValue) value;
            xpath.append(booleanFieldValue.asBoolean() ? TRUE : FALSE);
        } else if (value instanceof EnumValue) {
            String xpathExpr = resolveSymbol(formulaNode);
            xpath.append(xpathExpr);
        } else {
            xpath.append(constantNode.asExpression());
        }
    } else if (formulaNode instanceof FunctionCallNode) {
        FunctionCallNode functionCallNode = (FunctionCallNode) formulaNode;
        List<FormulaNode> arguments = functionCallNode.getArguments();
        FormulaFunction function = functionCallNode.getFunction();
        switch(function.getId()) {
            case "&&":
                appendBinaryInfixTo("and", arguments, xpath);
                break;
            case "==":
                appendBinaryInfixTo("=", arguments, xpath);
                break;
            case "||":
                appendBinaryInfixTo("or", arguments, xpath);
                break;
            case "containsAny":
            case "containsAll":
            case "notContainsAny":
            case "notContainsAll":
                appendFunction(function.getId(), arguments, xpath);
                break;
            case "!=":
            case ">":
            case ">=":
            case "<":
            case "<=":
                appendBinaryInfixTo(function.getId(), arguments, xpath);
                break;
            case "!":
                appendUnaryFunction("not", arguments.get(0), xpath);
                break;
            default:
                throw new XPathBuilderException("Unsupported function " + function.getId());
        }
    } else if (formulaNode instanceof GroupNode) {
        GroupNode groupNode = (GroupNode) formulaNode;
        FormulaNode expr = groupNode.getExpr();
        xpath.append("(");
        appendTo(expr, xpath);
        xpath.append(")");
    } else if (formulaNode instanceof SymbolNode) {
        SymbolNode symbolNode = (SymbolNode) formulaNode;
        String xpathExpr = resolveSymbol(symbolNode);
        xpath.append(xpathExpr);
    } else if (formulaNode instanceof CompoundExpr) {
        CompoundExpr compoundExpr = (CompoundExpr) formulaNode;
        List<FormulaNode> arguments = new ArrayList<>();
        arguments.add(compoundExpr.getValue());
        arguments.add(compoundExpr.getField());
        appendBinaryInfixTo("=", arguments, xpath);
    } else {
        throw new XPathBuilderException("Unknown expr node " + formulaNode);
    }
}
Also used : FormulaFunction(org.activityinfo.model.formula.functions.FormulaFunction) EnumValue(org.activityinfo.model.type.enumerated.EnumValue) ArrayList(java.util.ArrayList) BooleanFieldValue(org.activityinfo.model.type.primitive.BooleanFieldValue) ArrayList(java.util.ArrayList) List(java.util.List) FieldValue(org.activityinfo.model.type.FieldValue) BooleanFieldValue(org.activityinfo.model.type.primitive.BooleanFieldValue)

Example 2 with FormulaFunction

use of org.activityinfo.model.formula.functions.FormulaFunction in project activityinfo by bedatadriven.

the class FormulaParser method conjunction.

private FormulaNode conjunction() {
    FormulaNode left = equality();
    while (lexer.hasNext() && lexer.peek().isAndOperator()) {
        FormulaFunction op = function();
        FormulaNode right = equality();
        left = binaryInfixCall(op, left, right);
    }
    return left;
}
Also used : FormulaFunction(org.activityinfo.model.formula.functions.FormulaFunction)

Example 3 with FormulaFunction

use of org.activityinfo.model.formula.functions.FormulaFunction in project activityinfo by bedatadriven.

the class FormulaParser method term.

private FormulaNode term() {
    // <term> ::= <factor> | <term> + <factor> | <term> - <factor>
    FormulaNode left = factor();
    while (lexer.hasNext() && lexer.peek().isAdditiveOperator()) {
        FormulaFunction op = function();
        FormulaNode right = factor();
        left = binaryInfixCall(op, left, right);
    }
    return left;
}
Also used : FormulaFunction(org.activityinfo.model.formula.functions.FormulaFunction)

Example 4 with FormulaFunction

use of org.activityinfo.model.formula.functions.FormulaFunction in project activityinfo by bedatadriven.

the class FormulaParser method call.

private FormulaNode call(Token functionToken) {
    FormulaFunction function = function(functionToken);
    expect(TokenType.PAREN_START);
    List<FormulaNode> arguments = new ArrayList<>();
    while (true) {
        if (!lexer.hasNext()) {
            throw new FormulaSyntaxException("Unexpected end of formula");
        }
        TokenType nextToken = lexer.peek().getType();
        if (nextToken == TokenType.COMMA) {
            // Consume comma and parse next argument
            lexer.next();
            continue;
        }
        if (nextToken == TokenType.PAREN_END) {
            // consume paren and complete argument list
            Token closingParen = lexer.next();
            return new FunctionCallNode(function, arguments, new SourceRange(functionToken, closingParen));
        }
        // Otherwise parse the next argument
        arguments.add(expression());
    }
}
Also used : FormulaFunction(org.activityinfo.model.formula.functions.FormulaFunction) FormulaSyntaxException(org.activityinfo.model.formula.diagnostic.FormulaSyntaxException) ArrayList(java.util.ArrayList)

Example 5 with FormulaFunction

use of org.activityinfo.model.formula.functions.FormulaFunction in project activityinfo by bedatadriven.

the class FormulaParser method relational.

private FormulaNode relational() {
    FormulaNode left = term();
    while (lexer.hasNext() && lexer.peek().isRelationalOperator()) {
        FormulaFunction op = function();
        FormulaNode right = term();
        left = binaryInfixCall(op, left, right);
    }
    return left;
}
Also used : FormulaFunction(org.activityinfo.model.formula.functions.FormulaFunction)

Aggregations

FormulaFunction (org.activityinfo.model.formula.functions.FormulaFunction)10 FormulaSyntaxException (org.activityinfo.model.formula.diagnostic.FormulaSyntaxException)3 ArrayList (java.util.ArrayList)2 List (java.util.List)1 FieldValue (org.activityinfo.model.type.FieldValue)1 EnumValue (org.activityinfo.model.type.enumerated.EnumValue)1 BooleanFieldValue (org.activityinfo.model.type.primitive.BooleanFieldValue)1