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