queryformat.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 575 行 · 第 1/2 页

JAVA
575
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.query.sql;import org.apache.jackrabbit.core.query.AndQueryNode;import org.apache.jackrabbit.core.query.DerefQueryNode;import org.apache.jackrabbit.core.query.ExactQueryNode;import org.apache.jackrabbit.core.query.LocationStepQueryNode;import org.apache.jackrabbit.core.query.NodeTypeQueryNode;import org.apache.jackrabbit.core.query.NotQueryNode;import org.apache.jackrabbit.core.query.OrQueryNode;import org.apache.jackrabbit.core.query.OrderQueryNode;import org.apache.jackrabbit.core.query.PathQueryNode;import org.apache.jackrabbit.core.query.QueryConstants;import org.apache.jackrabbit.core.query.QueryNode;import org.apache.jackrabbit.core.query.QueryNodeVisitor;import org.apache.jackrabbit.core.query.QueryRootNode;import org.apache.jackrabbit.core.query.RelationQueryNode;import org.apache.jackrabbit.core.query.TextsearchQueryNode;import org.apache.jackrabbit.core.query.PropertyFunctionQueryNode;import org.apache.jackrabbit.name.NamespaceResolver;import org.apache.jackrabbit.name.NoPrefixDeclaredException;import org.apache.jackrabbit.name.QName;import org.apache.jackrabbit.name.NameFormat;import org.apache.jackrabbit.name.Path;import org.apache.jackrabbit.util.ISO8601;import javax.jcr.query.InvalidQueryException;import java.util.ArrayList;import java.util.Calendar;import java.util.Iterator;import java.util.List;import java.util.TimeZone;/** * Implements the query node tree serialization into a String. */class QueryFormat implements QueryNodeVisitor, QueryConstants {    /**     * Will be used to resolve QNames     */    private final NamespaceResolver resolver;    /**     * The String representation of the query node tree     */    private String statement;    /**     * List of exception objects created while creating the SQL string     */    private List exceptions = new ArrayList();    /**     * List of node types     */    private List nodeTypes = new ArrayList();    private QueryFormat(QueryRootNode root, NamespaceResolver resolver)            throws InvalidQueryException {        this.resolver = resolver;        statement = root.accept(this, new StringBuffer()).toString();        if (exceptions.size() > 0) {            Exception e = (Exception) exceptions.get(0);            throw new InvalidQueryException(e.getMessage(), e);        }    }    /**     * Creates a SQL <code>String</code> representation of the QueryNode tree     * argument <code>root</code>.     *     * @param root     the query node tree.     * @param resolver to resolve QNames.     * @return the SQL string representation of the QueryNode tree.     * @throws InvalidQueryException the query node tree cannot be represented     *                               as a SQL <code>String</code>.     */    public static String toString(QueryRootNode root, NamespaceResolver resolver)            throws InvalidQueryException {        return new QueryFormat(root, resolver).toString();    }    /**     * Returns the string representation.     *     * @return the string representation.     */    public String toString() {        return statement;    }    //-------------< QueryNodeVisitor interface >-------------------------------    public Object visit(QueryRootNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        try {            sb.append("SELECT");            QName[] selectProps = node.getSelectProperties();            if (selectProps.length == 0) {                sb.append(" *");            } else {                String comma = "";                for (int i = 0; i < selectProps.length; i++) {                    sb.append(comma).append(" ");                    appendName(selectProps[i], resolver, sb);                    comma = ",";                }            }            sb.append(" FROM");            // node type restrictions are within predicates of location nodes            // therefore we write the where clause first to a temp string to            // collect the node types.            StringBuffer tmp = new StringBuffer();            LocationStepQueryNode[] steps = node.getLocationNode().getPathSteps();            QueryNode[] predicates = steps[steps.length - 1].getPredicates();            // are there any relevant predicates?            for (int i = 0; i < predicates.length; i++) {                if (predicates[i].getType() != QueryNode.TYPE_NODETYPE) {                    tmp.append(" WHERE ");                }            }            String and = "";            for (int i = 0; i < predicates.length; i++) {                if (predicates[i].getType() != QueryNode.TYPE_NODETYPE) {                    tmp.append(and);                    and = " AND ";                }                predicates[i].accept(this, tmp);            }            // node types have been collected by now            String comma = "";            int ntCount = 0;            for (Iterator it = nodeTypes.iterator(); it.hasNext(); ntCount++) {                QName nt = (QName) it.next();                sb.append(comma).append(" ");                appendName(nt, resolver, sb);                comma = ",";            }            if (ntCount == 0) {                sb.append(" ");                sb.append(NameFormat.format(QName.NT_BASE, resolver));            }            // append WHERE clause            sb.append(tmp.toString());            if (steps.length == 2                    && steps[1].getIncludeDescendants()                    && steps[1].getNameTest() == null) {                // then this query selects all paths            } else if (steps.length == 1                    && steps[0].getIncludeDescendants()                    && steps[0].getNameTest() == null) {                // then this query selects all paths            } else {                if (predicates.length > 0) {                    sb.append(" AND ");                } else {                    sb.append(" WHERE ");                }                node.getLocationNode().accept(this, sb);            }        } catch (NoPrefixDeclaredException e) {            exceptions.add(e);        }        if (node.getOrderNode() != null) {            node.getOrderNode().accept(this, sb);        }        return sb;    }    public Object visit(OrQueryNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        boolean bracket = false;        if (node.getParent() instanceof LocationStepQueryNode                || node.getParent() instanceof AndQueryNode                || node.getParent() instanceof NotQueryNode) {            bracket = true;        }        if (bracket) {            sb.append("(");        }        String or = "";        QueryNode[] operands = node.getOperands();        for (int i = 0; i < operands.length; i++) {            sb.append(or);            operands[i].accept(this, sb);            or = " OR ";        }        if (bracket) {            sb.append(")");        }        return sb;    }    public Object visit(AndQueryNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        boolean bracket = false;        if (node.getParent() instanceof NotQueryNode) {            bracket = true;        }        if (bracket) {            sb.append("(");        }        String and = "";        QueryNode[] operands = node.getOperands();        for (int i = 0; i < operands.length; i++) {            sb.append(and);            int len = sb.length();            operands[i].accept(this, sb);            // check if something has been written at all            // might have been a node type query node            if (sb.length() - len > 0) {                and = " AND ";            } else {                and = "";            }        }        if (bracket) {            sb.append(")");        }        return sb;    }    public Object visit(NotQueryNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        QueryNode[] operands = node.getOperands();        if (operands.length > 0) {            sb.append("NOT ");            operands[0].accept(this, sb);        }        return sb;    }    public Object visit(ExactQueryNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        try {            appendName(node.getPropertyName(), resolver, sb);        } catch (NoPrefixDeclaredException e) {            exceptions.add(e);        }        sb.append("='").append(node.getValue()).append("'");        return sb;    }    public Object visit(NodeTypeQueryNode node, Object data) {        nodeTypes.add(node.getValue());        return data;    }    public Object visit(TextsearchQueryNode node, Object data) {        StringBuffer sb = (StringBuffer) data;        // escape quote        String query = node.getQuery().replaceAll("'", "''");        sb.append("CONTAINS(");        if (node.getRelativePath() == null) {            sb.append("*");        } else {            if (node.getRelativePath().getLength() > 1                    || !node.getReferencesProperty()) {                exceptions.add(new InvalidQueryException("Child axis not supported in SQL"));            } else {                try {                    appendName(node.getRelativePath().getNameElement().getName(), resolver, sb);                } catch (NoPrefixDeclaredException e) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?