xpathquerybuilder.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,077 行 · 第 1/4 页
JAVA
1,077 行
} catch (Throwable t) { // also catch any other exception throw new InvalidQueryException(t.getMessage(), t); } if (exceptions.size() > 0) { // simply report the first one Exception e = (Exception) exceptions.get(0); if (e instanceof InvalidQueryException) { // just re-throw throw (InvalidQueryException) e; } else { // otherwise package throw new InvalidQueryException(e.getMessage(), e); } } } /** * Creates a <code>QueryNode</code> tree from a XPath statement. * * @param statement the XPath statement. * @param resolver the namespace resolver to use. * @return the <code>QueryNode</code> tree for the XPath statement. * @throws InvalidQueryException if the XPath statement is malformed. */ public static QueryRootNode createQuery(String statement, NamespaceResolver resolver) throws InvalidQueryException { return new XPathQueryBuilder(statement, resolver).getRootNode(); } /** * Creates a String representation of the query node tree in XPath syntax. * * @param root the root of the query node tree. * @param resolver to resolve QNames. * @return a String representation of the query node tree. * @throws InvalidQueryException if the query node tree cannot be converted * into a String representation due to restrictions in XPath. */ public static String toString(QueryRootNode root, NamespaceResolver resolver) throws InvalidQueryException { return QueryFormat.toString(root, resolver); } /** * Returns the root node of the <code>QueryNode</code> tree. * * @return the root node of the <code>QueryNode</code> tree. */ QueryRootNode getRootNode() { return root; } //---------------------< XPathVisitor >------------------------------------- /** * Implements the generic visit method for this <code>XPathVisitor</code>. * * @param node the current node as created by the XPath parser. * @param data the current <code>QueryNode</code> created by this * <code>XPathVisitor</code>. * @return the current <code>QueryNode</code>. Can be different from * <code>data</code>. */ public Object visit(SimpleNode node, Object data) { QueryNode queryNode = (QueryNode) data; switch (node.getId()) { case JJTXPATH2: queryNode = createPathQueryNode(node); break; case JJTROOT: case JJTROOTDESCENDANTS: if (queryNode instanceof PathQueryNode) { ((PathQueryNode) queryNode).setAbsolute(true); } else { exceptions.add(new InvalidQueryException( "Unsupported root level query node: " + queryNode)); } break; case JJTSTEPEXPR: if (isAttributeAxis(node)) { if (queryNode.getType() == QueryNode.TYPE_RELATION || (queryNode.getType() == QueryNode.TYPE_DEREF && ((DerefQueryNode) queryNode).getRefProperty() == null) || queryNode.getType() == QueryNode.TYPE_ORDER || queryNode.getType() == QueryNode.TYPE_PATH || queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) { // traverse node.childrenAccept(this, queryNode); } else if (queryNode.getType() == QueryNode.TYPE_NOT) { // is null expression RelationQueryNode isNull = new RelationQueryNode(queryNode, RelationQueryNode.OPERATION_NULL); applyRelativePath(isNull); node.childrenAccept(this, isNull); NotQueryNode notNode = (NotQueryNode) queryNode; NAryQueryNode parent = (NAryQueryNode) notNode.getParent(); parent.removeOperand(notNode); parent.addOperand(isNull); } else { // not null expression RelationQueryNode notNull = new RelationQueryNode(queryNode, RelationQueryNode.OPERATION_NOT_NULL); applyRelativePath(notNull); node.childrenAccept(this, notNull); ((NAryQueryNode) queryNode).addOperand(notNull); } } else { if (queryNode.getType() == QueryNode.TYPE_PATH) { createLocationStep(node, (NAryQueryNode) queryNode); } else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH || queryNode.getType() == QueryNode.TYPE_RELATION) { node.childrenAccept(this, queryNode); } else { // step within a predicate RelationQueryNode tmp = new RelationQueryNode( null, RelationQueryNode.OPERATION_NOT_NULL); node.childrenAccept(this, tmp); if (tmpRelPath == null) { tmpRelPath = new Path.PathBuilder(); } tmpRelPath.addLast(tmp.getRelativePath().getNameElement()); } } break; case JJTNAMETEST: if (queryNode.getType() == QueryNode.TYPE_LOCATION || queryNode.getType() == QueryNode.TYPE_DEREF || queryNode.getType() == QueryNode.TYPE_RELATION || queryNode.getType() == QueryNode.TYPE_TEXTSEARCH || queryNode.getType() == QueryNode.TYPE_PATH) { createNodeTest(node, queryNode); } else if (queryNode.getType() == QueryNode.TYPE_ORDER) { createOrderSpec(node, (OrderQueryNode) queryNode); } else { // traverse node.childrenAccept(this, queryNode); } break; case JJTELEMENTNAMEORWILDCARD: if (queryNode.getType() == QueryNode.TYPE_LOCATION) { SimpleNode child = (SimpleNode) node.jjtGetChild(0); if (child.getId() != JJTANYNAME) { createNodeTest(child, queryNode); } } break; case JJTTEXTTEST: if (queryNode.getType() == QueryNode.TYPE_LOCATION) { LocationStepQueryNode loc = (LocationStepQueryNode) queryNode; loc.setNameTest(JCR_XMLTEXT); } break; case JJTTYPENAME: if (queryNode.getType() == QueryNode.TYPE_LOCATION) { LocationStepQueryNode loc = (LocationStepQueryNode) queryNode; String ntName = ((SimpleNode) node.jjtGetChild(0)).getValue(); try { QName nt = NameFormat.parse(ntName, resolver); NodeTypeQueryNode nodeType = new NodeTypeQueryNode(loc, nt); loc.addPredicate(nodeType); } catch (NameException e) { exceptions.add(new InvalidQueryException("Not a valid name: " + ntName)); } } break; case JJTOREXPR: NAryQueryNode parent = (NAryQueryNode) queryNode; QueryNode orQueryNode = new OrQueryNode(parent); parent.addOperand(orQueryNode); // traverse node.childrenAccept(this, orQueryNode); break; case JJTANDEXPR: parent = (NAryQueryNode) queryNode; QueryNode andQueryNode = new AndQueryNode(parent); parent.addOperand(andQueryNode); // traverse node.childrenAccept(this, andQueryNode); break; case JJTCOMPARISONEXPR: createExpression(node, (NAryQueryNode) queryNode); break; case JJTSTRINGLITERAL: case JJTDECIMALLITERAL: case JJTDOUBLELITERAL: case JJTINTEGERLITERAL: if (queryNode.getType() == QueryNode.TYPE_RELATION) { assignValue(node, (RelationQueryNode) queryNode); } else if (queryNode.getType() == QueryNode.TYPE_LOCATION) { if (node.getId() == JJTINTEGERLITERAL) { int index = Integer.parseInt(node.getValue()); ((LocationStepQueryNode) queryNode).setIndex(index); } else { exceptions.add(new InvalidQueryException("LocationStep only allows integer literal as position index")); } } else { exceptions.add(new InvalidQueryException("Parse error: data is not a RelationQueryNode")); } break; case JJTUNARYMINUS: if (queryNode.getType() == QueryNode.TYPE_RELATION) { ((RelationQueryNode) queryNode).setUnaryMinus(true); } else { exceptions.add(new InvalidQueryException("Parse error: data is not a RelationQueryNode")); } break; case JJTFUNCTIONCALL: queryNode = createFunction(node, queryNode); break; case JJTORDERBYCLAUSE: root.setOrderNode(new OrderQueryNode(root)); queryNode = root.getOrderNode(); node.childrenAccept(this, queryNode); break; case JJTORDERMODIFIER: if (node.jjtGetNumChildren() > 0 && ((SimpleNode) node.jjtGetChild(0)).getId() == JJTDESCENDING) { OrderQueryNode.OrderSpec[] specs = ((OrderQueryNode) queryNode).getOrderSpecs(); specs[specs.length - 1].setAscending(false); } break; case JJTPREDICATELIST: if (queryNode.getType() == QueryNode.TYPE_PATH) { // switch to last location QueryNode[] operands = ((PathQueryNode) queryNode).getOperands(); queryNode = operands[operands.length - 1]; } node.childrenAccept(this, queryNode); break; case JJTPREDICATE: if (queryNode.getType() == QueryNode.TYPE_LOCATION || queryNode.getType() == QueryNode.TYPE_DEREF) { node.childrenAccept(this, queryNode); } else { // predicate not allowed here exceptions.add(new InvalidQueryException("Unsupported location for predicate")); } break; case JJTDOTDOT: exceptions.add(new InvalidQueryException("Parent axis is not supported")); break; default: // per default traverse node.childrenAccept(this, queryNode); } return queryNode; } //----------------------< internal >---------------------------------------- /** * Applies {@link #tmpRelPath} to <code>node</code> and reset the path to * <code>null</code>. * * @param node a relation query node. */ private void applyRelativePath(RelationQueryNode node) { if (tmpRelPath != null) { try { Path relPath = tmpRelPath.getPath(); for (int i = 0; i < relPath.getLength(); i++) { node.addPathElement(relPath.getElement(i)); } } catch (MalformedPathException e) { // should never happen } tmpRelPath = null;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?