jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
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 GMT
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<String> deletable = new HashSet<String>();
 
     /**
      * List of open persistent indexes. This list may also contain an open
@@ -105,7 +105,8 @@
      * registered with indexNames and <b>must not</b> be used in regular index
      * operations (delete node, etc.)!
      */
-    private final List indexes = new ArrayList();
+    private final List<PersistentIndex> indexes =
+        new ArrayList<PersistentIndex>();
 
     /**
      * The internal namespace mappings of the query manager.
@@ -191,9 +192,9 @@
     private IndexingQueue indexingQueue;
 
     /**
-     * Set&lt;NodeId> of uuids that should not be indexed.
+     * Identifiers of nodes that should not be indexed.
      */
-    private final Set excludedIDs;
+    private final Set<NodeId> excludedIDs;
 
     /**
      * The next transaction id.
@@ -219,18 +220,17 @@
      * Creates a new MultiIndex.
      *
      * @param handler the search handler
-     * @param excludedIDs   Set&lt;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<NodeId> 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<NodeId>(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<UUID> remove, Collection<Document> 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<UUID> 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<Document> empty = Collections.emptyList();
+        update(Collections.singleton(uuid), empty);
     }
 
     /**
@@ -517,34 +522,33 @@
      * @return the <code>IndexReaders</code>.
      * @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<String> names = new HashSet<String>(Arrays.asList(indexNames));
+        Map<ReadOnlyIndexReader, PersistentIndex> indexReaders =
+            new HashMap<ReadOnlyIndexReader, PersistentIndex>();
 
         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<ReadOnlyIndexReader, PersistentIndex> 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<Term> 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<String> names = new HashSet<String>(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<ReadOnlyIndexReader> readerList =
+                    new ArrayList<ReadOnlyIndexReader>();
                 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<String> 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<UUID, Document> finished = new HashMap<UUID, Document>();
+        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 <code>Name</code> object.
          *
-         * @param name prefixed JCR name
-         * @return qualified name
+         * @param name The JCR name string.
+         * @return The corresponding <code>Name</code>.
          * @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 <code>Name</code>.
          * 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 <code>Name</code> 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 <code>Document</code> 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<Fieldable> doNotUseInExcerpt = new ArrayList<Fieldable>();
 
     /**
      * 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<Name> 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 <code>Name</code> 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<Name, ColumnImpl> columns = new LinkedHashMap<Name, ColumnImpl>();
+        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;
 
 /**
  * <code>QueryObjectModelImpl</code>...
@@ -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<ColumnImpl> columns = new ArrayList<ColumnImpl>();
+        // 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 <code>QueryResult</code> 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<String, ColumnImpl> columns = new LinkedHashMap<String, ColumnImpl>();
 
     /**
      * The result nodes including their score. This list is populated on a lazy
@@ -96,7 +87,7 @@
      * <p/>
      * The exact type is: <code>List&lt;ScoreNode[]></code>
      */
-    private final List resultNodes = new ArrayList();
+    private final List<ScoreNode[]> resultNodes = new ArrayList<ScoreNode[]>();
 
     /**
      * 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 <code>null</code> 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 <code>true</code> 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<ScoreNode[]>(), 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<ScoreNode[]> 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 <code>Name</code>s.
-     */
-    private Set propertySet;
+    private final Map<String, ColumnImpl> columns;
 
     /**
      * List of valid selector {@link Name}s.
      */
-    private final List selectorNames = new ArrayList();
+    private final List<Name> selectorNames = new ArrayList<Name>();
 
     /**
      * The item manager of the session that executes the query.
@@ -137,29 +132,33 @@
      *
      * @param scoreNodes      a <code>ScoreNodeIterator</code> that contains the
      *                        nodes of the query result.
-     * @param properties      <code>Name</code> 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        <code>NamespaceResolver</code> of the user
      *                        <code>Session</code>.
+     * @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 <code>null</code> if none is available.
+     * @throws NamespaceException if an error occurs while translating a JCR
+     *                            name.
      */
     RowIteratorImpl(ScoreNodeIterator scoreNodes,
-                    Name[] properties,
+                    Map<String, ColumnImpl> 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 <code>Row</code>.
+         * Returns the value of the indicated  column in this <code>Row</code>.
          * <p/>
-         * If <code>propertyName</code> is not among the column names of the
+         * If <code>columnbName</code> is not among the column names of the
          * query result table, an <code>ItemNotFoundException</code> is thrown.
          *
          * @return a <code>Value</code>
-         * @throws ItemNotFoundException if <code>propertyName</code> is not
+         * @throws ItemNotFoundException if <code>columnName</code> is not
          *                               among the column names of the query result table.
-         * @throws RepositoryException   if <code>propertyName</code> 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 <code>id</code>.
          *
+         * @param id a node id.
          * @return a StringValue or <code>null</code> 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 <code>text</code>.
          *
+         * @param text the text where to apply highlighting.
          * @return a StringValue or <code>null</code> 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 <code>-1</code> 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;



Mime
View raw message