public Object visit()

in jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql/JCRSQLQueryBuilder.java [320:455]


    public Object visit(ASTPredicate node, Object data) {
        NAryQueryNode parent = (NAryQueryNode) data;

        int type = node.getOperationType();
        QueryNode predicateNode;

        try {
            final Name[] tmp = new Name[2];
            final ASTLiteral[] value = new ASTLiteral[1];
            node.childrenAccept(new DefaultParserVisitor() {
                public Object visit(ASTIdentifier node, Object data) {
                    if (tmp[0] == null) {
                        tmp[0] = node.getName();
                    } else if (tmp[1] == null) {
                        tmp[1] = node.getName();
                    }
                    return data;
                }

                public Object visit(ASTLiteral node, Object data) {
                    value[0] = node;
                    return data;
                }

                public Object visit(ASTLowerFunction node, Object data) {
                    getIdentifier(node);
                    return data;
                }

                public Object visit(ASTUpperFunction node, Object data) {
                    getIdentifier(node);
                    return data;
                }

                private void getIdentifier(SimpleNode node) {
                    if (node.jjtGetNumChildren() > 0) {
                        Node n = node.jjtGetChild(0);
                        if (n instanceof ASTIdentifier) {
                            ASTIdentifier identifier = (ASTIdentifier) n;
                            if (tmp[0] == null) {
                                tmp[0] = identifier.getName();
                            } else if (tmp[1] == null) {
                                tmp[1] = identifier.getName();
                            }
                        }
                    }
                }
            }, data);
            Name identifier = tmp[0];

            if (identifier != null && identifier.equals(NameConstants.JCR_PATH)) {
                if (tmp[1] != null) {
                    // simply ignore, this is a join of a mixin node type
                } else {
                    createPathQuery(value[0].getValue(), parent.getType());
                }
                // done
                return data;
            }

            if (type == QueryConstants.OPERATION_BETWEEN) {
                AndQueryNode between = factory.createAndQueryNode(parent);
                RelationQueryNode rel = createRelationQueryNode(between,
                        identifier, QueryConstants.OPERATION_GE_GENERAL, (ASTLiteral) node.children[1]);
                node.childrenAccept(this, rel);
                between.addOperand(rel);
                rel = createRelationQueryNode(between,
                        identifier, QueryConstants.OPERATION_LE_GENERAL, (ASTLiteral) node.children[2]);
                node.childrenAccept(this, rel);
                between.addOperand(rel);
                predicateNode = between;
            } else if (type == QueryConstants.OPERATION_GE_GENERAL
                    || type == QueryConstants.OPERATION_GT_GENERAL
                    || type == QueryConstants.OPERATION_LE_GENERAL
                    || type == QueryConstants.OPERATION_LT_GENERAL
                    || type == QueryConstants.OPERATION_NE_GENERAL
                    || type == QueryConstants.OPERATION_EQ_GENERAL) {
                predicateNode = createRelationQueryNode(parent,
                        identifier, type, value[0]);
                node.childrenAccept(this, predicateNode);
            } else if (type == QueryConstants.OPERATION_LIKE) {
                ASTLiteral pattern = value[0];
                if (node.getEscapeString() != null) {
                    if (node.getEscapeString().length() == 1) {
                        // backslash is the escape character we use internally
                        pattern.setValue(translateEscaping(pattern.getValue(), node.getEscapeString().charAt(0), '\\'));
                    } else {
                        throw new IllegalArgumentException("ESCAPE string value must have length 1: '" + node.getEscapeString() + "'");
                    }
                } else {
                    // no escape character specified.
                    // if the pattern contains any backslash characters we need
                    // to escape them.
                    pattern.setValue(pattern.getValue().replaceAll("\\\\", "\\\\\\\\"));
                }
                predicateNode = createRelationQueryNode(parent,
                        identifier, type, pattern);
                node.childrenAccept(this, predicateNode);
            } else if (type == QueryConstants.OPERATION_IN) {
                OrQueryNode in = factory.createOrQueryNode(parent);
                for (int i = 1; i < node.children.length; i++) {
                    RelationQueryNode rel = createRelationQueryNode(in,
                            identifier, QueryConstants.OPERATION_EQ_VALUE, (ASTLiteral) node.children[i]);
                    node.childrenAccept(this, rel);
                    in.addOperand(rel);
                }
                predicateNode = in;
            } else if (type == QueryConstants.OPERATION_NULL
                    || type == QueryConstants.OPERATION_NOT_NULL) {
                predicateNode = createRelationQueryNode(parent,
                        identifier, type, null);
            } else if (type == QueryConstants.OPERATION_SIMILAR) {
                ASTLiteral literal;
                if (node.children.length == 1) {
                    literal = (ASTLiteral) node.children[0];
                } else {
                    literal = (ASTLiteral) node.children[1];
                }
                predicateNode = createRelationQueryNode(parent, identifier, type, literal);
            } else if (type == QueryConstants.OPERATION_SPELLCHECK) {
                predicateNode = createRelationQueryNode(parent,
                        NameConstants.JCR_PRIMARYTYPE, type,
                        (ASTLiteral) node.children[0]);
            } else {
                throw new IllegalArgumentException("Unknown operation type: " + type);
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            throw new IllegalArgumentException("Too few arguments in predicate");
        }

        if (predicateNode != null) {
            parent.addOperand(predicateNode);
        }

        return data;
    }