Package org.datanucleus.query.node

Examples of org.datanucleus.query.node.Node


        for (;;)
        {
            if (p.parseChar('+'))
            {
                processMultiplicativeExpression();
                Node expr = new Node(Node.OPERATOR, "+");
                expr.insertChildNode(stack.pop());
                expr.insertChildNode(stack.pop());
                stack.push(expr);
            }
            else if (p.parseChar('-'))
            {
                processMultiplicativeExpression();
                Node expr = new Node(Node.OPERATOR, "-");
                expr.insertChildNode(stack.pop());
                expr.insertChildNode(stack.pop());
                stack.push(expr);
            }
            else
            {
                break;
View Full Code Here


        for (;;)
        {
            if (p.parseChar('*'))
            {
                processMultiplicativeExpression();
                Node expr = new Node(Node.OPERATOR, "*");
                expr.insertChildNode(stack.pop());
                expr.insertChildNode(stack.pop());
                stack.push(expr);
            }
            else if (p.parseChar('/'))
            {
                processMultiplicativeExpression();
                Node expr = new Node(Node.OPERATOR, "/");
                expr.insertChildNode(stack.pop());
                expr.insertChildNode(stack.pop());
                stack.push(expr);
            }
            else if (p.parseChar('%'))
            {
                processMultiplicativeExpression();
                Node expr = new Node(Node.OPERATOR, "%");
                expr.insertChildNode(stack.pop());
                expr.insertChildNode(stack.pop());
                stack.push(expr);
            }
            else
            {
                break;
View Full Code Here

            processUnaryExpression();
        }
        else if (p.parseChar('-'))
        {
            processUnaryExpression();
            Node expr = new Node(Node.OPERATOR, "-");
            expr.insertChildNode(stack.pop());
            stack.push(expr);
        }
        else if (p.parseStringIgnoreCase("NOT "))
        {
            processUnaryExpression();
            Node expr = new Node(Node.OPERATOR, "!");
            expr.insertChildNode(stack.pop());
            stack.push(expr);
        }
        else
        {
            processPrimary();
View Full Code Here

    protected void processPrimary()
    {
        if (p.parseStringIgnoreCase("CURRENT_DATE"))
        {
            // Convert to a method call
            Node expr = new Node(Node.INVOKE, "CURRENT_DATE");
            stack.push(expr);
            return;
        }
        else if (p.parseStringIgnoreCase("CURRENT_TIMESTAMP"))
        {
            // Convert to a method call
            Node expr = new Node(Node.INVOKE, "CURRENT_TIMESTAMP");
            stack.push(expr);
            return;
        }
        else if (p.parseStringIgnoreCase("CURRENT_TIME"))
        {
            // Convert to a method call
            Node expr = new Node(Node.INVOKE, "CURRENT_TIME");
            stack.push(expr);
            return;
        }
        else if (p.parseStringIgnoreCase("DISTINCT "))
        {
            // Aggregates can have "count(DISTINCT field1)"
            Node distinctNode = new Node(Node.OPERATOR, "DISTINCT");
            processIdentifier();
            Node identifierNode = stack.pop();
            distinctNode.appendChildNode(identifierNode);
            stack.push(distinctNode);
            return;
        }
        else if (processCreator() || processLiteral() || processMethod())
        {
            return;
        }

        if (p.parseChar('('))
        {
            processExpression();
            if (!p.parseChar(')'))
            {
                throw new QueryCompilerSyntaxException("expected ')'", p.getIndex(), p.getInput());
            }
            return;
        }

        // if primary == null, literal not found...
        // We will have an identifier (variable, parameter, or field of candidate class)
        if (!processIdentifier())
        {
            throw new QueryCompilerSyntaxException("Identifier expected", p.getIndex(), p.getInput());
        }
        int size = stack.size();

        // Generate Node tree, including chained operations
        // e.g identifier.methodX().methodY().methodZ()
        //     -> node (IDENTIFIER) with child (INVOKE), with child (INVOKE), with child (INVOKE)
        // e.g identifier.fieldX.fieldY.fieldZ
        //     -> node (IDENTIFIER) with child (IDENTIFIER), with child (IDENTIFIER), with child (IDENTIFIER)
        while (p.parseChar('.'))
        {
            if (processMethod())
            {
                // "a.method(...)"
            }
            else if (processIdentifier())
            {
                // "a.field"
            }
            else
            {
                throw new QueryCompilerSyntaxException("Identifier expected", p.getIndex(), p.getInput());
            }
        }

        // For all added nodes, step back and chain them so we have
        // Node[IDENTIFIER, a]
        // +--- Node[IDENTIFIER, b]
        //      +--- Node[IDENTIFIER, c]
        while (stack.size() > size)
        {
            Node top = stack.pop();
            Node peek = stack.peek();
            peek.insertChildNode(top);
        }
    }
View Full Code Here

                    }
                }
            }
            while (stack.size() - 1 > size)
            {
                Node top =  stack.pop();
                Node peek = stack.peek();
                peek.insertChildNode(top);
            }
            Node expr = stack.pop();
            Node newExpr = new Node(Node.CREATOR);
            newExpr.insertChildNode(expr);
            stack.push(newExpr);
            return true;
        }
        return false;
    }
