/* * 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; import static org.apache.jackrabbit.spi.commons.name.NameConstants.JCR_LANGUAGE; import static org.apache.jackrabbit.spi.commons.name.NameConstants.JCR_STATEMENT; import static org.apache.jackrabbit.spi.commons.name.NameConstants.NT_QUERY; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.io.IOException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.query.InvalidQueryException; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; import javax.jcr.query.qom.QueryObjectModel; import javax.jcr.query.qom.QueryObjectModelFactory; import org.apache.jackrabbit.core.SearchManager; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.session.SessionContext; import org.apache.jackrabbit.core.session.SessionOperation; import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelFactoryImpl; import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree; /** * This class implements the {@link QueryManager} interface. */ public class QueryManagerImpl implements QueryManager { /** * Component context of the current session. */ private final SessionContext sessionContext; /** * The <code>SearchManager</code> holding the search index. */ private final SearchManager searchMgr; /** * The <code>QueryObjectModelFactory</code> for this query manager. */ private final QueryObjectModelFactoryImpl qomFactory; /** * Creates a new <code>QueryManagerImpl</code> for the passed * <code>session</code> * * @param sessionContext component context of the current session * @param searchMgr the search manager of this workspace. * @throws RepositoryException if an error occurs while initializing the * query manager. */ public QueryManagerImpl( final SessionContext sessionContext, final SearchManager searchMgr) throws RepositoryException { this.sessionContext = sessionContext; this.searchMgr = searchMgr; this.qomFactory = new QueryObjectModelFactoryImpl(sessionContext) { protected QueryObjectModel createQuery(QueryObjectModelTree qomTree) throws InvalidQueryException, RepositoryException { return searchMgr.createQueryObjectModel( sessionContext, qomTree, Query.JCR_JQOM, null); } }; } /** * {@inheritDoc} */ public Query createQuery(final String statement, final String language) throws RepositoryException { return perform(new SessionOperation<Query>() { public Query perform(SessionContext context) throws RepositoryException { QueryFactory qf = new QueryFactoryImpl(language); return qf.createQuery(statement, language); } public String toString() { return "node.createQuery(" + statement + ", " + language + ")"; } }); } /** * {@inheritDoc} */ public Query getQuery(final Node node) throws RepositoryException { return perform(new SessionOperation<Query>() { public Query perform(SessionContext context) throws RepositoryException { if (!node.isNodeType(context.getJCRName(NT_QUERY))) { throw new InvalidQueryException( "Node is not of type nt:query: " + node); } String statement = node.getProperty(context.getJCRName(JCR_STATEMENT)).getString(); String language = node.getProperty(context.getJCRName(JCR_LANGUAGE)).getString(); QueryFactory qf = new QueryFactoryImpl(node, language); return qf.createQuery(statement, language); } public String toString() { return "queryManager.getQuery(node)"; } }); } /** * {@inheritDoc} */ public String[] getSupportedQueryLanguages() throws RepositoryException { List<String> languages = new QueryFactoryImpl(Query.JCR_JQOM).getSupportedLanguages(); return languages.toArray(new String[languages.size()]); } //---------------------------< JSR 283 >------------------------------------ /** * Returns a <code>QueryObjectModelFactory</code> with which a JCR-JQOM * query can be built programmatically. * * @return a <code>QueryObjectModelFactory</code> object * @since JCR 2.0 */ public QueryObjectModelFactory getQOMFactory() { return qomFactory; } //-------------------------< Jackrabbit internal >-------------------------- /** * Returns the ids of the nodes that refer to the <code>node</code> by weak * references. * * @param node the target node. * @return the referring nodes. * @throws RepositoryException if an error occurs. */ public Iterable<Node> getWeaklyReferringNodes(final Node node) throws RepositoryException { return perform(new SessionOperation<Iterable<Node>>() { public Iterable<Node> perform(SessionContext context) throws RepositoryException { List<Node> nodes = new ArrayList<Node>(); try { NodeId nodeId = new NodeId(node.getIdentifier()); for (NodeId id : searchMgr.getWeaklyReferringNodes(nodeId)) { nodes.add(sessionContext.getSessionImpl().getNodeById(id)); } } catch (IOException e) { throw new RepositoryException(e); } return nodes; } public String toString() { return "queryManager.getWeaklyReferringNodes(node)"; } }); } //------------------------< testing only >---------------------------------- /** * @return the query handler implementation. */ QueryHandler getQueryHandler() { return searchMgr.getQueryHandler(); } //---------------------------< internal >----------------------------------- /** * Performs the given session operation. */ private <T> T perform(SessionOperation<T> operation) throws RepositoryException { return sessionContext.getSessionState().perform(operation); } private class QueryFactoryImpl extends CompoundQueryFactory { public QueryFactoryImpl(String language) { this(null, language); } public QueryFactoryImpl(final Node node, final String language) { super(Arrays.asList( new QOMQueryFactory(new QueryObjectModelFactoryImpl( sessionContext.getSessionImpl()) { @Override protected QueryObjectModel createQuery( QueryObjectModelTree qomTree) throws RepositoryException { return searchMgr.createQueryObjectModel( sessionContext, qomTree, language, node); } }, sessionContext.getSessionImpl().getValueFactory()), new AQTQueryFactory() { public Query createQuery(String statement, String language) throws RepositoryException { return searchMgr.createQuery( sessionContext, statement, language, node); } })); } } }