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 + -
显示快捷键?