View Full Code Here

                }
                return true;
            }
            if (method.equalsIgnoreCase("EXISTS"))
            {
                Node existsNode = new Node(Node.SUBQUERY, "EXISTS");
                processExpression(); // subquery variable
                Node subqueryNode = stack.pop();
                existsNode.appendChildNode(subqueryNode);
                stack.push(existsNode);
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }
                return true;
            }
            else if (method.equalsIgnoreCase("ANY"))
            {
                Node existsNode = new Node(Node.SUBQUERY, "ANY");
                processExpression(); // subquery variable
                Node subqueryNode = stack.pop();
                existsNode.appendChildNode(subqueryNode);
                stack.push(existsNode);
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }
                return true;
            }
            else if (method.equalsIgnoreCase("ALL"))
            {
                Node existsNode = new Node(Node.SUBQUERY, "ALL");
                processExpression(); // subquery variable
                Node subqueryNode = stack.pop();
                existsNode.appendChildNode(subqueryNode);
                stack.push(existsNode);
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }
                return true;
            }
            else if (method.equalsIgnoreCase("SOME"))
            {
                Node existsNode = new Node(Node.SUBQUERY, "SOME");
                processExpression(); // subquery variable
                Node subqueryNode = stack.pop();
                existsNode.appendChildNode(subqueryNode);
                stack.push(existsNode);
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }
                return true;
            }
            else if (method.equalsIgnoreCase("SUBSTRING"))
            {
                // SUBSTRING(string_primary, simple_arithmetic_expression[, simple_arithmetic_expression])
                // Convert to be {primary}.INVOKE(substring, {arg1[, arg2]})
                Node invokeNode = new Node(Node.INVOKE, "substring");
                processExpression();
                Node primaryNode = stack.pop();
                if (!p.parseChar(','))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                // First arg to substring(...) has origin 0, but JPQL has origin 1!
                processExpression();
                Node arg1 = stack.pop();
                Node oneNode = new Node(Node.LITERAL, 1);
                Node arg1Node = new Node(Node.OPERATOR, "-");
                arg1Node.insertChildNode(arg1);
                arg1Node.appendChildNode(oneNode);

                if (p.parseChar(','))
                {
                    // String.substring(arg1, arg2)
                    // Second arg to substring(...) has origin 0, but in JPQL is length of result!
                    processExpression();
                    Node arg2 = stack.pop();
                    Node arg2Node = new Node(Node.OPERATOR, "+");
                    arg2Node.appendChildNode(arg2);
                    arg2Node.appendChildNode(arg1Node);
                    if (!p.parseChar(')'))
                    {
                        throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                    }

                    primaryNode.appendChildNode(invokeNode);
                    invokeNode.addProperty(arg1Node);
                    invokeNode.addProperty(arg2Node);
                    stack.push(primaryNode);
                    return true;
                }
                else if (p.parseChar(')'))
                {
                    // String.substring(arg1)
                    primaryNode.appendChildNode(invokeNode);
                    invokeNode.addProperty(arg1Node);
                    stack.push(primaryNode);
                    return true;
                }
                else
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }
            }
            else if (method.equalsIgnoreCase("UPPER"))
            {
                // UPPER(string_primary)
                // Convert to be {primary}.INVOKE(toUpper)
                Node invokeNode = new Node(Node.INVOKE, "toUpperCase");
                processExpression();
                Node primaryNode = stack.pop();
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("LOWER"))
            {
                // UPPER(string_primary)
                // Convert to be {primary}.INVOKE(toLower)
                Node invokeNode = new Node(Node.INVOKE, "toLowerCase");
                processExpression();
                Node primaryNode = stack.pop();
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("LENGTH"))
            {
                // LENGTH(string_primary)
                // Convert to be {primary}.INVOKE(length)
                Node invokeNode = new Node(Node.INVOKE, "length");
                processExpression();
                Node primaryNode = stack.pop();
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("CONCAT"))
            {
                // CONCAT(string_primary, string_primary[, string_primary])
                // Convert to be {primary1}+{primary2}[+primary3]
                processExpression();
                Node prevNode = stack.pop();

                while (true)
                {
                    if (!p.parseChar(','))
                    {
                        throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                    }

                    processExpression();
                    Node thisNode = stack.pop();

                    Node currentNode = new Node(Node.OPERATOR, "+");
                    currentNode.appendChildNode(prevNode);
                    currentNode.appendChildNode(thisNode);
                    if (p.parseChar(')'))
                    {
                        stack.push(currentNode);
                        return true;
                    }
                    prevNode = currentNode;
                    currentNode = null;
                }
            }
            else if (method.equalsIgnoreCase("LOCATE"))
            {
                // LOCATE(string_primary, string_primary[, simple_arithmetic_expression])
                // Convert to ({stringExpr}.indexOf(strExpr[, posExpr]) + 1)
                processExpression();
                Node searchNode = stack.pop();
                if (!p.parseChar(','))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                processExpression();
                Node primaryNode = stack.pop();

                Node invokeNode = new Node(Node.INVOKE, "indexOf");
                invokeNode.addProperty(searchNode);

                Node oneNode = new Node(Node.LITERAL, 1);
                if (p.parseChar(','))
                {
                    processExpression();
                    Node fromPosNode = stack.pop();
                    Node positionNode = new Node(Node.OPERATOR, "-");
                    positionNode.appendChildNode(fromPosNode);
                    positionNode.appendChildNode(oneNode);
                    invokeNode.addProperty(positionNode);
                }
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                Node locateNode = new Node(Node.OPERATOR, "+");
                locateNode.appendChildNode(primaryNode);
                locateNode.appendChildNode(oneNode);
                stack.push(locateNode);
                return true;
            }
            else if (method.equalsIgnoreCase("TRIM"))
            {
                // TRIM([[LEADING | TRAILING | BOTH] [trim_character] FROM] string_primary)
                // Convert to be {primary}.INVOKE(trim|trimLeft|trimRight, [{trimChar}])
                String methodName = "trim";
                if (p.parseStringIgnoreCase("LEADING"))
                {
                    methodName = "trimLeft";
                }
                else if (p.parseStringIgnoreCase("TRAILING"))
                {
                    methodName = "trimRight";
                }
                else if (p.parseStringIgnoreCase("BOTH"))
                {
                    // Default
                }
                Node invokeNode = new Node(Node.INVOKE, methodName);

                Node trimCharNode = null;
                processExpression();
                Node next = stack.pop();
                if (p.parseChar(')'))
                {
                    next.appendChildNode(invokeNode);
                    stack.push(next);
                    return true;
                }
                else
                {
                    if (next.getNodeType() == Node.IDENTIFIER)
                    {
                        Object litValue = next.getNodeValue();
                        if (litValue instanceof String && ((String)litValue).equals("FROM"))
                        {
                            // FROM so ignore
                            processExpression(); // field expression that we are trimming
                            next = stack.pop();
                        }
                        else
                        {
                            // trim character first
                            trimCharNode = next;
                            if (p.parseStringIgnoreCase("FROM "))
                            {
                                // Ignore the FROM
                            }
                            processExpression();
                            next = stack.pop();
                        }
                    }
                    else
                    {
                        // No "trimChar" or FROM, so "next" is the string expression node
                    }

                    if (!p.parseChar(')'))
                    {
                        throw new QueryCompilerSyntaxException("')' expected", p.getIndex(), p.getInput());
                    }

                    next.appendChildNode(invokeNode);
                    if (trimCharNode != null)
                    {
                        invokeNode.addProperty(trimCharNode);
                    }
                    stack.push(next);
                    return true;
                }
            }
            else if (method.equalsIgnoreCase("SIZE"))
            {
                // SIZE(collection_valued_path_expression)
                // Convert to be {primary}.INVOKE(size)
                Node invokeNode = new Node(Node.INVOKE, "size");
                processExpression();
                Node primaryNode = stack.pop(); // Could check type ? (Collection/Map/array)
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("KEY"))
            {
                // KEY(identification_variable)
                // Convert to be {primary}.INVOKE(mapKey)
                Node invokeNode = new Node(Node.INVOKE, "mapKey");
                processExpression();
                Node primaryNode = stack.pop(); // Could check type ? (Map)
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("VALUE"))
            {
                // VALUE(identification_variable)
                // Convert to be {primary}.INVOKE(mapValue)
                Node invokeNode = new Node(Node.INVOKE, "mapValue");
                processExpression();
                Node primaryNode = stack.pop(); // Could check type ? (Map)
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else if (method.equalsIgnoreCase("ENTRY"))
            {
                // ENTRY(identification_variable)
                // Convert to be {primary}.INVOKE(mapEntry)
                Node invokeNode = new Node(Node.INVOKE, "mapEntry");
                processExpression();
                Node primaryNode = stack.pop(); // Could check type ? (Map)
                if (!p.parseChar(')'))
                {
                    throw new QueryCompilerSyntaxException("',' expected", p.getIndex(), p.getInput());
                }

                primaryNode.appendChildNode(invokeNode);
                stack.push(primaryNode);
                return true;
            }
            else
            {
                // Found syntax for a method, so invoke the method
                // TODO What if the method is not supported for JPQL?
                Node expr = new Node(Node.INVOKE, method);
                if (!p.parseChar(')'))
                {
                    do
                    {
                        // Argument for the method call, add as a node property
                        processExpression();
                        expr.addProperty(stack.pop());
                    }
                    while (p.parseChar(','));

                    if (!p.parseChar(')'))
                    {
View Full Code Here

     */
    public Expression compileFromExpression(Node node)
    {
        if (node.getNodeType() == Node.CLASS)
        {
            Node aliasNode = node.getFirstChild();
            ClassExpression clsExpr = new ClassExpression(symtbl, (String)aliasNode.getNodeValue());

            // Process any joins, chained down off the ClassExpression
            // So you can do clsExpr.getRight() to get the JoinExpression
            // then joinExpr.getRight() to get the next JoinExpression (if any)
            JoinExpression currentJoinExpr = null;
            Iterator childIter = node.getChildNodes().iterator();
            while (childIter.hasNext())
            {
                Node childNode = (Node)childIter.next();
                if (childNode.getNodeType() == Node.OPERATOR)
                {
                    String joinType = (String)childNode.getNodeValue();
                    JoinType joinTypeId = JoinType.JOIN_INNER;
                    if (joinType.equals("JOIN_INNER_FETCH"))
                    {
                        joinTypeId = JoinType.JOIN_INNER_FETCH;
                    }
                    else if (joinType.equals("JOIN_OUTER_FETCH"))
                    {
                        joinTypeId = JoinType.JOIN_OUTER_FETCH;
                    }
                    else if (joinType.equals("JOIN_OUTER"))
                    {
                        joinTypeId = JoinType.JOIN_OUTER;
                    }
                    Node joinedNode = childNode.getFirstChild();
                    Node joinedAliasNode = childNode.getNextChild();
                    PrimaryExpression primExpr = (PrimaryExpression)compilePrimaryExpression(joinedNode);

                    JoinExpression joinExpr = new JoinExpression(symtbl, primExpr,
                        (String)joinedAliasNode.getNodeValue(), joinTypeId);
                    if (currentJoinExpr != null)
                    {
                        currentJoinExpr.setJoinExpression(joinExpr);
                    }
                    else
View Full Code Here

    private Expression compilePrimaryExpression(Node node)
    {
        if (node.getNodeType() == Node.IDENTIFIER)
        {
            Node currentNode = node;
            List tupple = new ArrayList();
            Expression currentExpr = null;
            while (currentNode != null)
            {
                tupple.add(currentNode.getNodeValue());

                if (currentNode.getNodeType() == Node.INVOKE)
                {
                    if (currentExpr == null && tupple.size() > 1)
                    {
                        // Check for starting with parameter/variable
                        String first = (String)tupple.get(0);
                        Symbol firstSym = symtbl.getSymbol(first);
                        if (firstSym != null)
                        {
                            if (firstSym.getType() == Symbol.PARAMETER)
                            {
                                currentExpr = new ParameterExpression(symtbl, first, -1);
                                if (tupple.size() > 2)
                                {
                                    currentExpr = new PrimaryExpression(symtbl, currentExpr, tupple.subList(1, tupple.size()-1));
                                }
                            }
                            else if (firstSym.getType() == Symbol.VARIABLE)
                            {
                                currentExpr = new VariableExpression(symtbl, first);
                                if (tupple.size() > 2)
                                {
                                    currentExpr = new PrimaryExpression(symtbl, currentExpr, tupple.subList(1, tupple.size()-1));
                                }
                            }
                        }
                        if (currentExpr == null)
                        {
                            currentExpr = new PrimaryExpression(symtbl, tupple.subList(0, tupple.size()-1));
                        }
                    }

                    String methodName = (String)tupple.get(tupple.size()-1);
                    if (currentExpr instanceof PrimaryExpression)
                    {
                        // TODO Add plugin point to define aliases for methods for the query language
                        // ExpressionCompiler would need to know the query language name
                        String id = ((PrimaryExpression)currentExpr).getId();
                        if (id.equals("Math") || id.equals("java.lang.Math"))
                        {
                            methodName = "Math." + methodName;
                            currentExpr = null;
                        }
                        else if (id.equals("JDOHelper") || id.equals("javax.jdo.JDOHelper"))
                        {
                            methodName = "JDOHelper." + methodName;
                            currentExpr = null;
                        }
                    }
                    List parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                    currentExpr = new InvokeExpression(symtbl, currentExpr, methodName, parameterExprs);

                    currentNode = currentNode.getFirstChild();
                    tupple = new ArrayList();
                }
                else if (currentNode.getNodeType() == Node.CAST)
                {
                    if (currentExpr == null && tupple.size() > 1)
                    {
                        // Start from PrimaryExpression and invoke on that
                        currentExpr = new PrimaryExpression(symtbl, tupple.subList(0, tupple.size()-1));
                        PrimaryExpression primExpr = (PrimaryExpression)currentExpr;
                        if (primExpr.tuples.size() == 1)
                        {
                            Symbol sym = symtbl.getSymbol(primExpr.getId());
                            if (sym != null)
                            {
                                if (sym.getType() == Symbol.PARAMETER)
                                {
                                    // Parameter symbol registered for this identifier so use ParameterExpression
                                    currentExpr = new ParameterExpression(symtbl, primExpr.getId(), -1);
                                }
                                else if (sym.getType() == Symbol.VARIABLE)
                                {
                                    // Variable symbol registered for this identifier so use VariableExpression
                                    currentExpr = new VariableExpression(symtbl, primExpr.getId());
                                }
                            }
                        }
                    }

                    String className = (String)tupple.get(tupple.size()-1);
                    currentExpr = new CastExpression(symtbl, currentExpr, className);

                    currentNode = currentNode.getFirstChild();
                    tupple = new ArrayList();
                }
                else
                {
                    // Part of identifier chain
                    currentNode = currentNode.getFirstChild();
                }
            }

            if (currentExpr != null && tupple.size() > 0)
            {
                // We have a trailing identifier expression
                // e.g "((B)a).c" where we have a CastExpression and trailing "c"
                currentExpr = new PrimaryExpression(symtbl, currentExpr, tupple);
            }

            if (currentExpr == null)
            {
                // Find type of first of tupples
                String first = (String)tupple.get(0);
                Symbol firstSym = symtbl.getSymbol(first);
                if (firstSym != null)
                {
                    if (firstSym.getType() == Symbol.PARAMETER)
                    {
                        ParameterExpression paramExpr = new ParameterExpression(symtbl, first, -1);
                        if (tupple.size() > 1)
                        {
                            currentExpr = new PrimaryExpression(symtbl, paramExpr, tupple.subList(1, tupple.size()));
                        }
                        else
                        {
                            currentExpr = paramExpr;
                        }
                    }
                    else if (firstSym.getType() == Symbol.VARIABLE)
                    {
                        VariableExpression varExpr = new VariableExpression(symtbl, first);
                        if (tupple.size() > 1)
                        {
                            currentExpr = new PrimaryExpression(symtbl, varExpr, tupple.subList(1, tupple.size()));
                        }
                        else
                        {
                            currentExpr = varExpr;
                        }
                    }
                    else
                    {
                        currentExpr = new PrimaryExpression(symtbl, tupple);
                    }
                }
                else
                {
                    currentExpr = new PrimaryExpression(symtbl, tupple);
                }
            }

            return currentExpr;
        }
        else if (node.getNodeType() == Node.PARAMETER)
        {
            // "{paramExpr}", "{paramExpr}.invoke(...)", "{paramExpr}.invoke(...).invoke(...)"
            Object val = node.getNodeValue();
            Expression currentExpr = null;
            if (val instanceof Integer)
            {
                // Positional parameter TODO Store as Integer to avoid confusion
                currentExpr = new ParameterExpression(symtbl, "" + node.getNodeValue(),
                    ((ParameterNode)node).getPosition());
            }
            else
            {
                // Named parameter
                currentExpr = new ParameterExpression(symtbl, (String)node.getNodeValue(),
                    ((ParameterNode)node).getPosition());
            }

            Node childNode = node.getFirstChild();
            while (childNode != null)
            {
                if (childNode.getNodeType() == Node.INVOKE)
                {
                    String methodName = (String)childNode.getNodeValue();
                    List parameterExprs = getExpressionsForPropertiesOfNode(childNode);
                    currentExpr = new InvokeExpression(symtbl, currentExpr, methodName, parameterExprs);
                }
                else
                {
                    throw new QueryCompilerSyntaxException("Dont support compilation of " + node);
                }
                childNode = childNode.getFirstChild();
            }
            return currentExpr;
        }
        else if (node.getNodeType() == Node.INVOKE)
        {
            Node currentNode = node;
            List tupple = new ArrayList();
            Expression currentExpr = null;
            while (currentNode != null)
            {
                tupple.add(currentNode.getNodeValue());

                if (currentNode.getNodeType() == Node.INVOKE)
                {
                    String methodName = (String)tupple.get(tupple.size()-1);
                    List parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                    currentExpr = new InvokeExpression(symtbl, currentExpr, methodName, parameterExprs);

                    currentNode = currentNode.getFirstChild();
                    if (currentNode != null)
                    {
                        // Continue on along the chain
                        tupple = new ArrayList();
                        tupple.add(currentExpr); // Start from this expression
                    }
                }
                else
                {
                    // TODO What node type is this that comes after an INVOKE?
                    currentNode = currentNode.getFirstChild();
                }
            }
            return currentExpr;
        }
        else if (node.getNodeType() == Node.CREATOR)
        {
            Node currentNode = node.getFirstChild();
            List tupple = new ArrayList();
            boolean method = false;
            while (currentNode != null)
            {
                tupple.add(currentNode.getNodeValue());
                if (currentNode.getNodeType() == Node.INVOKE)
                {
                    method = true;
                    break;
                }
                currentNode = currentNode.getFirstChild();
            }

            List parameterExprs = null;
            if (method)
            {
                parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
            }
            else
            {
                parameterExprs = new ArrayList();
            }
            return new CreatorExpression(symtbl, tupple, parameterExprs);
        }
        else if (node.getNodeType() == Node.LITERAL)
        {
            Node currentNode = node;
            List tupple = new ArrayList();
            Expression currentExpr = null;
            while (currentNode != null)
            {
                tupple.add(currentNode.getNodeValue());

                if (currentNode.getNodeType() == Node.INVOKE)
                {
                    if (currentExpr == null && tupple.size() > 1)
                    {
                        // Start from Literal and invoke on that
                        currentExpr = new Literal(node.getNodeValue());
                    }

                    String methodName = (String)tupple.get(tupple.size()-1);
                    List parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                    currentExpr = new InvokeExpression(symtbl, currentExpr, methodName, parameterExprs);

                    currentNode = currentNode.getFirstChild();
                    tupple = new ArrayList();
                }
                else
                {
                    currentNode = currentNode.getFirstChild();
                }
            }

            if (currentExpr == null)
            {
                currentExpr = new Literal(node.getNodeValue());
            }
            return currentExpr;
        }
        else if (node.getNodeType() == Node.ARRAY)
        {
            Node currentNode = node;
            List<Node> arrayElements = (List<Node>)node.getNodeValue();

            // Check if this is an array literal
            boolean literal = true;
            Class type = null;
            Iterator<Node> iter = arrayElements.iterator();
            while (iter.hasNext())
            {
                Node element = iter.next();
                if (type == null)
                {
                    type = element.getNodeValue().getClass();
                }
                else if (type != element.getNodeValue().getClass())
                {
                    // TODO Allow for mixed-mode arrays e.g "(1,3,4,this.longField)"
                    throw new QueryCompilerSyntaxException("Array elements are of inconsistent types in " + node);
                }
                if (element.getNodeType() == Node.IDENTIFIER)
                {
                    literal = false;
                    break;
                }
            }

            Expression currentExpr = null;
            if (literal)
            {
                Object array = Array.newInstance(type, arrayElements.size());
                iter = arrayElements.iterator();
                int index = 0;
                while (iter.hasNext())
                {
                    Node element = iter.next();
                    Array.set(array, index++, element.getNodeValue());
                }
                currentExpr = new Literal(array);
            }
            else
            {
                // TODO Handle ArrayExpression
                throw new NucleusUserException("Compilation of an array of expressions is not yet supported");
            }
            currentNode = currentNode.getFirstChild();

            List tupple = new ArrayList();
            while (currentNode != null)
            {
                tupple.add(currentNode.getNodeValue());

                if (currentNode.getNodeType() == Node.INVOKE)
                {
                    if (currentExpr == null && tupple.size() > 1)
                    {
                        // Start from Literal and invoke on that
                        currentExpr = new Literal(node.getNodeValue());
                    }

                    String methodName = (String)tupple.get(tupple.size()-1);
                    List parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                    currentExpr = new InvokeExpression(symtbl, currentExpr, methodName, parameterExprs);

                    currentNode = currentNode.getFirstChild();
                    tupple = new ArrayList();
                }
                else
                {
                    currentNode = currentNode.getFirstChild();
                }
            }

            return currentExpr;
        }
        else if (node.getNodeType() == Node.SUBQUERY)
        {
            List children = node.getChildNodes();
            if (children.size() != 1)
            {
                throw new QueryCompilerSyntaxException("Invalid number of children for SUBQUERY node : " + node);
            }
            Node varNode = (Node)children.get(0);
            VariableExpression subqueryExpr = new VariableExpression(symtbl, varNode.getNodeId());
            Expression currentExpr = new SubqueryExpression((String)node.getNodeValue(), subqueryExpr);
            return currentExpr;
        }
        else
        {
View Full Code Here

            String classAlias = null;
            Class cls = resolveClass(className);
            List children = node[i].getChildNodes();
            for (int j=0;j<children.size();j++)
            {
                Node child = (Node)children.get(j);
                if (child.getNodeType() == Node.NAME) // Alias - maybe should assume it is the first child
                {
                    classAlias = (String)child.getNodeValue();
                }
            }

            if (classAlias != null && symtbl.getSymbol(classAlias) == null)
            {
                // Add symbol for this candidate under its alias
                symtbl.addSymbol(new PropertySymbol(classAlias, cls));
            }

            if (i == 0)
            {
                // First expression so set up candidateClass/alias
                candidateClass = cls;
                candidateAlias = classAlias;
            }

            Iterator childIter = node[i].getChildNodes().iterator();
            while (childIter.hasNext())
            {
                // Add entries in symbol table for any joined aliases
                Node childNode = (Node)childIter.next();
                if (childNode.getNodeType() == Node.OPERATOR)
                {
                    Node joinedNode = childNode.getFirstChild();
                    Symbol joinedSym = symtbl.getSymbol((String)joinedNode.getNodeValue());
                    if (joinedSym == null)
                    {
                        throw new QueryCompilerSyntaxException("FROM clause has identifier " + joinedNode.getNodeValue() + " but this is unknown");
                    }
                    AbstractClassMetaData joinedCmd = metaDataManager.getMetaDataForClass(joinedSym.getValueType(), clr);
                    Class joinedCls = joinedSym.getValueType();
                    while (joinedNode.getFirstChild() != null)
                    {
                        joinedNode = joinedNode.getFirstChild();
                        String joinedMember = (String)joinedNode.getNodeValue();
                        AbstractMemberMetaData mmd = joinedCmd.getMetaDataForMember(joinedMember);
                        if (mmd == null)
                        {
                            throw new QueryCompilerSyntaxException("FROM clause has reference to " + joinedCmd.getFullClassName() + "." + joinedMember + " but it doesn't exist!");
                        }

                        int relationType = mmd.getRelationType(clr);
                        switch (relationType)
                        {
                            case Relation.ONE_TO_ONE_UNI:
                            case Relation.ONE_TO_ONE_BI:
                            case Relation.MANY_TO_ONE_BI:
                                joinedCls = mmd.getType();
                                joinedCmd = metaDataManager.getMetaDataForClass(joinedCls, clr);
                                break;
                            case Relation.ONE_TO_MANY_UNI:
                            case Relation.ONE_TO_MANY_BI:
                            case Relation.MANY_TO_MANY_BI:
                                if (mmd.hasCollection())
                                {
                                    // TODO Don't currently allow interface field navigation
                                    joinedCmd = mmd.getCollection().getElementClassMetaData(clr);
                                    joinedCls = clr.classForName(joinedCmd.getFullClassName());
                                }
                                else if (mmd.hasArray())
                                {
                                    // TODO Don't currently allow interface field navigation
                                    joinedCmd = mmd.getArray().getElementClassMetaData(clr);
                                    joinedCls = clr.classForName(joinedCmd.getFullClassName());
                                }
                                break;
                            default:
                                break;
                        }
                    }

                    Node aliasNode = childNode.getNextChild();
                    if (aliasNode.getNodeType() == Node.NAME)
                    {
                        symtbl.addSymbol(new PropertySymbol((String)aliasNode.getNodeValue(), joinedCls));
                    }
                }
            }

            ExpressionCompiler comp = new ExpressionCompiler();
View Full Code Here

    public Expression compileFilter()
    {
        if (filter != null)
        {
            // Generate the node tree for the filter
            Node node = parser.parse(filter);

            ExpressionCompiler comp = new ExpressionCompiler();
            comp.setSymbolTable(symtbl);
            Expression expr = comp.compileExpression(node);
            expr.bind();
View Full Code Here

TOP

Related Classes of org.datanucleus.query.node.Node

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.