/* * 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.exoplatform.services.jcr.impl.core.query.lucene; import org.exoplatform.services.jcr.datamodel.InternalQName; import org.exoplatform.services.jcr.impl.core.SessionDataManager; import org.exoplatform.services.jcr.impl.core.SessionImpl; import org.exoplatform.services.jcr.impl.core.query.ExecutableQuery; import org.exoplatform.services.jcr.impl.core.query.PropertyTypeRegistry; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.jcr.RepositoryException; import javax.jcr.Value; /** * <code>AbstractQueryImpl</code> provides a base class for executable queries * based on {@link SearchIndex}. */ public abstract class AbstractQueryImpl implements ExecutableQuery { /** * The session of the user executing this query */ protected final SessionImpl session; /** * The item manager of the user executing this query */ protected final SessionDataManager itemMgr; /** * The actual search index */ protected final SearchIndex index; /** * The property type registry for type lookup. */ protected final PropertyTypeRegistry propReg; /** * If <code>true</code> the default ordering of the result nodes is in * document order. */ private boolean documentOrder = true; /** * Indicates does we should use case insensitive sorting by field in order by clause or not. */ private boolean caseInsensitiveOrder; /** * Set<Name>, where Name is a variable name in the query statement. */ private final Set<InternalQName> variableNames = new HashSet<InternalQName>(); /** * Binding of variable name to value. Maps {@link Name} to {@link Value}. */ private final Map<InternalQName, Value> bindValues = new HashMap<InternalQName, Value>(); /** * Creates a new query instance from a query string. * * @param session the session of the user executing this query. * @param itemMgr the item manager of the session executing this query. * @param index the search index. * @param propReg the property type registry. */ public AbstractQueryImpl(SessionImpl session, SessionDataManager itemMgr, SearchIndex index, PropertyTypeRegistry propReg) { this.session = session; this.itemMgr = itemMgr; this.index = index; this.propReg = propReg; } /** * If set <code>true</code> the result nodes will be in document order * per default (if no order by clause is specified). If set to * <code>false</code> the result nodes are returned in whatever sequence * the index has stored the nodes. That sequence is stable over multiple * invocations of the same query, but will change when nodes get added or * removed from the index. * <br> * The default value for this property is <code>true</code>. * @return the current value of this property. */ public boolean getRespectDocumentOrder() { return documentOrder; } /** * Sets a new value for this property. * * @param documentOrder if <code>true</code> the result nodes are in * document order per default. * * @see #getRespectDocumentOrder() */ public void setRespectDocumentOrder(boolean documentOrder) { this.documentOrder = documentOrder; } /** * Setter for {@link #caseInsensitiveOrder} field. */ public void setCaseInsensitiveOrder(boolean caseInsensitiveOrder) { this.caseInsensitiveOrder = caseInsensitiveOrder; } /** * Getter for {@link #caseInsensitiveOrder} field. */ public boolean isCaseInsensitiveOrder() { return caseInsensitiveOrder; } /** * Binds the given <code>value</code> to the variable named * <code>varName</code>. * * @param varName name of variable in query * @param value value to bind * @throws IllegalArgumentException if <code>varName</code> is not a valid * variable in this query. * @throws RepositoryException if an error occurs. */ public void bindValue(InternalQName varName, Value value) throws IllegalArgumentException, RepositoryException { if (!variableNames.contains(varName)) { throw new IllegalArgumentException("not a valid variable in this query"); } else { bindValues.put(varName, value); } } /** * Adds a name to the set of variables. * * @param varName the name of the variable. */ protected void addVariableName(InternalQName varName) { variableNames.add(varName); } /** * @return an unmodifiable map, which contains the variable names and their * respective value. */ protected Map<InternalQName, Value> getBindVariableValues() { return Collections.unmodifiableMap(bindValues); } /** * Returns <code>true</code> if this query node needs items under * /jcr:system to be queried. * * @return <code>true</code> if this query node needs content under * /jcr:system to be queried; <code>false</code> otherwise. */ public abstract boolean needsSystemTree(); }