jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r792142 [10/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/jackrab...
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/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Wed Jul  8 13:57:13 2009
@@ -45,6 +45,7 @@
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
 import org.apache.jackrabbit.spi.commons.query.DefaultQueryNodeFactory;
 import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree;
+import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
 import org.apache.jackrabbit.uuid.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,13 +60,12 @@
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.search.SortComparatorSource;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.HitCollector;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.Fieldable;
-import org.apache.commons.collections.iterators.TransformIterator;
-import org.apache.commons.collections.collection.TransformedCollection;
-import org.apache.commons.collections.IteratorUtils;
-import org.apache.commons.collections.Transformer;
 import org.xml.sax.SAXException;
 import org.w3c.dom.Element;
 
@@ -77,7 +77,6 @@
 import java.io.IOException;
 import java.io.File;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -93,26 +92,32 @@
  */
 public class SearchIndex extends AbstractQueryHandler {
 
-    public static final List VALID_SYSTEM_INDEX_NODE_TYPE_NAMES
-        = Collections.unmodifiableList(Arrays.asList(new Name[]{
-            NameConstants.NT_CHILDNODEDEFINITION,
-            NameConstants.NT_FROZENNODE,
-            NameConstants.NT_NODETYPE,
-            NameConstants.NT_PROPERTYDEFINITION,
-            NameConstants.NT_VERSION,
-            NameConstants.NT_VERSIONEDCHILD,
-            NameConstants.NT_VERSIONHISTORY,
-            NameConstants.NT_VERSIONLABELS,
-            NameConstants.REP_NODETYPES,
-            NameConstants.REP_SYSTEM,
-            NameConstants.REP_VERSIONSTORAGE,
-            // Supertypes
-            NameConstants.NT_BASE,
-            NameConstants.MIX_REFERENCEABLE
-        }));
-
-    private static final DefaultQueryNodeFactory DEFAULT_QUERY_NODE_FACTORY = new DefaultQueryNodeFactory(
-            VALID_SYSTEM_INDEX_NODE_TYPE_NAMES);
+    /**
+     * Valid node type names under /jcr:system. Used to determine if a
+     * query needs to be executed also against the /jcr:system tree.
+     */
+    public static final Collection<Name> VALID_SYSTEM_INDEX_NODE_TYPE_NAMES =
+        Collections.unmodifiableCollection(Arrays.asList(
+                NameConstants.NT_CHILDNODEDEFINITION,
+                NameConstants.NT_FROZENNODE,
+                NameConstants.NT_NODETYPE,
+                NameConstants.NT_PROPERTYDEFINITION,
+                NameConstants.NT_VERSION,
+                NameConstants.NT_VERSIONEDCHILD,
+                NameConstants.NT_VERSIONHISTORY,
+                NameConstants.NT_VERSIONLABELS,
+                NameConstants.REP_NODETYPES,
+                NameConstants.REP_SYSTEM,
+                NameConstants.REP_VERSIONSTORAGE,
+                // Supertypes
+                NameConstants.NT_BASE,
+                NameConstants.MIX_REFERENCEABLE));
+        
+    /**
+     * Default query node factory.
+     */
+    private static final DefaultQueryNodeFactory DEFAULT_QUERY_NODE_FACTORY =
+        new DefaultQueryNodeFactory(VALID_SYSTEM_INDEX_NODE_TYPE_NAMES);
 
     /** The logger instance for this class */
     private static final Logger log = LoggerFactory.getLogger(SearchIndex.class);
@@ -167,6 +172,11 @@
     public static final int DEFAULT_TERM_INFOS_INDEX_DIVISOR = 1;
 
     /**
+     * The default value for {@link #indexMergerPoolSize}.
+     */
+    public static final int DEFAULT_INDEX_MERGER_POOL_SIZE = 2;
+
+    /**
      * The path factory.
      */
     protected static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance();
@@ -342,7 +352,7 @@
     /**
      * The excerpt provider class. Implements {@link ExcerptProvider}.
      */
-    private Class excerptProviderClass = DefaultHTMLExcerpt.class;
+    private Class<?> excerptProviderClass = DefaultHTMLExcerpt.class;
 
     /**
      * The path to the indexing configuration file.
@@ -364,12 +374,12 @@
      * The indexing configuration class.
      * Implements {@link IndexingConfiguration}.
      */
-    private Class indexingConfigurationClass = IndexingConfigurationImpl.class;
+    private Class<?> indexingConfigurationClass = IndexingConfigurationImpl.class;
 
     /**
      * The class that implements {@link SynonymProvider}.
      */
-    private Class synonymProviderClass;
+    private Class<?> synonymProviderClass;
 
     /**
      * The currently set synonym provider.
@@ -400,7 +410,7 @@
     /**
      * The class that implements {@link SpellChecker}.
      */
-    private Class spellCheckerClass;
+    private Class<?> spellCheckerClass;
 
     /**
      * The spell checker for this query handler or <code>null</code> if none is
@@ -440,6 +450,11 @@
     private boolean initializeHierarchyCache = true;
 
     /**
+     * The number of worker threads for merging index segments.
+     */
+    private int indexMergerPoolSize = DEFAULT_INDEX_MERGER_POOL_SIZE;
+
+    /**
      * Indicates if this <code>SearchIndex</code> is closed and cannot be used
      * anymore.
      */
@@ -465,7 +480,7 @@
             throw new IOException("SearchIndex requires 'path' parameter in configuration!");
         }
 
-        Set excludedIDs = new HashSet();
+        Set<NodeId> excludedIDs = new HashSet<NodeId>();
         if (context.getExcludedNodeId() != null) {
             excludedIDs.add(context.getExcludedNodeId());
         }
@@ -520,12 +535,11 @@
                 if (autoRepair) {
                     check.repair(true);
                 } else {
-                    List errors = check.getErrors();
+                    List<ConsistencyCheckError> errors = check.getErrors();
                     if (errors.size() == 0) {
                         log.info("No errors detected.");
                     }
-                    for (Iterator it = errors.iterator(); it.hasNext();) {
-                        ConsistencyCheckError err = (ConsistencyCheckError) it.next();
+                    for (ConsistencyCheckError err : errors) {
                         log.info(err.toString());
                     }
                 }
@@ -542,7 +556,7 @@
         if (!index.getIndexFormatVersion().equals(getIndexFormatVersion())) {
             log.warn("Using Version {} for reading. Please re-index version " +
                     "storage for optimal performance.",
-                    new Integer(getIndexFormatVersion().getVersion()));
+                    getIndexFormatVersion().getVersion());
         }
     }
 
