### Eclipse Workspace Patch 1.0 #P oak-jcr Index: src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/jcr/query/QueryManagerImpl.java (working copy) @@ -38,7 +38,7 @@ import org.apache.jackrabbit.oak.api.PropertyValue; import org.apache.jackrabbit.oak.api.Result; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.jcr.SessionDelegate; import org.apache.jackrabbit.oak.jcr.query.qom.QueryObjectModelFactoryImpl; import org.apache.jackrabbit.oak.namepath.NamePathMapper; @@ -51,7 +51,7 @@ public class QueryManagerImpl implements QueryManager { private final QueryObjectModelFactoryImpl qomFactory; - private final SessionQueryEngine queryEngine; + private final QueryEngine queryEngine; private final SessionDelegate sessionDelegate; private final HashSet supportedQueryLanguages = new HashSet(); Index: src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (working copy) @@ -41,7 +41,7 @@ import org.apache.jackrabbit.oak.api.CommitFailedException; import org.apache.jackrabbit.oak.api.ContentSession; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.TreeLocation; import org.apache.jackrabbit.oak.commons.PathUtils; @@ -446,7 +446,7 @@ } @Nonnull - public SessionQueryEngine getQueryEngine() { + public QueryEngine getQueryEngine() { return root.getQueryEngine(); } #P oak-core Index: src/main/java/org/apache/jackrabbit/oak/api/QueryEngine.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/api/QueryEngine.java (revision 1420120) +++ src/main/java/org/apache/jackrabbit/oak/api/QueryEngine.java (working copy) @@ -27,7 +27,7 @@ *

