Search in sources :

Example 21 with ASTIdentifier

use of org.apache.commons.jexl2.parser.ASTIdentifier in project commons-jexl by apache.

the class Interpreter method visit.

@Override
protected Object visit(final ASTFunctionNode node, final Object data) {
    final ASTIdentifier functionNode = (ASTIdentifier) node.jjtGetChild(0);
    final String nsid = functionNode.getNamespace();
    final Object namespace = (nsid != null) ? resolveNamespace(nsid, node) : context;
    final ASTArguments argNode = (ASTArguments) node.jjtGetChild(1);
    return call(node, namespace, functionNode, argNode);
}
Also used : ASTIdentifier(org.apache.commons.jexl3.parser.ASTIdentifier) ASTArguments(org.apache.commons.jexl3.parser.ASTArguments)

Example 22 with ASTIdentifier

use of org.apache.commons.jexl2.parser.ASTIdentifier in project commons-jexl by apache.

the class Interpreter method visit.

@Override
protected Object visit(final ASTReference node, final Object data) {
    cancelCheck(node);
    final int numChildren = node.jjtGetNumChildren();
    final JexlNode parent = node.jjtGetParent();
    // pass first piece of data in and loop through children
    Object object = null;
    JexlNode objectNode = null;
    JexlNode ptyNode = null;
    StringBuilder ant = null;
    boolean antish = !(parent instanceof ASTReference);
    int v = 1;
    main: for (int c = 0; c < numChildren; c++) {
        objectNode = node.jjtGetChild(c);
        if (objectNode instanceof ASTMethodNode) {
            antish = false;
            if (object == null) {
                // we may be performing a method call on an antish var
                if (ant != null) {
                    final JexlNode child = objectNode.jjtGetChild(0);
                    if (child instanceof ASTIdentifierAccess) {
                        final int alen = ant.length();
                        ant.append('.');
                        ant.append(((ASTIdentifierAccess) child).getName());
                        object = context.get(ant.toString());
                        if (object != null) {
                            object = visit((ASTMethodNode) objectNode, object, context);
                            continue;
                        }
                        // remove method name from antish
                        ant.delete(alen, ant.length());
                        ptyNode = objectNode;
                    }
                }
                break;
            }
        } else if (objectNode instanceof ASTArrayAccess) {
            antish = false;
            if (object == null) {
                ptyNode = objectNode;
                break;
            }
        }
        // attempt to evaluate the property within the object (visit(ASTIdentifierAccess node))
        object = objectNode.jjtAccept(this, object);
        cancelCheck(node);
        if (object != null) {
            // disallow mixing antish variable & bean with same root; avoid ambiguity
            antish = false;
        } else if (antish) {
            // create first from first node
            if (ant == null) {
                // if we still have a null object, check for an antish variable
                final JexlNode first = node.jjtGetChild(0);
                if (!(first instanceof ASTIdentifier)) {
                    // not an identifier, not antish
                    ptyNode = objectNode;
                    break main;
                }
                final ASTIdentifier afirst = (ASTIdentifier) first;
                ant = new StringBuilder(afirst.getName());
                // *... and continue
                if (!options.isAntish()) {
                    antish = false;
                    continue;
                }
                // skip the first node case since it was trialed in jjtAccept above and returned null
                if (c == 0) {
                    continue;
                }
            }
            // catch up to current node
            for (; v <= c; ++v) {
                final JexlNode child = node.jjtGetChild(v);
                if (!(child instanceof ASTIdentifierAccess)) {
                    // not an identifier, not antish
                    ptyNode = objectNode;
                    break main;
                }
                final ASTIdentifierAccess achild = (ASTIdentifierAccess) child;
                if (achild.isSafe() || achild.isExpression()) {
                    break main;
                }
                ant.append('.');
                ant.append(achild.getName());
            }
            // solve antish
            object = context.get(ant.toString());
        } else if (c != numChildren - 1) {
            // only the last one may be null
            ptyNode = objectNode;
            // 
            break;
        }
    }
    // dealing with null
    if (object == null) {
        if (ptyNode != null) {
            if (ptyNode.isSafeLhs(isSafe())) {
                return null;
            }
            if (ant != null) {
                final String aname = ant.toString();
                final boolean defined = isVariableDefined(frame, block, aname);
                return unsolvableVariable(node, aname, !defined);
            }
            return unsolvableProperty(node, stringifyProperty(ptyNode), ptyNode == objectNode, null);
        }
        if (antish) {
            if (node.isSafeLhs(isSafe())) {
                return null;
            }
            final String aname = ant != null ? ant.toString() : "?";
            final boolean defined = isVariableDefined(frame, block, aname);
            // defined but null; arg of a strict operator?
            if (defined && !isStrictOperand(node)) {
                return null;
            }
            return unsolvableVariable(node, aname, !defined);
        }
    }
    return object;
}
Also used : JexlNode(org.apache.commons.jexl3.parser.JexlNode) ASTIdentifier(org.apache.commons.jexl3.parser.ASTIdentifier) ASTMethodNode(org.apache.commons.jexl3.parser.ASTMethodNode) ASTReference(org.apache.commons.jexl3.parser.ASTReference) ASTIdentifierAccess(org.apache.commons.jexl3.parser.ASTIdentifierAccess) ASTArrayAccess(org.apache.commons.jexl3.parser.ASTArrayAccess)

