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);
}
}
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;
}
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;
}
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());
}
}
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;
}
Aggregations