* What query languages are supported depends on the registered query parsers. */ -public interface SessionQueryEngine { +public interface QueryEngine { /** * Get the list of supported query languages. @@ -63,7 +63,4 @@ long limit, long offset, Map bindings, NamePathMapper namePathMapper) throws ParseException; - // TODO pass namespace mapping - // TODO pass node type information (select * from [xyz] is supposed to return at least the mandatory columns for xyz) - } Index: src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java (working copy) @@ -22,7 +22,9 @@ import java.io.InputStream; import java.security.AccessController; import java.security.PrivilegedAction; +import java.text.ParseException; import java.util.Collections; +import java.util.Map; import javax.annotation.Nonnull; import javax.security.auth.Subject; @@ -30,11 +32,14 @@ import org.apache.jackrabbit.oak.api.Blob; import org.apache.jackrabbit.oak.api.BlobFactory; import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.PropertyValue; +import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.TreeLocation; +import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.plugins.commit.DefaultConflictHandler; -import org.apache.jackrabbit.oak.query.SessionQueryEngineImpl; +import org.apache.jackrabbit.oak.query.QueryEngineImpl; import org.apache.jackrabbit.oak.spi.commit.ConflictHandler; import org.apache.jackrabbit.oak.spi.observation.ChangeExtractor; import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider; @@ -287,18 +292,20 @@ } @Override - public SessionQueryEngine getQueryEngine() { + public QueryEngine getQueryEngine() { checkLive(); - return new SessionQueryEngineImpl(indexProvider) { + return new QueryEngineImpl(indexProvider) { + @Override - protected NodeState getRootNodeState() { + protected NodeState getRootState() { return rootTree.getNodeState(); } - + @Override - protected Root getRoot() { + protected Root getRootTree() { return RootImpl.this; } + }; } Index: src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/api/SessionQueryEngine.java (working copy) @@ -1,69 +0,0 @@ -/* - * 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.oak.api; - -import java.text.ParseException; -import java.util.List; -import java.util.Map; - -import org.apache.jackrabbit.oak.namepath.NamePathMapper; - -/** - * The query engine allows to parse and execute queries. - *

- * What query languages are supported depends on the registered query parsers. - */ -public interface SessionQueryEngine { - - /** - * Get the list of supported query languages. - * - * @return the supported query languages - */ - List getSupportedQueryLanguages(); - - /** - * Parse the query (check if it's valid) and get the list of bind variable names. - * - * @param statement - * @param language - * @return the list of bind variable names - * @throws ParseException - */ - List getBindVariableNames(String statement, String language) throws ParseException; - - /** - * Execute a query and get the result. - * - * @param statement the query statement - * @param language the language - * @param limit the maximum result set size - * @param offset the number of rows to skip - * @param bindings the bind variable value bindings - * @param namePathMapper the name and path mapper to use - * @return the result - * @throws ParseException if the statement could not be parsed - * @throws IllegalArgumentException if there was an error executing the query - */ - Result executeQuery(String statement, String language, - long limit, long offset, Map bindings, - NamePathMapper namePathMapper) throws ParseException; - - // TODO pass namespace mapping - // TODO pass node type information (select * from [xyz] is supposed to return at least the mandatory columns for xyz) - -} Index: src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/security/user/UserProvider.java (working copy) @@ -140,7 +140,7 @@ *

User and Group Access

*

By ID

* Accessing authorizables by ID is achieved by calculating the ContentId - * associated with that user/group and using {@link org.apache.jackrabbit.oak.api.SessionQueryEngine} + * associated with that user/group and using {@link org.apache.jackrabbit.oak.api.QueryEngine} * to find the corresponding {@code Tree}. The result is validated to really * represent a user/group tree. * @@ -153,7 +153,7 @@ * If the principal instance passed to {@link #getAuthorizableByPrincipal(java.security.Principal)} * is a {@code TreeBasedPrincipal} the lookup is equivalent to * {@link #getAuthorizableByPath(String)}. Otherwise the user/group is search - * for using {@link org.apache.jackrabbit.oak.api.SessionQueryEngine} looking + * for using {@link org.apache.jackrabbit.oak.api.QueryEngine} looking * for a property {@link UserConstants#REP_PRINCIPAL_NAME} that matches the * name of the specified principal. */ Index: src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/query/SessionQueryEngineImpl.java (working copy) @@ -1,80 +0,0 @@ -/* - * 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.oak.query; - -import java.text.ParseException; -import java.util.List; -import java.util.Map; - -import org.apache.jackrabbit.oak.api.PropertyValue; -import org.apache.jackrabbit.oak.api.Result; -import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; -import org.apache.jackrabbit.oak.namepath.NamePathMapper; -import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; -import org.apache.jackrabbit.oak.spi.state.NodeState; - -/** - * The query engine implementation bound to a session. - */ -public abstract class SessionQueryEngineImpl implements SessionQueryEngine { - - private final QueryIndexProvider indexProvider; - - public SessionQueryEngineImpl(QueryIndexProvider indexProvider) { - this.indexProvider = indexProvider; - } - - /** - * The implementing class must return the current root {@link NodeState} - * associated with the {@link ContentSession}. - * - * @return the current root {@link NodeState}. - */ - protected abstract NodeState getRootNodeState(); - - /** - * The implementing class must return the root associated with the - * {@link ContentSession}. - * - * @return the root associated with the {@link ContentSession}. - */ - protected abstract Root getRoot(); - - @Override - public List getSupportedQueryLanguages() { - return createQueryEngine().getSupportedQueryLanguages(); - } - - @Override - public List getBindVariableNames(String statement, String language) - throws ParseException { - return createQueryEngine().getBindVariableNames(statement, language); - } - - @Override - public Result executeQuery(String statement, String language, long limit, - long offset, Map bindings, - NamePathMapper namePathMapper) throws ParseException { - return createQueryEngine().executeQuery(statement, language, limit, - offset, bindings, getRoot(), namePathMapper); - } - - private QueryEngineImpl createQueryEngine() { - return new QueryEngineImpl(getRootNodeState(), indexProvider); - } -} Index: src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (working copy) @@ -23,6 +23,8 @@ import java.util.Map.Entry; import org.apache.jackrabbit.oak.api.PropertyValue; +import org.apache.jackrabbit.oak.api.QueryEngine; +import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.Root; import org.apache.jackrabbit.oak.namepath.NamePathMapper; import org.apache.jackrabbit.oak.query.index.TraversingIndex; @@ -36,7 +38,7 @@ /** * The query engine implementation. */ -public class QueryEngineImpl { +public abstract class QueryEngineImpl implements QueryEngine { static final String SQL2 = "JCR-SQL2"; static final String SQL = "sql"; @@ -47,14 +49,27 @@ private static final Logger LOG = LoggerFactory.getLogger(QueryEngineImpl.class); - private final NodeState rootState; private final QueryIndexProvider indexProvider; - public QueryEngineImpl(NodeState rootState, QueryIndexProvider indexProvider) { - this.rootState = rootState; + public QueryEngineImpl(QueryIndexProvider indexProvider) { this.indexProvider = indexProvider; } + + /** + * Get the current root node state, to run the query against. + * + * @return the node state + */ + protected abstract NodeState getRootState(); + + /** + * Get the current root tree, to run the query against. + * + * @return the node state + */ + protected abstract Root getRootTree(); + @Override public List getSupportedQueryLanguages() { return Arrays.asList(SQL2, SQL, XPATH, JQOM, SQL2 + NO_LITERALS, SQL + NO_LITERALS, XPATH + NO_LITERALS); @@ -68,12 +83,13 @@ * @return the list of bind variable names * @throws ParseException */ + @Override public List getBindVariableNames(String statement, String language) throws ParseException { Query q = parseQuery(statement, language); return q.getBindVariableNames(); } - private Query parseQuery(String statement, String language) throws ParseException { + private static Query parseQuery(String statement, String language) throws ParseException { Query q; if (LOG.isDebugEnabled()) { LOG.debug(language + ": " + statement); @@ -105,13 +121,14 @@ } return q; } - - public ResultImpl executeQuery(String statement, String language, - long limit, long offset, Map bindings, - Root rootTree, + + @Override + public Result executeQuery(String statement, String language, long limit, + long offset, Map bindings, NamePathMapper namePathMapper) throws ParseException { Query q = parseQuery(statement, language); - q.setRootTree(rootTree); + q.setRootTree(getRootTree()); + q.setRootState(getRootState()); q.setNamePathMapper(namePathMapper); q.setLimit(limit); q.setOffset(offset); @@ -122,13 +139,13 @@ } q.setQueryEngine(this); q.prepare(); - return q.executeQuery(this.rootState); + return q.executeQuery(); } - public QueryIndex getBestIndex(Query query, Filter filter) { + public QueryIndex getBestIndex(Query query, NodeState rootState, Filter filter) { QueryIndex best = null; double bestCost = Double.MAX_VALUE; - for (QueryIndex index : getIndexes()) { + for (QueryIndex index : getIndexes(rootState)) { double cost = index.getCost(filter, rootState); if (LOG.isDebugEnabled()) { LOG.debug("cost for " + index.getIndexName() + " is " + cost); @@ -147,7 +164,7 @@ return best; } - private List getIndexes() { + private List getIndexes(NodeState rootState) { return indexProvider.getQueryIndexes(rootState); } Index: src/main/java/org/apache/jackrabbit/oak/api/Root.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/api/Root.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/api/Root.java (working copy) @@ -130,7 +130,7 @@ * @return the query engine */ @Nonnull - SessionQueryEngine getQueryEngine(); + QueryEngine getQueryEngine(); /** * Returns the blob factory (TODO: review if that really belongs to the OAK-API. see also todos on BlobFactory) Index: src/main/java/org/apache/jackrabbit/oak/query/Query.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/Query.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/query/Query.java (working copy) @@ -93,6 +93,7 @@ private long size = -1; private boolean prepared; private Root rootTree; + private NodeState rootState; private NamePathMapper namePathMapper; Query(String statement, SourceImpl source, ConstraintImpl constraint, OrderingImpl[] orderings, @@ -299,11 +300,11 @@ this.measure = measure; } - public ResultImpl executeQuery(NodeState rootState) { - return new ResultImpl(this, rootState); + public ResultImpl executeQuery() { + return new ResultImpl(this); } - Iterator getRows(NodeState rootState) { + Iterator getRows() { prepare(); Iterator it; if (explain) { @@ -589,12 +590,16 @@ } public QueryIndex getBestIndex(Filter filter) { - return queryEngine.getBestIndex(this, filter); + return queryEngine.getBestIndex(this, rootState, filter); } public void setRootTree(Root rootTree) { this.rootTree = rootTree; } + + public void setRootState(NodeState rootState) { + this.rootState = rootState; + } public void setNamePathMapper(NamePathMapper namePathMapper) { this.namePathMapper = namePathMapper; Index: src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (revision 1420149) +++ src/test/java/org/apache/jackrabbit/oak/query/AbstractQueryTest.java (working copy) @@ -38,7 +38,7 @@ import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.ResultRow; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.api.Tree; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.spi.query.PropertyValues; @@ -61,7 +61,7 @@ protected static final String TEST_INDEX_NAME = "test-index"; - protected SessionQueryEngine qe; + protected QueryEngine qe; protected ContentSession session; protected Root root; Index: src/main/java/org/apache/jackrabbit/oak/security/user/UserQueryManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/security/user/UserQueryManager.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/security/user/UserQueryManager.java (working copy) @@ -29,7 +29,7 @@ import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.ResultRow; import org.apache.jackrabbit.oak.api.Root; -import org.apache.jackrabbit.oak.api.SessionQueryEngine; +import org.apache.jackrabbit.oak.api.QueryEngine; import org.apache.jackrabbit.oak.security.user.query.XPathQueryBuilder; import org.apache.jackrabbit.oak.security.user.query.XPathQueryEvaluator; import org.apache.jackrabbit.oak.spi.security.user.AuthorizableType; @@ -104,7 +104,7 @@ boolean exact, AuthorizableType type) throws RepositoryException { // TODO: replace XPATH String statement = buildXPathStatement(relPath, value, exact, type); - SessionQueryEngine queryEngine = root.getQueryEngine(); + QueryEngine queryEngine = root.getQueryEngine(); try { Result result = queryEngine.executeQuery(statement, javax.jcr.query.Query.XPATH, Long.MAX_VALUE, 0, null, userManager.getNamePathMapper()); return Iterators.filter(Iterators.transform(result.getRows().iterator(), new ResultRowToAuthorizable()), Predicates.notNull()); Index: src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java (revision 1420149) +++ src/main/java/org/apache/jackrabbit/oak/query/ResultImpl.java (working copy) @@ -18,11 +18,11 @@ import java.util.Iterator; import java.util.List; + import org.apache.jackrabbit.oak.api.Result; import org.apache.jackrabbit.oak.api.ResultRow; import org.apache.jackrabbit.oak.query.ast.ColumnImpl; import org.apache.jackrabbit.oak.query.ast.SelectorImpl; -import org.apache.jackrabbit.oak.spi.state.NodeState; /** * A query result. @@ -30,11 +30,9 @@ public class ResultImpl implements Result { protected final Query query; - protected final NodeState rootState; - ResultImpl(Query query, NodeState rootState) { + ResultImpl(Query query) { this.query = query; - this.rootState = rootState; } @Override @@ -63,7 +61,7 @@ @Override public Iterator iterator() { - return query.getRows(rootState); + return query.getRows(); } };