Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 1560 invoked from network); 27 Apr 2009 12:44:10 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 27 Apr 2009 12:44:10 -0000 Received: (qmail 33414 invoked by uid 500); 27 Apr 2009 12:44:10 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 33355 invoked by uid 500); 27 Apr 2009 12:44:10 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 33346 invoked by uid 99); 27 Apr 2009 12:44:10 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Apr 2009 12:44:10 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Apr 2009 12:43:56 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9068523888AF; Mon, 27 Apr 2009 12:43:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r768954 [1/4] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query... Date: Mon, 27 Apr 2009 12:43:31 -0000 To: commits@jackrabbit.apache.org From: mreutegg@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090427124334.9068523888AF@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mreutegg Date: Mon Apr 27 12:43:28 2009 New Revision: 768954 URL: http://svn.apache.org/viewvc?rev=768954&view=rev Log: JCR-2076: JSR 283: Joins Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/AndConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ChildNodeConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ComparisonConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/Constraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DescendantNodeConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DynamicOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/EvaluationContext.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/FullTextConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/HierarchyConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LengthOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LikeConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LowerCaseOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeLocalNameOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeNameOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NotConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/OrConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyExistenceConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyValueOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/QueryConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/SameNodeConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/SelectorBasedConstraint.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/UpperCaseOperand.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/AbstractCondition.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/AncestorNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/AncestorPathNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ChildNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/Condition.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/DescendantPathNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/EquiJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/Join.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ParentNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/SameNodeJoin.java (with props) jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ScoreNodeMap.java (with props) jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/ - copied from r768218, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/qom/ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/AbstractJoinTest.java (with props) jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/DescendantNodeJoinConditionTest.java (with props) jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/EquiJoinConditionTest.java (with props) jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/SameNodeJoinConditionTest.java (with props) Removed: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JQOM2LuceneQueryBuilder.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/WildcardTermEnum.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/AbstractQOMTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/BindVariableValueTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/ChildNodeTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/DescendantNodeTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/LengthTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/NodeLocalNameTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/NodeNameTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/PropertyExistenceTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/QueryObjectModelFactoryTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/SameNodeTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/SelectorTest.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/TestAll.java jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/query/qom/UpperLowerCaseTest.java jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/ChildNodeJoinConditionImpl.java jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/DescendantNodeJoinConditionImpl.java jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/EquiJoinConditionImpl.java jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/query/qom/SameNodeJoinConditionImpl.java Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java (added) +++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,132 @@ +/* + * 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.api.jsr283.query; + +import javax.jcr.RepositoryException; +import javax.jcr.Node; + +/** + * Row... + */ +public interface Row extends javax.jcr.query.Row { + + /** + * Returns the Node corresponding to this Row. + *

