From 6358a077c385cb7ea2fa86d92d7c373d8972d70f Mon Sep 17 00:00:00 2001 From: Jukka Zitting Date: Thu, 9 Jul 2009 11:39:05 +0000 Subject: [PATCH] JCR-1104: JSR 283 support Upgraded to the latest pre-release version of the JCR 2.0 API jar. Adjusted sources accordingly (see JCR-2200 and JCR-2201 for the missing pieces). git-svn-id: https://svn.apache.org/repos/asf/jackrabbit/trunk@792508 13f79535-47bb-0310-9956-ffa450edef68 --- README.txt | 11 +++++----- RELEASE-NOTES.txt | 6 ++++-- .../jackrabbit/core/query/QueryImpl.java | 8 +++++++- .../core/query/QueryManagerImpl.java | 6 ++---- .../core/query/lucene/QueryResultImpl.java | 7 +++++++ .../query/lucene/SingleColumnQueryResult.java | 1 + .../test/api/query/AbstractQueryTest.java | 9 +++++++++ .../query/qom/FullTextSearchScoreTest.java | 4 ++-- .../qom/QueryObjectModelFactoryTest.java | 8 ++++++-- .../jackrabbit/jcr2spi/query/QueryImpl.java | 6 ++++++ .../jcr2spi/query/QueryManagerImpl.java | 11 ++++------ .../jcr2spi/query/QueryObjectModelImpl.java | 5 +++++ .../jcr2spi/query/QueryResultImpl.java | 7 +++++++ jackrabbit-parent/pom.xml | 2 +- .../qom/QueryObjectModelFactoryImpl.java | 16 +++------------ .../spi/commons/query/sql2/Parser.java | 20 +++++++++++-------- .../spi/commons/query/sql2/ParserTest.java | 6 +++--- 17 files changed, 84 insertions(+), 49 deletions(-) diff --git a/README.txt b/README.txt index 202a63a56dd..c5bf875b065 100644 --- a/README.txt +++ b/README.txt @@ -10,10 +10,10 @@ observation, and more. Typical applications that use content repositories include content management, document management, and records management systems. -Jackrabbit is currently based on the Proposed Final Draft (PFD) version -of the JCR 2.0 API defined by the Java Specification Request 283 -(JSR 283, http://jcp.org/en/jsr/detail?id=283). Version 1.0 of the -JCR API was specified by JSR 170. +Jackrabbit is currently based on a pre-release version of the JCR 2.0 API +defined by the Java Specification Request 283 (JSR 283, +http://jcp.org/en/jsr/detail?id=283). Version 1.0 of the JCR API was +specified by JSR 170. Apache Jackrabbit is a project of the Apache Software Foundation. @@ -25,7 +25,7 @@ jcr-2.0-b18.xml files from https://issues.apache.org/jira/browse/JCR-1104 and install them to your local Maven repository: mvn install:install-file \ - -Dfile=jcr-2.0-b18.jar -DpomFile=jcr-2.0-b18.xml + -Dfile=jcr-2.0-b19.jar -DpomFile=jcr-2.0-b19.xml Once you've installed the jar, you can build Jackrabbit like this: @@ -89,4 +89,3 @@ Credits See http://jackrabbit.apache.org/jackrabbit-team.html for the list of Jackrabbit committers and main contributors. - diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index e545153d563..0dad5f509c8 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -45,12 +45,12 @@ Jackrabbit releases, please see the Jackrabbit issue tracker at JCR 2.0 feature completeness ---------------------------- -The following 39 top level JCR 2.0 implementation issues are being tracked in +The following 41 top level JCR 2.0 implementation issues are being tracked in the Jackrabbit issue tracker. Most of them have already been partially implemented, but the issue will only be marked as resolved once no more related work is needed. -Open (14 issues) +Open (16 issues) [JCR-1565] JSR 283 lifecycle management [JCR-1588] JSR 283: Access Control [JCR-1590] JSR 283: Locking @@ -65,6 +65,8 @@ Open (14 issues) [JCR-2137] Use type StaticOperand for fullTextSearchExpression [JCR-2140] JSR 283: Baselines [JCR-2198] Text.escapeIllegalJCRChars should be adjusted to match the ... + [JCR-2200] Implement Query.getBindVariableNames() + [JCR-2201] Implement QueryResult.getSelectorNames() Resolved (25 issues) [JCR-1564] JSR 283 namespace handling diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryImpl.java index 9e1b68bdcba..a5e17cac285 100644 --- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryImpl.java +++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryImpl.java @@ -195,6 +195,12 @@ public Node storeAsNode(String absPath) } } + // TODO: JCR-2200: Implement Query.getBindVariableNames() + public String[] getBindVariableNames() throws RepositoryException { + throw new UnsupportedRepositoryOperationException( + "JCR-2200: Implement Query.getBindVariableNames()"); + } + /** * Binds the given value to the variable named * varName. @@ -267,5 +273,5 @@ protected void checkInitialized() { throw new IllegalStateException("not initialized"); } } -} +} diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java index f9e10b3afc8..80ad2673904 100644 --- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java +++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/QueryManagerImpl.java @@ -80,8 +80,7 @@ public QueryManagerImpl(final SessionImpl session, this.session = session; this.itemMgr = itemMgr; this.searchMgr = searchMgr; - this.qomFactory = new QueryObjectModelFactoryImpl( - session, session.getValueFactory()) { + this.qomFactory = new QueryObjectModelFactoryImpl(session) { protected QueryObjectModel createQuery(QueryObjectModelTree qomTree) throws InvalidQueryException, RepositoryException { return searchMgr.createQueryObjectModel( @@ -194,8 +193,7 @@ public QueryFactoryImpl(String language) { public QueryFactoryImpl(final Node node, final String language) { super(Arrays.asList( - new QOMQueryFactory(new QueryObjectModelFactoryImpl( - session, session.getValueFactory()) { + new QOMQueryFactory(new QueryObjectModelFactoryImpl(session) { protected QueryObjectModel createQuery(QueryObjectModelTree qomTree) throws InvalidQueryException, RepositoryException { return searchMgr.createQueryObjectModel( diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java index d3ab4d9909f..6d156fb5163 100644 --- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java +++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java @@ -27,6 +27,7 @@ import javax.jcr.ItemNotFoundException; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; +import javax.jcr.UnsupportedRepositoryOperationException; import javax.jcr.query.QueryResult; import javax.jcr.query.RowIterator; import java.io.IOException; @@ -181,6 +182,12 @@ public QueryResultImpl(SearchIndex index, } } + // TODO: JCR-2201: Implement QueryResult.getSelectorNames() + public String[] getSelectorNames() throws RepositoryException { + throw new UnsupportedRepositoryOperationException( + "JCR-2201: Implement QueryResult.getSelectorNames()"); + } + /** * {@inheritDoc} */ diff --git a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java index fe079725dc0..89360ee9d85 100644 --- a/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java +++ b/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java @@ -85,4 +85,5 @@ protected MultiColumnQueryHits executeQuery(long resultFetchHint) protected ExcerptProvider createExcerptProvider() throws IOException { return index.createExcerptProvider(query); } + } diff --git a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractQueryTest.java b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractQueryTest.java index db0f340aacf..8359ab3d7a8 100644 --- a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractQueryTest.java +++ b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/AbstractQueryTest.java @@ -30,6 +30,8 @@ import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Session; +import javax.jcr.ValueFactory; + import java.util.Set; import java.util.HashSet; import java.util.Iterator; @@ -80,6 +82,11 @@ public abstract class AbstractQueryTest extends AbstractJCRTest { */ protected QueryObjectModelFactory qf; + /** + * The value factory for creating literals for the query object model. + */ + protected ValueFactory vf; + /** * The query manager for {@link #superuser} */ @@ -100,11 +107,13 @@ protected void setUp() throws Exception { xpathRoot = "/" + jcrRoot + ISO9075.encodePath(testRoot); qm = superuser.getWorkspace().getQueryManager(); qf = qm.getQOMFactory(); + vf = superuser.getValueFactory(); } protected void tearDown() throws Exception { qm = null; qf = null; + vf = null; super.tearDown(); } diff --git a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/FullTextSearchScoreTest.java b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/FullTextSearchScoreTest.java index e05e852d899..53efc2284f5 100644 --- a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/FullTextSearchScoreTest.java +++ b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/FullTextSearchScoreTest.java @@ -45,7 +45,7 @@ public void testOrdering() throws RepositoryException { QueryObjectModel qom = qf.createQuery( qf.selector(testNodeType, "s"), qf.and( - qf.fullTextSearch("s", null, "fox"), + qf.fullTextSearch("s", null, qf.literal(vf.createValue("fox"))), qf.descendantNode("s", testRootNode.getPath()) ), new Ordering[]{qf.ascending(qf.fullTextSearchScore("s"))}, @@ -72,7 +72,7 @@ public void testConstraint() throws RepositoryException { qf.selector(testNodeType, "s"), qf.and( qf.and( - qf.fullTextSearch("s", null, "fox"), + qf.fullTextSearch("s", null, qf.literal(vf.createValue("fox"))), qf.comparison( qf.fullTextSearchScore("s"), QueryObjectModelFactory.JCR_OPERATOR_GREATER_THAN, diff --git a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/QueryObjectModelFactoryTest.java b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/QueryObjectModelFactoryTest.java index 8c8ad4fba94..bfb4fbeee2f 100644 --- a/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/QueryObjectModelFactoryTest.java +++ b/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/query/qom/QueryObjectModelFactoryTest.java @@ -373,7 +373,9 @@ public void testEquiJoinCondition() throws RepositoryException { * Test case for {@link QueryObjectModelFactory#fullTextSearch(String, String, String)} */ public void testFullTextSearch() throws RepositoryException { - FullTextSearch ftSearch = qf.fullTextSearch(SELECTOR_NAME1, propertyName1, FULLTEXT_SEARCH_EXPR); + FullTextSearch ftSearch = qf.fullTextSearch( + SELECTOR_NAME1, propertyName1, + qf.literal(vf.createValue(FULLTEXT_SEARCH_EXPR))); assertEquals("Wrong selector name", SELECTOR_NAME1, ftSearch.getSelectorName()); assertEquals("Wrong propertyName", propertyName1, ftSearch.getPropertyName()); // TODO is there some way to check the contents of a StaticOperand? @@ -387,7 +389,9 @@ public void testFullTextSearch() throws RepositoryException { * Test case for {@link QueryObjectModelFactory#fullTextSearch(String, String, String)} */ public void testFullTextSearchAllProperties() throws RepositoryException { - FullTextSearch ftSearch = qf.fullTextSearch(SELECTOR_NAME1, null, FULLTEXT_SEARCH_EXPR); + FullTextSearch ftSearch = qf.fullTextSearch( + SELECTOR_NAME1, null, + qf.literal(vf.createValue(FULLTEXT_SEARCH_EXPR))); assertEquals("Wrong selector name", SELECTOR_NAME1, ftSearch.getSelectorName()); assertNull("Property name must be null", ftSearch.getPropertyName()); // TODO is there some way to check the contents of a StaticOperand? diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java index d94140f54b3..9c62adce961 100644 --- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java +++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryImpl.java @@ -220,6 +220,12 @@ public Node storeAsNode(String absPath) throws ItemExistsException, } } + // TODO: JCR-2200: Implement Query.getBindVariableNames() + public String[] getBindVariableNames() throws RepositoryException { + throw new UnsupportedRepositoryOperationException( + "JCR-2200: Implement Query.getBindVariableNames()"); + } + /** * @see Query#bindValue(String, Value) */ diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java index 359eab606ac..9ce5f3a8c1b 100644 --- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java +++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryManagerImpl.java @@ -116,8 +116,7 @@ public Query getQuery(Node node) String language = node.getProperty(resolver.getJCRName(NameConstants.JCR_LANGUAGE)).getString(); if (Query.JCR_JQOM.equals(language)) { - QueryObjectModelFactory qomFactory = new QOMFactory( - node, resolver, valueFactory); + QueryObjectModelFactory qomFactory = new QOMFactory(node, resolver); QueryObjectModelBuilder builder = QueryObjectModelBuilderRegistry.getQueryObjectModelBuilder(language); return builder.createQueryObjectModel(statement, qomFactory, valueFactory); } else { @@ -137,7 +136,7 @@ public String[] getSupportedQueryLanguages() throws RepositoryException { * @see QueryManager#getQOMFactory() */ public QueryObjectModelFactory getQOMFactory() { - return new QOMFactory(null, mgrProvider.getNamePathResolver(), valueFactory); + return new QOMFactory(null, mgrProvider.getNamePathResolver()); } //------------------------------------------------------------< private >--- @@ -158,10 +157,8 @@ private class QOMFactory extends QueryObjectModelFactoryImpl { private final Node node; - public QOMFactory(Node node, - NamePathResolver resolver, - ValueFactory factory) { - super(resolver, factory); + public QOMFactory(Node node, NamePathResolver resolver) { + super(resolver); this.node = node; } diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryObjectModelImpl.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryObjectModelImpl.java index 90ac8707725..0fc8cb05cc2 100644 --- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryObjectModelImpl.java +++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryObjectModelImpl.java @@ -180,5 +180,10 @@ public void bindValue(String varName, Value value) throws IllegalArgumentException, RepositoryException { throw new UnsupportedOperationException(); } + + public String[] getBindVariableNames() throws RepositoryException { + throw new UnsupportedOperationException(); + } + } } diff --git a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java index e47c238dda3..d374affeac2 100644 --- a/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java +++ b/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/query/QueryResultImpl.java @@ -60,6 +60,13 @@ class QueryResultImpl implements QueryResult { this.queryInfo = queryInfo; } + /** + * {@inheritDoc} + */ + public String[] getSelectorNames() throws RepositoryException { + return queryInfo.getColumnNames(); + } + /** * {@inheritDoc} */ diff --git a/jackrabbit-parent/pom.xml b/jackrabbit-parent/pom.xml index f370322cc34..4ff32b32704 100644 --- a/jackrabbit-parent/pom.xml +++ b/jackrabbit-parent/pom.xml @@ -147,7 +147,7 @@ javax.jcr jcr - 2.0-b18 + 2.0-b19 provided diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/QueryObjectModelFactoryImpl.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/QueryObjectModelFactoryImpl.java index 681a699b3ed..92cc4ae49de 100644 --- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/QueryObjectModelFactoryImpl.java +++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/QueryObjectModelFactoryImpl.java @@ -58,7 +58,6 @@ import javax.jcr.query.qom.UpperCase; import javax.jcr.RepositoryException; import javax.jcr.Value; -import javax.jcr.ValueFactory; /** * QueryObjectModelFactoryImpl implements the query object model @@ -71,15 +70,8 @@ public abstract class QueryObjectModelFactoryImpl implements QueryObjectModelFac */ private final NamePathResolver resolver; - /** - * Value factory of the current session. - */ - private final ValueFactory factory; - - public QueryObjectModelFactoryImpl( - NamePathResolver resolver, ValueFactory factory) { + public QueryObjectModelFactoryImpl(NamePathResolver resolver) { this.resolver = resolver; - this.factory = factory; } /** @@ -529,7 +521,7 @@ public FullTextSearch fullTextSearch(String propertyName, */ public FullTextSearch fullTextSearch(String selectorName, String propertyName, - String fullTextSearchExpression) + StaticOperand fullTextSearchExpression) throws InvalidQueryException, RepositoryException { if (fullTextSearchExpression == null) { throw new IllegalArgumentException( @@ -539,11 +531,9 @@ public FullTextSearch fullTextSearch(String selectorName, if (propertyName != null) { propName = checkPropertyName(propertyName); } - Literal literal = - literal(factory.createValue(fullTextSearchExpression)); return new FullTextSearchImpl(resolver, checkSelectorName(selectorName), propName, - checkFullTextSearchExpression(literal)); + checkFullTextSearchExpression(fullTextSearchExpression)); } /** diff --git a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java index cc5fea895f8..51adb262616 100644 --- a/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java +++ b/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/sql2/Parser.java @@ -139,9 +139,9 @@ private Selector parseSelector() throws RepositoryException { private String readName() throws RepositoryException { if (readIf("[")) { if (currentTokenType == VALUE) { - String s = readString(); + Value value = readString(); read("]"); - return s; + return value.getString(); } else { int level = 1; StringBuilder buff = new StringBuilder(); @@ -330,16 +330,20 @@ private Constraint parseConditionFuntionIf(String functionName) throws Repositor if (readIf(".")) { if (readIf("*")) { read(","); - c = factory.fullTextSearch(name, null, readString()); + c = factory.fullTextSearch( + name, null, factory.literal(readString())); } else { String selector = name; name = readName(); read(","); - c = factory.fullTextSearch(selector, name, readString()); + c = factory.fullTextSearch( + selector, name, factory.literal(readString())); } } else { read(","); - c = factory.fullTextSearch(getOnlySelectorName(), name, readString()); + c = factory.fullTextSearch( + getOnlySelectorName(), name, + factory.literal(readString())); } } else if ("ISSAMENODE".equalsIgnoreCase(functionName)) { String name = readName(); @@ -635,13 +639,13 @@ private String readAny() throws RepositoryException { return s; } - private String readString() throws RepositoryException { + private Value readString() throws RepositoryException { if (currentTokenType != VALUE) { throw getSyntaxError("string value"); } - String s = currentValue.getString(); + Value value = currentValue; read(); - return s; + return value; } private void addExpected(String token) { diff --git a/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/sql2/ParserTest.java b/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/sql2/ParserTest.java index b4aba81f429..df4fa4fee07 100644 --- a/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/sql2/ParserTest.java +++ b/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/query/sql2/ParserTest.java @@ -46,8 +46,8 @@ public class ParserTest extends TestCase { static class QOMF extends QueryObjectModelFactoryImpl { - public QOMF(NamePathResolver resolver, ValueFactory factory) { - super(resolver, factory); + public QOMF(NamePathResolver resolver) { + super(resolver); } protected QueryObjectModel createQuery(QueryObjectModelTree qomTree) throws InvalidQueryException, @@ -60,8 +60,8 @@ protected QueryObjectModel createQuery(QueryObjectModelTree qomTree) throws Inva protected void setUp() throws Exception { super.setUp(); NamePathResolver resolver = new DefaultNamePathResolver(new DummyNamespaceResolver()); + QueryObjectModelFactoryImpl factory = new QOMF(resolver); ValueFactory vf = new ValueFactoryQImpl(QValueFactoryImpl.getInstance(), resolver); - QueryObjectModelFactoryImpl factory = new QOMF(resolver, vf); parser = new Parser(factory, vf); }