@@ -581,39 +595,39 @@
     public void updateNodes(NodeIdIterator remove, NodeStateIterator add)
             throws RepositoryException, IOException {
         checkOpen();
-        final Map aggregateRoots = new HashMap();
-        final HashSet removedUUIDs = new HashSet();
-        final Set addedUUIDs = new HashSet();
-
-        index.update(IteratorUtils.toList(new TransformIterator(remove,
-                new Transformer() {
-                    public Object transform(Object input) {
-                        UUID uuid = ((NodeId) input).getUUID();
-                        removedUUIDs.add(uuid);
-                        return uuid;
-                    }
-                })), IteratorUtils.toList(new TransformIterator(add,
-                new Transformer() {
-                    public Object transform(Object input) {
-                        NodeState state = (NodeState) input;
-                        if (state == null) {
-                            return null;
-                        }
-                        UUID uuid = state.getNodeId().getUUID();
-                        addedUUIDs.add(uuid);
-                        removedUUIDs.remove(uuid);
-                        Document doc = null;
-                        try {
-                            doc = createDocument(state, getNamespaceMappings(),
-                                    index.getIndexFormatVersion());
-                            retrieveAggregateRoot(state, aggregateRoots);
-                        } catch (RepositoryException e) {
-                            log.warn("Exception while creating document for node: "
-                                    + state.getNodeId() + ": " + e.toString());
-                        }
-                        return doc;
-                    }
-                })));
+
+        Map<UUID, NodeState> aggregateRoots = new HashMap<UUID, NodeState>();
+        Set<UUID> removedUUIDs = new HashSet<UUID>();
+        Set<UUID> addedUUIDs = new HashSet<UUID>();
+
+        Collection<UUID> removeCollection = new ArrayList<UUID>();
+        while (remove.hasNext()) {
+            UUID uuid = remove.nextNodeId().getUUID();
+            removeCollection.add(uuid);
+            removedUUIDs.add(uuid);
+        }
+
+        Collection<Document> addCollection = new ArrayList<Document>();
+        while (add.hasNext()) {
+            NodeState state = add.nextNodeState();
+            if (state != null) {
+                UUID uuid = state.getNodeId().getUUID();
+                addedUUIDs.add(uuid);
+                removedUUIDs.remove(uuid);
+                retrieveAggregateRoot(state, aggregateRoots);
+
+                try {
+                    addCollection.add(createDocument(
+                            state, getNamespaceMappings(),
+                            index.getIndexFormatVersion()));
+                } catch (RepositoryException e) {
+                    log.warn("Exception while creating document for node: "
+                            + state.getNodeId() + ": " + e.toString());
+                }
+            }
+        }
+
+        index.update(removeCollection, addCollection);
 
         // remove any aggregateRoot nodes that are new
         // and therefore already up-to-date
@@ -623,24 +637,21 @@
         retrieveAggregateRoot(removedUUIDs, aggregateRoots);
 
         // update aggregates if there are any affected
-        if (aggregateRoots.size() > 0) {
-            Collection modified = TransformedCollection.decorate(
-                    new ArrayList(),
-                    new Transformer() {
-                        public Object transform(Object input) {
-                            NodeState state = (NodeState) input;
-                            try {
-                                return createDocument(state,
-                                        getNamespaceMappings(),
-                                        index.getIndexFormatVersion());
-                            } catch (RepositoryException e) {
-                                log.warn("Exception while creating document for node: "
-                                        + state.getNodeId() + ": " + e.toString());
-                            }
-                            return null;
-                        }
-                    });
-            modified.addAll(aggregateRoots.values());
+        if (!aggregateRoots.isEmpty()) {
+            Collection<Document> modified =
+                new ArrayList<Document>(aggregateRoots.size());
+
+            for (NodeState state : aggregateRoots.values()) {
+                try {
+                    modified.add(createDocument(
+                            state, getNamespaceMappings(),
+                            index.getIndexFormatVersion()));
+                } catch (RepositoryException e) {
+                    log.warn("Exception while creating document for node: "
+                            + state.getNodeId(), e);
+                }
+            }
+
             index.update(aggregateRoots.keySet(), modified);
         }
     }
@@ -696,8 +707,42 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    public Iterable<NodeId> getWeaklyReferringNodes(NodeId id)
+            throws RepositoryException, IOException {
+        final List<Integer> docs = new ArrayList<Integer>();
+        final List<NodeId> ids = new ArrayList<NodeId>();
+        final IndexReader reader = getIndexReader();
+        try {
+            IndexSearcher searcher = new IndexSearcher(reader);
+            try {
+                Query q = new TermQuery(new Term(
+                        FieldNames.WEAK_REFS, id.getUUID().toString()));
+                searcher.search(q, new HitCollector() {
+                    public void collect(int doc, float score) {
+                        docs.add(doc);
+                    }
+                });
+            } finally {
+                searcher.close();
+            }
+            for (Integer doc : docs) {
+                Document d = reader.document(doc, FieldSelectors.UUID);
+                UUID uuid = UUID.fromString(d.get(FieldNames.UUID));
+                ids.add(new NodeId(uuid));
+            }
+        } finally {
+            Util.closeOrRelease(reader);
+        }
+        return ids;
+    }
+
+    /**
      * This method returns the QueryNodeFactory used to parse Queries. This method
      * may be overridden to provide a customized QueryNodeFactory
+     *
+     * @return the query node factory.
      */
     protected DefaultQueryNodeFactory getQueryNodeFactory() {
         return DEFAULT_QUERY_NODE_FACTORY;
@@ -776,30 +821,24 @@
      *
      * @param session         the session that executes the query.
      * @param query           the query.
-     * @param orderProps      name of the properties for sort order.
-     * @param orderSpecs      the order specs for the sort order properties.
-     *                        <code>true</code> indicates ascending order,
-     *                        <code>false</code> indicates descending.
+     * @param orderings       the order specs for the sort order.
      * @param resultFetchHint a hint on how many results should be fetched.
      * @return the query hits.
      * @throws IOException if an error occurs while searching the index.
      */
     public MultiColumnQueryHits executeQuery(SessionImpl session,
                                              MultiColumnQuery query,
-                                             Path[] orderProps,
-                                             boolean[] orderSpecs,
+                                             Ordering[] orderings,
                                              long resultFetchHint)
             throws IOException {
         checkOpen();
 
-        Sort sort = new Sort(createSortFields(orderProps, orderSpecs));
-
         final IndexReader reader = getIndexReader();
         JackrabbitIndexSearcher searcher = new JackrabbitIndexSearcher(
                 session, reader, getContext().getItemStateManager());
         searcher.setSimilarity(getSimilarity());
         return new FilterMultiColumnQueryHits(
-                query.execute(searcher, sort, resultFetchHint)) {
+                query.execute(searcher, orderings, resultFetchHint)) {
             public void close() throws IOException {
                 try {
                     super.close();
@@ -977,7 +1016,7 @@
      */
     protected SortField[] createSortFields(Path[] orderProps,
                                            boolean[] orderSpecs) {
-        List sortFields = new ArrayList();
+        List<SortField> sortFields = new ArrayList<SortField>();
         for (int i = 0; i < orderProps.length; i++) {
             if (orderProps[i].getLength() == 1
                     && NameConstants.JCR_SCORE.equals(orderProps[i].getNameElement().getName())) {
@@ -990,7 +1029,23 @@
                 sortFields.add(new SortField(orderProps[i].getString(), scs, !orderSpecs[i]));
             }
         }
-        return (SortField[]) sortFields.toArray(new SortField[sortFields.size()]);
+        return sortFields.toArray(new SortField[sortFields.size()]);
+    }
+
+    /**
+     * Creates internal orderings for the QOM ordering specifications.
+     *
+     * @param orderings the QOM ordering specifications.
+     * @return the internal orderings.
+     * @throws RepositoryException if an error occurs.
+     */
+    protected Ordering[] createOrderings(OrderingImpl[] orderings)
+            throws RepositoryException {
+        Ordering[] ords = new Ordering[orderings.length];
+        for (int i = 0; i < orderings.length; i++) {
+            ords[i] = Ordering.fromQOM(orderings[i], scs, nsMappings);
+        }
+        return ords;
     }
 
     /**
@@ -1101,7 +1156,7 @@
     protected DirectoryManager createDirectoryManager()
             throws IOException {
         try {
-            Class clazz = Class.forName(directoryManagerClass);
+            Class<?> clazz = Class.forName(directoryManagerClass);
             if (!DirectoryManager.class.isAssignableFrom(clazz)) {
                 throw new IOException(directoryManagerClass +
                         " is not a DirectoryManager implementation");
@@ -1237,44 +1292,36 @@
             }
             try {
                 ItemStateManager ism = getContext().getItemStateManager();
-                for (int i = 0; i < aggregateRules.length; i++) {
+                for (AggregateRule aggregateRule : aggregateRules) {
                     boolean ruleMatched = false;
                     // node includes
-                    NodeState[] aggregates = aggregateRules[i].getAggregatedNodeStates(state);
+                    NodeState[] aggregates = aggregateRule.getAggregatedNodeStates(state);
                     if (aggregates != null) {
                         ruleMatched = true;
-                        for (int j = 0; j < aggregates.length; j++) {
-                            Document aDoc = createDocument(aggregates[j],
-                                    getNamespaceMappings(),
-                                    index.getIndexFormatVersion());
+                        for (NodeState aggregate : aggregates) {
+                            Document aDoc = createDocument(aggregate, getNamespaceMappings(), index.getIndexFormatVersion());
                             // transfer fields to doc if there are any
                             Fieldable[] fulltextFields = aDoc.getFieldables(FieldNames.FULLTEXT);
                             if (fulltextFields != null) {
-                                for (int k = 0; k < fulltextFields.length; k++) {
-                                    doc.add(fulltextFields[k]);
+                                for (Fieldable fulltextField : fulltextFields) {
+                                    doc.add(fulltextField);
                                 }
-                                doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID,
-                                        aggregates[j].getNodeId().getUUID().toString(),
-                                        Field.Store.NO,
-                                        Field.Index.NOT_ANALYZED_NO_NORMS));
+                                doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, aggregate.getNodeId().getUUID().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                             }
                         }
                     }
                     // property includes
-                    PropertyState[] propStates = aggregateRules[i].getAggregatedPropertyStates(state);
+                    PropertyState[] propStates = aggregateRule.getAggregatedPropertyStates(state);
                     if (propStates != null) {
                         ruleMatched = true;
-                        for (int j = 0; j < propStates.length; j++) {
-                            PropertyState propState = propStates[j];
-                            String namePrefix = FieldNames.createNamedValue(
-                                    getNamespaceMappings().translateName(propState.getName()), "");
+                        for (PropertyState propState : propStates) {
+                            String namePrefix = FieldNames.createNamedValue(getNamespaceMappings().translateName(propState.getName()), "");
                             NodeState parent = (NodeState) ism.getItemState(propState.getParentId());
                             Document aDoc = createDocument(parent, getNamespaceMappings(), getIndex().getIndexFormatVersion());
                             // find the right fields to transfer
                             Fieldable[] fields = aDoc.getFieldables(FieldNames.PROPERTIES);
                             Token t = new Token();
-                            for (int k = 0; k < fields.length; k++) {
-                                Fieldable field = fields[k];
+                            for (Fieldable field : fields) {
                                 // assume properties fields use SingleTokenStream
                                 t = field.tokenStreamValue().next(t);
                                 String value = new String(t.termBuffer(), 0, t.termLength());
@@ -1287,10 +1334,7 @@
                                     value = FieldNames.createNamedValue(path, value);
                                     t.setTermBuffer(value);
                                     doc.add(new Field(field.name(), new SingletonTokenStream(t)));
-                                    doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID,
-                                            parent.getNodeId().getUUID().toString(),
-                                            Field.Store.NO,
-                                            Field.Index.NOT_ANALYZED_NO_NORMS));
+                                    doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, parent.getNodeId().getUUID().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS));
                                 }
                             }
                         }
@@ -1350,15 +1394,16 @@
      * @param map   aggregate roots are collected in this map. Key=UUID,
      *              value=NodeState.
      */
-    protected void retrieveAggregateRoot(NodeState state, Map map) {
+    protected void retrieveAggregateRoot(
+            NodeState state, Map<UUID, NodeState> map) {
         if (indexingConfig != null) {
             AggregateRule[] aggregateRules = indexingConfig.getAggregateRules();
             if (aggregateRules == null) {
                 return;
             }
             try {
-                for (int i = 0; i < aggregateRules.length; i++) {
-                    NodeState root = aggregateRules[i].getAggregateRoot(state);
+                for (AggregateRule aggregateRule : aggregateRules) {
+                    NodeState root = aggregateRule.getAggregateRoot(state);
                     if (root != null) {
                         map.put(root.getNodeId().getUUID(), root);
                     }
@@ -1375,10 +1420,10 @@
      * and puts it into <code>map</code>.
      *
      * @param removedUUIDs   the UUIDs of removed nodes.
-     * @param map            aggregate roots are collected in this map.
-     *                       Key=UUID, value=NodeState.
+     * @param map            aggregate roots are collected in this map
      */
-    protected void retrieveAggregateRoot(Set removedUUIDs, Map map) {
+    protected void retrieveAggregateRoot(
+            Set<UUID> removedUUIDs, Map<UUID, NodeState> map) {
         if (indexingConfig != null) {
             AggregateRule[] aggregateRules = indexingConfig.getAggregateRules();
             if (aggregateRules == null) {
@@ -1389,22 +1434,21 @@
             try {
                 CachingMultiIndexReader reader = index.getIndexReader();
                 try {
-                    Term aggregateUUIDs = new Term(
-                            FieldNames.AGGREGATED_NODE_UUID, "");
+                    Term aggregateUUIDs =
+                        new Term(FieldNames.AGGREGATED_NODE_UUID, "");
                     TermDocs tDocs = reader.termDocs();
                     try {
                         ItemStateManager ism = getContext().getItemStateManager();
-                        Iterator it = removedUUIDs.iterator();
-                        while (it.hasNext()) {
-                            UUID uuid = (UUID) it.next();
-                            aggregateUUIDs = aggregateUUIDs.createTerm(
-                                    uuid.toString());
+                        for (UUID uuid : removedUUIDs) {
+                            aggregateUUIDs =
+                                aggregateUUIDs.createTerm(uuid.toString());
                             tDocs.seek(aggregateUUIDs);
                             while (tDocs.next()) {
-                                Document doc = reader.document(tDocs.doc(), FieldSelectors.UUID);
-                                NodeId nId = new NodeId(UUID.fromString(
-                                        doc.get(FieldNames.UUID)));
-                                map.put(nId.getUUID(), ism.getItemState(nId));
+                                Document doc = reader.document(
+                                        tDocs.doc(), FieldSelectors.UUID);
+                                NodeId nId = new NodeId(
+                                        UUID.fromString(doc.get(FieldNames.UUID)));
+                                map.put(nId.getUUID(), (NodeState) ism.getItemState(nId));
                                 found++;
                             }
                         }
@@ -1418,8 +1462,7 @@
                 log.warn("Exception while retrieving aggregate roots", e);
             }
             time = System.currentTimeMillis() - time;
-            log.debug("Retrieved {} aggregate roots in {} ms.",
-                    new Integer(found), new Long(time));
+            log.debug("Retrieved {} aggregate roots in {} ms.", found, time);
         }
     }
 
@@ -1481,8 +1524,8 @@
          * {@inheritDoc}
          */
         public void release() throws IOException {
-            for (int i = 0; i < subReaders.length; i++) {
-                subReaders[i].release();
+            for (CachingMultiIndexReader subReader : subReaders) {
+                subReader.release();
             }
         }
 
@@ -1526,8 +1569,8 @@
 
         public int hashCode() {
             int hash = 0;
-            for (int i = 0; i < subReaders.length; i++) {
-                hash = 31 * hash + subReaders[i].hashCode();
+            for (CachingMultiIndexReader subReader : subReaders) {
+                hash = 31 * hash + subReader.hashCode();
             }
             return hash;
         }
@@ -1536,8 +1579,7 @@
          * {@inheritDoc}
          */
         public ForeignSegmentDocId createDocId(UUID uuid) throws IOException {
-            for (int i = 0; i < subReaders.length; i++) {
-                CachingMultiIndexReader subReader = subReaders[i];
+            for (CachingMultiIndexReader subReader : subReaders) {
                 ForeignSegmentDocId doc = subReader.createDocId(uuid);
                 if (doc != null) {
                     return doc;
@@ -1584,7 +1626,7 @@
      */
     public void setAnalyzer(String analyzerClassName) {
         try {
-            Class analyzerClass = Class.forName(analyzerClassName);
+            Class<?> analyzerClass = Class.forName(analyzerClassName);
             analyzer.setDefaultAnalyzer((Analyzer) analyzerClass.newInstance());
         } catch (Exception e) {
             log.warn("Invalid Analyzer class: " + analyzerClassName, e);
@@ -1879,7 +1921,7 @@
      */
     public void setExcerptProviderClass(String className) {
         try {
-            Class clazz = Class.forName(className);
+            Class<?> clazz = Class.forName(className);
             if (ExcerptProvider.class.isAssignableFrom(clazz)) {
                 excerptProviderClass = clazz;
             } else {
@@ -1924,7 +1966,7 @@
      */
     public void setIndexingConfigurationClass(String className) {
         try {
-            Class clazz = Class.forName(className);
+            Class<?> clazz = Class.forName(className);
             if (IndexingConfiguration.class.isAssignableFrom(clazz)) {
                 indexingConfigurationClass = clazz;
             } else {
@@ -1954,7 +1996,7 @@
      */
     public void setSynonymProviderClass(String className) {
         try {
-            Class clazz = Class.forName(className);
+            Class<?> clazz = Class.forName(className);
             if (SynonymProvider.class.isAssignableFrom(clazz)) {
                 synonymProviderClass = clazz;
             } else {
@@ -1988,7 +2030,7 @@
      */
     public void setSpellCheckerClass(String className) {
         try {
-            Class clazz = Class.forName(className);
+            Class<?> clazz = Class.forName(className);
             if (SpellChecker.class.isAssignableFrom(clazz)) {
                 spellCheckerClass = clazz;
             } else {
@@ -2057,7 +2099,7 @@
      */
     public void setSimilarityClass(String className) {
         try {
-            Class similarityClass = Class.forName(className);
+            Class<?> similarityClass = Class.forName(className);
             similarity = (Similarity) similarityClass.newInstance();
         } catch (Exception e) {
             log.warn("Invalid Similarity class: " + className, e);
@@ -2139,6 +2181,26 @@
         this.initializeHierarchyCache = initializeHierarchyCache;
     }
 
+    /**
+     * @return the current size of the index merger pool.
+     */
+    public int getIndexMergerPoolSize() {
+        return indexMergerPoolSize;
+    }
+
+    /**
+     * Sets a new value for the index merger pool size.
+     *
+     * @param indexMergerPoolSize the number of worker threads.
+     * @throws IllegalArgumentException if the size is less than or equal 0.
+     */
+    public void setIndexMergerPoolSize(int indexMergerPoolSize) {
+        if (indexMergerPoolSize <= 0) {
+            throw new IllegalArgumentException("must be greater than 0");
+        }
+        this.indexMergerPoolSize = indexMergerPoolSize;
+    }
+
     //----------------------------< internal >----------------------------------
 
     /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldCache.java Wed Jul  8 13:57:13 2009
@@ -21,7 +21,7 @@
 import org.apache.lucene.index.TermEnum;
 import org.apache.lucene.index.TermPositions;
 import org.apache.lucene.index.TermDocs;
-import org.apache.lucene.search.SortComparator;
+import org.apache.lucene.search.SortComparatorSource;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -58,7 +58,7 @@
         /**
          * Values (Comparable) map indexed by document id.
          */
-        public final Map valuesMap;
+        public final Map<Integer, Comparable> valuesMap;
 
         /**
          * Boolean indicating whether the {@link #valuesMap} impl has to be used
@@ -86,17 +86,17 @@
 
         public Comparable getValue(int i) {
             if (sparse) {
-                return valuesMap == null ? null : (Comparable) valuesMap.get(new Integer(i));
+                return valuesMap == null ? null : valuesMap.get(i);
             } else {
                 return values[i];
             }
         }
 
-        private Map getValuesMap(Comparable[] values, int setValues) {
-            Map map = new HashMap(setValues);
+        private Map<Integer, Comparable> getValuesMap(Comparable[] values, int setValues) {
+            Map<Integer, Comparable> map = new HashMap<Integer, Comparable>(setValues);
             for (int i = 0; i < values.length && setValues > 0; i++) {
                 if (values[i] != null) {
-                    map.put(new Integer(i), values[i]);
+                    map.put(i, values[i]);
                     setValues--;
                 }
             }
@@ -121,7 +121,7 @@
     /**
      * The internal cache. Maps Entry to array of interpreted term values.
      */
-    private final Map cache = new WeakHashMap();
+    private final Map<IndexReader, Map<Key, ValueIndex>> cache = new WeakHashMap<IndexReader, Map<Key, ValueIndex>>();
 
     /**
      * Private constructor.
@@ -147,7 +147,7 @@
     public ValueIndex getValueIndex(IndexReader reader,
                                     String field,
                                     String prefix,
-                                    SortComparator comparator)
+                                    SortComparatorSource comparator)
             throws IOException {
 
         if (reader instanceof ReadOnlyIndexReader) {
@@ -225,27 +225,27 @@
      * See if a <code>ValueIndex</code> object is in the cache.
      */
     ValueIndex lookup(IndexReader reader, String field,
-                                  String prefix, SortComparator comparer) {
+                      String prefix, SortComparatorSource comparer) {
         Key key = new Key(field, prefix, comparer);
         synchronized (this) {
-            HashMap readerCache = (HashMap) cache.get(reader);
+            Map<Key, ValueIndex> readerCache = cache.get(reader);
             if (readerCache == null) {
                 return null;
             }
-            return (ValueIndex) readerCache.get(key);
+            return readerCache.get(key);
         }
     }
 
     /**
      * Put a <code>ValueIndex</code> <code>value</code> to cache.
      */
-    Object store(IndexReader reader, String field, String prefix,
-                 SortComparator comparer, ValueIndex value) {
+    ValueIndex store(IndexReader reader, String field, String prefix,
+                 SortComparatorSource comparer, ValueIndex value) {
         Key key = new Key(field, prefix, comparer);
         synchronized (this) {
-            HashMap readerCache = (HashMap) cache.get(reader);
+            Map<Key, ValueIndex> readerCache = cache.get(reader);
             if (readerCache == null) {
-                readerCache = new HashMap();
+                readerCache = new HashMap<Key, ValueIndex>();
                 cache.put(reader, readerCache);
             }
             return readerCache.put(key, value);
@@ -263,13 +263,15 @@
     private Comparable getValue(String value, int type) {
         switch (type) {
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(Boolean.valueOf(value).booleanValue());
+                return Boolean.valueOf(value);
             case PropertyType.DATE:
-                return new Long(DateField.stringToTime(value));
+                return DateField.stringToTime(value);
             case PropertyType.LONG:
-                return new Long(LongField.stringToLong(value));
+                return LongField.stringToLong(value);
             case PropertyType.DOUBLE:
-                return new Double(DoubleField.stringToDouble(value));
+                return DoubleField.stringToDouble(value);
+            case PropertyType.DECIMAL:
+                return DecimalField.stringToDecimal(value);
             default:
                 return value;
         }
@@ -283,12 +285,12 @@
 
         private final String field;
         private final String prefix;
-        private final SortComparator comparator;
+        private final SortComparatorSource comparator;
 
         /**
          * Creates <code>Key</code> for ValueIndex lookup.
          */
-        Key(String field, String prefix, SortComparator comparator) {
+        Key(String field, String prefix, SortComparatorSource comparator) {
             this.field = field.intern();
             this.prefix = prefix.intern();
             this.comparator = comparator;

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SharedFieldSortComparator.java Wed Jul  8 13:57:13 2009
@@ -17,14 +17,11 @@
 package org.apache.jackrabbit.core.query.lucene;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.ScoreDoc;
 import org.apache.lucene.search.ScoreDocComparator;
 import org.apache.lucene.search.SortComparator;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.document.Document;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.PropertyState;
@@ -45,6 +42,8 @@
  */
 public class SharedFieldSortComparator extends SortComparator {
 
+    private static final long serialVersionUID = 2609351820466200052L;
+
     /**
      * The name of the shared field in the lucene index.
      */
@@ -124,104 +123,6 @@
     }
 
     /**
-     * Checks if <code>reader</code> is of type {@link MultiIndexReader} and if
-     * that's the case calls this method recursively for each reader within the
-     * multi index reader; otherwise the reader is simply added to the list.
-     *
-     * @param readers the list of index readers.
-     * @param reader  the reader to check.
-     */
-    private static void getIndexReaders(List readers, IndexReader reader) {
-        if (reader instanceof MultiIndexReader) {
-            IndexReader[] r = ((MultiIndexReader) reader).getIndexReaders();
-            for (int i = 0; i < r.length; i++) {
-                getIndexReaders(readers, r[i]);
-            }
-        } else {
-            readers.add(reader);
-        }
-    }
-
-    /**
-     * Abstract base class of {@link ScoreDocComparator} implementations.
-     */
-    abstract class AbstractScoreDocComparator implements ScoreDocComparator {
-
-        /**
-         * The index readers.
-         */
-        protected final List readers = new ArrayList();
-
-        /**
-         * The document number starts for the {@link #readers}.
-         */
-        protected final int[] starts;
-
-        public AbstractScoreDocComparator(IndexReader reader)
-                throws IOException {
-            getIndexReaders(readers, reader);
-
-            int maxDoc = 0;
-            this.starts = new int[readers.size() + 1];
-
-            for (int i = 0; i < readers.size(); i++) {
-                IndexReader r = (IndexReader) readers.get(i);
-                starts[i] = maxDoc;
-                maxDoc += r.maxDoc();
-            }
-            starts[readers.size()] = maxDoc;
-        }
-
-        /**
-         * Compares sort values of <code>i</code> and <code>j</code>. If the
-         * sort values have differing types, then the sort order is defined on
-         * the type itself by calling <code>compareTo()</code> on the respective
-         * type class names.
-         *
-         * @param i first score doc.
-         * @param j second score doc.
-         * @return a negative integer if <code>i</code> should come before
-         *         <code>j</code><br> a positive integer if <code>i</code>
-         *         should come after <code>j</code><br> <code>0</code> if they
-         *         are equal
-         */
-        public int compare(ScoreDoc i, ScoreDoc j) {
-            return Util.compare(sortValue(i), sortValue(j));
-        }
-
-        public int sortType() {
-            return SortField.CUSTOM;
-        }
-
-        /**
-         * Returns the reader index for document <code>n</code>.
-         *
-         * @param n document number.
-         * @return the reader index.
-         */
-        protected int readerIndex(int n) {
-            int lo = 0;
-            int hi = readers.size() - 1;
-
-            while (hi >= lo) {
-                int mid = (lo + hi) >> 1;
-                int midValue = starts[mid];
-                if (n < midValue) {
-                    hi = mid - 1;
-                } else if (n > midValue) {
-                    lo = mid + 1;
-                } else {
-                    while (mid + 1 < readers.size() && starts[mid + 1] == midValue) {
-                        mid++;
-                    }
-                    return mid;
-                }
-            }
-            return hi;
-        }
-    }
-
-    /**
      * A score doc comparator that works for order by clauses with properties
      * directly on the result nodes.
      */
@@ -240,7 +141,7 @@
 
             String namedValue = FieldNames.createNamedValue(propertyName, "");
             for (int i = 0; i < readers.size(); i++) {
-                IndexReader r = (IndexReader) readers.get(i);
+                IndexReader r = readers.get(i);
                 indexes[i] = SharedFieldCache.INSTANCE.getValueIndex(r, field,
                         namedValue, SharedFieldSortComparator.this);
             }
@@ -283,7 +184,7 @@
         public Comparable sortValue(ScoreDoc i) {
             try {
                 int idx = readerIndex(i.doc);
-                IndexReader reader = (IndexReader) readers.get(idx);
+                IndexReader reader = readers.get(idx);
                 Document doc = reader.document(i.doc - starts[idx], FieldSelectors.UUID);
                 String uuid = doc.get(FieldNames.UUID);
                 Path path = hmgr.getPath(new NodeId(UUID.fromString(uuid)));
@@ -330,8 +231,8 @@
          * {@inheritDoc}
          */
         public Comparable sortValue(ScoreDoc i) {
-            for (int j = 0; j < comparators.length; j++) {
-                Comparable c = comparators[j].sortValue(i);
+            for (ScoreDocComparator comparator : comparators) {
+                Comparable c = comparator.sortValue(i);
                 if (c != null) {
                     return c;
                 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleColumnQueryResult.java Wed Jul  8 13:57:13 2009
@@ -23,7 +23,7 @@
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.lucene.search.Query;
 
@@ -38,6 +38,16 @@
      */
     private final Query query;
 
+    /**
+     * 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;
+
     public SingleColumnQueryResult(SearchIndex index,
                                    ItemManager itemMgr,
                                    SessionImpl session,
@@ -45,15 +55,17 @@
                                    AbstractQueryImpl queryImpl,
                                    Query query,
                                    SpellSuggestion spellSuggestion,
-                                   Name[] selectProps,
+                                   ColumnImpl[] columns,
                                    Path[] orderProps,
                                    boolean[] orderSpecs,
                                    boolean documentOrder,
                                    long offset,
                                    long limit) throws RepositoryException {
         super(index, itemMgr, session, accessMgr, queryImpl, spellSuggestion,
-                selectProps, orderProps, orderSpecs, documentOrder, offset, limit);
+                columns, documentOrder, offset, limit);
         this.query = query;
+        this.orderProps = orderProps;
+        this.orderSpecs = orderSpecs;
         // if document order is requested get all results right away
         getResults(docOrder ? Integer.MAX_VALUE : index.getResultFetchSize());
     }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java Wed Jul  8 13:57:13 2009
@@ -80,7 +80,7 @@
     /**
      * The score nodes.
      */
-    private final List scoreNodes = new ArrayList();
+    private final List<ScoreNode> scoreNodes = new ArrayList<ScoreNode>();
 
     /**
      * The total number of hits.
@@ -136,7 +136,7 @@
             this.numHits = Math.max(this.numHits, hitIndex * 2);
             getHits();
         }
-        return (ScoreNode) scoreNodes.get(hitIndex);
+        return scoreNodes.get(hitIndex);
     }
 
     /**
@@ -161,7 +161,7 @@
             NodeId id = new NodeId(UUID.fromString(uuid));
             scoreNodes.add(new ScoreNode(id, docs[i].score, docs[i].doc));
         }
-        log.debug("getHits() {}/{}", new Integer(scoreNodes.size()), new Integer(numHits));
+        log.debug("getHits() {}/{}", scoreNodes.size(), numHits);
         // double hits for next round
         numHits *= 2;
     }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java Wed Jul  8 13:57:13 2009
@@ -25,9 +25,10 @@
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
-import java.util.Iterator;
 import java.util.regex.Pattern;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
@@ -51,8 +52,8 @@
      * @param old the document to dispose.
      */
     public static void disposeDocument(Document old) {
-        for (Iterator it = old.getFields().iterator(); it.hasNext(); ) {
-            Fieldable f = (Fieldable) it.next();
+        for (Object o : old.getFields()) {
+            Fieldable f = (Fieldable) o;
             try {
                 if (f.readerValue() != null) {
                     f.readerValue().close();
@@ -75,8 +76,8 @@
      *         otherwise.
      */
     public static boolean isDocumentReady(Document doc) {
-        for (Iterator it = doc.getFields().iterator(); it.hasNext(); ) {
-            Fieldable f = (Fieldable) it.next();
+        for (Object o : doc.getFields()) {
+            Fieldable f = (Fieldable) o;
             if (f instanceof LazyTextExtractorField) {
                 LazyTextExtractorField field = (LazyTextExtractorField) f;
                 if (!field.isExtractorFinished()) {
@@ -145,21 +146,24 @@
             case PropertyType.BINARY:
                 return null;
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(value.getBoolean());
+                return value.getBoolean();
             case PropertyType.DATE:
-                return new Long(value.getDate().getTimeInMillis());
+                return value.getDate().getTimeInMillis();
             case PropertyType.DOUBLE:
-                return new Double(value.getDouble());
+                return value.getDouble();
             case PropertyType.LONG:
-                return new Long(value.getLong());
+                return value.getLong();
+            case PropertyType.DECIMAL:
+                return value.getDecimal();
             case PropertyType.NAME:
                 return value.getName().toString();
             case PropertyType.PATH:
                 return value.getPath().toString();
+            case PropertyType.URI:
+            case PropertyType.WEAKREFERENCE:
             case PropertyType.REFERENCE:
             case PropertyType.STRING:
                 return value.getString();
-            // TODO: JSR 283 adds new property types
             default:
                 return null;
         }
@@ -180,19 +184,22 @@
             throws ValueFormatException, RepositoryException {
         switch (value.getType()) {
             case PropertyType.BOOLEAN:
-                return ComparableBoolean.valueOf(value.getBoolean());
+                return value.getBoolean();
             case PropertyType.DATE:
-                return new Long(value.getDate().getTimeInMillis());
+                return value.getDate().getTimeInMillis();
             case PropertyType.DOUBLE:
-                return new Double(value.getDouble());
+                return value.getDouble();
             case PropertyType.LONG:
-                return new Long(value.getLong());
+                return value.getLong();
+            case PropertyType.DECIMAL:
+                return value.getDecimal();
             case PropertyType.NAME:
             case PropertyType.PATH:
+            case PropertyType.URI:
+            case PropertyType.WEAKREFERENCE:
             case PropertyType.REFERENCE:
             case PropertyType.STRING:
                 return value.getString();
-                // TODO: JSR 283 now node types
             default:
                 throw new RepositoryException("Unsupported type: "
                         + PropertyType.nameFromValue(value.getType()));
@@ -252,24 +259,43 @@
         Comparable c2;
         switch (v1.getType()) {
             case PropertyType.BOOLEAN:
-                c2 = ComparableBoolean.valueOf(v2.getBoolean());
+                c2 = v2.getBoolean();
                 break;
             case PropertyType.DATE:
-                c2 = new Long(v2.getDate().getTimeInMillis());
+                c2 = v2.getDate().getTimeInMillis();
                 break;
             case PropertyType.DOUBLE:
-                c2 = new Double(v2.getDouble());
+                c2 = v2.getDouble();
                 break;
             case PropertyType.LONG:
-                c2 = new Long(v2.getLong());
+                c2 = v2.getLong();
+                break;
+            case PropertyType.DECIMAL:
+                c2 = v2.getDecimal();
                 break;
             case PropertyType.NAME:
+                if (v2.getType() == PropertyType.URI) {
+                    String s = v2.getString();
+                    if (s.startsWith("./")) {
+                        s = s.substring(2);
+                    }
+                    // need to decode
+                    try {
+                        c2 = URLDecoder.decode(s, "UTF-8");
+                    } catch (UnsupportedEncodingException e) {
+                        throw new RepositoryException(e);
+                    }
+                } else {
+                    c2 = v2.getString();
+                }
+                break;
             case PropertyType.PATH:
             case PropertyType.REFERENCE:
+            case PropertyType.WEAKREFERENCE:
+            case PropertyType.URI:
             case PropertyType.STRING:
                 c2 = v2.getString();
                 break;
-                // TODO: JSR 283 now node types
             default:
                 throw new RepositoryException("Unsupported type: "
                         + PropertyType.nameFromValue(v2.getType()));
@@ -335,15 +361,16 @@
      *         cannot be determined.
      */
     public static long getLength(InternalValue value) {
-        // TODO: support new JSR 283 property types
-        if (value.getType() == PropertyType.BINARY) {
-            return value.getBLOBFileValue().getLength();
-        } else
         if (value.getType() == PropertyType.NAME
                 || value.getType() == PropertyType.PATH) {
             return -1;
         } else {
-            return value.toString().length();
+            try {
+                return value.getLength();
+            } catch (RepositoryException e) {
+                log.warn("Unable to determine length of value.", e.getMessage());
+                return -1;
+            }
         }
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ComparisonConstraint.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ComparisonConstraint.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ComparisonConstraint.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ComparisonConstraint.java Wed Jul  8 13:57:13 2009
@@ -76,10 +76,10 @@
         if (sn == null) {
             return false;
         }
-        Value[] values = operand1.getValues(sn, context);
         try {
-            for (int i = 0; i < values.length; i++) {
-                if (evaluate(values[i])) {
+            Value[] values = operand1.getValues(sn, context);
+            for (Value value : values) {
+                if (evaluate(value)) {
                     return true;
                 }
             }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/ConstraintBuilder.java Wed Jul  8 13:57:13 2009
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
 import java.util.Map;
+import java.net.URLDecoder;
 
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
@@ -30,17 +31,12 @@
 import org.apache.jackrabbit.spi.commons.query.qom.AndImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.BindVariableValueImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.ChildNodeImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.ChildNodeJoinConditionImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.ComparisonImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.ConstraintImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.DescendantNodeImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.DescendantNodeJoinConditionImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.DynamicOperandImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.EquiJoinConditionImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.FullTextSearchImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.FullTextSearchScoreImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.JoinImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.LengthImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.LiteralImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.LowerCaseImpl;
@@ -49,16 +45,13 @@
 import org.apache.jackrabbit.spi.commons.query.qom.NotImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.Operator;
 import org.apache.jackrabbit.spi.commons.query.qom.OrImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.OrderingImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.PropertyExistenceImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.PropertyValueImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.QOMTreeVisitor;
-import org.apache.jackrabbit.spi.commons.query.qom.QueryObjectModelTree;
 import org.apache.jackrabbit.spi.commons.query.qom.SameNodeImpl;
-import org.apache.jackrabbit.spi.commons.query.qom.SameNodeJoinConditionImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.SelectorImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.StaticOperandImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.UpperCaseImpl;
+import org.apache.jackrabbit.spi.commons.query.qom.DefaultQOMTreeVisitor;
 
 /**
  * <code>ConstraintBuilder</code> builds a {@link Constraint} from a tree of
@@ -80,7 +73,7 @@
      *                             constraint.
      */
     public static Constraint create(ConstraintImpl constraint,
-                                    Map bindVariableValues,
+                                    Map<Name, Value> bindVariableValues,
                                     SelectorImpl[] selectors,
                                     LuceneQueryFactory factory,
                                     ValueFactory vf)
@@ -98,12 +91,12 @@
     /**
      * A QOM tree visitor that translates the contraints.
      */
-    private static final class Visitor implements QOMTreeVisitor {
+    private static final class Visitor extends DefaultQOMTreeVisitor {
 
         /**
          * The bind variables and their values.
          */
-        private final Map bindVariableValues;
+        private final Map<Name, Value> bindVariableValues;
 
         /**
          * The selectors of the query.
@@ -128,7 +121,7 @@
          * @param factory            the lucene query factory.
          * @param vf                 the value factory of the current session.
          */
-        Visitor(Map bindVariableValues,
+        Visitor(Map<Name, Value> bindVariableValues,
                 SelectorImpl[] selectors,
                 LuceneQueryFactory factory,
                 ValueFactory vf) {
@@ -155,17 +148,6 @@
                     getSelector(node.getSelectorQName()));
         }
 
-        public Object visit(ChildNodeJoinConditionImpl node, Object data)
-                throws Exception {
-            // not used
-            return null;
-        }
-
-        public Object visit(ColumnImpl node, Object data) throws Exception {
-            // not used
-            return null;
-        }
-
         public Object visit(ComparisonImpl node, Object data) throws Exception {
             DynamicOperandImpl op1 = (DynamicOperandImpl) node.getOperand1();
             Operator operator = node.getOperatorInstance();
@@ -188,18 +170,6 @@
                     getSelector(node.getSelectorQName()));
         }
 
-        public Object visit(DescendantNodeJoinConditionImpl node, Object data)
-                throws Exception {
-            // not used
-            return null;
-        }
-
-        public Object visit(EquiJoinConditionImpl node, Object data)
-                throws Exception {
-            // not used
-            return null;
-        }
-
         public Object visit(FullTextSearchImpl node, Object data)
                 throws Exception {
             return new FullTextConstraint(node,
@@ -208,13 +178,7 @@
 
         public Object visit(FullTextSearchScoreImpl node, Object data)
                 throws Exception {
-            // TODO
-            return null;
-        }
-
-        public Object visit(JoinImpl node, Object data) throws Exception {
-            // not used
-            return null;
+            return new FullTextSearchScoreOperand();
         }
 
         public Object visit(LengthImpl node, Object data) throws Exception {
@@ -236,7 +200,7 @@
 
         public Object visit(LowerCaseImpl node, Object data) throws Exception {
             DynamicOperandImpl operand = (DynamicOperandImpl) node.getOperand();
-            return new LowerCaseOperand((DynamicOperand) operand.accept(this, null));
+            return new LowerCaseOperand((DynamicOperand) operand.accept(this, data));
         }
 
         public Object visit(NodeLocalNameImpl node, Object data) throws Exception {
@@ -246,25 +210,35 @@
         public Object visit(NodeNameImpl node, Object data) throws Exception {
             Value staticValue = (Value) data;
             switch (staticValue.getType()) {
+                // STRING, PATH and URI may be convertable to a NAME -> check
                 case PropertyType.STRING:
                 case PropertyType.PATH:
+                case PropertyType.URI:
                     // make sure static value is valid NAME
                     try {
-                            vf.createValue(staticValue.getString(), PropertyType.NAME);
+                        String s = staticValue.getString();
+                        if (staticValue.getType() == PropertyType.URI) {
+                            if (s.startsWith("./")) {
+                                s = s.substring(2);
+                            }
+                            // need to decode
+                            s = URLDecoder.decode(s, "UTF-8");
+                        }
+                        vf.createValue(s, PropertyType.NAME);
                     } catch (ValueFormatException e) {
                             throw new InvalidQueryException("Value " +
                                 staticValue.getString() +
-                                " cannot be converted into STRING");
+                                " cannot be converted into NAME");
                     }
                     break;
+                // the following types cannot be converted to NAME
                 case PropertyType.DATE:
                 case PropertyType.DOUBLE:
-                    // TODO case PropertyType.DECIMAL:
+                case PropertyType.DECIMAL:
                 case PropertyType.LONG:
                 case PropertyType.BOOLEAN:
                 case PropertyType.REFERENCE:
-                // TODO case PropertyType.WEAKREFERENCE:
-                // TODO case PropertyType.URI
+                case PropertyType.WEAKREFERENCE:
                     throw new InvalidQueryException(staticValue.getString() +
                             " cannot be converted into a NAME value");
             }
@@ -277,11 +251,6 @@
             return new NotConstraint((Constraint) c.accept(this, null));
         }
 
-        public Object visit(OrderingImpl node, Object data) throws Exception {
-            // not used
-            return null;
-        }
-
         public Object visit(OrImpl node, Object data) throws Exception {
             ConstraintImpl left = (ConstraintImpl) node.getConstraint1();
             ConstraintImpl right = (ConstraintImpl) node.getConstraint2();
@@ -299,45 +268,23 @@
             return new PropertyValueOperand(node);
         }
 
-        public Object visit(QueryObjectModelTree node, Object data)
-                throws Exception {
-            // not used
-            return null;
-        }
-
         public Object visit(SameNodeImpl node, Object data) throws Exception {
             return new SameNodeConstraint(node,
                     getSelector(node.getSelectorQName()));
         }
 
-        public Object visit(SameNodeJoinConditionImpl node, Object data)
-                throws Exception {
-            // not used
-            return null;
-        }
-
-        public Object visit(SelectorImpl node, Object data) throws Exception {
-            // not used
-            return null;
-        }
-
         public Object visit(UpperCaseImpl node, Object data) throws Exception {
             DynamicOperandImpl operand = (DynamicOperandImpl) node.getOperand();
-            return new UpperCaseOperand((DynamicOperand) operand.accept(this, null));
+            return new UpperCaseOperand((DynamicOperand) operand.accept(this, data));
         }
 
         private SelectorImpl getSelector(Name name) {
-            if (name == null) {
-                // assume default selector
-                return selectors[0];
-            }
-            for (int i = 0; i < selectors.length; i++) {
-                if (selectors[i].getSelectorQName().equals(name)) {
-                    return selectors[i];
+            for (SelectorImpl selector : selectors) {
+                if (selector.getSelectorQName().equals(name)) {
+                    return selector;
                 }
             }
             return null;
         }
-
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DynamicOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DynamicOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DynamicOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/DynamicOperand.java Wed Jul  8 13:57:13 2009
@@ -16,9 +16,8 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.Value;
+import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
 
@@ -40,8 +39,8 @@
      * @param sn      the current score node.
      * @param context the evaluation context.
      * @return the values for the given score node.
-     * @throws IOException if an error occurs while retrieving the value.
+     * @throws RepositoryException if an error occurs while retrieving the value.
      */
     public abstract Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException;
+            throws RepositoryException;
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LengthOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LengthOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LengthOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LengthOperand.java Wed Jul  8 13:57:13 2009
@@ -16,16 +16,16 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.Value;
-import javax.jcr.ValueFactory;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
 import org.apache.jackrabbit.core.query.lucene.Util;
 import org.apache.jackrabbit.core.state.PropertyState;
 import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.value.ValueFactoryImpl;
+import org.apache.jackrabbit.spi.QValueFactory;
 
 /**
  * <code>LengthOperand</code> implements a length operand.
@@ -51,22 +51,28 @@
      * {@inheritDoc}
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
+            throws RepositoryException {
         PropertyState ps = property.getPropertyState(sn, context);
         if (ps == null) {
             return EMPTY;
         } else {
-            try {
-                ValueFactory vf = context.getSession().getValueFactory();
-                InternalValue[] values = ps.getValues();
-                Value[] lengths = new Value[values.length];
-                for (int i = 0; i < lengths.length; i++) {
-                    lengths[i] = vf.createValue(Util.getLength(values[i]));
+            ValueFactoryImpl vf = (ValueFactoryImpl) context.getSession().getValueFactory();
+            QValueFactory qvf = vf.getQValueFactory();
+            InternalValue[] values = ps.getValues();
+            Value[] lengths = new Value[values.length];
+            for (int i = 0; i < lengths.length; i++) {
+                long len;
+                int type = values[i].getType();
+                if (type == PropertyType.NAME) {
+                    len = vf.createValue(qvf.create(values[i].getName())).getString().length();
+                } else if (type == PropertyType.PATH) {
+                    len = vf.createValue(qvf.create(values[i].getPath())).getString().length();
+                } else {
+                    len = Util.getLength(values[i]);
                 }
-                return lengths;
-            } catch (RepositoryException e) {
-                throw Util.createIOException(e);
+                lengths[i] = vf.createValue(len);
             }
+            return lengths;
         }
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LowerCaseOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LowerCaseOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LowerCaseOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/LowerCaseOperand.java Wed Jul  8 13:57:13 2009
@@ -16,14 +16,11 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
-import org.apache.jackrabbit.core.query.lucene.Util;
 
 /**
  * <code>LowerCaseOperand</code> implements a lower case operand.
@@ -49,16 +46,12 @@
      * {@inheritDoc}
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
-        try {
-            ValueFactory vf = context.getSession().getValueFactory();
-            Value[] values = operand.getValues(sn, context);
-            for (int i = 0; i < values.length; i++) {
-                values[i] = vf.createValue(values[i].getString().toLowerCase());
-            }
-            return values;
-        } catch (RepositoryException e) {
-            throw Util.createIOException(e);
+            throws RepositoryException {
+        ValueFactory vf = context.getSession().getValueFactory();
+        Value[] values = operand.getValues(sn, context);
+        for (int i = 0; i < values.length; i++) {
+            values[i] = vf.createValue(values[i].getString().toLowerCase());
         }
+        return values;
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeLocalNameOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeLocalNameOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeLocalNameOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeLocalNameOperand.java Wed Jul  8 13:57:13 2009
@@ -16,13 +16,10 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
-import org.apache.jackrabbit.core.query.lucene.Util;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.util.Text;
 
@@ -38,17 +35,14 @@
      * @param sn      the score node.
      * @param context the evaluation context.
      * @return the local node name.
-     * @throws IOException if an error occurs while reading the local name.
+     * @throws RepositoryException if an error occurs while reading the local
+     *                             name.
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
-        try {
-            SessionImpl session = context.getSession();
-            String name = session.getNodeById(sn.getNodeId()).getName();
-            return new Value[]{session.getValueFactory().createValue(
-                    Text.getLocalName(name))};
-        } catch (RepositoryException e) {
-            throw Util.createIOException(e);
-        }
+            throws RepositoryException {
+        SessionImpl session = context.getSession();
+        String name = session.getNodeById(sn.getNodeId()).getName();
+        return new Value[]{session.getValueFactory().createValue(
+                Text.getLocalName(name))};
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeNameOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeNameOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeNameOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/NodeNameOperand.java Wed Jul  8 13:57:13 2009
@@ -16,13 +16,11 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.PropertyType;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
-import org.apache.jackrabbit.core.query.lucene.Util;
 import org.apache.jackrabbit.core.SessionImpl;
 
 /**
@@ -37,16 +35,12 @@
      * @param sn      the score node.
      * @param context the evaluation context.
      * @return the node name.
-     * @throws IOException if an error occurs while reading the name.
+     * @throws RepositoryException if an error occurs while reading the name.
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
-        try {
-            SessionImpl session = context.getSession();
-            String name = session.getNodeById(sn.getNodeId()).getName();
-            return new Value[]{session.getValueFactory().createValue(name)};
-        } catch (RepositoryException e) {
-            throw Util.createIOException(e);
-        }
+            throws RepositoryException {
+        SessionImpl session = context.getSession();
+        String name = session.getNodeById(sn.getNodeId()).getName();
+        return new Value[]{session.getValueFactory().createValue(name, PropertyType.NAME)};
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyValueOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyValueOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyValueOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/PropertyValueOperand.java Wed Jul  8 13:57:13 2009
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.Value;
 import javax.jcr.Property;
 import javax.jcr.Node;
@@ -26,7 +24,6 @@
 
 import org.apache.jackrabbit.spi.commons.query.qom.PropertyValueImpl;
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
-import org.apache.jackrabbit.core.query.lucene.Util;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.PropertyState;
 import org.apache.jackrabbit.core.state.ItemStateException;
@@ -61,11 +58,11 @@
      * @param sn the current score node.
      * @param context the evaluation context.
      * @return the property state or <code>null</code>.
-     * @throws IOException if an error occurs while reading.
+     * @throws RepositoryException if an error occurs while reading.
      */
     public final PropertyState getPropertyState(ScoreNode sn,
-                                          EvaluationContext context)
-            throws IOException {
+                                                EvaluationContext context)
+            throws RepositoryException {
         ItemStateManager ism = context.getItemStateManager();
         PropertyId propId = new PropertyId(sn.getNodeId(), operand.getPropertyQName());
         try {
@@ -73,7 +70,7 @@
         } catch (NoSuchItemStateException e) {
             return null;
         } catch (ItemStateException e) {
-            throw Util.createIOException(e);
+            throw new RepositoryException(e);
         }
     }
 
@@ -84,19 +81,17 @@
      * @param sn the current score node.
      * @param context the evaluation context.
      * @return the property or <code>null</code>.
-     * @throws IOException if an error occurs while reading.
+     * @throws RepositoryException if an error occurs while reading.
      */
     public final Property getProperty(ScoreNode sn,
                                       EvaluationContext context)
-            throws IOException {
+            throws RepositoryException {
         SessionImpl session = context.getSession();
         try {
             Node n = session.getNodeById(sn.getNodeId());
             return n.getProperty(operand.getPropertyName());
         } catch (PathNotFoundException e) {
             return null;
-        } catch (RepositoryException e) {
-            throw Util.createIOException(e);
         }
     }
 
@@ -104,19 +99,15 @@
      * {@inheritDoc}
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
+            throws RepositoryException {
         Property prop = getProperty(sn, context);
         if (prop == null) {
             return EMPTY;
         } else {
-            try {
-                if (prop.getDefinition().isMultiple()) {
-                    return prop.getValues();
-                } else {
-                    return new Value[]{prop.getValue()};
-                }
-            } catch (RepositoryException e) {
-                throw Util.createIOException(e);
+            if (prop.getDefinition().isMultiple()) {
+                return prop.getValues();
+            } else {
+                return new Value[]{prop.getValue()};
             }
         }
     }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/QueryConstraint.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/QueryConstraint.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/QueryConstraint.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/QueryConstraint.java Wed Jul  8 13:57:13 2009
@@ -17,7 +17,8 @@
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
 import java.io.IOException;
-import java.util.BitSet;
+import java.util.Map;
+import java.util.HashMap;
 
 import javax.jcr.RepositoryException;
 
@@ -49,9 +50,10 @@
     private final LuceneQueryFactory factory;
 
     /**
-     * The bitset with the matching document numbers.
+     * Map of document numbers with their respective score value that match the
+     * query constraint.
      */
-    private BitSet matches;
+    private Map<Integer, Float> matches;
 
     /**
      * Creates a new query constraint using the given lucene query.
@@ -95,7 +97,11 @@
     private boolean evaluate(ScoreNode sn, EvaluationContext context)
             throws IOException {
         initMatches(context);
-        return matches.get(sn.getDoc(context.getIndexReader()));
+        Float score = matches.get(sn.getDoc(context.getIndexReader()));
+        if (score != null) {
+            sn.setScore(score);
+        }
+        return score != null;
     }
 
     /**
@@ -120,10 +126,10 @@
             IndexReader reader = context.getIndexReader();
             QueryHits hits = context.evaluate(and);
             try {
-                matches = new BitSet();
+                matches = new HashMap<Integer, Float>();
                 ScoreNode sn;
                 while ((sn = hits.nextScoreNode()) != null) {
-                    matches.set(sn.getDoc(reader));
+                    matches.put(sn.getDoc(reader), sn.getScore());
                 }
             } finally {
                 hits.close();

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/UpperCaseOperand.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/UpperCaseOperand.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/UpperCaseOperand.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/constraint/UpperCaseOperand.java Wed Jul  8 13:57:13 2009
@@ -16,14 +16,11 @@
  */
 package org.apache.jackrabbit.core.query.lucene.constraint;
 
-import java.io.IOException;
-
 import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.query.lucene.ScoreNode;
-import org.apache.jackrabbit.core.query.lucene.Util;
 
 /**
  * <code>UpperCaseOperand</code> implements an upper case operand.
@@ -49,16 +46,12 @@
      * {@inheritDoc}
      */
     public Value[] getValues(ScoreNode sn, EvaluationContext context)
-            throws IOException {
-        try {
-            ValueFactory vf = context.getSession().getValueFactory();
-            Value[] values = operand.getValues(sn, context);
-            for (int i = 0; i < values.length; i++) {
-                values[i] = vf.createValue(values[i].getString().toUpperCase());
-            }
-            return values;
-        } catch (RepositoryException e) {
-            throw Util.createIOException(e);
+            throws RepositoryException {
+        ValueFactory vf = context.getSession().getValueFactory();
+        Value[] values = operand.getValues(sn, context);
+        for (int i = 0; i < values.length; i++) {
+            values[i] = vf.createValue(values[i].getString().toUpperCase());
         }
+        return values;
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java Wed Jul  8 13:57:13 2009
@@ -90,9 +90,8 @@
             return true;
         }
         // delete files first
-        File[] files = directory.listFiles();
-        for (int i = 0; i < files.length; i++) {
-            if (!files[i].delete()) {
+        for (File file : directory.listFiles()) {
+            if (!file.delete()) {
                 return false;
             }
         }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/RAMDirectoryManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/RAMDirectoryManager.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/RAMDirectoryManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/RAMDirectoryManager.java Wed Jul  8 13:57:13 2009
@@ -33,7 +33,7 @@
     /**
      * Map of directories. Key=String(directory name), Value=Directory.
      */
-    private final Map directories = new HashMap();
+    private final Map<String, Directory> directories = new HashMap<String, Directory>();
 
     /**
      * {@inheritDoc}
@@ -55,7 +55,7 @@
      */
     public Directory getDirectory(String name) {
         synchronized (directories) {
-            Directory dir = (Directory) directories.get(name);
+            Directory dir = directories.get(name);
             if (dir == null) {
                 dir = new RAMDirectory();
                 directories.put(name, dir);
@@ -69,7 +69,7 @@
      */
     public String[] getDirectoryNames() throws IOException {
         synchronized (directories) {
-            return (String[]) directories.keySet().toArray(
+            return directories.keySet().toArray(
                     new String[directories.size()]);
         }
     }
@@ -92,7 +92,7 @@
             if (directories.containsKey(to)) {
                 return false;
             }
-            Directory dir = (Directory) directories.remove(from);
+            Directory dir = directories.remove(from);
             if (dir == null) {
                 return false;
             }



Mime
View raw message