xpathquerybuilder.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,077 行 · 第 1/4 页
JAVA
1,077 行
node.jjtGetChild(1).jjtAccept(this, like); // check property name if (like.getRelativePath() == null) { exceptions.add(new InvalidQueryException("Wrong first argument type for jcr:like")); } SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0); if (literal.getId() == JJTSTRINGLITERAL) { like.setStringValue(unescapeQuotes(literal.getValue())); } else { exceptions.add(new InvalidQueryException("Wrong second argument type for jcr:like")); } } else { exceptions.add(new InvalidQueryException("Unsupported location for function jcr:like")); } } else { // wrong number of arguments exceptions.add(new InvalidQueryException("Wrong number of arguments for jcr:like")); } } else if (NameFormat.format(FN_TRUE, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { RelationQueryNode rel = (RelationQueryNode) queryNode; rel.setStringValue("true"); } else { exceptions.add(new InvalidQueryException("Unsupported location for true()")); } } else if (NameFormat.format(FN_FALSE, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { RelationQueryNode rel = (RelationQueryNode) queryNode; rel.setStringValue("false"); } else { exceptions.add(new InvalidQueryException("Unsupported location for false()")); } } else if (NameFormat.format(FN_POSITION, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { RelationQueryNode rel = (RelationQueryNode) queryNode; if (rel.getOperation() == RelationQueryNode.OPERATION_EQ_GENERAL) { // set dummy value to set type of relation query node // will be overwritten when the tree is furhter parsed. rel.setPositionValue(1); rel.addPathElement(Path.PathElement.create(FN_POSITION_FULL)); } else { exceptions.add(new InvalidQueryException("Unsupported expression with position(). Only = is supported.")); } } else { exceptions.add(new InvalidQueryException("Unsupported location for position()")); } } else if (NameFormat.format(FN_FIRST, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { ((RelationQueryNode) queryNode).setPositionValue(1); } else if (queryNode.getType() == QueryNode.TYPE_LOCATION) { ((LocationStepQueryNode) queryNode).setIndex(1); } else { exceptions.add(new InvalidQueryException("Unsupported location for first()")); } } else if (NameFormat.format(FN_LAST, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { ((RelationQueryNode) queryNode).setPositionValue(LocationStepQueryNode.LAST); } else if (queryNode.getType() == QueryNode.TYPE_LOCATION) { ((LocationStepQueryNode) queryNode).setIndex(LocationStepQueryNode.LAST); } else { exceptions.add(new InvalidQueryException("Unsupported location for last()")); } } else if (NameFormat.format(JCR_DEREF, resolver).equals(fName)) { // check number of arguments if (node.jjtGetNumChildren() == 3) { boolean descendant = false; if (queryNode.getType() == QueryNode.TYPE_LOCATION) { LocationStepQueryNode loc = (LocationStepQueryNode) queryNode; // remember if descendant axis descendant = loc.getIncludeDescendants(); queryNode = loc.getParent(); ((NAryQueryNode) queryNode).removeOperand(loc); } if (queryNode.getType() == QueryNode.TYPE_PATH) { PathQueryNode pathNode = (PathQueryNode) queryNode; DerefQueryNode derefNode = new DerefQueryNode(pathNode, null, false); // assign property name node.jjtGetChild(1).jjtAccept(this, derefNode); // check property name if (derefNode.getRefProperty() == null) { exceptions.add(new InvalidQueryException("Wrong first argument type for jcr:deref")); } SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0); if (literal.getId() == JJTSTRINGLITERAL) { String value = literal.getValue(); // strip quotes value = value.substring(1, value.length() - 1); if (!value.equals("*")) { QName name = null; try { name = ISO9075.decode(NameFormat.parse(value, resolver)); } catch (NameException e) { exceptions.add(new InvalidQueryException("Illegal name: " + value)); } derefNode.setNameTest(name); } } else { exceptions.add(new InvalidQueryException("Second argument for jcr:deref must be a String")); } // check if descendant if (!descendant) { Node p = node.jjtGetParent(); for (int i = 0; i < p.jjtGetNumChildren(); i++) { SimpleNode c = (SimpleNode) p.jjtGetChild(i); if (c == node) { break; } descendant = (c.getId() == JJTSLASHSLASH || c.getId() == JJTROOTDESCENDANTS); } } derefNode.setIncludeDescendants(descendant); pathNode.addPathStep(derefNode); } else { exceptions.add(new InvalidQueryException("Unsupported location for jcr:deref()")); } } } else if (NameFormat.format(JCR_SCORE, resolver).equals(fName)) { if (queryNode.getType() == QueryNode.TYPE_ORDER) { createOrderSpec(node, (OrderQueryNode) queryNode); } else { exceptions.add(new InvalidQueryException("Unsupported location for jcr:score()")); } } else if (NameFormat.format(FN_LOWER_CASE, resolver).equals(fName)) { if (node.jjtGetNumChildren() == 2) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { RelationQueryNode relNode = (RelationQueryNode) queryNode; relNode.addOperand(new PropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.LOWER_CASE)); // get property name node.jjtGetChild(1).jjtAccept(this, relNode); } else { exceptions.add(new InvalidQueryException("Unsupported location for fn:lower-case()")); } } else { exceptions.add(new InvalidQueryException("Wrong number of argument for fn:lower-case()")); } } else if (NameFormat.format(FN_UPPER_CASE, resolver).equals(fName)) { if (node.jjtGetNumChildren() == 2) { if (queryNode.getType() == QueryNode.TYPE_RELATION) { RelationQueryNode relNode = (RelationQueryNode) queryNode; relNode.addOperand(new PropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.UPPER_CASE)); // get property name node.jjtGetChild(1).jjtAccept(this, relNode); } else { exceptions.add(new InvalidQueryException("Unsupported location for fn:upper-case()")); } } else { exceptions.add(new InvalidQueryException("Unsupported location for fn:upper-case()")); } } else if (queryNode.getType() == QueryNode.TYPE_RELATION) { // use function name as name of a pseudo property in a relation try { QName name = NameFormat.parse(fName + "()", resolver); RelationQueryNode relNode = (RelationQueryNode) queryNode; relNode.setRelativePath(Path.create(name, 0)); } catch (NameException e) { exceptions.add(e); } } else if (queryNode.getType() == QueryNode.TYPE_PATH) { // use function name as name of a pseudo property in select clause try { QName name = NameFormat.parse(fName + "()", resolver); root.addSelectProperty(name); } catch (NameException e) { exceptions.add(e); } } else { exceptions.add(new InvalidQueryException("Unsupported function: " + fName)); } } catch (NoPrefixDeclaredException e) { exceptions.add(e); } return queryNode; } private OrderQueryNode.OrderSpec createOrderSpec(SimpleNode node, OrderQueryNode queryNode) { SimpleNode child = (SimpleNode) node.jjtGetChild(0); OrderQueryNode.OrderSpec spec = null; try { String propName = child.getValue(); if (child.getId() == JJTQNAMELPAR) { // function name // cut off left parenthesis at end propName = propName.substring(0, propName.length() - 1); } QName name = ISO9075.decode(NameFormat.parse(propName, resolver)); spec = new OrderQueryNode.OrderSpec(name, true); queryNode.addOrderSpec(spec); } catch (NameException e) { exceptions.add(new InvalidQueryException("Illegal name: " + child.getValue())); } return spec; } /** * Returns true if <code>node</code> has a child node which is the attribute * axis. * * @param node a node with type {@link #JJTSTEPEXPR}. * @return <code>true</code> if this step expression uses the attribute axis. */ private boolean isAttributeAxis(SimpleNode node) { for (int i = 0; i < node.jjtGetNumChildren(); i++) { if (((SimpleNode) node.jjtGetChild(i)).getId() == JJTAT) { return true; } } return false; } /** * Returns <code>true</code> if the NodeTest <code>node</code> is an * attribute name test. * Example: * <pre> * StepExpr * At @ * NodeTest * NameTest * QName foo * </pre> * @param node a node with type {@link #JJTNAMETEST}. * @return <code>true</code> if the name test <code>node</code> is on the * attribute axis. */ private boolean isAttributeNameTest(SimpleNode node) { SimpleNode stepExpr = (SimpleNode) node.jjtGetParent().jjtGetParent(); if (stepExpr.getId() == JJTSTEPEXPR) { return ((SimpleNode) stepExpr.jjtGetChild(0)).getId() == JJTAT; } return false; } /** * Unescapes single or double quotes depending on how <code>literal</code> * is enclosed and strips enclosing quotes. * * </p> * Examples:</br> * <code>"foo""bar"</code> -> <code>foo"bar</code></br> * <code>'foo''bar'</code> -> <code>foo'bar</code></br> * but:</br> * <code>'foo""bar'</code> -> <code>foo""bar</code> * * @param literal the string literal to unescape * @return the unescaped and stripped literal. */ private String unescapeQuotes(String literal) { String value = literal.substring(1, literal.length() - 1); if (value.length() == 0) { // empty string return value; } if (literal.charAt(0) == '"') { value = value.replaceAll("\"\"", "\""); } else { value = value.replaceAll("''", "'"); } return value; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?