queryformat.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 575 行 · 第 1/2 页
JAVA
575 行
exceptions.add(e); } } } sb.append(", '"); sb.append(query).append("')"); return sb; } public Object visit(PathQueryNode node, Object data) { StringBuffer sb = (StringBuffer) data; try { if (containsDescendantOrSelf(node)) { sb.append("("); sb.append(NameFormat.format(QName.JCR_PATH, resolver)); sb.append(" LIKE '"); LocationStepQueryNode[] steps = node.getPathSteps(); for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() == null || steps[i].getNameTest().getLocalName().length() > 0) { sb.append('/'); } if (steps[i].getIncludeDescendants()) { sb.append("%/"); } steps[i].accept(this, sb); } sb.append('\''); sb.append(" OR "); sb.append(NameFormat.format(QName.JCR_PATH, resolver)); sb.append(" LIKE '"); for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() == null || steps[i].getNameTest().getLocalName().length() > 0) { sb.append('/'); } if (steps[i].getNameTest() != null) { steps[i].accept(this, sb); } } sb.append("')"); } else if (containsAllChildrenMatch(node)) { sb.append(NameFormat.format(QName.JCR_PATH, resolver)); sb.append(" LIKE '"); StringBuffer path = new StringBuffer(); LocationStepQueryNode[] steps = node.getPathSteps(); for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() == null || steps[i].getNameTest().getLocalName().length() > 0) { path.append('/'); } steps[i].accept(this, path); } sb.append(path); sb.append('\''); sb.append(" AND NOT "); sb.append(NameFormat.format(QName.JCR_PATH, resolver)); sb.append(" LIKE '"); sb.append(path).append("/%").append('\''); } else { // just do a best effort sb.append(NameFormat.format(QName.JCR_PATH, resolver)); sb.append(" LIKE '"); LocationStepQueryNode[] steps = node.getPathSteps(); for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() == null || steps[i].getNameTest().getLocalName().length() > 0) { sb.append('/'); } steps[i].accept(this, sb); } sb.append('\''); } } catch (NoPrefixDeclaredException e) { exceptions.add(e); } return sb; } public Object visit(LocationStepQueryNode node, Object data) { StringBuffer sb = (StringBuffer) data; if (node.getNameTest() == null) { sb.append("%"); } else { if (node.getNameTest().getLocalName().length() > 0) { try { sb.append(NameFormat.format(node.getNameTest(), resolver)); } catch (NoPrefixDeclaredException e) { exceptions.add(e); } if (node.getIndex() == LocationStepQueryNode.NONE) { sb.append("[%]"); } else if (node.getIndex() == 1) { // do nothing } else { sb.append('[').append(node.getIndex()).append(']'); } } else { // empty name test indicates root node } } return sb; } public Object visit(DerefQueryNode node, Object data) { exceptions.add(new InvalidQueryException("jcr:deref() function not supported in SQL")); return data; } public Object visit(RelationQueryNode node, Object data) { Path relPath = node.getRelativePath(); if (relPath.getLength() > 1) { exceptions.add(new InvalidQueryException("Child axis not supported in SQL")); return data; } StringBuffer sb = (StringBuffer) data; try { StringBuffer propName = new StringBuffer(); appendName(relPath.getNameElement().getName(), resolver, propName); // surround name with property function node.acceptOperands(this, propName); sb.append(propName); if (node.getOperation() == OPERATION_EQ_VALUE || node.getOperation() == OPERATION_EQ_GENERAL) { sb.append(" = "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_GE_VALUE || node.getOperation() == OPERATION_GE_GENERAL) { sb.append(" >= "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_GT_VALUE || node.getOperation() == OPERATION_GT_GENERAL) { sb.append(" > "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_LE_VALUE || node.getOperation() == OPERATION_LE_GENERAL) { sb.append(" <= "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_LIKE) { sb.append(" LIKE "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_LT_VALUE || node.getOperation() == OPERATION_LT_GENERAL) { sb.append(" < "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_NE_VALUE || node.getOperation() == OPERATION_NE_GENERAL) { sb.append(" <> "); appendValue(node, sb); } else if (node.getOperation() == OPERATION_NULL) { sb.append(" IS NULL"); } else if (node.getOperation() == OPERATION_NOT_NULL) { sb.append(" IS NOT NULL"); } else { exceptions.add(new InvalidQueryException("Invalid operation: " + node.getOperation())); } if (node.getOperation() == OPERATION_LIKE && node.getStringValue().indexOf('\\') > -1) { sb.append(" ESCAPE '\\'"); } } catch (NoPrefixDeclaredException e) { exceptions.add(e); } return sb; } public Object visit(OrderQueryNode node, Object data) { StringBuffer sb = (StringBuffer) data; sb.append(" ORDER BY"); OrderQueryNode.OrderSpec[] specs = node.getOrderSpecs(); if (specs.length > 0) { try { String comma = ""; for (int i = 0; i < specs.length; i++) { sb.append(comma).append(" "); appendName(specs[i].getProperty(), resolver, sb); if (!specs[i].isAscending()) { sb.append(" DESC"); } comma = ","; } } catch (NoPrefixDeclaredException e) { exceptions.add(e); } } else { sb.append(" SCORE"); } return sb; } public Object visit(PropertyFunctionQueryNode node, Object data) { StringBuffer sb = (StringBuffer) data; String functionName = node.getFunctionName(); if (functionName.equals(PropertyFunctionQueryNode.LOWER_CASE)) { sb.insert(0, "LOWER(").append(")"); } else if (functionName.equals(PropertyFunctionQueryNode.UPPER_CASE)) { sb.insert(0, "UPPER(").append(")"); } else { exceptions.add(new InvalidQueryException("Unsupported function: " + functionName)); } return sb; } //------------------------< internal >-------------------------------------- /** * Appends the <code>name</code> to the <code>StringBuffer</code> * <code>b</code> using the <code>NamespaceResolver</code> * <code>resolver</code>. The <code>name</code> is put in double quotes * if the local part of <code>name</code> contains a space character. * * @param name the <code>QName</code> to print. * @param resolver to resolve <code>name</code>. * @param b where to output the <code>name</code>. * @throws NoPrefixDeclaredException if <code>name</code> contains a uri * that is not declared in <code>resolver</code>. */ private static void appendName(QName name, NamespaceResolver resolver, StringBuffer b) throws NoPrefixDeclaredException { boolean quote = name.getLocalName().indexOf(' ') > -1; if (quote) { b.append('"'); } b.append(NameFormat.format(name, resolver)); if (quote) { b.append('"'); } } private void appendValue(RelationQueryNode node, StringBuffer b) { if (node.getValueType() == TYPE_LONG) { b.append(node.getLongValue()); } else if (node.getValueType() == TYPE_DOUBLE) { b.append(node.getDoubleValue()); } else if (node.getValueType() == TYPE_STRING) { b.append("'").append(node.getStringValue().replaceAll("'", "''")).append("'"); } else if (node.getValueType() == TYPE_DATE || node.getValueType() == TYPE_TIMESTAMP) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.setTime(node.getDateValue()); b.append("TIMESTAMP '").append(ISO8601.format(cal)).append("'"); } else { exceptions.add(new InvalidQueryException("Invalid type: " + node.getValueType())); } } /** * Returns <code>true</code> if <code>path</code> contains exactly one * step with a descendant-or-self axis and an explicit name test; returns * <code>false</code> otherwise. * * @param path the path node. * @return <code>true</code> if <code>path</code> contains exactly one * step with a descendant-or-self axis. */ private static boolean containsDescendantOrSelf(PathQueryNode path) { LocationStepQueryNode[] steps = path.getPathSteps(); int count = 0; for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() != null && steps[i].getIncludeDescendants()) { count++; } } return count == 1; } /** * Returns <code>true</code> if <code>path</code> contains exactly one * location step which matches all node names. That is, matches any children * of a given node. That location step must be the last one in the sequence * of location steps. * * @param path the path node. * @return <code>true</code> if the last step matches any node name. */ private static boolean containsAllChildrenMatch(PathQueryNode path) { LocationStepQueryNode[] steps = path.getPathSteps(); int count = 0; for (int i = 0; i < steps.length; i++) { if (steps[i].getNameTest() == null && !steps[i].getIncludeDescendants()) { if (i == steps.length - 1 && count == 0) { return true; } count++; } } return false; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?