Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java (revision 785) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java (working copy) @@ -97,6 +97,10 @@ public static I18n workspaceNameIsInvalid; public static I18n errorVerifyingWorkspaceName; + // Query-related messages + public static I18n notStoredQuery; + public static I18n invalidQueryLanguage; + static { try { I18n.initialize(JcrI18n.class); Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java (revision 0) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrQueryManager.java (revision 0) @@ -0,0 +1,208 @@ +/* + * JBoss DNA (http://www.jboss.org/dna) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * JBoss DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.dna.jcr; + +import java.util.Arrays; +import javax.jcr.ItemNotFoundException; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.query.InvalidQueryException; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; +import net.jcip.annotations.Immutable; +import org.jboss.dna.graph.property.NamespaceRegistry; +import org.jboss.dna.graph.property.Path; + +/** + * Place-holder implementation of {@link QueryManager} interface. + */ +@Immutable +class JcrQueryManager implements QueryManager { + + private final JcrSession session; + + JcrQueryManager( JcrSession session ) { + this.session = session; + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.QueryManager#createQuery(java.lang.String, java.lang.String) + */ + public Query createQuery( String statement, + String language ) throws InvalidQueryException { + return this.createQuery(statement, language, null); + } + + /** + * Creates a new query by specifying the query statement itself, the language in which the query is stated, and, optionally, + * the node from which the query was loaded. If the query statement is syntactically invalid, given the language specified, an + * {@code InvalidQueryException} is thrown. The language must be a string from among those returned by {@code + * QueryManager#getSupportedQueryLanguages()}; if it is not, then an {@code InvalidQueryException} is thrown. + * + * @param statement + * @param language + * @param storedNode + * @return A {@code Query} object + * @throws InvalidQueryException if statement is invalid or language is unsupported. + * @see javax.jcr.query.QueryManager#createQuery(java.lang.String, java.lang.String) + */ + private Query createQuery( String statement, + String language, + AbstractJcrNode storedNode ) throws InvalidQueryException { + if (Query.XPATH.equals(language)) { + return new XPathQuery(this.session, statement, storedNode); + } + throw new InvalidQueryException(JcrI18n.invalidQueryLanguage.text(language, Arrays.asList(getSupportedQueryLanguages()))); + + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.QueryManager#getQuery(javax.jcr.Node) + */ + public Query getQuery( Node node ) throws InvalidQueryException, RepositoryException { + assert node instanceof AbstractJcrNode; + + JcrNodeType nodeType = (JcrNodeType)node.getPrimaryNodeType(); + if (!nodeType.getInternalName().equals(JcrNtLexicon.QUERY)) { + throw new InvalidQueryException(JcrI18n.notStoredQuery.text()); + } + + // These are both mandatory properties for nodes of nt:query + NamespaceRegistry registry = session.getExecutionContext().getNamespaceRegistry(); + String statement = node.getProperty(JcrLexicon.STATEMENT.getString(registry)).getString(); + String language = node.getProperty(JcrLexicon.LANGUAGE.getString(registry)).getString(); + + return createQuery(statement, language, (AbstractJcrNode)node); + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.QueryManager#getSupportedQueryLanguages() + */ + public String[] getSupportedQueryLanguages() { + return new String[] {Query.XPATH}; + } + + @Immutable + protected abstract class AbstractJcrQuery implements Query { + private final JcrSession session; + private final String language; + private final String statement; + private final Path storedPath; + + protected AbstractJcrQuery( JcrSession session, + String statement, + String language, + AbstractJcrNode storedNode ) { + assert session != null; + assert statement != null; + assert language != null; + + this.session = session; + this.language = language; + this.statement = statement; + + try { + this.storedPath = storedNode != null ? storedNode.path() : null; + } catch (RepositoryException re) { + throw new IllegalStateException(re); + } + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.Query#execute() + */ + public abstract QueryResult execute(); + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.Query#getLanguage() + */ + public String getLanguage() { + return language; + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.Query#getStatement() + */ + public String getStatement() { + return statement; + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.Query#getStoredQueryPath() + */ + public String getStoredQueryPath() throws ItemNotFoundException { + if (storedPath == null) { + throw new ItemNotFoundException(JcrI18n.notStoredQuery.text()); + } + return storedPath.getString(session.getExecutionContext().getNamespaceRegistry()); + } + + /** + * {@inheritDoc} + * + * @see javax.jcr.query.Query#storeAsNode(java.lang.String) + */ + public Node storeAsNode( java.lang.String absPath ) throws UnsupportedRepositoryOperationException { + throw new UnsupportedRepositoryOperationException(); + } + + } + + @Immutable + protected class XPathQuery extends AbstractJcrQuery { + + XPathQuery( JcrSession session, + String statement, + AbstractJcrNode storedNode ) { + super(session, statement, Query.XPATH, storedNode); + } + + /** + * {@inheritDoc} + * + * @see org.jboss.dna.jcr.JcrQueryManager.AbstractJcrQuery#execute() + */ + @Override + public QueryResult execute() { + throw new UnsupportedOperationException(); + } + } + +} Index: dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java =================================================================== --- dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (revision 785) +++ dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java (working copy) @@ -107,6 +107,11 @@ private final JcrNodeTypeManager nodeTypeManager; /** + * Reference to the JCR query manager for this workspace. + */ + private final JcrQueryManager queryManager; + + /** * The {@link Session} instance that this corresponds with this workspace. */ private final JcrSession session; @@ -149,6 +154,7 @@ // This must be initialized after the session this.nodeTypeManager = new JcrNodeTypeManager(session.getExecutionContext(), repository.getRepositoryTypeManager()); + this.queryManager = new JcrQueryManager(this.session); } final String getSourceName() { @@ -212,7 +218,7 @@ * {@inheritDoc} */ public final QueryManager getQueryManager() { - throw new UnsupportedOperationException(); + return queryManager; } /** Index: dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties =================================================================== --- dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties (revision 785) +++ dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties (working copy) @@ -83,3 +83,6 @@ noNegativeDepth=Depth parameter ({0}) cannot be negative tooDeep=Depth parameter ({0}) cannot be greater than the result of getDepth() for this node + +notStoredQuery=This query has not been stored or loaded +invalidQueryLanguage="{0}" is not a valid query langauge. Supported languages are: {1} \ No newline at end of file Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (revision 785) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java (working copy) @@ -107,7 +107,7 @@ addTestSuite(org.apache.jackrabbit.test.api.PropertyReadMethodsTest.class); addTestSuite(org.apache.jackrabbit.test.api.RepositoryDescriptorTest.class); addTestSuite(org.apache.jackrabbit.test.api.SessionReadMethodsTest.class); - // addTestSuite(org.apache.jackrabbit.test.api.WorkspaceReadMethodsTest.class); + addTestSuite(org.apache.jackrabbit.test.api.WorkspaceReadMethodsTest.class); addTestSuite(org.apache.jackrabbit.test.api.ReferenceableRootNodesTest.class); addTestSuite(org.apache.jackrabbit.test.api.ExportSysViewTest.class); addTestSuite(org.apache.jackrabbit.test.api.ExportDocViewTest.class); @@ -118,13 +118,13 @@ // addTestSuite(org.apache.jackrabbit.test.api.query.XPathDocOrderTest.class); // addTestSuite(org.apache.jackrabbit.test.api.query.XPathOrderByTest.class); // addTestSuite(org.apache.jackrabbit.test.api.query.XPathJcrPathTest.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.DerefQueryLevel1Test.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.GetLanguageTest.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.GetPersistentQueryPathLevel1Test.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.GetStatementTest.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.GetSupportedQueryLanguagesTest.class); + addTestSuite(org.apache.jackrabbit.test.api.query.DerefQueryLevel1Test.class); + addTestSuite(org.apache.jackrabbit.test.api.query.GetLanguageTest.class); + addTestSuite(org.apache.jackrabbit.test.api.query.GetPersistentQueryPathLevel1Test.class); + addTestSuite(org.apache.jackrabbit.test.api.query.GetStatementTest.class); + addTestSuite(org.apache.jackrabbit.test.api.query.GetSupportedQueryLanguagesTest.class); // addTestSuite(org.apache.jackrabbit.test.api.query.GetPropertyNamesTest.class); - // addTestSuite(org.apache.jackrabbit.test.api.query.PredicatesTest.class); + addTestSuite(org.apache.jackrabbit.test.api.query.PredicatesTest.class); // addTestSuite(org.apache.jackrabbit.test.api.query.SimpleSelectionTest.class); // The tests in this suite are level one Index: dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java =================================================================== --- dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java (revision 785) +++ dna-jcr/src/test/java/org/jboss/dna/jcr/JcrWorkspaceTest.java (working copy) @@ -160,9 +160,9 @@ workspace.getObservationManager(); } - @Test( expected = UnsupportedOperationException.class ) - public void shouldNotAllowGetQueryManager() throws Exception { - workspace.getQueryManager(); + @Test + public void shouldProvideQueryManager() throws Exception { + assertThat(workspace.getQueryManager(), notNullValue()); } @Test