+ * A RepositoryException is thrown if this Row + * contains values from more than one node. This will be the case when more + * than one selector is included among the columns specified for the query. + * + * @return a Node + * @throws RepositoryException if this query has more than one selector + * (and therefore, this Row corresponds to more than one + * Node) or if another error occurs. + * @since JCR 2.0 + */ + public Node getNode() throws RepositoryException; + + /** + * Returns the Node corresponding to this Row and + * the specified selector. If this Row is from a result involving + * outer joins, it may have no Node corresponding to the specified selector. + * In such a case this method returns null. + * + * @param selectorName a String + * @return a Node + * @throws RepositoryException if selectorName is not the alias + * of a selector in this query or if another error occurs. + * @since JCR 2.0 + */ + public Node getNode(String selectorName) throws RepositoryException; + + /** + * Equivalent to Row.getNode().getPath(). However, some + * implementations may be able gain efficiency by not resolving the actual + * Node. + * + * @return a String + * @throws RepositoryException if this query has more than one selector + * (and therefore, this Row corresponds to more than one + * Node) or if another error occurs. + * @since JCR 2.0 + */ + public String getPath() throws RepositoryException; + + /** + * Equivalent to Row.getNode(selectorName).getPath(). However, some + * implementations may be able gain efficiency by not resolving the actual + * Node. If this Row is from a result involving + * outer joins, it may have no Node corresponding to the specified + * selector. In such a case this method returns null. + * + * @param selectorName a String + * @return a String + * @throws RepositoryException if selectorName is not the alias + * of a selector in this query or if another error occurs. + * @since JCR 2.0 + */ + public String getPath(String selectorName) throws RepositoryException; + + /** + * Returns the full text search score for this row associated with the + * default selector. This corresponds to the score of a particular node. + *

+ * If no FullTextSearchScore AQM object is associated with the + * default selector this method will still return a value. However, in that + * case the returned value may not be meaningful or may simply reflect the + * minimum possible relevance level (for example, in some systems this might + * be a score of 0). + *

+ * Note, in JCR-SQL2 a FullTextSearchScore AQM object is represented + * by a SCORE() function. In JCR-JQOM it is represented by a + * Java object of type javax.jcr.query.qom.FullTextSearchScore. + * + * @return a double + * @throws RepositoryException if this query has more than one selector + * (and therefore, this Row corresponds to more than one + * Node) or if another error occurs. + * @since JCR 2.0 + */ + public double getScore() throws RepositoryException; + + /** + * Returns the full text search score for this row associated with the + * specified selector. This corresponds to the score of a particular node. + *

+ * If no FullTextSearchScore AQM object is associated with the + * selector selectorName this method will still return a value. + * However, in that case the returned value may not be meaningful or may + * simply reflect the minimum possible relevance level (for example, in some + * systems this might be a score of 0). + *

+ * Note, in JCR-SQL2 a FullTextSearchScore AQM object is represented + * by a SCORE() function. In JCR-JQOM it is represented by a + * Java object of type javax.jcr.query.qom.FullTextSearchScore. + *

+ * If this Row is from a result involving + * outer joins, it may have no Node corresponding to the specified selector. + * In such a case this method returns an implementation selected value, as it would if there were no + * FullTextSearchScore associated with the selector. + * + * @param selectorName a String + * @return a double + * @throws RepositoryException if selectorName is not the alias + * of a selector in this query or if another error occurs. + * @since JCR 2.0 + */ + public double getScore(String selectorName) throws RepositoryException; +} Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/query/Row.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/AbstractQueryImpl.java Mon Apr 27 12:43:28 2009 @@ -162,9 +162,4 @@ * /jcr:system to be queried; false otherwise. */ public abstract boolean needsSystemTree(); - - /** - * @return the selector names for this query. - */ - public abstract Name[] getSelectorNames(); } Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,89 @@ +/* + * 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.lucene; + +import java.io.IOException; +import java.util.Arrays; + +import org.apache.jackrabbit.core.query.lucene.constraint.Constraint; +import org.apache.lucene.search.Sort; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * FilterMultiColumnQuery wraps a multi column query and filters + * out rows that do not satisfy a given constraint. + */ +public class FilterMultiColumnQuery implements MultiColumnQuery { + + /** + * The logger instance for this class. + */ + private static final Logger log = LoggerFactory.getLogger(FilterMultiColumnQuery.class); + + /** + * The query to filter. + */ + private final MultiColumnQuery query; + + /** + * The constraint for filtering. + */ + private final Constraint constraint; + + /** + * Creates a new filter multi column query for the given query + * and constraint. + * + * @param query the query to filter. + * @param constraint the constraint for filtering. + */ + public FilterMultiColumnQuery(MultiColumnQuery query, + Constraint constraint) { + this.query = query; + this.constraint = constraint; + } + + /** + * {@inheritDoc} + */ + public MultiColumnQueryHits execute(final JackrabbitIndexSearcher searcher, + Sort sort, + long resultFetchHint) + throws IOException { + return new FilterMultiColumnQueryHits(query.execute( + searcher, sort, resultFetchHint)) { + + { + log.debug(Arrays.asList(getSelectorNames()).toString()); + } + + public ScoreNode[] nextScoreNodes() throws IOException { + ScoreNode[] next; + do { + next = super.nextScoreNodes(); + if (log.isDebugEnabled()) { + if (next != null) { + log.debug(Arrays.asList(next).toString()); + } + } + } while (next != null && !constraint.evaluate(next, getSelectorNames(), searcher)); + return next; + } + }; + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/FilterMultiColumnQuery.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java Mon Apr 27 12:43:28 2009 @@ -20,7 +20,10 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.apache.lucene.index.IndexReader; +import org.apache.jackrabbit.core.query.lucene.constraint.EvaluationContext; import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.state.ItemStateManager; +import org.apache.jackrabbit.spi.Name; import java.io.IOException; @@ -28,7 +31,9 @@ * JackrabbitIndexSearcher implements an index searcher with * jackrabbit specific optimizations. */ -public class JackrabbitIndexSearcher extends IndexSearcher { +public class JackrabbitIndexSearcher + extends IndexSearcher + implements EvaluationContext { /** * The session that executes the query. @@ -41,15 +46,24 @@ private final IndexReader reader; /** + * The item state manager of the workspace. + */ + private final ItemStateManager ism; + + /** * Creates a new jackrabbit index searcher. * * @param s the session that executes the query. * @param r the index reader. + * @param ism the shared item state manager. */ - public JackrabbitIndexSearcher(SessionImpl s, IndexReader r) { + public JackrabbitIndexSearcher(SessionImpl s, + IndexReader r, + ItemStateManager ism) { super(r); this.session = s; this.reader = r; + this.ism = ism; } /** @@ -58,15 +72,17 @@ * @param query the query to execute. * @param sort the sort criteria. * @param resultFetchHint a hint on how many results should be fetched. + * @param selectorName the single selector name for the query hits. * @return the query hits. * @throws IOException if an error occurs while executing the query. */ public MultiColumnQueryHits execute(Query query, Sort sort, - long resultFetchHint) + long resultFetchHint, + Name selectorName) throws IOException { - return new QueryHitsAdapter(evaluate(query, sort, resultFetchHint), - QueryImpl.DEFAULT_SELECTOR_NAME); + return new QueryHitsAdapter( + evaluate(query, sort, resultFetchHint), selectorName); } /** @@ -96,6 +112,8 @@ return hits; } + //------------------------< EvaluationContext >----------------------------- + /** * Evaluates the query and returns the hits that match the query. * @@ -106,4 +124,18 @@ public QueryHits evaluate(Query query) throws IOException { return evaluate(query, new Sort(), Integer.MAX_VALUE); } + + /** + * @return session that executes the query. + */ + public SessionImpl getSession() { + return session; + } + + /** + * @return the item state manager of the workspace. + */ + public ItemStateManager getItemStateManager() { + return ism; + } } Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,100 @@ +/* + * 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.lucene; + +import java.io.IOException; + +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortComparatorSource; +import org.apache.lucene.index.IndexReader; +import org.apache.jackrabbit.core.query.lucene.join.Join; +import org.apache.jackrabbit.core.HierarchyManager; +import org.apache.jackrabbit.spi.commons.query.qom.JoinConditionImpl; + +/** + * JoinQuery implements a query that performs a join. + */ +public class JoinQuery implements MultiColumnQuery { + + /** + * The left side of the join. + */ + private final MultiColumnQuery left; + + /** + * The right side of the join. + */ + private final MultiColumnQuery right; + + /** + * The join type. + */ + private final int joinType; + + /** + * The QOM join condition. + */ + private final JoinConditionImpl joinCondition; + + /** + * The sort comparator source of the index. + */ + private final SortComparatorSource scs; + + /** + * The hierarchy manager of the workspace. + */ + private final HierarchyManager hmgr; + + /** + * Creates a new join query. + * + * @param left the left side of the query. + * @param right the right side of the query. + * @param joinType the join type. + * @param joinCondition the join condition. + * @param scs the sort comparator source of the index. + * @param hmgr the hierarchy manager of the workspace. + */ + public JoinQuery(MultiColumnQuery left, + MultiColumnQuery right, + int joinType, + JoinConditionImpl joinCondition, + SortComparatorSource scs, + HierarchyManager hmgr) { + this.left = left; + this.right = right; + this.joinType = joinType; + this.joinCondition = joinCondition; + this.scs = scs; + this.hmgr = hmgr; + } + + /** + * {@inheritDoc} + */ + public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher, + Sort sort, + long resultFetchHint) + throws IOException { + IndexReader reader = searcher.getIndexReader(); + HierarchyResolver resolver = (HierarchyResolver) reader; + return Join.create(left.execute(searcher, sort, resultFetchHint), + right.execute(searcher, sort, resultFetchHint), + joinType, joinCondition, reader, resolver, scs, hmgr); + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JoinQuery.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,78 @@ +/* + * 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.lucene; + +import javax.jcr.RepositoryException; + +import org.apache.lucene.search.Query; +import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl; +import org.apache.jackrabbit.spi.commons.query.qom.FullTextSearchImpl; +import org.apache.jackrabbit.spi.commons.query.qom.PropertyExistenceImpl; +import org.apache.jackrabbit.spi.commons.query.qom.SourceImpl; +import org.apache.jackrabbit.spi.commons.query.qom.JoinImpl; + +/** + * LuceneQueryFactory implements a factory that creates lucene + * queries from given QOM elements. + */ +public interface LuceneQueryFactory { + + /** + * Creates a lucene query for the given QOM selector. + * + * @param selector the selector. + * @return a lucene query for the given selector. + * @throws RepositoryException if an error occurs while creating the query. + */ + public Query create(SelectorImpl selector) throws RepositoryException; + + /** + * Creates a lucene query for the given QOM full text search. + * + * @param constraint the full text search constraint. + * @return the lucene query for the given constraint. + * @throws RepositoryException if an error occurs while creating the query. + */ + public Query create(FullTextSearchImpl constraint) throws RepositoryException; + + /** + * Creates a lucene query for the given QOM property existence constraint. + * + * @param constraint the QOM constraint. + * @return the lucene query for the given constraint. + * @throws RepositoryException if an error occurs while creating the query. + */ + public Query create(PropertyExistenceImpl constraint) throws RepositoryException; + + /** + * Creates a multi column query for the given QOM source. + * + * @param source the QOM source. + * @return a multi column query for the given source. + * @throws RepositoryException if an error occurs while creating the query. + */ + public MultiColumnQuery create(SourceImpl source) throws RepositoryException; + + /** + * Creates a multi column query for the given QOM join. + * + * @param join the QOM join. + * @return the multi column query for the given join. + * @throws RepositoryException if an error occurs while creating the query. + */ + public MultiColumnQuery create(JoinImpl join) throws RepositoryException; +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,255 @@ +/* + * 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.lucene; + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; + +import javax.jcr.nodetype.NodeTypeManager; +import javax.jcr.nodetype.NodeType; +import javax.jcr.nodetype.NodeTypeIterator; +import javax.jcr.RepositoryException; + +import org.apache.lucene.search.Query; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.SortComparatorSource; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.analysis.Analyzer; +import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl; +import org.apache.jackrabbit.spi.commons.query.qom.FullTextSearchImpl; +import org.apache.jackrabbit.spi.commons.query.qom.PropertyExistenceImpl; +import org.apache.jackrabbit.spi.commons.query.qom.SourceImpl; +import org.apache.jackrabbit.spi.commons.query.qom.JoinImpl; +import org.apache.jackrabbit.spi.commons.query.qom.DefaultQOMTreeVisitor; +import org.apache.jackrabbit.spi.commons.query.qom.JoinConditionImpl; +import org.apache.jackrabbit.spi.commons.name.NameConstants; +import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; +import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.HierarchyManager; + +/** + * LuceneQueryFactoryImpl implements a lucene query factory. + */ +public class LuceneQueryFactoryImpl implements LuceneQueryFactory { + + /** + * Session of the user executing this query + */ + private final SessionImpl session; + + /** + * The source comparator source. + */ + private final SortComparatorSource scs; + + /** + * The hierarchy manager. + */ + private final HierarchyManager hmgr; + + /** + * Namespace mappings to internal prefixes + */ + private final NamespaceMappings nsMappings; + + /** + * NamePathResolver to map namespace mappings to internal prefixes + */ + private final NamePathResolver npResolver; + + /** + * The analyzer instance to use for contains function query parsing + */ + private final Analyzer analyzer; + + /** + * The synonym provider or null if none is configured. + */ + private final SynonymProvider synonymProvider; + + /** + * The index format version. + */ + private final IndexFormatVersion version; + + /** + * Creates a new lucene query factory. + * + * @param session the session that executes the query. + * @param scs the sort comparator source of the index. + * @param hmgr the hierarchy manager of the workspace. + * @param nsMappings the index internal namespace mappings. + * @param analyzer the analyzer of the index. + * @param synonymProvider the synonym provider of the index. + * @param version the version of the index format. + */ + public LuceneQueryFactoryImpl(SessionImpl session, + SortComparatorSource scs, + HierarchyManager hmgr, + NamespaceMappings nsMappings, + Analyzer analyzer, + SynonymProvider synonymProvider, + IndexFormatVersion version) { + this.session = session; + this.scs = scs; + this.hmgr = hmgr; + this.nsMappings = nsMappings; + this.analyzer = analyzer; + this.synonymProvider = synonymProvider; + this.version = version; + this.npResolver = NamePathResolverImpl.create(nsMappings); + } + + /** + * {@inheritDoc} + */ + public Query create(SelectorImpl selector) throws RepositoryException { + List terms = new ArrayList(); + String mixinTypesField = npResolver.getJCRName(NameConstants.JCR_MIXINTYPES); + String primaryTypeField = npResolver.getJCRName(NameConstants.JCR_PRIMARYTYPE); + + NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager(); + NodeType base = null; + try { + base = ntMgr.getNodeType(session.getJCRName(selector.getNodeTypeQName())); + } catch (RepositoryException e) { + // node type does not exist + } + + if (base != null && base.isMixin()) { + // search for nodes where jcr:mixinTypes is set to this mixin + Term t = new Term(FieldNames.PROPERTIES, + FieldNames.createNamedValue(mixinTypesField, + npResolver.getJCRName(selector.getNodeTypeQName()))); + terms.add(t); + } else { + // search for nodes where jcr:primaryType is set to this type + Term t = new Term(FieldNames.PROPERTIES, + FieldNames.createNamedValue(primaryTypeField, + npResolver.getJCRName(selector.getNodeTypeQName()))); + terms.add(t); + } + + // now search for all node types that are derived from base + if (base != null) { + NodeTypeIterator allTypes = ntMgr.getAllNodeTypes(); + while (allTypes.hasNext()) { + NodeType nt = allTypes.nextNodeType(); + NodeType[] superTypes = nt.getSupertypes(); + if (Arrays.asList(superTypes).contains(base)) { + Name n = session.getQName(nt.getName()); + String ntName = nsMappings.translateName(n); + Term t; + if (nt.isMixin()) { + // search on jcr:mixinTypes + t = new Term(FieldNames.PROPERTIES, + FieldNames.createNamedValue(mixinTypesField, ntName)); + } else { + // search on jcr:primaryType + t = new Term(FieldNames.PROPERTIES, + FieldNames.createNamedValue(primaryTypeField, ntName)); + } + terms.add(t); + } + } + } + Query q; + if (terms.size() == 1) { + q = new JackrabbitTermQuery((Term) terms.get(0)); + } else { + BooleanQuery b = new BooleanQuery(); + for (Iterator it = terms.iterator(); it.hasNext();) { + b.add(new JackrabbitTermQuery((Term) it.next()), BooleanClause.Occur.SHOULD); + } + q = b; + } + return q; + } + + /** + * {@inheritDoc} + */ + public Query create(FullTextSearchImpl fts) throws RepositoryException { + String fieldname; + if (fts.getPropertyName() == null) { + // fulltext on node + fieldname = FieldNames.FULLTEXT; + } else { + // final path element is a property name + Name propName = fts.getPropertyQName(); + StringBuffer tmp = new StringBuffer(); + tmp.append(nsMappings.getPrefix(propName.getNamespaceURI())); + tmp.append(":").append(FieldNames.FULLTEXT_PREFIX); + tmp.append(propName.getLocalName()); + fieldname = tmp.toString(); + } + QueryParser parser = new JackrabbitQueryParser( + fieldname, analyzer, synonymProvider); + try { + return parser.parse(fts.getFullTextSearchExpression()); + } catch (ParseException e) { + throw new RepositoryException(e); + } + } + + /** + * {@inheritDoc} + */ + public Query create(PropertyExistenceImpl prop) throws RepositoryException { + String propName = npResolver.getJCRName(prop.getPropertyQName()); + return Util.createMatchAllQuery(propName, version); + } + + /** + * {@inheritDoc} + */ + public MultiColumnQuery create(SourceImpl source) throws RepositoryException { + // source is either selector or join + try { + return (MultiColumnQuery) source.accept(new DefaultQOMTreeVisitor() { + public Object visit(JoinImpl node, Object data) throws Exception { + return create(node); + } + + public Object visit(SelectorImpl node, Object data) throws Exception { + return MultiColumnQueryAdapter.adapt( + create(node), node.getSelectorQName()); + } + }, null); + } catch (RepositoryException e) { + throw e; + } catch (Exception e) { + throw new RepositoryException(e); + } + } + + /** + * {@inheritDoc} + */ + public MultiColumnQuery create(JoinImpl join) throws RepositoryException { + MultiColumnQuery left = create((SourceImpl) join.getLeft()); + MultiColumnQuery right = create((SourceImpl) join.getRight()); + return new JoinQuery(left, right, join.getJoinType(), + (JoinConditionImpl) join.getJoinCondition(), scs, hmgr); + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryFactoryImpl.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java Mon Apr 27 12:43:28 2009 @@ -57,9 +57,10 @@ if (!scorer.next()) { return null; } - String uuid = reader.document(scorer.doc()).get(FieldNames.UUID); + int doc = scorer.doc(); + String uuid = reader.document(doc).get(FieldNames.UUID); NodeId id = new NodeId(UUID.fromString(uuid)); - return new ScoreNode(id, scorer.score()); + return new ScoreNode(id, scorer.score(), doc); } /** Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,42 @@ +/* + * 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.lucene; + +import java.io.IOException; + +import org.apache.lucene.search.Sort; + +/** + * MultiColumnQuery defines an interface for a query that returns + * {@link MultiColumnQueryHits}. + */ +public interface MultiColumnQuery { + + /** + * Executes this query and returns multi column query hits. + * + * @param searcher the index searcher. + * @param sort the sort criteria. + * @param resultFetchHint the result fetch hint. + * @return the query hits. + * @throws IOException if an error occurs while executing the query. + */ + public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher, + Sort sort, + long resultFetchHint) + throws IOException; +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQuery.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,72 @@ +/* + * 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.lucene; + +import java.io.IOException; + +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.jackrabbit.spi.Name; + +/** + * MultiColumnQueryAdapter adapts a lucene query to act like a + * {@link MultiColumnQuery}. + */ +public class MultiColumnQueryAdapter implements MultiColumnQuery { + + /** + * The underlying lucene query. + */ + private final Query query; + + /** + * The selector name for the query hits. + */ + private final Name selectorName; + + /** + * Creates a new adapter for the given query. + * + * @param query a lucene query. + * @param selectorName the selector name for the query hits. + */ + private MultiColumnQueryAdapter(Query query, Name selectorName) { + this.query = query; + this.selectorName = selectorName; + } + + /** + * Adapts the given query. + * + * @param query the lucene query to adapt. + * @param selectorName the selector name for the query hits. + * @return a {@link MultiColumnQuery} that wraps the given lucene query. + */ + public static MultiColumnQuery adapt(Query query, Name selectorName) { + return new MultiColumnQueryAdapter(query, selectorName); + } + + /** + * {@inheritDoc} + */ + public MultiColumnQueryHits execute(JackrabbitIndexSearcher searcher, + Sort sort, + long resultFetchHint) + throws IOException { + return searcher.execute(query, sort, resultFetchHint, selectorName); + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryAdapter.java ------------------------------------------------------------------------------ svn:eol-style = native Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,76 @@ +/* + * 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.lucene; + +import java.io.IOException; + +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.core.ItemManager; +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.security.AccessManager; +import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.Path; + +/** + * MultiColumnQueryResult implements a query result that executes + * a {@link MultiColumnQuery}. + */ +public class MultiColumnQueryResult extends QueryResultImpl { + + /** + * The query to execute. + */ + private final MultiColumnQuery query; + + public MultiColumnQueryResult(SearchIndex index, + ItemManager itemMgr, + SessionImpl session, + AccessManager accessMgr, + AbstractQueryImpl queryImpl, + MultiColumnQuery query, + SpellSuggestion spellSuggestion, + Name[] selectProps, + Path[] orderProps, + boolean[] orderSpecs, + boolean documentOrder, + long offset, + long limit) throws RepositoryException { + super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion, + selectProps, orderProps, orderSpecs, documentOrder, offset, limit); + this.query = query; + // if document order is requested get all results right away + getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize()); + } + + /** + * {@inheritDoc} + */ + protected MultiColumnQueryHits executeQuery(long resultFetchHint) + throws IOException { + return index.executeQuery(session, query, orderProps, + orderSpecs, resultFetchHint); + } + + /** + * {@inheritDoc} + */ + protected ExcerptProvider createExcerptProvider() throws IOException { + // TODO + return null; + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiColumnQueryResult.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java Mon Apr 27 12:43:28 2009 @@ -853,18 +853,12 @@ protected void addLength(Document doc, String propertyName, InternalValue value) { - long length; - if (value.getType() == PropertyType.BINARY) { - length = value.getBLOBFileValue().getLength(); - } else if (value.getType() == PropertyType.NAME - || value.getType() == PropertyType.PATH) { - return; - } else { - length = value.toString().length(); + long length = Util.getLength(value); + if (length != -1) { + doc.add(new Field(FieldNames.PROPERTY_LENGTHS, + FieldNames.createNamedLength(propertyName, length), + Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); } - doc.add(new Field(FieldNames.PROPERTY_LENGTHS, - FieldNames.createNamedLength(propertyName, length), - Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS)); } /** Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java Mon Apr 27 12:43:28 2009 @@ -128,7 +128,7 @@ ascSpecs[i] = orderSpecs[i].isAscending(); } - return new QueryResultImpl(index, itemMgr, + return new SingleColumnQueryResult(index, itemMgr, session, session.getAccessManager(), this, query, new SpellSuggestion(index.getSpellChecker(), root), getSelectProperties(), orderProperties, ascSpecs, @@ -195,10 +195,4 @@ return this.root.needsSystemTree(); } - /** - * {@inheritDoc} - */ - public Name[] getSelectorNames() { - return new Name[]{DEFAULT_SELECTOR_NAME}; - } } Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java Mon Apr 27 12:43:28 2009 @@ -17,6 +17,8 @@ package org.apache.jackrabbit.core.query.lucene; import org.apache.jackrabbit.core.query.PropertyTypeRegistry; +import org.apache.jackrabbit.core.query.lucene.constraint.ConstraintBuilder; +import org.apache.jackrabbit.core.query.lucene.constraint.Constraint; import org.apache.jackrabbit.spi.commons.query.jsr283.qom.QueryObjectModelConstants; import org.apache.jackrabbit.spi.commons.query.jsr283.qom.PropertyValue; import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree; @@ -24,13 +26,11 @@ import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl; import org.apache.jackrabbit.spi.commons.query.qom.DefaultTraversingQOMTreeVisitor; import org.apache.jackrabbit.spi.commons.query.qom.BindVariableValueImpl; -import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl; import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl; import org.apache.jackrabbit.core.SessionImpl; import org.apache.jackrabbit.core.ItemManager; import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.spi.Path; -import org.apache.lucene.search.Query; import javax.jcr.RepositoryException; import javax.jcr.UnsupportedRepositoryOperationException; @@ -77,22 +77,10 @@ return true; } - /** - * {@inheritDoc} - */ - public Name[] getSelectorNames() { - SelectorImpl[] selectors = qomTree.getSource().getSelectors(); - Name[] names = new Name[selectors.length]; - for (int i = 0; i < names.length; i++) { - names[i] = selectors[i].getSelectorQName(); - } - return names; - } - //-------------------------< ExecutableQuery >------------------------------ /** - * Executes this query and returns a {@link javax.jcr.query.QueryResult}. + * Executes this query and returns a {@link QueryResult}. * * @param offset the offset in the total result set * @param limit the maximum result size @@ -101,11 +89,22 @@ */ public QueryResult execute(long offset, long limit) throws RepositoryException { - Query query = JQOM2LuceneQueryBuilder.createQuery(qomTree, session, - index.getContext().getItemStateManager(), + + LuceneQueryFactory factory = new LuceneQueryFactoryImpl(session, + index.getSortComparatorSource(), + index.getContext().getHierarchyManager(), index.getNamespaceMappings(), index.getTextAnalyzer(), - propReg, index.getSynonymProvider(), getBindVariableValues(), - index.getIndexFormatVersion()); + index.getSynonymProvider(), index.getIndexFormatVersion()); + + MultiColumnQuery query = factory.create(qomTree.getSource()); + + if (qomTree.getConstraint() != null) { + Constraint c = ConstraintBuilder.create(qomTree.getConstraint(), + getBindVariableValues(), qomTree.getSource().getSelectors(), + factory, session.getValueFactory()); + query = new FilterMultiColumnQuery(query, c); + } + ColumnImpl[] columns = qomTree.getColumns(); Name[] selectProps = new Name[columns.length]; @@ -126,7 +125,7 @@ orderings[i].getOperand() + " not yet implemented"); } } - return new QueryResultImpl(index, itemMgr, + return new MultiColumnQueryResult(index, itemMgr, session, session.getAccessManager(), // TODO: spell suggestion missing this, query, null, selectProps, orderProps, orderSpecs, Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java Mon Apr 27 12:43:28 2009 @@ -21,7 +21,6 @@ import org.apache.jackrabbit.core.security.AccessManager; import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.spi.Path; -import org.apache.lucene.search.Query; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,9 +36,9 @@ import java.util.NoSuchElementException; /** - * Implements the javax.jcr.query.QueryResult interface. + * Implements the QueryResult interface. */ -public class QueryResultImpl implements QueryResult { +public abstract class QueryResultImpl implements QueryResult { /** * The logger instance for this class @@ -49,12 +48,12 @@ /** * The search index to execute the query. */ - private final SearchIndex index; + protected final SearchIndex index; /** * The item manager of the session executing the query */ - private final ItemManager itemMgr; + protected final ItemManager itemMgr; /** * The session executing the query @@ -64,7 +63,7 @@ /** * The access manager of the session that executes the query. */ - private final AccessManager accessMgr; + protected final AccessManager accessMgr; /** * The query instance which created this query result. @@ -72,11 +71,6 @@ protected final AbstractQueryImpl queryImpl; /** - * The lucene query to execute. - */ - protected final Query query; - - /** * The spell suggestion or null if not available. */ protected final SpellSuggestion spellSuggestion; @@ -112,6 +106,12 @@ private int numResults = -1; /** + * The selector names associated with the score nodes. The selector names + * are set when the query is executed via {@link #getResults(long)}. + */ + private Name[] selectorNames; + + /** * The number of results that are invalid, either because a node does not * exist anymore or because the session does not have access to the node. */ @@ -120,7 +120,7 @@ /** * If true nodes are returned in document order. */ - private final boolean docOrder; + protected final boolean docOrder; /** * The excerpt provider or null if none was created yet. @@ -138,7 +138,8 @@ private final long limit; /** - * Creates a new query result. + * Creates a new query result. The concrete sub class is responsible for + * calling {@link #getResults(long)} after this constructor had been called. * * @param index the search index where the query is executed. * @param itemMgr the item manager of the session executing the @@ -148,7 +149,6 @@ * query. * @param queryImpl the query instance which created this query * result. - * @param query the lucene query to execute on the index. * @param spellSuggestion the spell suggestion or null if none * is available. * @param selectProps the select properties of the query. @@ -167,7 +167,6 @@ SessionImpl session, AccessManager accessMgr, AbstractQueryImpl queryImpl, - Query query, SpellSuggestion spellSuggestion, Name[] selectProps, Path[] orderProps, @@ -180,7 +179,6 @@ this.session = session; this.accessMgr = accessMgr; this.queryImpl = queryImpl; - this.query = query; this.spellSuggestion = spellSuggestion; this.selectProps = selectProps; this.orderProps = orderProps; @@ -188,8 +186,6 @@ this.docOrder = orderProps.length == 0 && documentOrder; this.offset = offset; this.limit = limit; - // if document order is requested get all results right away - getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize()); } /** @@ -222,13 +218,13 @@ public RowIterator getRows() throws RepositoryException { if (excerptProvider == null) { try { - excerptProvider = index.createExcerptProvider(query); + excerptProvider = createExcerptProvider(); } catch (IOException e) { throw new RepositoryException(e); } } return new RowIteratorImpl(getScoreNodes(), selectProps, - queryImpl.getSelectorNames(), itemMgr, + selectorNames, itemMgr, index.getContext().getHierarchyManager(), session, excerptProvider, spellSuggestion); } @@ -241,10 +237,17 @@ * @return hits for this query result. * @throws IOException if an error occurs while executing the query. */ - protected MultiColumnQueryHits executeQuery(long resultFetchHint) throws IOException { - return index.executeQuery(session, queryImpl, - query, orderProps, orderSpecs, resultFetchHint); - } + protected abstract MultiColumnQueryHits executeQuery(long resultFetchHint) + throws IOException; + + /** + * Creates an excerpt provider for this result set. + * + * @return an excerpt provider. + * @throws IOException if an error occurs. + */ + protected abstract ExcerptProvider createExcerptProvider() + throws IOException; //--------------------------------< internal >------------------------------ @@ -271,7 +274,7 @@ * @throws RepositoryException if an error occurs while executing the * query. */ - private void getResults(long size) throws RepositoryException { + protected void getResults(long size) throws RepositoryException { if (log.isDebugEnabled()) { log.debug("getResults({}) limit={}", new Long(size), new Long(limit)); } @@ -295,6 +298,8 @@ result = executeQuery(maxResultSize); log.debug("query executed in {} ms", new Long(System.currentTimeMillis() - time)); + // set selector names + selectorNames = result.getSelectorNames(); if (resultNodes.isEmpty() && offset > 0) { // collect result offset into dummy list Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java Mon Apr 27 12:43:28 2009 @@ -251,7 +251,7 @@ * Implements the {@link javax.jcr.query.Row} interface, which represents * a row in the query result. */ - class RowImpl implements Row { + class RowImpl implements org.apache.jackrabbit.api.jsr283.query.Row { /** * The score for this result row Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java Mon Apr 27 12:43:28 2009 @@ -16,13 +16,18 @@ */ package org.apache.jackrabbit.core.query.lucene; +import java.io.IOException; + import org.apache.jackrabbit.core.NodeId; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermDocs; /** * ScoreNode implements a simple container which holds a mapping * of {@link NodeId} to a score value. */ -final class ScoreNode { +public final class ScoreNode { /** * The id of a node. @@ -35,14 +40,32 @@ private final float score; /** + * The lucene document number for this score node. Set to -1 if + * unknown. + */ + private final int doc; + + /** * Creates a new ScoreNode. * * @param id the node id. * @param score the score value. */ - ScoreNode(NodeId id, float score) { + public ScoreNode(NodeId id, float score) { + this(id, score, -1); + } + + /** + * Creates a new ScoreNode. + * + * @param id the node id. + * @param score the score value. + * @param doc the document number. + */ + public ScoreNode(NodeId id, float score, int doc) { this.id = id; this.score = score; + this.doc = doc; } /** @@ -58,4 +81,42 @@ public float getScore() { return score; } + + /** + * Returns the document number for this score node. + * + * @param reader the current index reader to look up the document if + * needed. + * @return the document number. + * @throws IOException if an error occurs while reading from the index or + * the node is not present in the index. + */ + public int getDoc(IndexReader reader) throws IOException { + if (doc == -1) { + TermDocs docs = reader.termDocs(new Term(FieldNames.UUID, id.toString())); + try { + if (docs.next()) { + return docs.doc(); + } else { + throw new IOException("Node with id " + id + " not found in index"); + } + } finally { + docs.close(); + } + } else { + return doc; + } + } + + public String toString() { + StringBuffer sb = new StringBuffer(id.toString()); + sb.append("("); + if (doc != -1) { + sb.append(doc); + } else { + sb.append("?"); + } + sb.append(")"); + return sb.toString(); + } } Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Mon Apr 27 12:43:28 2009 @@ -754,10 +754,52 @@ Sort sort = new Sort(createSortFields(orderProps, orderSpecs)); final IndexReader reader = getIndexReader(queryImpl.needsSystemTree()); - JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher(session, reader); + JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher( + session, reader, getContext().getItemStateManager()); searcher.setSimilarity(getSimilarity()); return new FilterMultiColumnQueryHits( - searcher.execute(query, sort, resultFetchHint)) { + searcher.execute(query, sort, resultFetchHint, + QueryImpl.DEFAULT_SELECTOR_NAME)) { + public void close() throws IOException { + try { + super.close(); + } finally { + PerQueryCache.getInstance().dispose(); + Util.closeOrRelease(reader); + } + } + }; + } + + /** + * Executes the query on the search index. + * + * @param session the session that executes the query. + * @param query the query. + * @param orderProps name of the properties for sort order. + * @param orderSpecs the order specs for the sort order properties. + * true indicates ascending order, + * false indicates descending. + * @param resultFetchHint a hint on how many results should be fetched. + * @return the query hits. + * @throws IOException if an error occurs while searching the index. + */ + public MultiColumnQueryHits executeQuery(SessionImpl session, + MultiColumnQuery query, + Path[] orderProps, + boolean[] orderSpecs, + long resultFetchHint) + throws IOException { + checkOpen(); + + Sort sort = new Sort(createSortFields(orderProps, orderSpecs)); + + final IndexReader reader = getIndexReader(); + JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher( + session, reader, getContext().getItemStateManager()); + searcher.setSimilarity(getSimilarity()); + return new FilterMultiColumnQueryHits( + query.execute(searcher, sort, resultFetchHint)) { public void close() throws IOException { try { super.close(); @@ -988,6 +1030,13 @@ } /** + * @return the sort comparator source for this index. + */ + protected SortComparatorSource getSortComparatorSource() { + return scs; + } + + /** * Factory method to create the TextExtractor instance. * * @return the TextExtractor instance this index should use. Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java Mon Apr 27 12:43:28 2009 @@ -36,7 +36,7 @@ * but it only works on the basis of a field name. There is no further control * over the terms to iterate, that's why we use our own implementation. */ -class SharedFieldCache { +public class SharedFieldCache { /** * Expert: Stores term text values and document ordering data. Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java Mon Apr 27 12:43:28 2009 @@ -20,8 +20,6 @@ import java.util.ArrayList; import java.util.List; -import javax.jcr.PropertyType; - import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.ScoreDocComparator; @@ -188,23 +186,7 @@ * are equal */ public int compare(ScoreDoc i, ScoreDoc j) { - Comparable iTerm = sortValue(i); - Comparable jTerm = sortValue(j); - - if (iTerm == jTerm) { - return 0; - } else if (iTerm == null) { - return -1; - } else if (jTerm == null) { - return 1; - } else if (iTerm.getClass() == jTerm.getClass()) { - return iTerm.compareTo(jTerm); - } else { - // differing types -> compare class names - String iName = iTerm.getClass().getName(); - String jName = jTerm.getClass().getName(); - return iName.compareTo(jName); - } + return Util.compare(sortValue(i), sortValue(j)); } public int sortType() { @@ -256,11 +238,11 @@ super(reader); this.indexes = new SharedFieldCache.ValueIndex[readers.size()]; + String namedValue = FieldNames.createNamedValue(propertyName, ""); for (int i = 0; i < readers.size(); i++) { IndexReader r = (IndexReader) readers.get(i); indexes[i] = SharedFieldCache.INSTANCE.getValueIndex(r, field, - FieldNames.createNamedValue(propertyName, ""), - SharedFieldSortComparator.this); + namedValue, SharedFieldSortComparator.this); } } @@ -317,43 +299,13 @@ } InternalValue[] values = state.getValues(); if (values.length > 0) { - return getComparable(values[0]); + return Util.getComparable(values[0]); } return null; } catch (Exception e) { return null; } } - - /** - * Returns a comparable for the value. - * - * @param value an internal value. - * @return a comparable for the given value. - */ - private Comparable getComparable(InternalValue value) { - switch (value.getType()) { - case PropertyType.BINARY: - return null; - case PropertyType.BOOLEAN: - return ComparableBoolean.valueOf(value.getBoolean()); - case PropertyType.DATE: - return new Long(value.getDate().getTimeInMillis()); - case PropertyType.DOUBLE: - return new Double(value.getDouble()); - case PropertyType.LONG: - return new Long(value.getLong()); - case PropertyType.NAME: - return value.getQName().toString(); - case PropertyType.PATH: - return value.getPath().toString(); - case PropertyType.REFERENCE: - case PropertyType.STRING: - return value.getString(); - default: - return null; - } - } } /** Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java?rev=768954&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java Mon Apr 27 12:43:28 2009 @@ -0,0 +1,76 @@ +/* + * 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.lucene; + +import java.io.IOException; + +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.core.ItemManager; +import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.security.AccessManager; +import org.apache.jackrabbit.spi.Name; +import org.apache.jackrabbit.spi.Path; +import org.apache.lucene.search.Query; + +/** + * SingleColumnQueryResult implements a query result that returns + * a single column. That is, executes a lucene query. + */ +public class SingleColumnQueryResult extends QueryResultImpl { + + /** + * The query to execute. + */ + private final Query query; + + public SingleColumnQueryResult(SearchIndex index, + ItemManager itemMgr, + SessionImpl session, + AccessManager accessMgr, + AbstractQueryImpl queryImpl, + Query query, + SpellSuggestion spellSuggestion, + Name[] selectProps, + Path[] orderProps, + boolean[] orderSpecs, + boolean documentOrder, + long offset, + long limit) throws RepositoryException { + super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion, + selectProps, orderProps, orderSpecs, documentOrder, offset, limit); + this.query = query; + // if document order is requested get all results right away + getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize()); + } + + /** + * {@inheritDoc} + */ + protected MultiColumnQueryHits executeQuery(long resultFetchHint) + throws IOException { + return index.executeQuery(session, queryImpl, query, + orderProps, orderSpecs, resultFetchHint); + } + + /** + * {@inheritDoc} + */ + protected ExcerptProvider createExcerptProvider() throws IOException { + return index.createExcerptProvider(query); + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java?rev=768954&r1=768953&r2=768954&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java Mon Apr 27 12:43:28 2009 @@ -159,7 +159,7 @@ for (int i = scoreNodes.size(); i < docs.length; i++) { String uuid = reader.document(docs[i].doc).get(FieldNames.UUID); NodeId id = new NodeId(UUID.fromString(uuid)); - scoreNodes.add(new ScoreNode(id, docs[i].score)); + scoreNodes.add(new ScoreNode(id, docs[i].score, docs[i].doc)); } log.debug("getHits() {}/{}", new Integer(scoreNodes.size()), new Integer(numHits)); // double hits for next round