Example 23 with ASTIdentifier

use of org.apache.commons.jexl2.parser.ASTIdentifier in project commons-jexl by apache.

the class TemplateInterpreter method visit.

/**
 * Interprets a function node.
 * print() and include() must be decoded by this interpreter since delegating to the Uberspect
 * may be sandboxing the interpreter itself making it unable to call the function.
 * @param node the function node
 * @param data the data
 * @return the function evaluation result.
 */
@Override
protected Object visit(final ASTFunctionNode node, Object data) {
    final int argc = node.jjtGetNumChildren();
    if (argc == 2) {
        final ASTIdentifier functionNode = (ASTIdentifier) node.jjtGetChild(0);
        if ("jexl".equals(functionNode.getNamespace())) {
            final String functionName = functionNode.getName();
            final ASTArguments argNode = (ASTArguments) node.jjtGetChild(1);
            if ("print".equals(functionName)) {
                // evaluate the arguments
                Object[] argv = visit(argNode, null);
                if (argv != null && argv.length > 0 && argv[0] instanceof Number) {
                    print(((Number) argv[0]).intValue());
                    return null;
                }
            }
            if ("include".equals(functionName)) {
                // evaluate the arguments
                Object[] argv = visit(argNode, null);
                if (argv != null && argv.length > 0) {
                    if (argv[0] instanceof TemplateScript) {
                        TemplateScript script = (TemplateScript) argv[0];
                        if (argv.length > 1) {
                            argv = Arrays.copyOfRange(argv, 1, argv.length);
                        } else {
                            argv = null;
                        }
                        include(script, argv);
                        return null;
                    }
                }
            }
            // fail safe
            throw new JxltEngine.Exception(node.jexlInfo(), "no callable template function " + functionName, null);
        }
    }
    return super.visit(node, data);
}
Also used : ASTIdentifier(org.apache.commons.jexl3.parser.ASTIdentifier) ASTArguments(org.apache.commons.jexl3.parser.ASTArguments)

Example 24 with ASTIdentifier

use of org.apache.commons.jexl2.parser.ASTIdentifier in project commons-jexl by apache.

the class Dumper method dump.

private void dump(final JexlNode node, final Object data) {
    final int num = node.jjtGetNumChildren();
    indent();
    strb.append(node.getClass().getSimpleName());
    if (node instanceof ASTIdentifier) {
        strb.append("@");
        strb.append(node.toString());
    } else if (node instanceof ASTIdentifierAccess) {
        strb.append("@");
        strb.append(node.toString());
    }
    strb.append('(');
    indent += 1;
    for (int c = 0; c < num; ++c) {
        final JexlNode child = node.jjtGetChild(c);
        if (c > 0) {
            strb.append(',');
        }
        strb.append('\n');
        dump(child, data);
    }
    indent -= 1;
    if (num > 0) {
        strb.append('\n');
        indent();
    }
    strb.append(')');
}
Also used : ASTIdentifier(org.apache.commons.jexl3.parser.ASTIdentifier) JexlNode(org.apache.commons.jexl3.parser.JexlNode) ASTIdentifierAccess(org.apache.commons.jexl3.parser.ASTIdentifierAccess)

Example 25 with ASTIdentifier

use of org.apache.commons.jexl2.parser.ASTIdentifier in project commons-jexl by apache.

the class Engine method getVariables.

/**
 * Fills up the list of variables accessed by a node.
 * @param script the owning script
 * @param node the node
 * @param collector the variable collector
 */
