Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 97897 invoked from network); 8 Jul 2009 13:59:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 8 Jul 2009 13:59:20 -0000 Received: (qmail 40385 invoked by uid 500); 8 Jul 2009 13:59:29 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 40303 invoked by uid 500); 8 Jul 2009 13:59:29 -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 40290 invoked by uid 99); 8 Jul 2009 13:59:29 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Jul 2009 13:59:29 +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; Wed, 08 Jul 2009 13:59:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 2377E23889B6; Wed, 8 Jul 2009 13:58:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r792142 [9/35] - in /jackrabbit/sandbox/JCR-1456: ./ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/ jackrabbit-core/ jackrabbit-core/src/main/java/org/apache/jackrabb... Date: Wed, 08 Jul 2009 13:57:46 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090708135817.2377E23889B6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java Wed Jul 8 13:57:13 2009 @@ -97,7 +97,7 @@ /** * Names of index directories that can be deleted. */ - private final Set deletable = new HashSet(); + private final Set deletable = new HashSet(); /** * List of open persistent indexes. This list may also contain an open @@ -105,7 +105,8 @@ * registered with indexNames and must not be used in regular index * operations (delete node, etc.)! */ - private final List indexes = new ArrayList(); + private final List indexes = + new ArrayList(); /** * The internal namespace mappings of the query manager. @@ -191,9 +192,9 @@ private IndexingQueue indexingQueue; /** - * Set<NodeId> of uuids that should not be indexed. + * Identifiers of nodes that should not be indexed. */ - private final Set excludedIDs; + private final Set excludedIDs; /** * The next transaction id. @@ -219,18 +220,17 @@ * Creates a new MultiIndex. * * @param handler the search handler - * @param excludedIDs Set<NodeId> that contains uuids that should not - * be indexed nor further traversed. + * @param excludedIDs identifiers of nodes that should + * neither be indexed nor further traversed * @throws IOException if an error occurs */ - MultiIndex(SearchIndex handler, - Set excludedIDs) throws IOException { + MultiIndex(SearchIndex handler, Set excludedIDs) throws IOException { this.directoryManager = handler.getDirectoryManager(); this.indexDir = directoryManager.getDirectory("."); this.handler = handler; this.cache = new DocNumberCache(handler.getCacheSize()); this.redoLog = new RedoLog(indexDir); - this.excludedIDs = new HashSet(excludedIDs); + this.excludedIDs = new HashSet(excludedIDs); this.nsMappings = handler.getNamespaceMappings(); if (indexNames.exists(indexDir)) { @@ -241,7 +241,7 @@ removeDeletable(); // initialize IndexMerger - merger = new IndexMerger(this); + merger = new IndexMerger(this, handler.getIndexMergerPoolSize()); merger.setMaxMergeDocs(handler.getMaxMergeDocs()); merger.setMergeFactor(handler.getMergeFactor()); merger.setMinMergeDocs(handler.getMinMergeDocs()); @@ -400,7 +400,9 @@ * indicate that a node could not be indexed successfully. * @throws IOException if an error occurs while updating the index. */ - synchronized void update(Collection remove, Collection add) throws IOException { + synchronized void update( + Collection remove, Collection add) + throws IOException { // make sure a reader is available during long updates if (add.size() > handler.getBufferSize()) { getIndexReader().release(); @@ -414,13 +416,14 @@ executeAndLog(new Start(transactionId)); boolean flush = false; - for (Iterator it = remove.iterator(); it.hasNext(); ) { - executeAndLog(new DeleteNode(transactionId, (UUID) it.next())); + + for (UUID uuid : remove) { + executeAndLog(new DeleteNode(transactionId, uuid)); } - for (Iterator it = add.iterator(); it.hasNext(); ) { - Document doc = (Document) it.next(); - if (doc != null) { - executeAndLog(new AddNode(transactionId, doc)); + + for (Document document : add) { + if (document != null) { + executeAndLog(new AddNode(transactionId, document)); // commit volatile index if needed flush |= checkVolatileCommit(); } @@ -448,7 +451,8 @@ * index. */ void addDocument(Document doc) throws IOException { - update(Collections.EMPTY_LIST, Arrays.asList(new Document[]{doc})); + Collection empty = Collections.emptyList(); + update(empty, Collections.singleton(doc)); } /** @@ -458,7 +462,8 @@ * @throws IOException if an error occurs while deleting the document. */ void removeDocument(UUID uuid) throws IOException { - update(Arrays.asList(new UUID[]{uuid}), Collections.EMPTY_LIST); + Collection empty = Collections.emptyList(); + update(Collections.singleton(uuid), empty); } /** @@ -517,34 +522,33 @@ * @return the IndexReaders. * @throws IOException if an error occurs acquiring the index readers. */ - synchronized IndexReader[] getIndexReaders(String[] indexNames, IndexListener listener) - throws IOException { - Set names = new HashSet(Arrays.asList(indexNames)); - Map indexReaders = new HashMap(); + synchronized IndexReader[] getIndexReaders( + String[] indexNames, IndexListener listener) throws IOException { + Set names = new HashSet(Arrays.asList(indexNames)); + Map indexReaders = + new HashMap(); try { - for (Iterator it = indexes.iterator(); it.hasNext();) { - PersistentIndex index = (PersistentIndex) it.next(); + for (PersistentIndex index : indexes) { if (names.contains(index.getName())) { indexReaders.put(index.getReadOnlyIndexReader(listener), index); } } } catch (IOException e) { // release readers obtained so far - for (Iterator it = indexReaders.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - ReadOnlyIndexReader reader = (ReadOnlyIndexReader) entry.getKey(); + for (Map.Entry entry + : indexReaders.entrySet()) { try { - reader.release(); + entry.getKey().release(); } catch (IOException ex) { log.warn("Exception releasing index reader: " + ex); } - ((PersistentIndex) entry.getValue()).resetListener(); + entry.getValue().resetListener(); } throw e; } - return (IndexReader[]) indexReaders.keySet().toArray(new IndexReader[indexReaders.size()]); + return indexReaders.keySet().toArray(new IndexReader[indexReaders.size()]); } /** @@ -559,8 +563,7 @@ synchronized PersistentIndex getOrCreateIndex(String indexName) throws IOException { // check existing - for (Iterator it = indexes.iterator(); it.hasNext();) { - PersistentIndex idx = (PersistentIndex) it.next(); + for (PersistentIndex idx : indexes) { if (idx.getName().equals(indexName)) { return idx; } @@ -596,8 +599,7 @@ */ synchronized boolean hasIndex(String indexName) throws IOException { // check existing - for (Iterator it = indexes.iterator(); it.hasNext();) { - PersistentIndex idx = (PersistentIndex) it.next(); + for (PersistentIndex idx : indexes) { if (idx.getName().equals(indexName)) { return true; } @@ -620,7 +622,7 @@ */ void replaceIndexes(String[] obsoleteIndexes, PersistentIndex index, - Collection deleted) + Collection deleted) throws IOException { if (handler.isInitializeHierarchyCache()) { @@ -641,10 +643,9 @@ executeAndLog(new Start(Action.INTERNAL_TRANS_REPL_INDEXES)); } // delete obsolete indexes - Set names = new HashSet(Arrays.asList(obsoleteIndexes)); - for (Iterator it = names.iterator(); it.hasNext();) { + Set names = new HashSet(Arrays.asList(obsoleteIndexes)); + for (String indexName : names) { // do not try to delete indexes that are already gone - String indexName = (String) it.next(); if (indexNames.contains(indexName)) { executeAndLog(new DeleteIndex(getTransactionId(), indexName)); } @@ -657,8 +658,7 @@ executeAndLog(new AddIndex(getTransactionId(), index.getName())); // delete documents in index - for (Iterator it = deleted.iterator(); it.hasNext();) { - Term id = (Term) it.next(); + for (Term id : deleted) { index.removeDocument(id); } index.commit(); @@ -720,7 +720,8 @@ // some other read thread might have created the reader in the // meantime -> check again if (multiReader == null) { - List readerList = new ArrayList(); + List readerList = + new ArrayList(); for (int i = 0; i < indexes.size(); i++) { PersistentIndex pIdx = (PersistentIndex) indexes.get(i); if (indexNames.contains(pIdx.getName())) { @@ -729,7 +730,7 @@ } readerList.add(volatileIndex.getReadOnlyIndexReader()); ReadOnlyIndexReader[] readers = - (ReadOnlyIndexReader[]) readerList.toArray(new ReadOnlyIndexReader[readerList.size()]); + readerList.toArray(new ReadOnlyIndexReader[readerList.size()]); multiReader = new CachingMultiIndexReader(readers, cache); } multiReader.acquire(); @@ -1077,9 +1078,7 @@ checkIndexingQueue(true); } checkVolatileCommit(); - List children = node.getChildNodeEntries(); - for (Iterator it = children.iterator(); it.hasNext();) { - ChildNodeEntry child = (ChildNodeEntry) it.next(); + for (ChildNodeEntry child : node.getChildNodeEntries()) { Path childPath = PATH_FACTORY.create(path, child.getName(), child.getIndex(), false); NodeState childState = null; @@ -1101,8 +1100,8 @@ */ private void attemptDelete() { synchronized (deletable) { - for (Iterator it = deletable.iterator(); it.hasNext(); ) { - String indexName = (String) it.next(); + for (Iterator it = deletable.iterator(); it.hasNext(); ) { + String indexName = it.next(); if (directoryManager.delete(indexName)) { it.remove(); } else { @@ -1183,11 +1182,10 @@ * the indexing queue to the index. */ private void checkIndexingQueue(boolean transactionPresent) { - Document[] docs = indexingQueue.getFinishedDocuments(); - Map finished = new HashMap(); - for (int i = 0; i < docs.length; i++) { - String uuid = docs[i].get(FieldNames.UUID); - finished.put(UUID.fromString(uuid), docs[i]); + Map finished = new HashMap(); + for (Document document : indexingQueue.getFinishedDocuments()) { + UUID uuid = UUID.fromString(document.get(FieldNames.UUID)); + finished.put(uuid, document); } // now update index with the remaining ones if there are any @@ -1196,18 +1194,17 @@ new Long(finished.size())); // remove documents from the queue - for (Iterator it = finished.keySet().iterator(); it.hasNext(); ) { - indexingQueue.removeDocument(it.next().toString()); + for (UUID uuid : finished.keySet()) { + indexingQueue.removeDocument(uuid.toString()); } try { if (transactionPresent) { - for (Iterator it = finished.keySet().iterator(); it.hasNext(); ) { - executeAndLog(new DeleteNode(getTransactionId(), (UUID) it.next())); + for (UUID uuid : finished.keySet()) { + executeAndLog(new DeleteNode(getTransactionId(), uuid)); } - for (Iterator it = finished.values().iterator(); it.hasNext(); ) { - executeAndLog(new AddNode( - getTransactionId(), (Document) it.next())); + for (Document document : finished.values()) { + executeAndLog(new AddNode(getTransactionId(), document)); } } else { update(finished.keySet(), finished.values()); @@ -1767,8 +1764,7 @@ */ public void execute(MultiIndex index) throws IOException { // get index if it exists - for (Iterator it = index.indexes.iterator(); it.hasNext();) { - PersistentIndex idx = (PersistentIndex) it.next(); + for (PersistentIndex idx : index.indexes) { if (idx.getName().equals(indexName)) { idx.close(); index.deleteIndex(idx); Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NamePathResolverImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NamePathResolverImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NamePathResolverImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NamePathResolverImpl.java Wed Jul 8 13:57:13 2009 @@ -79,10 +79,10 @@ //-------------------------------------------------------< NameResolver >--- /** - * Parses the prefixed JCR name and returns the resolved qualified name. + * Parses the prefixed JCR name and returns the resolved Name object. * - * @param name prefixed JCR name - * @return qualified name + * @param name The JCR name string. + * @return The corresponding Name. * @throws IllegalNameException if the JCR name format is invalid * @throws NamespaceException if the namespace prefix can not be resolved */ @@ -91,14 +91,14 @@ } /** - * Returns the prefixed JCR name for the given qualified name. + * Returns the qualified JCR name for the given Name. * Note, that the JCR prefix is always retrieved from the NamespaceResolver * even if the name is in the defaut namespace. This is a special treatement * for query specific implementation, which defines a prefix for all namespace * URIs including the default namespace. * - * @param name qualified name - * @return prefixed JCR name + * @param name A Name object. + * @return The corresponding qualified JCR name string. * @throws NamespaceException if the namespace URI can not be resolved */ public String getJCRName(Name name) throws NamespaceException { Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIndexer.java Wed Jul 8 13:57:13 2009 @@ -24,7 +24,6 @@ import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.PropertyState; import org.apache.jackrabbit.core.state.ChildNodeEntry; -import org.apache.jackrabbit.core.value.BLOBFileValue; import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.extractor.TextExtractor; import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; @@ -45,11 +44,12 @@ import java.io.InputStream; import java.io.Reader; import java.util.Calendar; -import java.util.Iterator; import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.Date; +import java.net.URI; +import java.math.BigDecimal; /** * Creates a lucene Document object from a {@link javax.jcr.Node}. @@ -112,7 +112,7 @@ * List of {@link FieldNames#FULLTEXT} fields which should not be used in * an excerpt. */ - protected List doNotUseInExcerpt = new ArrayList(); + protected List doNotUseInExcerpt = new ArrayList(); /** * Creates a new node indexer. @@ -198,8 +198,8 @@ addParentChildRelation(doc, node.getParentId()); } else { // shareable node - for (Iterator it = node.getSharedSet().iterator(); it.hasNext(); ) { - addParentChildRelation(doc, (NodeId) it.next()); + for (NodeId id : node.getSharedSet()) { + addParentChildRelation(doc, id); } // mark shareable nodes doc.add(new Field(FieldNames.SHAREABLE_NODE, "", @@ -214,23 +214,21 @@ // unknown uri<->prefix mappings } - Set props = node.getPropertyNames(); - for (Iterator it = props.iterator(); it.hasNext();) { - Name propName = (Name) it.next(); + Set props = node.getPropertyNames(); + for (Name propName : props) { PropertyId id = new PropertyId(node.getNodeId(), propName); try { PropertyState propState = (PropertyState) stateProvider.getItemState(id); // add each property to the _PROPERTIES_SET for searching // beginning with V2 - if (indexFormatVersion.getVersion() - >= IndexFormatVersion.V2.getVersion()) { + if (indexFormatVersion.getVersion() >= IndexFormatVersion.V2.getVersion()) { addPropertyName(doc, propState.getName()); } InternalValue[] values = propState.getValues(); - for (int i = 0; i < values.length; i++) { - addValue(doc, values[i], propState.getName()); + for (InternalValue value : values) { + addValue(doc, value, propState.getName()); } if (values.length > 1) { // real multi-valued @@ -244,8 +242,8 @@ } // now add fields that are not used in excerpt (must go at the end) - for (Iterator it = doNotUseInExcerpt.iterator(); it.hasNext(); ) { - doc.add((Fieldable) it.next()); + for (Fieldable field : doNotUseInExcerpt) { + doc.add(field); } return doc; } @@ -296,12 +294,12 @@ switch (value.getType()) { case PropertyType.BINARY: if (isIndexed(name)) { - addBinaryValue(doc, fieldName, value.getBLOBFileValue()); + addBinaryValue(doc, fieldName, value); } break; case PropertyType.BOOLEAN: if (isIndexed(name)) { - addBooleanValue(doc, fieldName, Boolean.valueOf(value.getBoolean())); + addBooleanValue(doc, fieldName, value.getBoolean()); } break; case PropertyType.DATE: @@ -311,17 +309,22 @@ break; case PropertyType.DOUBLE: if (isIndexed(name)) { - addDoubleValue(doc, fieldName, new Double(value.getDouble())); + addDoubleValue(doc, fieldName, value.getDouble()); } break; case PropertyType.LONG: if (isIndexed(name)) { - addLongValue(doc, fieldName, new Long(value.getLong())); + addLongValue(doc, fieldName, value.getLong()); } break; case PropertyType.REFERENCE: if (isIndexed(name)) { - addReferenceValue(doc, fieldName, value.getUUID()); + addReferenceValue(doc, fieldName, value.getUUID(), false); + } + break; + case PropertyType.WEAKREFERENCE: + if (isIndexed(name)) { + addReferenceValue(doc, fieldName, value.getUUID(), true); } break; case PropertyType.PATH: @@ -329,6 +332,11 @@ addPathValue(doc, fieldName, value.getPath()); } break; + case PropertyType.URI: + if (isIndexed(name)) { + addURIValue(doc, fieldName, value.getURI()); + } + break; case PropertyType.STRING: if (isIndexed(name)) { // never fulltext index jcr:uuid String @@ -348,11 +356,18 @@ if (name.equals(NameConstants.JCR_PRIMARYTYPE) || name.equals(NameConstants.JCR_MIXINTYPES) || isIndexed(name)) { - addNameValue(doc, fieldName, value.getQName()); + addNameValue(doc, fieldName, value.getName()); + } + break; + case PropertyType.DECIMAL: + if (isIndexed(name)) { + addDecimalValue(doc, fieldName, value.getDecimal()); } break; + + default: - throw new IllegalArgumentException("illegal internal value type"); + throw new IllegalArgumentException("illegal internal value type: " + value.getType()); } // add length @@ -390,7 +405,7 @@ */ protected void addBinaryValue(Document doc, String fieldName, - Object internalValue) { + InternalValue internalValue) { // 'check' if node is of type nt:resource try { String jcrData = mappings.getPrefix(Name.NS_JCR_URI) + ":data"; @@ -410,8 +425,7 @@ encoding = encodingValue.getString(); } - InputStream stream = - ((BLOBFileValue) internalValue).getStream(); + InputStream stream = internalValue.getStream(); Reader reader = extractor.extractText(stream, type, encoding); doc.add(createFulltextField(reader)); } @@ -521,7 +535,7 @@ * @param internalValue The value for the field to add to the document. */ protected void addDoubleValue(Document doc, String fieldName, Object internalValue) { - double doubleVal = ((Double) internalValue).doubleValue(); + double doubleVal = (Double) internalValue; doc.add(createFieldWithoutNorms(fieldName, DoubleField.doubleToString(doubleVal), PropertyType.DOUBLE)); } @@ -536,28 +550,50 @@ * @param internalValue The value for the field to add to the document. */ protected void addLongValue(Document doc, String fieldName, Object internalValue) { - long longVal = ((Long) internalValue).longValue(); + long longVal = (Long) internalValue; doc.add(createFieldWithoutNorms(fieldName, LongField.longToString(longVal), PropertyType.LONG)); } /** + * Adds the long value to the document as the named field. The long + * value is converted to an indexable string value using the {@link LongField} + * class. + * + * @param doc The document to which to add the field + * @param fieldName The name of the field to add + * @param internalValue The value for the field to add to the document. + */ + protected void addDecimalValue(Document doc, String fieldName, Object internalValue) { + BigDecimal decVal = (BigDecimal) internalValue; + doc.add(createFieldWithoutNorms(fieldName, DecimalField.decimalToString(decVal), + PropertyType.DECIMAL)); + } + + /** * Adds the reference value to the document as the named field. The value's * string representation is added as the reference data. Additionally the - * reference data is stored in the index. + * reference data is stored in the index. As of Jackrabbit 2.0 this method + * also adds the reference UUID as a {@link FieldNames#WEAK_REFS} field + * to the index if it is a weak reference. * * @param doc The document to which to add the field * @param fieldName The name of the field to add * @param internalValue The value for the field to add to the document. + * @param weak Flag indicating whether it's a WEAKREFERENCE (true) or a REFERENCE (flase) */ - protected void addReferenceValue(Document doc, String fieldName, Object internalValue) { + protected void addReferenceValue(Document doc, String fieldName, Object internalValue, boolean weak) { UUID value = (UUID) internalValue; String uuid = value.toString(); doc.add(createFieldWithoutNorms(fieldName, uuid, - PropertyType.REFERENCE)); + weak ? PropertyType.WEAKREFERENCE : PropertyType.REFERENCE)); doc.add(new Field(FieldNames.PROPERTIES, FieldNames.createNamedValue(fieldName, uuid), Field.Store.YES, Field.Index.NO, Field.TermVector.NO)); + if (weak) { + doc.add(new Field(FieldNames.WEAK_REFS, uuid, Field.Store.NO, + Field.Index.NOT_ANALYZED_NO_NORMS)); + } } /** @@ -582,6 +618,19 @@ } /** + * Adds the uri value to the document as the named field. + * + * @param doc The document to which to add the field + * @param fieldName The name of the field to add + * @param internalValue The value for the field to add to the document. + */ + protected void addURIValue(Document doc, String fieldName, Object internalValue) { + URI uri = (URI) internalValue; + doc.add(createFieldWithoutNorms(fieldName, uri.toString(), + PropertyType.URI)); + } + + /** * Adds the string value to the document both as the named field and for * full text indexing. * @@ -692,7 +741,7 @@ /** * Adds the name value to the document as the named field. The name * value is converted to an indexable string treating the internal value - * as a qualified name and mapping the name space using the name space + * as a Name and mapping the name space using the name space * mappings with which this class has been created. * * @param doc The document to which to add the field Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java Wed Jul 8 13:57:13 2009 @@ -124,7 +124,13 @@ * @return 'ParentAxisQuery'. */ public String toString(String field) { - return "ParentAxisQuery"; + StringBuffer sb = new StringBuffer(); + sb.append("ParentAxisQuery("); + sb.append(contextQuery); + sb.append(", "); + sb.append(nameTest); + sb.append(")"); + return sb.toString(); } //-----------------------< ParentAxisWeight >------------------------------- Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryImpl.java Wed Jul 8 13:57:13 2009 @@ -16,14 +16,14 @@ */ package org.apache.jackrabbit.core.query.lucene; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.Map; +import java.util.LinkedHashMap; import javax.jcr.RepositoryException; import javax.jcr.nodetype.PropertyDefinition; import javax.jcr.query.InvalidQueryException; import javax.jcr.query.QueryResult; +import javax.jcr.query.qom.QueryObjectModelFactory; import org.apache.jackrabbit.core.ItemManager; import org.apache.jackrabbit.core.SessionImpl; @@ -42,6 +42,7 @@ import org.apache.jackrabbit.spi.commons.query.QueryNodeFactory; import org.apache.jackrabbit.spi.commons.query.QueryParser; import org.apache.jackrabbit.spi.commons.query.QueryRootNode; +import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl; import org.apache.lucene.search.Query; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -131,21 +132,28 @@ return new SingleColumnQueryResult(index, itemMgr, session, session.getAccessManager(), this, query, new SpellSuggestion(index.getSpellChecker(), root), - getSelectProperties(), orderProperties, ascSpecs, - getRespectDocumentOrder(), offset, limit); + getColumns(), orderProperties, ascSpecs, + orderProperties.length == 0 && getRespectDocumentOrder(), + offset, limit); } /** - * Returns the select properties for this query. + * Returns the columns for this query. * - * @return array of select property names. + * @return array of columns. * @throws RepositoryException if an error occurs. */ - protected Name[] getSelectProperties() throws RepositoryException { - // get select properties - List selectProps = new ArrayList(); - selectProps.addAll(Arrays.asList(root.getSelectProperties())); - if (selectProps.size() == 0) { + protected ColumnImpl[] getColumns() throws RepositoryException { + QueryObjectModelFactory qomFactory = session.getWorkspace().getQueryManager().getQOMFactory(); + // get columns + Map columns = new LinkedHashMap(); + for (Name name : root.getSelectProperties()) { + String pn = session.getJCRName(name); + ColumnImpl col = (ColumnImpl) qomFactory.column( + session.getJCRName(DEFAULT_SELECTOR_NAME), pn, pn); + columns.put(name, col); + } + if (columns.size() == 0) { // use node type constraint LocationStepQueryNode[] steps = root.getLocationNode().getPathSteps(); final Name[] ntName = new Name[1]; @@ -165,23 +173,23 @@ } NodeTypeImpl nt = session.getNodeTypeManager().getNodeType(ntName[0]); PropertyDefinition[] propDefs = nt.getPropertyDefinitions(); - for (int i = 0; i < propDefs.length; i++) { - PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) propDefs[i]; + for (PropertyDefinition pd : propDefs) { + PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) pd; if (!propDef.definesResidual() && !propDef.isMultiple()) { - selectProps.add(propDef.getQName()); + columns.put(propDef.getQName(), columnForName(propDef.getQName())); } } } // add jcr:path and jcr:score if not selected already - if (!selectProps.contains(NameConstants.JCR_PATH)) { - selectProps.add(NameConstants.JCR_PATH); + if (!columns.containsKey(NameConstants.JCR_PATH)) { + columns.put(NameConstants.JCR_PATH, columnForName(NameConstants.JCR_PATH)); } - if (!selectProps.contains(NameConstants.JCR_SCORE)) { - selectProps.add(NameConstants.JCR_SCORE); + if (!columns.containsKey(NameConstants.JCR_SCORE)) { + columns.put(NameConstants.JCR_SCORE, columnForName(NameConstants.JCR_SCORE)); } - return (Name[]) selectProps.toArray(new Name[selectProps.size()]); + return columns.values().toArray(new ColumnImpl[columns.size()]); } /** @@ -195,4 +203,18 @@ return this.root.needsSystemTree(); } + /** + * Returns a column for the given property name and the default selector + * name. + * + * @param propertyName the name of the property as well as the column. + * @return a column. + * @throws RepositoryException if an error occurs while creating the column. + */ + protected ColumnImpl columnForName(Name propertyName) throws RepositoryException { + QueryObjectModelFactory qomFactory = session.getWorkspace().getQueryManager().getQOMFactory(); + String name = session.getJCRName(propertyName); + return (ColumnImpl) qomFactory.column( + session.getJCRName(DEFAULT_SELECTOR_NAME), name, name); + } } Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryObjectModelImpl.java Wed Jul 8 13:57:13 2009 @@ -16,25 +16,29 @@ */ package org.apache.jackrabbit.core.query.lucene; +import java.util.List; +import java.util.ArrayList; + import javax.jcr.RepositoryException; -import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.nodetype.PropertyDefinition; import javax.jcr.query.QueryResult; -import javax.jcr.query.qom.PropertyValue; -import javax.jcr.query.qom.QueryObjectModelConstants; +import javax.jcr.query.InvalidQueryException; +import javax.jcr.query.qom.QueryObjectModelFactory; import org.apache.jackrabbit.core.ItemManager; import org.apache.jackrabbit.core.SessionImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; +import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; +import org.apache.jackrabbit.core.nodetype.PropertyDefinitionImpl; import org.apache.jackrabbit.core.query.PropertyTypeRegistry; import org.apache.jackrabbit.core.query.lucene.constraint.Constraint; import org.apache.jackrabbit.core.query.lucene.constraint.ConstraintBuilder; -import org.apache.jackrabbit.spi.Name; -import org.apache.jackrabbit.spi.Path; -import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl; import org.apache.jackrabbit.spi.commons.query.qom.BindVariableValueImpl; import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl; import org.apache.jackrabbit.spi.commons.query.qom.DefaultTraversingQOMTreeVisitor; -import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl; import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree; +import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl; +import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl; /** * QueryObjectModelImpl... @@ -54,14 +58,17 @@ * @param index the search index. * @param propReg the property type registry. * @param qomTree the query object model tree. + * @throws InvalidQueryException if the QOM tree is invalid. */ public QueryObjectModelImpl(SessionImpl session, ItemManager itemMgr, SearchIndex index, PropertyTypeRegistry propReg, - QueryObjectModelTree qomTree) { + QueryObjectModelTree qomTree) + throws InvalidQueryException { super(session, itemMgr, index, propReg); this.qomTree = qomTree; + checkNodeTypes(); extractBindVariableNames(); } @@ -106,32 +113,33 @@ } - ColumnImpl[] columns = qomTree.getColumns(); - Name[] selectProps = new Name[columns.length]; - for (int i = 0; i < columns.length; i++) { - selectProps[i] = columns[i].getPropertyQName(); - } - OrderingImpl[] orderings = qomTree.getOrderings(); - // TODO: there are many kinds of DynamicOperand that can be ordered by - Path[] orderProps = new Path[orderings.length]; - boolean[] orderSpecs = new boolean[orderings.length]; - for (int i = 0; i < orderings.length; i++) { - orderSpecs[i] = - QueryObjectModelConstants.JCR_ORDER_ASCENDING.equals( - orderings[i].getOrder()); - if (orderings[i].getOperand() instanceof PropertyValue) { - PropertyValue pv = (PropertyValue) orderings[i].getOperand(); - orderProps[i] = PathFactoryImpl.getInstance().create(pv.getPropertyName()); + List columns = new ArrayList(); + // expand columns without name + for (ColumnImpl column : qomTree.getColumns()) { + if (column.getColumnName() == null) { + QueryObjectModelFactory qomFactory = getQOMFactory(); + NodeTypeManagerImpl ntMgr = session.getNodeTypeManager(); + SelectorImpl selector = qomTree.getSelector(column.getSelectorQName()); + NodeTypeImpl nt = ntMgr.getNodeType(selector.getNodeTypeQName()); + for (PropertyDefinition pd : nt.getPropertyDefinitions()) { + PropertyDefinitionImpl propDef = (PropertyDefinitionImpl) pd; + if (!propDef.definesResidual() && !propDef.isMultiple()) { + String sn = selector.getSelectorName(); + String pn = propDef.getName(); + columns.add((ColumnImpl) qomFactory.column(sn, pn, sn + "." + pn)); + } + } } else { - throw new UnsupportedRepositoryOperationException("order by with" + - orderings[i].getOperand() + " not yet implemented"); + columns.add(column); } } + OrderingImpl[] orderings = qomTree.getOrderings(); return new MultiColumnQueryResult(index, itemMgr, session, session.getAccessManager(), // TODO: spell suggestion missing - this, query, null, selectProps, orderProps, orderSpecs, - getRespectDocumentOrder(), offset, limit); + this, query, null, columns.toArray(new ColumnImpl[columns.size()]), + orderings, orderings.length == 0 && getRespectDocumentOrder(), + offset, limit); } //--------------------------< internal >------------------------------------ @@ -152,4 +160,26 @@ // will never happen } } + + /** + * Checks if the selector node types are valid. + * + * @throws InvalidQueryException if one of the selector node types is + * unknown. + */ + private void checkNodeTypes() throws InvalidQueryException { + try { + qomTree.accept(new DefaultTraversingQOMTreeVisitor() { + public Object visit(SelectorImpl node, Object data) throws Exception { + String ntName = node.getNodeTypeName(); + if (!session.getNodeTypeManager().hasNodeType(ntName)) { + throw new Exception(ntName + " is not a known node type"); + } + return super.visit(node, data); + } + }, null); + } catch (Exception e) { + throw new InvalidQueryException(e.getMessage()); + } + } } Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java Wed Jul 8 13:57:13 2009 @@ -20,12 +20,11 @@ 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.jackrabbit.spi.commons.query.qom.ColumnImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.ItemNotFoundException; -import javax.jcr.NamespaceException; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.query.QueryResult; @@ -34,6 +33,8 @@ import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.Map; +import java.util.LinkedHashMap; /** * Implements the QueryResult interface. @@ -76,19 +77,9 @@ protected final SpellSuggestion spellSuggestion; /** - * The select properties + * The columns to select. */ - protected final Name[] selectProps; - - /** - * The relative paths of properties to use for ordering the result set. - */ - protected final Path[] orderProps; - - /** - * The order specifier for each of the order properties. - */ - protected final boolean[] orderSpecs; + protected final Map columns = new LinkedHashMap(); /** * The result nodes including their score. This list is populated on a lazy @@ -96,7 +87,7 @@ *

* The exact type is: List<ScoreNode[]> */ - private final List resultNodes = new ArrayList(); + private final List resultNodes = new ArrayList(); /** * This is the raw number of results that matched the query. This number @@ -133,7 +124,7 @@ private final long offset; /** - * The maximum size of this result if limit > 0 + * The maximum size of this result if limit >= 0 */ private final long limit; @@ -151,16 +142,15 @@ * result. * @param spellSuggestion the spell suggestion or null if none * is available. - * @param selectProps the select properties of the query. - * @param orderProps the relative paths of the order properties. - * @param orderSpecs the order specs, one for each order property - * name. + * @param columns the select properties of the query. * @param documentOrder if true the result is returned in * document order. * @param limit the maximum result size * @param offset the offset in the total result set * @throws RepositoryException if an error occurs while reading from the * repository. + * @throws IllegalArgumentException if any of the columns does not have a + * column name. */ public QueryResultImpl(SearchIndex index, ItemManager itemMgr, @@ -168,9 +158,7 @@ AccessManager accessMgr, AbstractQueryImpl queryImpl, SpellSuggestion spellSuggestion, - Name[] selectProps, - Path[] orderProps, - boolean[] orderSpecs, + ColumnImpl[] columns, boolean documentOrder, long offset, long limit) throws RepositoryException { @@ -180,29 +168,24 @@ this.accessMgr = accessMgr; this.queryImpl = queryImpl; this.spellSuggestion = spellSuggestion; - this.selectProps = selectProps; - this.orderProps = orderProps; - this.orderSpecs = orderSpecs; - this.docOrder = orderProps.length == 0 && documentOrder; + this.docOrder = documentOrder; this.offset = offset; this.limit = limit; + for (ColumnImpl column : columns) { + String cn = column.getColumnName(); + if (cn == null) { + String msg = column + " does not have a column name"; + throw new IllegalArgumentException(msg); + } + this.columns.put(cn, column); + } } /** * {@inheritDoc} */ public String[] getColumnNames() throws RepositoryException { - try { - String[] propNames = new String[selectProps.length]; - for (int i = 0; i < selectProps.length; i++) { - propNames[i] = session.getJCRName(selectProps[i]); - } - return propNames; - } catch (NamespaceException npde) { - String msg = "encountered invalid property name"; - log.debug(msg); - throw new RepositoryException(msg, npde); - } + return columns.keySet().toArray(new String[columns.size()]); } /** @@ -223,7 +206,7 @@ throw new RepositoryException(e); } } - return new RowIteratorImpl(getScoreNodes(), selectProps, + return new RowIteratorImpl(getScoreNodes(), columns, selectorNames, itemMgr, index.getContext().getHierarchyManager(), session, session.getValueFactory(), excerptProvider, spellSuggestion); @@ -276,17 +259,17 @@ */ protected void getResults(long size) throws RepositoryException { if (log.isDebugEnabled()) { - log.debug("getResults({}) limit={}", new Long(size), new Long(limit)); + log.debug("getResults({}) limit={}", size, limit); } long maxResultSize = size; // is there any limit? - if (limit > 0) { + if (limit >= 0) { maxResultSize = limit; } - if (resultNodes.size() >= maxResultSize) { + if (resultNodes.size() >= maxResultSize && selectorNames != null) { // we already have them all return; } @@ -297,13 +280,13 @@ long time = System.currentTimeMillis(); result = executeQuery(maxResultSize); log.debug("query executed in {} ms", - new Long(System.currentTimeMillis() - time)); + System.currentTimeMillis() - time); // set selector names selectorNames = result.getSelectorNames(); if (resultNodes.isEmpty() && offset > 0) { // collect result offset into dummy list - collectScoreNodes(result, new ArrayList(), offset); + collectScoreNodes(result, new ArrayList(), offset); } else { int start = resultNodes.size() + invalid + (int) offset; result.skip(start); @@ -312,7 +295,7 @@ time = System.currentTimeMillis(); collectScoreNodes(result, resultNodes, maxResultSize); log.debug("retrieved ScoreNodes in {} ms", - new Long(System.currentTimeMillis() - time)); + System.currentTimeMillis() - time); // update numResults numResults = result.getSize(); @@ -342,7 +325,7 @@ * @throws RepositoryException if an error occurs while checking access rights. */ private void collectScoreNodes(MultiColumnQueryHits hits, - List collector, + List collector, long maxResults) throws IOException, RepositoryException { while (collector.size() < maxResults) { @@ -371,10 +354,10 @@ */ private boolean isAccessGranted(ScoreNode[] nodes) throws RepositoryException { - for (int i = 0; i < nodes.length; i++) { + for (ScoreNode node : nodes) { try { // TODO: rather use AccessManager.canRead(Path) - if (nodes[i] != null && !accessMgr.isGranted(nodes[i].getNodeId(), AccessManager.READ)) { + if (node != null && !accessMgr.isGranted(node.getNodeId(), AccessManager.READ)) { return false; } } catch (ItemNotFoundException e) { @@ -459,7 +442,7 @@ return -1; } long size = total - offset; - if (limit > 0 && size > limit) { + if (limit >= 0 && size > limit) { return limit; } else { return size; @@ -540,7 +523,7 @@ break; } } - next = (ScoreNode[]) resultNodes.get(nextPos); + next = resultNodes.get(nextPos); } position++; } Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java Wed Jul 8 13:57:13 2009 @@ -17,7 +17,6 @@ package org.apache.jackrabbit.core.query.lucene; import org.apache.jackrabbit.core.NodeImpl; -import org.apache.jackrabbit.core.PropertyImpl; import org.apache.jackrabbit.core.NodeId; import org.apache.jackrabbit.core.ItemManager; import org.apache.jackrabbit.core.HierarchyManager; @@ -30,6 +29,7 @@ import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl; import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl; +import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl; import org.apache.jackrabbit.util.ISO9075; import org.slf4j.LoggerFactory; import org.slf4j.Logger; @@ -46,11 +46,10 @@ import javax.jcr.query.Row; import javax.jcr.query.RowIterator; import java.util.Arrays; -import java.util.HashSet; import java.util.NoSuchElementException; -import java.util.Set; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.io.IOException; /** @@ -87,19 +86,15 @@ private final ScoreNodeIterator scoreNodes; /** - * Array of select property names + * Linked map of {@link ColumnImpl columns}, indexed by their column name + * (String). */ - private final Name[] properties; - - /** - * Set of select property Names. - */ - private Set propertySet; + private final Map columns; /** * List of valid selector {@link Name}s. */ - private final List selectorNames = new ArrayList(); + private final List selectorNames = new ArrayList(); /** * The item manager of the session that executes the query. @@ -137,29 +132,33 @@ * * @param scoreNodes a ScoreNodeIterator that contains the * nodes of the query result. - * @param properties Name of the select properties. + * @param columns the columns to select. * @param selectorNames the selector names. * @param itemMgr the item manager of the session that executes the * query. * @param hmgr the hierarchy manager of the workspace. * @param resolver NamespaceResolver of the user * Session. + * @param valueFactory the value factory of the current session. * @param exProvider the excerpt provider associated with the query * result that created this row iterator. * @param spellSuggestion the spell suggestion associated with the query * result or null if none is available. + * @throws NamespaceException if an error occurs while translating a JCR + * name. */ RowIteratorImpl(ScoreNodeIterator scoreNodes, - Name[] properties, + Map columns, Name[] selectorNames, ItemManager itemMgr, HierarchyManager hmgr, NamePathResolver resolver, ValueFactory valueFactory, ExcerptProvider exProvider, - SpellSuggestion spellSuggestion) { + SpellSuggestion spellSuggestion) + throws NamespaceException { this.scoreNodes = scoreNodes; - this.properties = properties; + this.columns = columns; this.selectorNames.addAll(Arrays.asList(selectorNames)); this.itemMgr = itemMgr; this.hmgr = hmgr; @@ -296,35 +295,10 @@ */ public Value[] getValues() throws RepositoryException { if (values == null) { - Value[] tmp = new Value[properties.length]; - for (int i = 0; i < properties.length; i++) { - if (getNodeImpl().hasProperty(properties[i])) { - PropertyImpl prop = getNodeImpl().getProperty(properties[i]); - if (!prop.getDefinition().isMultiple()) { - if (prop.getDefinition().getRequiredType() == PropertyType.UNDEFINED) { - tmp[i] = valueFactory.createValue(prop.getString()); - } else { - tmp[i] = prop.getValue(); - } - } else { - // mvp values cannot be returned - tmp[i] = null; - } - } else { - // property not set or one of the following: - // jcr:path / jcr:score / rep:excerpt / rep:spellcheck - if (NameConstants.JCR_PATH.equals(properties[i])) { - tmp[i] = valueFactory.createValue(getNodeImpl().getPath(), PropertyType.PATH); - } else if (NameConstants.JCR_SCORE.equals(properties[i])) { - tmp[i] = valueFactory.createValue(Math.round(score * 1000f)); - } else if (isExcerptFunction(properties[i])) { - tmp[i] = getExcerpt(); - } else if (isSpellCheckFunction(properties[i])) { - tmp[i] = getSpellCheckedStatement(); - } else { - tmp[i] = null; - } - } + Value[] tmp = new Value[columns.size()]; + int i = 0; + for (String columnName : columns.keySet()) { + tmp[i++] = getValue(columnName); } values = tmp; } @@ -335,45 +309,50 @@ } /** - * Returns the value of the indicated property in this Row. + * Returns the value of the indicated column in this Row. *

- * If propertyName is not among the column names of the + * If columnbName is not among the column names of the * query result table, an ItemNotFoundException is thrown. * * @return a Value - * @throws ItemNotFoundException if propertyName is not + * @throws ItemNotFoundException if columnName is not * among the column names of the query result table. - * @throws RepositoryException if propertyName is not a - * valid property name. + * @throws RepositoryException if another error occurs. */ - public Value getValue(String propertyName) throws ItemNotFoundException, RepositoryException { - if (propertySet == null) { - // create the set first - Set tmp = new HashSet(); - tmp.addAll(Arrays.asList(properties)); - propertySet = tmp; - } + public Value getValue(String columnName) throws ItemNotFoundException, RepositoryException { try { - Name prop = resolver.getQName(propertyName); - if (!propertySet.contains(prop)) { - if (isExcerptFunction(propertyName)) { + ColumnImpl col = columns.get(columnName); + if (col == null) { + if (isExcerptFunction(columnName)) { // excerpt function with parameter - return getExcerpt(propertyName); + return getExcerpt(columnName); } else { - throw new ItemNotFoundException(propertyName); + throw new ItemNotFoundException(columnName); } } - if (NameConstants.JCR_PATH.equals(prop)) { - QValue p = valueFactory.getQValueFactory().create(hmgr.getPath(sn[0].getNodeId())); + Node n = getNode(col.getSelectorName()); + if (n == null) { + return null; + } + + if (NameConstants.JCR_PATH.equals(col.getPropertyQName())) { + int idx = getSelectorIndex(col.getSelectorName()); + QValue p = valueFactory.getQValueFactory().create(hmgr.getPath(sn[idx].getNodeId())); return valueFactory.createValue(p); - } else if (getNodeImpl().hasProperty(prop)) { - Property p = getNodeImpl().getProperty(prop); - if (p.getDefinition().getRequiredType() == PropertyType.UNDEFINED) { - return valueFactory.createValue(p.getString()); + } else if (n.hasProperty(col.getPropertyName())) { + Property p = n.getProperty(col.getPropertyName()); + if (p.getDefinition().isMultiple()) { + // mvp values cannot be returned + return null; } else { - return p.getValue(); + if (p.getDefinition().getRequiredType() == PropertyType.UNDEFINED) { + return valueFactory.createValue(p.getString()); + } else { + return p.getValue(); + } } } else { + Name prop = resolver.getQName(columnName); // either jcr:score, rep:excerpt, // rep:spellcheck or not set if (NameConstants.JCR_SCORE.equals(prop)) { @@ -387,9 +366,9 @@ } } } catch (NameException e) { - if (isExcerptFunction(propertyName)) { + if (isExcerptFunction(columnName)) { // excerpt function with parameter - return getExcerpt(propertyName); + return getExcerpt(columnName); } else { throw new RepositoryException(e.getMessage(), e); } @@ -427,7 +406,6 @@ public Node getNode(String selectorName) throws RepositoryException { ScoreNode s = sn[getSelectorIndex(selectorName)]; if (s == null) { - // TODO correct? return null; } return (Node) itemMgr.getItem(s.getNodeId()); @@ -517,8 +495,7 @@ public double getScore(String selectorName) throws RepositoryException { ScoreNode s = sn[getSelectorIndex(selectorName)]; if (s == null) { - // TODO correct? - return Double.NaN; + return 0; } return s.getScore(); } @@ -644,6 +621,7 @@ /** * Creates an excerpt for node with the given id. * + * @param id a node id. * @return a StringValue or null if the excerpt cannot be * created or an error occurs. */ @@ -655,7 +633,7 @@ long time = System.currentTimeMillis(); String excerpt = excerptProvider.getExcerpt(id, 3, 150); time = System.currentTimeMillis() - time; - log.debug("Created excerpt in {} ms.", new Long(time)); + log.debug("Created excerpt in {} ms.", time); if (excerpt != null) { return valueFactory.createValue(excerpt); } else { @@ -669,6 +647,7 @@ /** * Highlights the matching terms in the passed text. * + * @param text the text where to apply highlighting. * @return a StringValue or null if highlighting fails. */ private Value highlight(String text) { @@ -681,7 +660,7 @@ long time = System.currentTimeMillis(); text = hep.highlight(text); time = System.currentTimeMillis() - time; - log.debug("Highlighted text in {} ms.", new Long(time)); + log.debug("Highlighted text in {} ms.", time); return valueFactory.createValue(text); } catch (IOException e) { return null; Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNode.java Wed Jul 8 13:57:13 2009 @@ -37,7 +37,7 @@ /** * The score of the node. */ - private final float score; + private float score; /** * The lucene document number for this score node. Set to -1 if @@ -83,6 +83,15 @@ } /** + * Sets a new score value. + * + * @param score the score value. + */ + public void setScore(float score) { + this.score = score; + } + + /** * Returns the document number for this score node. * * @param reader the current index reader to look up the document if Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java?rev=792142&r1=792141&r2=792142&view=diff ============================================================================== --- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java (original) +++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ScoreNodeIteratorImpl.java Wed Jul 8 13:57:13 2009 @@ -16,7 +16,6 @@ */ package org.apache.jackrabbit.core.query.lucene; -import java.util.Collection; import java.util.Arrays; import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;