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