protected void getVariables(final ASTJexlScript script, final JexlNode node, final VarCollector collector) {
    if (node instanceof ASTIdentifier) {
        final JexlNode parent = node.jjtGetParent();
        if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
            // skip identifiers for methods and functions
            collector.collect(null);
            return;
        }
        final ASTIdentifier identifier = (ASTIdentifier) node;
        final int symbol = identifier.getSymbol();
        // symbols that are captured are considered "global" variables
        if (symbol >= 0 && script != null && !script.isCapturedSymbol(symbol)) {
            collector.collect(null);
        } else {
            // start collecting from identifier
            collector.collect(identifier);
            collector.add(identifier.getName());
        }
    } else if (node instanceof ASTIdentifierAccess) {
        final JexlNode parent = node.jjtGetParent();
        if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
            // skip identifiers for methods and functions
            collector.collect(null);
            return;
        }
        // belt and suspender since an identifier should have been seen first
        if (collector.isCollecting()) {
            collector.add(((ASTIdentifierAccess) node).getName());
        }
    } else if (node instanceof ASTArrayAccess && collector.mode > 0) {
        final int num = node.jjtGetNumChildren();
        // collect only if array access is const and follows an identifier
        boolean collecting = collector.isCollecting();
        for (int i = 0; i < num; ++i) {
            final JexlNode child = node.jjtGetChild(i);
            if (collecting && child.isConstant()) {
                // collect all constants or only string and number literals
                final boolean collect = collector.mode > 1 || (child instanceof ASTStringLiteral || child instanceof ASTNumberLiteral);
                if (collect) {
                    final String image = child.toString();
                    collector.add(image);
                }
            } else {
                collecting = false;
                collector.collect(null);
                getVariables(script, child, collector);
                collector.collect(null);
            }
        }
    } else {
        final int num = node.jjtGetNumChildren();
        for (int i = 0; i < num; ++i) {
            getVariables(script, node.jjtGetChild(i), collector);
        }
        collector.collect(null);
    }
}
Also used : ASTStringLiteral(org.apache.commons.jexl3.parser.ASTStringLiteral) ASTFunctionNode(org.apache.commons.jexl3.parser.ASTFunctionNode) ASTIdentifier(org.apache.commons.jexl3.parser.ASTIdentifier) JexlNode(org.apache.commons.jexl3.parser.JexlNode) ASTMethodNode(org.apache.commons.jexl3.parser.ASTMethodNode) ASTIdentifierAccess(org.apache.commons.jexl3.parser.ASTIdentifierAccess) ASTArrayAccess(org.apache.commons.jexl3.parser.ASTArrayAccess) ASTNumberLiteral(org.apache.commons.jexl3.parser.ASTNumberLiteral)

Aggregations

ASTIdentifier (org.apache.commons.jexl2.parser.ASTIdentifier)26 JexlNode (org.apache.commons.jexl2.parser.JexlNode)19 ASTReference (org.apache.commons.jexl2.parser.ASTReference)10 ASTIdentifier (org.apache.commons.jexl3.parser.ASTIdentifier)10 ExceededValueThresholdMarkerJexlNode (datawave.query.jexl.nodes.ExceededValueThresholdMarkerJexlNode)8 ExceededTermThresholdMarkerJexlNode (datawave.query.jexl.nodes.ExceededTermThresholdMarkerJexlNode)7 ASTEQNode (org.apache.commons.jexl2.parser.ASTEQNode)7 ASTStringLiteral (org.apache.commons.jexl2.parser.ASTStringLiteral)7 JexlNode (org.apache.commons.jexl3.parser.JexlNode)7 ASTNENode (org.apache.commons.jexl2.parser.ASTNENode)6 ASTFunctionNode (org.apache.commons.jexl2.parser.ASTFunctionNode)5 ASTGENode (org.apache.commons.jexl2.parser.ASTGENode)5 ASTGTNode (org.apache.commons.jexl2.parser.ASTGTNode)5 ASTLENode (org.apache.commons.jexl2.parser.ASTLENode)5 ASTLTNode (org.apache.commons.jexl2.parser.ASTLTNode)5 ASTIdentifierAccess (org.apache.commons.jexl3.parser.ASTIdentifierAccess)5 ASTAndNode (org.apache.commons.jexl2.parser.ASTAndNode)4 ASTERNode (org.apache.commons.jexl2.parser.ASTERNode)4 ASTNullLiteral (org.apache.commons.jexl2.parser.ASTNullLiteral)4 ASTOrNode (org.apache.commons.jexl2.parser.ASTOrNode)4