xpathquerybuilder.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,077 行 · 第 1/4 页

JAVA
1,077
字号
        }    }    /**     * Creates a <code>LocationStepQueryNode</code> at the current position     * in parent.     *     * @param node   the current node in the xpath syntax tree.     * @param parent the parent <code>PathQueryNode</code>.     * @return the created <code>LocationStepQueryNode</code>.     */    private LocationStepQueryNode createLocationStep(SimpleNode node, NAryQueryNode parent) {        LocationStepQueryNode queryNode = null;        boolean descendant = false;        Node p = node.jjtGetParent();        for (int i = 0; i < p.jjtGetNumChildren(); i++) {            SimpleNode c = (SimpleNode) p.jjtGetChild(i);            if (c == node) {                queryNode = new LocationStepQueryNode(parent, null, descendant);                parent.addOperand(queryNode);                break;            }            descendant = (c.getId() == JJTSLASHSLASH                    || c.getId() == JJTROOTDESCENDANTS);        }        node.childrenAccept(this, queryNode);        return queryNode;    }    /**     * Assigns a QName to one of the follwing QueryNodes:     * {@link RelationQueryNode}, {@link DerefQueryNode}, {@link RelationQueryNode},     * {@link PathQueryNode}, {@link OrderQueryNode}, {@link TextsearchQueryNode}.     *     * @param node      the current node in the xpath syntax tree.     * @param queryNode the query node.     */    private void createNodeTest(SimpleNode node, QueryNode queryNode) {        if (node.jjtGetNumChildren() > 0) {            SimpleNode child = (SimpleNode) node.jjtGetChild(0);            if (child.getId() == JJTQNAME || child.getId() == JJTQNAMEFORITEMTYPE) {                try {                    QName name = ISO9075.decode(NameFormat.parse(child.getValue(), resolver));                    if (queryNode.getType() == QueryNode.TYPE_LOCATION) {                        if (name.equals(JCR_ROOT)) {                            name = LocationStepQueryNode.EMPTY_NAME;                        }                        ((LocationStepQueryNode) queryNode).setNameTest(name);                    } else if (queryNode.getType() == QueryNode.TYPE_DEREF) {                        ((DerefQueryNode) queryNode).setRefProperty(name);                    } else if (queryNode.getType() == QueryNode.TYPE_RELATION) {                        Path.PathElement element = Path.PathElement.create(name);                        ((RelationQueryNode) queryNode).addPathElement(element);                    } else if (queryNode.getType() == QueryNode.TYPE_PATH) {                        root.addSelectProperty(name);                    } else if (queryNode.getType() == QueryNode.TYPE_ORDER) {                        root.getOrderNode().addOrderSpec(name, true);                    } else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {                        TextsearchQueryNode ts = (TextsearchQueryNode) queryNode;                        ts.addPathElement(Path.PathElement.create(name));                        if (isAttributeNameTest(node)) {                            ts.setReferencesProperty(true);                        }                    }                } catch (NameException e) {                    exceptions.add(new InvalidQueryException("Illegal name: " + child.getValue()));                }            } else if (child.getId() == JJTSTAR) {                if (queryNode.getType() == QueryNode.TYPE_LOCATION) {                    ((LocationStepQueryNode) queryNode).setNameTest(null);                } else if (queryNode.getType() == QueryNode.TYPE_RELATION) {                    ((RelationQueryNode) queryNode).addPathElement(                            Path.PathElement.create(RelationQueryNode.STAR_NAME_TEST));                } else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {                    ((TextsearchQueryNode) queryNode).addPathElement(                            Path.PathElement.create(RelationQueryNode.STAR_NAME_TEST));                }            } else {                exceptions.add(new InvalidQueryException("Unsupported location for name test: " + child));            }        }    }    /**     * Creates a new {@link org.apache.jackrabbit.core.query.RelationQueryNode}     * with <code>queryNode</code> as its parent node.     *     * @param node      a comparison expression node.     * @param queryNode the current <code>QueryNode</code>.     */    private void createExpression(SimpleNode node, NAryQueryNode queryNode) {        if (node.getId() != JJTCOMPARISONEXPR) {            throw new IllegalArgumentException("node must be of type ComparisonExpr");        }        // get operation type        String opType = node.getValue();        int type = 0;        if (opType.equals(OP_EQ)) {            type = RelationQueryNode.OPERATION_EQ_VALUE;        } else if (opType.equals(OP_SIGN_EQ)) {            type = RelationQueryNode.OPERATION_EQ_GENERAL;        } else if (opType.equals(OP_GT)) {            type = RelationQueryNode.OPERATION_GT_VALUE;        } else if (opType.equals(OP_SIGN_GT)) {            type = RelationQueryNode.OPERATION_GT_GENERAL;        } else if (opType.equals(OP_GE)) {            type = RelationQueryNode.OPERATION_GE_VALUE;        } else if (opType.equals(OP_SIGN_GE)) {            type = RelationQueryNode.OPERATION_GE_GENERAL;        } else if (opType.equals(OP_LE)) {            type = RelationQueryNode.OPERATION_LE_VALUE;        } else if (opType.equals(OP_SIGN_LE)) {            type = RelationQueryNode.OPERATION_LE_GENERAL;        } else if (opType.equals(OP_LT)) {            type = RelationQueryNode.OPERATION_LT_VALUE;        } else if (opType.equals(OP_SIGN_LT)) {            type = RelationQueryNode.OPERATION_LT_GENERAL;        } else if (opType.equals(OP_NE)) {            type = RelationQueryNode.OPERATION_NE_VALUE;        } else if (opType.equals(OP_SIGN_NE)) {            type = RelationQueryNode.OPERATION_NE_GENERAL;        } else {            exceptions.add(new InvalidQueryException("Unsupported ComparisonExpr type:" + node.getValue()));        }        final RelationQueryNode rqn = new RelationQueryNode(queryNode, type);        // traverse        node.childrenAccept(this, rqn);        // check if string transformation is valid        rqn.acceptOperands(new DefaultQueryNodeVisitor() {            public Object visit(PropertyFunctionQueryNode node, Object data) {                String functionName = node.getFunctionName();                if ((functionName.equals(PropertyFunctionQueryNode.LOWER_CASE)                        || functionName.equals(PropertyFunctionQueryNode.UPPER_CASE))                            && rqn.getValueType() != QueryConstants.TYPE_STRING) {                    String msg = "Upper and lower case function are only supported with String literals";                    exceptions.add(new InvalidQueryException(msg));                }                return data;            }        }, null);        queryNode.addOperand(rqn);    }    /**     * Creates the primary path query node.     *     * @param node xpath node representing the root of the parsed tree.     * @return the path qurey node     */    private PathQueryNode createPathQueryNode(SimpleNode node) {        root.setLocationNode(new PathQueryNode(root));        node.childrenAccept(this, root.getLocationNode());        return root.getLocationNode();    }    /**     * Assigns a value to the <code>queryNode</code>.     *     * @param node      must be of type string, decimal, double or integer; otherwise     *                  an InvalidQueryException is added to {@link #exceptions}.     * @param queryNode current node in the query tree.     */    private void assignValue(SimpleNode node, RelationQueryNode queryNode) {        if (node.getId() == JJTSTRINGLITERAL) {            queryNode.setStringValue(unescapeQuotes(node.getValue()));        } else if (node.getId() == JJTDECIMALLITERAL) {            queryNode.setDoubleValue(Double.parseDouble(node.getValue()));        } else if (node.getId() == JJTDOUBLELITERAL) {            queryNode.setDoubleValue(Double.parseDouble(node.getValue()));        } else if (node.getId() == JJTINTEGERLITERAL) {            // if this is an expression that contains position() do not change            // the type.            if (queryNode.getValueType() == QueryConstants.TYPE_POSITION) {                queryNode.setPositionValue(Integer.parseInt(node.getValue()));            } else {                queryNode.setLongValue(Long.parseLong(node.getValue()));            }        } else {            exceptions.add(new InvalidQueryException("Unsupported literal type:" + node.toString()));        }    }    /**     * Creates a function based on <code>node</code>.     *     * @param node      the function node from the xpath tree.     * @param queryNode the current query node.     * @return the function node     */    private QueryNode createFunction(SimpleNode node, QueryNode queryNode) {        // find out function name        String fName = ((SimpleNode) node.jjtGetChild(0)).getValue();        fName = fName.substring(0, fName.length() - 1);        try {            if (NameFormat.format(FN_NOT, resolver).equals(fName)                    || NameFormat.format(FN_NOT_10, resolver).equals(fName)) {                if (queryNode instanceof NAryQueryNode) {                    QueryNode not = new NotQueryNode(queryNode);                    ((NAryQueryNode) queryNode).addOperand(not);                    // @todo is this needed?                    queryNode = not;                    // traverse                    if (node.jjtGetNumChildren() == 2) {                        node.jjtGetChild(1).jjtAccept(this, queryNode);                    } else {                        exceptions.add(new InvalidQueryException("fn:not only supports one expression argument"));                    }                } else {                    exceptions.add(new InvalidQueryException("Unsupported location for function fn:not"));                }            } else if (NameFormat.format(XS_DATETIME, resolver).equals(fName)) {                // check arguments                if (node.jjtGetNumChildren() == 2) {                    if (queryNode instanceof RelationQueryNode) {                        RelationQueryNode rel = (RelationQueryNode) queryNode;                        SimpleNode literal = (SimpleNode) node.jjtGetChild(1).jjtGetChild(0);                        if (literal.getId() == JJTSTRINGLITERAL) {                            String value = literal.getValue();                            // strip quotes                            value = value.substring(1, value.length() - 1);                            Calendar c = ISO8601.parse(value);                            if (c == null) {                                exceptions.add(new InvalidQueryException("Unable to parse string literal for xs:dateTime: " + value));                            } else {                                rel.setDateValue(c.getTime());                            }                        } else {                            exceptions.add(new InvalidQueryException("Wrong argument type for xs:dateTime"));                        }                    } else {                        exceptions.add(new InvalidQueryException("Unsupported location for function xs:dateTime"));                    }                } else {                    // wrong number of arguments                    exceptions.add(new InvalidQueryException("Wrong number of arguments for xs:dateTime"));                }            } else if (NameFormat.format(JCR_CONTAINS, resolver).equals(fName)) {                // check number of arguments                if (node.jjtGetNumChildren() == 3) {                    if (queryNode instanceof NAryQueryNode) {                        SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);                        if (literal.getId() == JJTSTRINGLITERAL) {                            TextsearchQueryNode contains = new TextsearchQueryNode(                                    queryNode, unescapeQuotes(literal.getValue()));                            // assign property name                            SimpleNode path = (SimpleNode) node.jjtGetChild(1);                            path.jjtAccept(this, contains);                            ((NAryQueryNode) queryNode).addOperand(contains);                        } else {                            exceptions.add(new InvalidQueryException("Wrong argument type for jcr:contains"));                        }                    }                } else {                    // wrong number of arguments                    exceptions.add(new InvalidQueryException("Wrong number of arguments for jcr:contains"));                }            } else if (NameFormat.format(JCR_LIKE, resolver).equals(fName)) {                // check number of arguments                if (node.jjtGetNumChildren() == 3) {                    if (queryNode instanceof NAryQueryNode) {                        RelationQueryNode like = new RelationQueryNode(queryNode, RelationQueryNode.OPERATION_LIKE);                        ((NAryQueryNode) queryNode).addOperand(like);                        // assign property name

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?