jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r792142 [34/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-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QueryInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QueryInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QueryInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/QueryInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -16,33 +16,22 @@
  */
 package org.apache.jackrabbit.spi2dav;
 
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.jcr.RepositoryException;
 import javax.jcr.ValueFactory;
-import javax.jcr.Value;
 import javax.jcr.RangeIterator;
 
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.QueryInfo;
-import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.QueryResultRow;
-import org.apache.jackrabbit.spi.QValue;
-import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.IdFactory;
 import org.apache.jackrabbit.util.ISO9075;
-import org.apache.jackrabbit.webdav.DavServletResponse;
 import org.apache.jackrabbit.webdav.MultiStatus;
 import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.jcr.search.SearchResultProperty;
-import org.apache.jackrabbit.webdav.property.DavProperty;
-import org.apache.jackrabbit.webdav.property.DavPropertySet;
-import org.apache.jackrabbit.spi.commons.value.ValueFormat;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,13 +45,11 @@
      */
     private static final Logger log = LoggerFactory.getLogger(QueryInfoImpl.class);
 
-    private static final double UNDEFINED_SCORE = -1;
+    private final String[] columnNames;
 
-    private final Name[] columnNames;
-    private int scoreIndex = -1;
-    private final Map results = new LinkedHashMap();
+    private final List<QueryResultRow> results = new ArrayList<QueryResultRow>();
 
-    public QueryInfoImpl(MultiStatus ms, SessionInfo sessionInfo, URIResolver uriResolver,
+    public QueryInfoImpl(MultiStatus ms, IdFactory idFactory,
                          NamePathResolver resolver, ValueFactory valueFactory,
                          QValueFactory qValueFactory)
         throws RepositoryException {
@@ -70,43 +57,17 @@
         String responseDescription = ms.getResponseDescription();
         if (responseDescription != null) {
             String[] cn = responseDescription.split(" ");
-            this.columnNames = new Name[cn.length];
+            this.columnNames = new String[cn.length];
             for (int i = 0; i < cn.length; i++) {
-                String jcrColumnNames = ISO9075.decode(cn[i]);
-                try {
-                    columnNames[i] = resolver.getQName(jcrColumnNames);
-                    if (NameConstants.JCR_SCORE.equals(columnNames[i])) {
-                        scoreIndex = i;
-                    }
-                } catch (NameException e) {
-                    throw new RepositoryException(e);
-                }
+                columnNames[i] = ISO9075.decode(cn[i]);
             }
         } else {
             throw new RepositoryException("Missing column infos: Unable to build QueryInfo object.");
         }
 
-        MultiStatusResponse[] responses = ms.getResponses();
-        for (int i = 0; i < responses.length; i++) {
-            MultiStatusResponse response = responses[i];
-            String href = response.getHref();
-            DavPropertySet okSet = response.getProperties(DavServletResponse.SC_OK);
-
-            DavProperty davProp = okSet.get(SearchResultProperty.SEARCH_RESULT_PROPERTY);
-            SearchResultProperty resultProp = new SearchResultProperty(davProp, valueFactory);
-            Value[] values = resultProp.getValues();
-            QValue[] qValues = new QValue[values.length];
-            for (int j = 0; j < values.length; j++) {
-                try {
-                    qValues[j] = (values[j] == null) ?  null : ValueFormat.getQValue(values[j], resolver, qValueFactory);
-                } catch (RepositoryException e) {
-                    // should not occur
-                    log.error("Malformed value: " + values[j].toString());
-                }
-            }
-
-            NodeId nodeId = uriResolver.getNodeId(href, sessionInfo);
-            results.put(nodeId, qValues);
+        for (MultiStatusResponse response : ms.getResponses()) {
+            results.add(new QueryResultRowImpl(response, columnNames, resolver,
+                    qValueFactory, valueFactory, idFactory));
         }
     }
 
@@ -114,112 +75,15 @@
      * @see QueryInfo#getRows()
      */
     public RangeIterator getRows() {
-        return new QueryResultRowIterator();
+        return new RangeIteratorAdapter(results);
     }
 
     /**
      * @see QueryInfo#getColumnNames()
      */
-    public Name[] getColumnNames() {
-        return columnNames;
-    }
-
-    //--------------------------------------------------------< inner class >---
-    /**
-     * Inner class implementing the <code>RangeIterator</code> for the query
-     * result rows. 
-     */
-    private class QueryResultRowIterator implements RangeIterator {
-
-        private final Iterator keyIterator;
-        private long pos = 0;
-
-        private QueryResultRowIterator() {
-            keyIterator = results.keySet().iterator();
-        }
-
-        private QueryResultRow nextQueryResultRow() {
-            final NodeId nId = (NodeId) keyIterator.next();
-            final QValue[] qValues = (QValue[]) results.get(nId);
-            pos++;
-
-            return new QueryResultRow() {
-                /**
-                 * @see QueryResultRow#getNodeId()
-                 */
-                public NodeId getNodeId() {
-                    return nId;
-                }
-
-                /**
-                 * @see QueryResultRow#getScore()
-                 */
-                public double getScore() {
-                    if (scoreIndex != -1 && qValues[scoreIndex] != null) {
-                        try {
-                            return Double.parseDouble(qValues[scoreIndex].getString());
-                        } catch (RepositoryException e) {
-                            log.error("Error while building query score", e);
-                        }   return UNDEFINED_SCORE;
-                    } else {
-                        log.error("Cannot determined jcr:score from query results.");
-                        return UNDEFINED_SCORE;
-                    }
-                }
-
-                /**
-                 * @see QueryResultRow#getValues()
-                 */
-                public QValue[] getValues() {
-                    return qValues;
-                }
-            };
-        }
-
-        //--------------------------------------------------< RangeIterator >---
-        /**
-         * @see RangeIterator#skip(long)
-         */
-        public void skip(long skipNum) {
-            while (skipNum-- > 0) {
-                nextQueryResultRow();
-            }
-        }
-
-        /**
-         * @see RangeIterator#getSize()
-         */
-        public long getSize() {
-            return results.size();
-        }
-
-        /**
-         * @see RangeIterator#getPosition()
-         */
-        public long getPosition() {
-            return pos;
-        }
-
-        //-------------------------------------------------------< Iterator >---
-        /**
-         * @see Iterator#remove()
-         */
-        public void remove() {
-            throw new UnsupportedOperationException("Remove not implemented");
-        }
-
-        /**
-         * @see Iterator#hasNext()
-         */
-        public boolean hasNext() {
-            return keyIterator.hasNext();
-        }
-
-        /**
-         * @see Iterator#next()
-         */
-        public Object next() {
-            return nextQueryResultRow();
-        }
+    public String[] getColumnNames() {
+        String[] names = new String[columnNames.length];
+        System.arraycopy(columnNames, 0, names, 0, columnNames.length);
+        return names;
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Wed Jul  8 13:57:13 2009
@@ -201,13 +201,15 @@
 
     private static Logger log = LoggerFactory.getLogger(RepositoryServiceImpl.class);
 
-    private static final EventType[] ALL_EVENTS = new EventType[5];
+    private static final EventType[] ALL_EVENTS = new EventType[7];
     static {
         ALL_EVENTS[0] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.NODE_ADDED);
         ALL_EVENTS[1] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.NODE_REMOVED);
         ALL_EVENTS[2] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_ADDED);
         ALL_EVENTS[3] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_CHANGED);
         ALL_EVENTS[4] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PROPERTY_REMOVED);
+        ALL_EVENTS[5] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.NODE_MOVED);
+        ALL_EVENTS[6] = SubscriptionImpl.getEventType(javax.jcr.observation.Event.PERSIST);
     }
     private static final SubscriptionInfo S_INFO = new SubscriptionInfo(ALL_EVENTS, true, INFINITE_TIMEOUT);
 
@@ -345,7 +347,11 @@
 
     protected NamePathResolver getNamePathResolver(SessionInfo sessionInfo) throws RepositoryException {
         checkSessionInfo(sessionInfo);
-        NamePathResolver resolver = ((SessionInfoImpl) sessionInfo).getNamePathResolver();
+        return getNamePathResolver(((SessionInfoImpl) sessionInfo));
+    }
+
+    private NamePathResolver getNamePathResolver(SessionInfoImpl sessionInfo) {
+        NamePathResolver resolver = sessionInfo.getNamePathResolver();
         if (resolver == null) {
             resolver = new NamePathResolverImpl(sessionInfo);
             ((SessionInfoImpl) sessionInfo).setNamePathResolver(resolver);
@@ -985,6 +991,68 @@
     }
 
     /**
+     * @see RepositoryService#getReferences(SessionInfo, NodeId, Name, boolean)
+     */
+    public Iterator<PropertyId> getReferences(SessionInfo sessionInfo, NodeId nodeId, Name propertyName, boolean weakReferences) throws ItemNotFoundException, RepositoryException {
+        // set of properties to be retrieved
+        DavPropertyNameSet nameSet = new DavPropertyNameSet();
+        if (weakReferences) {
+            nameSet.add(ItemResourceConstants.JCR_WEAK_REFERENCES);
+        } else {
+            nameSet.add(ItemResourceConstants.JCR_REFERENCES);
+        }
+
+        DavMethodBase method = null;
+        try {
+            String uri = getItemUri(nodeId, sessionInfo);
+            method = new PropFindMethod(uri, nameSet, DEPTH_0);
+            getClient(sessionInfo).executeMethod(method);
+            method.checkSuccess();
+
+            MultiStatusResponse[] responses = method.getResponseBodyAsMultiStatus().getResponses();
+            if (responses.length < 1) {
+                throw new ItemNotFoundException("Unable to retrieve the node with id " + saveGetIdString(nodeId, sessionInfo));
+            }
+
+            List<PropertyId> refIds = new ArrayList<PropertyId>();
+            for (int i = 0; i < responses.length; i++) {
+                if (isSameResource(uri, responses[i])) {
+                    MultiStatusResponse resp = responses[i];
+                    DavPropertySet props = resp.getProperties(DavServletResponse.SC_OK);
+                    DavProperty p;
+                    if (weakReferences) {
+                        p = props.get(ItemResourceConstants.JCR_WEAK_REFERENCES);
+                    } else {
+                        p = props.get(ItemResourceConstants.JCR_REFERENCES);
+                    }
+
+                    if (p == null) {
+                        return Collections.EMPTY_LIST.iterator();
+                    } else {
+                        HrefProperty hp = new HrefProperty(p);
+                        for (Iterator it = hp.getHrefs().iterator(); it.hasNext();) {
+                            String propHref = it.next().toString();
+                            PropertyId propId = uriResolver.getPropertyId(propHref, sessionInfo);
+                            if (propertyName == null || propertyName.equals(propId.getName())) {
+                                refIds.add(propId);
+                            }
+                        }
+                    }
+                }
+            }
+            return refIds.iterator();
+        } catch (IOException e) {
+            throw new RepositoryException(e);
+        } catch (DavException e) {
+            throw ExceptionConverter.generate(e);
+        } finally {
+            if (method != null) {
+                method.releaseConnection();
+            }
+        }
+    }
+
+    /**
      * @see RepositoryService#getPropertyInfo(SessionInfo, PropertyId)
      */
     public PropertyInfo getPropertyInfo(SessionInfo sessionInfo, PropertyId propertyId) throws RepositoryException {
@@ -1547,6 +1615,38 @@
     }
 
     /**
+     * @see RepositoryService#createActivity(SessionInfo, String)
+     */
+    public NodeId createActivity(SessionInfo sessionInfo, String title) throws UnsupportedRepositoryOperationException, RepositoryException {
+        // TODO
+        throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+    }
+
+    /**
+     * @see RepositoryService#removeActivity(SessionInfo, NodeId)
+     */
+    public void removeActivity(SessionInfo sessionInfo, NodeId activityId) throws UnsupportedRepositoryOperationException, RepositoryException {
+        // TODO
+        throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+    }
+
+    /**
+     * @see RepositoryService#mergeActivity(SessionInfo, NodeId)
+     */
+    public Iterator mergeActivity(SessionInfo sessionInfo, NodeId activityId) throws UnsupportedRepositoryOperationException, RepositoryException {
+        // TODO
+        throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+    }
+
+    /**
+     * @see RepositoryService#createConfiguration(SessionInfo, NodeId, NodeId)
+     */
+    public NodeId createConfiguration(SessionInfo sessionInfo, NodeId nodeId, NodeId baselineId) throws UnsupportedRepositoryOperationException, RepositoryException {
+        // TODO
+        throw new UnsupportedOperationException("JCR-2104: JSR 283 Versioning. Implementation missing");
+    }
+
+    /**
      * @see RepositoryService#getSupportedQueryLanguages(SessionInfo)
      */
     public String[] getSupportedQueryLanguages(SessionInfo sessionInfo) throws RepositoryException {
@@ -1567,30 +1667,43 @@
         }
     }
 
-    public void checkQueryStatement(SessionInfo sessionInfo,
+    public String[] checkQueryStatement(SessionInfo sessionInfo,
                                     String statement,
                                     String language,
                                     Map namespaces)
             throws InvalidQueryException, RepositoryException {
         // TODO implement
+        return new String[0];
     }
 
     /**
-     * @see RepositoryService#executeQuery(SessionInfo, String, String, Map)
+     * @see RepositoryService#executeQuery(SessionInfo, String, String,java.util.Map,long,long,java.util.Map
      */
-    public QueryInfo executeQuery(SessionInfo sessionInfo, String statement, String language, Map namespaces) throws RepositoryException {
+    public QueryInfo executeQuery(SessionInfo sessionInfo, String statement, String language, Map<String, String> namespaces, long limit, long offset, Map<String, QValue> values) throws RepositoryException {
         SearchMethod method = null;
         try {
             String uri = uriResolver.getWorkspaceUri(sessionInfo.getWorkspaceName());
             SearchInfo sInfo = new SearchInfo(language,
                     Namespace.EMPTY_NAMESPACE, statement, namespaces);
+
+            if (limit != -1) {
+                sInfo.setNumberResults(limit);
+            }
+            if (offset != -1) {
+                sInfo.setOffset(offset);
+            }
+
+            if (!(values == null || values.isEmpty())) {
+                throw new UnsupportedOperationException("Implementation missing:  JCR-2107");
+            }
+
             method = new SearchMethod(uri, sInfo);
             getClient(sessionInfo).executeMethod(method);
             method.checkSuccess();
 
             MultiStatus ms = method.getResponseBodyAsMultiStatus();
             NamePathResolver resolver = getNamePathResolver(sessionInfo);
-            return new QueryInfoImpl(ms, sessionInfo, uriResolver, resolver, valueFactory, getQValueFactory());
+            return new QueryInfoImpl(ms, idFactory, resolver, valueFactory, getQValueFactory());
         } catch (IOException e) {
             throw new RepositoryException(e);
         } catch (DavException e) {
@@ -1647,6 +1760,16 @@
     }
 
     /**
+     * @see RepositoryService#getEvents(SessionInfo, EventFilter,long) 
+     */
+    public EventBundle getEvents(SessionInfo sessionInfo, EventFilter filter,
+                                   long after) throws
+            RepositoryException, UnsupportedRepositoryOperationException {
+        // TODO
+        throw new UnsupportedRepositoryOperationException();
+    }
+
+    /**
      * @see RepositoryService#createSubscription(SessionInfo, EventFilter[])
      */
     public Subscription createSubscription(SessionInfo sessionInfo,
@@ -1784,7 +1907,7 @@
         }
     }
 
-    private List buildEventList(Element bundleElement, SessionInfo sessionInfo) {
+    private List buildEventList(Element bundleElement, SessionInfoImpl sessionInfo) {
         List events = new ArrayList();
         ElementIterator eventElementIterator = DomUtil.getChildren(bundleElement, ObservationConstants.XML_EVENT, ObservationConstants.NAMESPACE);
         while (eventElementIterator.hasNext()) {
@@ -1832,7 +1955,8 @@
                 log.warn("Unable to build event parentId: ", e.getMessage());
             }
 
-            events.add(new EventImpl(eventId, eventPath, parentId, type, evElem));
+
+            events.add(new EventImpl(eventId, eventPath, parentId, type, evElem, getNamePathResolver(sessionInfo), getQValueFactory()));
         }
 
         return events;
@@ -2286,7 +2410,7 @@
             } else {
                 // TODO: use multipart-POST instead of ValuesProperty
                 DavPropertySet setProperties = new DavPropertySet();
-                // qualified values must be converted to jcr values
+                // SPI values must be converted to jcr values
                 Value[] jcrValues = new Value[values.length];
                 for (int i = 0; i < values.length; i++) {
                     jcrValues[i] = ValueFormat.getJCRValue(values[i], resolver, valueFactory);
@@ -2303,7 +2427,7 @@
         }
 
         private RequestEntity getEntity(QValue value) throws RepositoryException {
-            // qualified value must be converted to jcr value
+            // SPI value must be converted to jcr value
             InputStream in;
             int type = value.getType();
             String contentType = JcrValueType.contentTypeFromType(type);
@@ -2312,15 +2436,15 @@
                 switch (type) {
                     case PropertyType.NAME:
                     case PropertyType.PATH:
-                        Value v = ValueFormat.getJCRValue(value, resolver, valueFactory);
-                        ent = new StringRequestEntity(v.getString(), contentType, "UTF-8");
+                        String str = ValueFormat.getJCRString(value, resolver);
+                        ent = new StringRequestEntity(str, contentType, "UTF-8");
                         break;
                     case PropertyType.BINARY:
                         in = value.getStream();
                         ent = new InputStreamRequestEntity(in, contentType);
                         break;
                     default:
-                        String str = value.getString();
+                        str = value.getString();
                         ent = new StringRequestEntity(str, contentType, "UTF-8");
                         break;
                 }
@@ -2400,6 +2524,24 @@
         }
 
         /**
+         * @see Batch#setPrimaryType(NodeId, Name)
+         */
+        public void setPrimaryType(NodeId nodeId, Name primaryNodeTypeName) throws RepositoryException {
+            checkConsumed();
+            try {
+                DavPropertySet setProperties = new DavPropertySet();
+                setProperties.add(new NodeTypeProperty(ItemResourceConstants.JCR_PRIMARYNODETYPE, new String[] {resolver.getJCRName(primaryNodeTypeName)}, false));
+
+                String uri = getItemUri(nodeId, sessionInfo);
+                PropPatchMethod method = new PropPatchMethod(uri, setProperties, new DavPropertyNameSet());
+
+                methods.add(method);
+            } catch (IOException e) {
+                throw new RepositoryException(e);
+            }
+        }
+
+        /**
          * @see Batch#move(NodeId, NodeId, Name)
          */
         public void move(NodeId srcNodeId, NodeId destParentNodeId, Name destName) throws RepositoryException {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -16,20 +16,18 @@
  */
 package org.apache.jackrabbit.spi2dav;
 
-import org.apache.jackrabbit.spi.SessionInfo;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Arrays;
 
 /**
  * <code>SessionInfoImpl</code>...
  */
-public class SessionInfoImpl implements SessionInfo {
+public class SessionInfoImpl extends org.apache.jackrabbit.spi.commons.SessionInfoImpl {
 
     private final CredentialsWrapper credentials;
-    private final String workspaceName;
-    private final Set lockTokens = new HashSet();
     private final Set sessionScopedTokens = new HashSet();
 
     private String lastBatchId;
@@ -37,7 +35,8 @@
 
     SessionInfoImpl(CredentialsWrapper creds, String workspaceName) {
         this.credentials = creds;
-        this.workspaceName = workspaceName;
+
+        super.setWorkspacename(workspaceName);
     }
 
     //--------------------------------------------------------< SessionInfo >---
@@ -48,34 +47,6 @@
         return credentials.getUserId();
     }
 
-    /**
-     * @inheritDoc
-     */
-    public String getWorkspaceName() {
-        return workspaceName;
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public String[] getLockTokens() {
-        return (String[]) lockTokens.toArray(new String[lockTokens.size()]);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public void addLockToken(String lockToken) {
-        lockTokens.add(lockToken);
-    }
-
-    /**
-     * @inheritDoc
-     */
-    public void removeLockToken(String lockToken) {
-        lockTokens.remove(lockToken);
-    }
-
     //--------------------------------------------------------------------------
 
     CredentialsWrapper getCredentials() {
@@ -119,7 +90,7 @@
      * JCR API for they belong to session-scoped locks.
      */
     String[] getAllLockTokens() {
-        Set s = new HashSet(lockTokens);
+        Set s = new HashSet(Arrays.asList(getLockTokens()));
         s.addAll(sessionScopedTokens);
         return (String[]) s.toArray(new String[s.size()]);
     }
@@ -128,7 +99,7 @@
         if (sessionScoped) {
             sessionScopedTokens.add(token);
         } else {
-            lockTokens.add(token);
+            super.addLockToken(token);
         }
     }
 
@@ -136,7 +107,7 @@
         if (sessionScoped) {
             sessionScopedTokens.remove(token);
         } else {
-            lockTokens.remove(token);
+            super.removeLockToken(token);
         }
     }
 }
\ No newline at end of file

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/ItemInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -40,8 +40,7 @@
     private final boolean isNode;
 
     /**
-     * Creates a new serializable item info for the given qualified
-     * <code>item</code> info.
+     * Creates a new <code>ItemInfo</code>.
      *
      * @param path     the path to this item.
      * @param isNode   if this item is a node.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/NodeInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -55,8 +55,7 @@
     private int numberOfChildNodes = -1;
 
     /**
-     * Creates a new serializable item info for the given qualified
-     * <code>item</code> info.
+     * Creates a new <code>NodeInfo</code>.
      *
      * @param id The node id.
      * @param path the path to this item.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java Wed Jul  8 13:57:13 2009
@@ -23,9 +23,9 @@
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.value.AbstractQValueFactory;
 import org.apache.jackrabbit.spi.commons.value.AbstractQValue;
+import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.util.ISO8601;
 import org.apache.jackrabbit.util.TransientFileFactory;
-import org.apache.jackrabbit.value.ValueFactoryImpl;
 import org.apache.jackrabbit.webdav.DavException;
 import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants;
 import org.apache.jackrabbit.webdav.jcr.property.ValuesProperty;
@@ -40,6 +40,8 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
+import javax.jcr.Binary;
+import javax.jcr.ValueFactory;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.ParserConfigurationException;
 import java.io.ByteArrayInputStream;
@@ -69,6 +71,7 @@
 
     private final NamePathResolver resolver;
     private final ValueLoader loader;
+    private final ValueFactory vf;
 
     public QValueFactoryImpl() {
         this(null, null);
@@ -77,6 +80,7 @@
     QValueFactoryImpl(NamePathResolver resolver, ValueLoader loader) {
         this.resolver = resolver;
         this.loader = loader;
+        vf = new ValueFactoryQImpl(this, resolver);
     }
 
     /**
@@ -137,9 +141,14 @@
                     return new QValueImpl(NAME_FACTORY.create(value));
                 case PropertyType.STRING:
                 case PropertyType.REFERENCE:
+                case PropertyType.WEAKREFERENCE:
                     return new QValueImpl(value, type);
                 case PropertyType.BINARY:
                     return new BinaryQValue(value.getBytes(DEFAULT_ENCODING));
+                case PropertyType.DECIMAL:
+                    return new QValueImpl(new BigDecimal(value));
+                case PropertyType.URI:
+                    return new QValueImpl(URI.create(value));
             }
         } catch (IllegalArgumentException ex) {
             // given String value cannot be converted to Long/Double/Path/Name
@@ -185,12 +194,23 @@
     }
 
     /**
+     * @see QValueFactory#create(URI)
+     */
+    public QValue create(URI value) {
+        return new QValueImpl(value);
+    }
+
+    /**
+     * @see QValueFactory#create(URI)
+     */
+    public QValue create(BigDecimal value) {
+        return new QValueImpl(value);
+    }
+
+    /**
      * @see QValueFactory#create(Name)
      */
     public QValue create(Name value) {
-        if (value == null) {
-            throw new IllegalArgumentException("Cannot create QValue from null value.");
-        }
         return new QValueImpl(value);
     }
 
@@ -198,9 +218,6 @@
      * @see QValueFactory#create(Path)
      */
     public QValue create(Path value) {
-        if (value == null) {
-            throw new IllegalArgumentException("Cannot create QValue from null value.");
-        }
         return new QValueImpl(value);
     }
 
@@ -273,6 +290,14 @@
             super(value);
         }
 
+        protected QValueImpl(BigDecimal value) {
+            super(value);
+        }
+
+        protected QValueImpl(URI value) {
+            super(value);
+        }
+
         //---------------------------------------------------------< QValue >---
         /**
          * @see QValue#getString()
@@ -294,6 +319,27 @@
         }
 
         /**
+         * @see org.apache.jackrabbit.spi.QValue#getDecimal()
+         */
+        public BigDecimal getDecimal() throws RepositoryException {
+            if (val instanceof BigDecimal) {
+                return (BigDecimal) val;
+            } else if (val instanceof Double) {
+                return new BigDecimal((Double) val);
+            } else if (val instanceof Long) {
+                return new BigDecimal((Long) val);
+            } else if (val instanceof Calendar) {
+                return new BigDecimal(((Calendar) val).getTimeInMillis());
+            } else {
+                try {
+                    return new BigDecimal(getString());
+                } catch (NumberFormatException e) {
+                    throw new ValueFormatException("not a valid decimal string: " + getString(), e);
+                }
+            }
+        }
+
+        /**
          * @see QValue#getCalendar()
          */
         public Calendar getCalendar() throws RepositoryException {
@@ -307,6 +353,10 @@
                 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
                 cal.setTimeInMillis(((Long) val).longValue());
                 return cal;
+            } else if (val instanceof BigDecimal) {
+                Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00"));
+                cal.setTimeInMillis(((BigDecimal) val).longValue());
+                return cal;
             } else {
                 String str = getString();
                 Calendar cal = ISO8601.parse(str);
@@ -332,6 +382,8 @@
         public double getDouble() throws RepositoryException {
             if (val instanceof Double) {
                 return ((Double) val).doubleValue();
+            } else if (val instanceof BigDecimal) {
+                return ((BigDecimal) val).doubleValue();
             } else if (val instanceof Calendar) {
                 return ((Calendar) val).getTimeInMillis();
             } else {
@@ -358,6 +410,8 @@
                 return ((Long) val).longValue();
             } else if (val instanceof Double) {
                 return ((Double) val).longValue();
+            } else if (val instanceof BigDecimal) {
+                return ((BigDecimal) val).longValue();
             } else if (val instanceof Calendar) {
                 return ((Calendar) val).getTimeInMillis();
             } else {
@@ -378,6 +432,37 @@
                 }
             }
         }
+
+        /**
+         * @see QValue#getBinary()
+         */
+        public Binary getBinary() throws RepositoryException {
+            // TODO FIXME consolidate Binary implementations
+            return new Binary() {
+                public InputStream getStream() throws RepositoryException {
+                    return QValueImpl.this.getStream();
+                }
+
+                public int read(byte[] b, long position) throws IOException, RepositoryException {
+                    InputStream in = getStream();
+                    try {
+                        in.skip(position);
+                        return in.read(b);
+                    } finally {
+                        in.close();
+                    }
+                }
+
+                public long getSize() throws RepositoryException {
+                    return getLength();
+                }
+
+                public void dispose() {
+                }
+
+            };
+        }
+
     }
 
     //--------------------------------------------------------< Inner Class >---
@@ -770,6 +855,37 @@
         }
 
         /**
+         * @see QValue#getBinary()
+         */
+        public Binary getBinary() throws RepositoryException {
+            // TODO FIXME consolidate Binary implementations
+            // TODO optimize
+            return new Binary() {
+                public InputStream getStream() throws RepositoryException {
+                    return BinaryQValue.this.getStream();
+                }
+
+                public int read(byte[] b, long position) throws IOException, RepositoryException {
+                    InputStream in = getStream();
+                    try {
+                        in.skip(position);
+                        return in.read(b);
+                    } finally {
+                        in.close();
+                    }
+                }
+
+                public long getSize() throws RepositoryException {
+                    return getLength();
+                }
+
+                public void dispose() {
+                }
+
+            };
+        }
+
+        /**
          * Frees temporarily allocated resources such as temporary file, buffer, etc.
          * If this <code>BinaryQValue</code> is backed by a persistent resource
          * calling this method will have no effect.
@@ -967,7 +1083,7 @@
                     Document doc = db.parse(in);
                     Element prop = DomUtil.getChildElement(doc, ItemResourceConstants.JCR_VALUES.getName(), ItemResourceConstants.JCR_VALUES.getNamespace());
                     DavProperty p = DefaultDavProperty.createFromXml(prop);
-                    ValuesProperty vp = new ValuesProperty(p, PropertyType.BINARY, ValueFactoryImpl.getInstance());
+                    ValuesProperty vp = new ValuesProperty(p, PropertyType.BINARY, vf);
 
                     Value[] jcrVs = vp.getJcrValues();
                     init(jcrVs[index].getStream(), true);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/RepositoryServiceImpl.java Wed Jul  8 13:57:13 2009
@@ -43,6 +43,7 @@
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
 import org.apache.jackrabbit.spi.commons.name.PathBuilder;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi2dav.ExceptionConverter;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.webdav.DavException;
@@ -379,10 +380,15 @@
     }
 
     private static void addIfHeader(SessionInfo sInfo, HttpMethod method) {
-        String[] locktokens = sInfo.getLockTokens();
-        if (locktokens != null && locktokens.length > 0) {
-            IfHeader ifH = new IfHeader(locktokens);
-            method.setRequestHeader(ifH.getHeaderName(), ifH.getHeaderValue());
+        try {
+            String[] locktokens = sInfo.getLockTokens();
+            if (locktokens != null && locktokens.length > 0) {
+                IfHeader ifH = new IfHeader(locktokens);
+                method.setRequestHeader(ifH.getHeaderName(), ifH.getHeaderValue());
+            }
+        } catch (RepositoryException e) {
+            // should never get here
+            log.error("Unable to retrieve lock tokens: omitted from request header.");
         }
     }
 
@@ -587,7 +593,18 @@
             for (int i = 0; i < mixinNodeTypeNames.length; i++) {
                 vs[i] = getQValueFactory(sessionInfo).create(mixinNodeTypeNames[i]);
             }
-            addProperty(nodeId, resolver.getQName(JcrConstants.JCR_MIXINTYPES), vs);
+            addProperty(nodeId, NameConstants.JCR_MIXINTYPES, vs);
+        }
+
+        /**
+         * @inheritDoc
+         */
+        public void setPrimaryType(NodeId nodeId, Name primaryNodeTypeName) throws RepositoryException {
+            assertMethod();
+
+            NamePathResolver resolver = getNamePathResolver(sessionInfo);
+            QValue v = getQValueFactory(sessionInfo).create(primaryNodeTypeName);
+            addProperty(nodeId, NameConstants.JCR_PRIMARYTYPE, v);
         }
 
         /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/pom.xml?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/pom.xml (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/pom.xml Wed Jul  8 13:57:13 2009
@@ -69,28 +69,24 @@
               <value>
                 org.apache.jackrabbit.jcr2spi.name.NamespaceRegistryTest#testReRegisteredNamespaceVisibility
                 org.apache.jackrabbit.jcr2spi.name.NamespaceRegistryTest#testRegisteredNamespaceVisibility
-                org.apache.jackrabbit.value.BinaryValueTest#testBinaryValueEquals
-                org.apache.jackrabbit.test.api.lock.LockManagerTest
-                org.apache.jackrabbit.test.api.observation.GetDateTest
-                org.apache.jackrabbit.test.api.observation.GetIdentifierTest
-                org.apache.jackrabbit.test.api.observation.GetInfoTest
-                org.apache.jackrabbit.test.api.observation.GetUserDataTest
-                org.apache.jackrabbit.test.api.observation.NodeMovedTest
-                org.apache.jackrabbit.test.api.observation.NodeReorderTest
-                org.apache.jackrabbit.test.api.observation.EventJournalTest
-                org.apache.jackrabbit.test.api.version.RestoreTest#testRestoreNameJcr2
+                org.apache.jackrabbit.test.api.ShareableNodeTest
+                org.apache.jackrabbit.test.api.version.simple
+                org.apache.jackrabbit.test.api.NodeReadMethodsTest#testGetPropertiesNamePatternArray
+                org.apache.jackrabbit.test.api.version.ActivitiesTest
+                org.apache.jackrabbit.test.api.nodetype.NodeTypeCreationTest#testPropertyDefinitionTemplate
               </value>
             </property>
           </systemProperties>
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>rat-maven-plugin</artifactId>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
         <configuration>
           <excludes>
             <exclude>src/test/resources/jaas.config</exclude>
             <exclude>src/test/resources/testdata.xml</exclude>
+            <exclude>*.log</exclude>
           </excludes>
         </configuration>
       </plugin>
@@ -125,13 +121,6 @@
       <artifactId>jackrabbit-jcr-commons</artifactId>
       <version>2.0-SNAPSHOT</version>
     </dependency>
-    <!-- tmp dependency to jackrabbit-api until jsr 283 is released -->
-    <dependency>
-      <groupId>org.apache.jackrabbit</groupId>
-      <artifactId>jackrabbit-api</artifactId>
-      <version>2.0-SNAPSHOT</version>
-    </dependency>
-    <!-- end of tmp dependency -->
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/BatchReadConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/BatchReadConfig.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/BatchReadConfig.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/BatchReadConfig.java Wed Jul  8 13:57:13 2009
@@ -34,7 +34,7 @@
     private Map depthMap = new HashMap(0);
 
     /**
-     * Return the depth for the given qualified node type name. If the name is
+     * Return the depth for the given node type name. If the name is
      * not defined in this configuration, the {@link #DEPTH_DEFAULT default value}
      * is returned.
      *

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/EventSubscription.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/EventSubscription.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/EventSubscription.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/EventSubscription.java Wed Jul  8 13:57:13 2009
@@ -19,29 +19,17 @@
 import org.apache.jackrabbit.spi.EventBundle;
 import org.apache.jackrabbit.spi.EventFilter;
 import org.apache.jackrabbit.spi.Event;
-import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.IdFactory;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.Subscription;
-import org.apache.jackrabbit.spi.commons.EventImpl;
+import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.commons.EventBundleImpl;
 import org.apache.jackrabbit.spi.commons.EventFilterImpl;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
-import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
-import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
 import javax.jcr.observation.EventListener;
 import javax.jcr.observation.ObservationManager;
-import javax.jcr.Session;
-import javax.jcr.Node;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.NamespaceException;
 import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Iterator;
@@ -66,49 +54,50 @@
             | javax.jcr.observation.Event.NODE_REMOVED
             | javax.jcr.observation.Event.PROPERTY_ADDED
             | javax.jcr.observation.Event.PROPERTY_CHANGED
-            | javax.jcr.observation.Event.PROPERTY_REMOVED;
+            | javax.jcr.observation.Event.PROPERTY_REMOVED
+            | javax.jcr.observation.Event.NODE_MOVED
+            | javax.jcr.observation.Event.PERSIST;
 
-    private final List eventBundles = new ArrayList();
-
-    private final IdFactory idFactory;
+    private final List<EventBundle> eventBundles = new ArrayList<EventBundle>();
 
     private final SessionInfoImpl sessionInfo;
 
     /**
      * Current list of filters. Copy on write is performed on this list.
      */
-    private volatile List filters;
+    private volatile List<EventFilter> filters;
 
     /**
-     * The resolver of the underlying session.
+     * Set to <code>true</code> if this subscription has been disposed.
      */
-    private final NamePathResolver resolver;
+    private volatile boolean disposed = false;
 
     /**
-     * Set to <code>true</code> if this subscription has been disposed.
+     * The event factory.
      */
-    private volatile boolean disposed = false;
+    private final EventFactory eventFactory;
 
     /**
      * Creates a new subscription for the passed session.
      *
-     * @param idFactory   the id factory.
-     * @param sessionInfo the session info.
-     * @param filters     the filters that should be applied to the generated
-     *                    events.
+     * @param idFactory     the id factory.
+     * @param qValueFactory the QValueFactory.
+     * @param sessionInfo   the session info.
+     * @param filters       the filters that should be applied to the generated
+     *                      events.
      * @throws RepositoryException if an error occurs while an event listener is
      *                             registered with the session.
      */
     EventSubscription(IdFactory idFactory,
+                      QValueFactory qValueFactory,
                       SessionInfoImpl sessionInfo,
                       EventFilter[] filters) throws RepositoryException {
-        this.idFactory = idFactory;
         this.sessionInfo = sessionInfo;
-        this.resolver = sessionInfo.getNamePathResolver();
+        this.eventFactory = new EventFactory(sessionInfo.getSession(),
+                sessionInfo.getNamePathResolver(), idFactory, qValueFactory);
         setFilters(filters);
         ObservationManager obsMgr = sessionInfo.getSession().getWorkspace().getObservationManager();
-        obsMgr.addEventListener(this, EventSubscription.ALL_EVENTS,
-                "/", true, null, null, true);
+        obsMgr.addEventListener(this, EventSubscription.ALL_EVENTS, "/", true, null, null, true);
     }
 
     /**
@@ -127,12 +116,12 @@
      */
     void setFilters(EventFilter[] filters) throws RepositoryException {
         // check type
-        for (int i = 0; i < filters.length; i++) {
-            if (!(filters[i] instanceof EventFilterImpl)) {
+        for (EventFilter filter : filters) {
+            if (!(filter instanceof EventFilterImpl)) {
                 throw new RepositoryException("Unknown filter implementation");
             }
         }
-        List tmp = new ArrayList(Arrays.asList(filters));
+        List<EventFilter> tmp = new ArrayList<EventFilter>(Arrays.asList(filters));
         this.filters = Collections.unmodifiableList(tmp);
 
     }
@@ -221,43 +210,10 @@
         if (disposed) {
             return;
         }
-        List spiEvents = new ArrayList();
+        List<Event> spiEvents = new ArrayList<Event>();
         while (events.hasNext()) {
             try {
-                Session session = sessionInfo.getSession();
-                javax.jcr.observation.Event e = events.nextEvent();
-                Path p = resolver.getQPath(e.getPath());
-                Path parent = p.getAncestor(1);
-                NodeId parentId = idFactory.createNodeId((String) null, parent);
-                ItemId itemId = null;
-                Node node = null;
-                switch (e.getType()) {
-                    case Event.NODE_ADDED:
-                        node = session.getItem(e.getPath()).getParent();
-                    case Event.NODE_REMOVED:
-                        itemId = idFactory.createNodeId((String) null, p);
-                        break;
-                    case Event.PROPERTY_ADDED:
-                    case Event.PROPERTY_CHANGED:
-                        node = session.getItem(e.getPath()).getParent();
-                    case Event.PROPERTY_REMOVED:
-                        itemId = idFactory.createPropertyId(parentId,
-                                p.getNameElement().getName());
-                        break;
-                }
-                Name nodeTypeName = null;
-                Name[] mixinTypes = new Name[0];
-                if (node != null) {
-                    try {
-                        parentId = idFactory.createNodeId(node.getUUID(), null);
-                    } catch (UnsupportedRepositoryOperationException ex) {
-                        // not referenceable
-                    }
-                    nodeTypeName = resolver.getQName(node.getPrimaryNodeType().getName());
-                    mixinTypes = getNodeTypeNames(node.getMixinNodeTypes(), resolver);
-                }
-                Event spiEvent = new EventImpl(e.getType(), p, itemId, parentId,
-                        nodeTypeName, mixinTypes, e.getUserID());
+                Event spiEvent = eventFactory.fromJCREvent(events.nextEvent());
                 spiEvents.add(spiEvent);
             } catch (Exception ex) {
                 log.warn("Unable to create SPI Event: " + ex);
@@ -269,25 +225,4 @@
             eventBundles.notify();
         }
     }
-
-    /**
-     * Returns the qualified names of the passed node types using the namespace
-     * resolver to parse the names.
-     *
-     * @param nt         the node types
-     * @param resolver
-     * @return the qualified names of the node types.
-     * @throws NameException if a node type returns an illegal name.
-     * @throws NamespaceException if the name of a node type contains a
-     * prefix that is not known to <code>resolver</code>.
-     */
-    private static Name[] getNodeTypeNames(NodeType[] nt, NameResolver resolver)
-            throws NameException, NamespaceException {
-        Name[] names = new Name[nt.length];
-        for (int i = 0; i < nt.length; i++) {
-            Name ntName = resolver.getQName(nt[i].getName());
-            names[i] = ntName;
-        }
-        return names;
-    }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/NodeInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/NodeInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/NodeInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/NodeInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -59,12 +59,12 @@
     }
 
     /**
-     * Returns the qualified names of the passed node types using the namespace
+     * Returns the names of the passed node types using the namespace
      * resolver to parse the names.
      *
-     * @param nt         the node types
-     * @param resolver
-     * @return the qualified names of the node types.
+     * @param nt the node types from which the names should be retrieved.
+     * @param resolver The name and path resolver.
+     * @return the names of the node types.
      * @throws NameException   if a node type returns an illegal name.
      * @throws NamespaceException if the name of a node type contains a
      *                            prefix that is not known to <code>resolver</code>.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeDefinitionImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeDefinitionImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeDefinitionImpl.java Wed Jul  8 13:57:13 2009
@@ -31,7 +31,7 @@
         extends org.apache.jackrabbit.spi.commons.QNodeDefinitionImpl {
 
     /**
-     * Creates a new qualified node definition based on a JCR NodeDefinition.
+     * Creates a new node definition based on a JCR <code>NodeDefinition</code>.
      *
      * @param nodeDef    the node definition.
      * @param resolver
@@ -54,12 +54,12 @@
     }
 
     /**
-     * Returns the qualified names of the passed node types using the namespace
+     * Returns the names of the passed node types using the namespace
      * resolver to parse the names.
      *
      * @param nt         the node types
      * @param resolver
-     * @return the qualified names of the node types.
+     * @return the names of the node types.
      * @throws NameException   if a node type returns an illegal name.
      * @throws NamespaceException if the name of a node type contains a
      *                            prefix that is not known to <code>resolver</code>.

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeTypeDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeTypeDefinitionImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeTypeDefinitionImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QNodeTypeDefinitionImpl.java Wed Jul  8 13:57:13 2009
@@ -31,14 +31,14 @@
 import javax.jcr.NamespaceException;
 
 /**
- * <code>QNodeTypeDefinitionImpl</code> implements a qualified node type
+ * <code>QNodeTypeDefinitionImpl</code> implements a SPI node type
  * definition based on a JCR {@link NodeType}.
  */
 class QNodeTypeDefinitionImpl
         extends org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl {
 
     /**
-     * Creates a new qualified node type definition based on a JCR
+     * Creates a new SPI node type definition based on a JCR
      * <code>NodeType</code>.
      *
      * @param nt            the JCR node type.
@@ -66,12 +66,11 @@
     }
 
     /**
-     * Returns the qualified names of the passed node types using the namespace
-     * resolver to parse the names.
+     * Builds the names of the passed node types using the given <code>resolver</code>.
      *
      * @param nt the node types.
      * @param resolver the name and path resolver.
-     * @return the qualified names of the node types.
+     * @return the names of the node types.
      * @throws IllegalNameException   if a node type returns an illegal name.
      * @throws NamespaceException if the name of a node type contains a
      *                            prefix that is not known to <code>rResolver</code>.
@@ -88,12 +87,12 @@
     }
 
     /**
-     * Returns qualified property definitions for JCR property definitions.
+     * Builds SPI property definitions from the given {@link javax.jcr.nodetype.PropertyDefinition}s.
      *
      * @param propDefs   the JCR property definitions.
      * @param resolver
      * @param factory    the value factory.
-     * @return qualified property definitions.
+     * @return property definitions.
      * @throws RepositoryException    if an error occurs while converting the
      *                                definitions.
      */
@@ -109,11 +108,11 @@
     }
 
     /**
-     * Returns qualified node definitions for JCR node definitions.
+     * Builds SPI node definitions from the given JCR node definitions.
      *
      * @param nodeDefs the JCR node definitions.
      * @param resolver the name and path resolver.
-     * @return qualified node definitions.
+     * @return node definitions.
      * @throws IllegalNameException   if the node definition contains an illegal
      *                                name.
      * @throws NamespaceException if the name of a node definition contains

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QPropertyDefinitionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QPropertyDefinitionImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QPropertyDefinitionImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QPropertyDefinitionImpl.java Wed Jul  8 13:57:13 2009
@@ -19,10 +19,12 @@
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QValueConstraint;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NameException;
 import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
 import org.apache.jackrabbit.spi.commons.value.ValueFormat;
+import org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint;
 
 import javax.jcr.nodetype.PropertyDefinition;
 import javax.jcr.RepositoryException;
@@ -31,14 +33,14 @@
 import javax.jcr.NamespaceException;
 
 /**
- * <code>QPropertyDefinitionImpl</code> implements a qualified property
+ * <code>QPropertyDefinitionImpl</code> implements a property
  * definition based on a JCR {@link javax.jcr.nodetype.PropertyDefinition}.
  */
 class QPropertyDefinitionImpl
         extends org.apache.jackrabbit.spi.commons.QPropertyDefinitionImpl {
 
     /**
-     * Creates a new qualified property definition based on
+     * Creates a new property definition based on
      * <code>propDef</code>.
      *
      * @param propDef       the JCR property definition.
@@ -53,13 +55,17 @@
             throws RepositoryException, NameException {
         super(propDef.getName().equals(ANY_NAME.getLocalName()) ? ANY_NAME : resolver.getQName(propDef.getName()),
                 resolver.getQName(propDef.getDeclaringNodeType().getName()),
-                propDef.isAutoCreated(), propDef.isMandatory(),
-                propDef.getOnParentVersion(), propDef.isProtected(),
+                propDef.isAutoCreated(),
+                propDef.isMandatory(),
+                propDef.getOnParentVersion(),
+                propDef.isProtected(),
                 convertValues(propDef.getDefaultValues(), resolver, qValueFactory),
-                propDef.isMultiple(), propDef.getRequiredType(),
-                convertConstraints(propDef.getValueConstraints(), resolver, qValueFactory, propDef.getRequiredType()),
-                convertQueryOperators(propDef.getAvailableQueryOperators(), resolver),
-                propDef.isFullTextSearchable(), propDef.isQueryOrderable());
+                propDef.isMultiple(),
+                propDef.getRequiredType(),
+                ValueConstraint.create(propDef.getRequiredType(), propDef.getValueConstraints(), resolver),
+                propDef.getAvailableQueryOperators(),
+                propDef.isFullTextSearchable(),
+                propDef.isQueryOrderable());
     }
 
     /**
@@ -87,36 +93,6 @@
     }
 
     /**
-     * Makes sure name and path constraints are parsed correctly using the
-     * namespace resolver.
-     *
-     * @param constraints  the constraint strings from the JCR property
-     *                     definition.
-     * @param resolver
-     * @param factory      the QValueFactory.
-     * @param requiredType the required type of the property definition.
-     * @return SPI formatted constraint strings.
-     * @throws RepositoryException if an error occurs while converting the
-     *                             constraint strings.
-     */
-    private static String[] convertConstraints(String[] constraints,
-                                               NamePathResolver resolver,
-                                               QValueFactory factory,
-                                               int requiredType)
-            throws RepositoryException {
-        if (requiredType == PropertyType.REFERENCE
-                || requiredType == PropertyType.NAME
-                || requiredType == PropertyType.PATH) {
-            int type = requiredType == PropertyType.REFERENCE ? PropertyType.NAME : requiredType;
-            for (int i = 0; i < constraints.length; i++) {
-                constraints[i] = ValueFormat.getQValue(
-                        constraints[i], type, resolver, factory).getString();
-            }
-        }
-        return constraints;
-    }
-
-    /**
      * Convert String jcr names to Name objects.
      *
      * @param aqos

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryInfoImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryInfoImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryInfoImpl.java Wed Jul  8 13:57:13 2009
@@ -19,19 +19,24 @@
 import org.apache.jackrabbit.spi.QueryInfo;
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
 import org.apache.jackrabbit.commons.iterator.RangeIteratorDecorator;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.query.QueryResult;
 import javax.jcr.query.Row;
+import javax.jcr.query.Query;
+import javax.jcr.query.qom.QueryObjectModel;
+import javax.jcr.query.qom.Source;
+import javax.jcr.query.qom.Join;
+import javax.jcr.query.qom.Selector;
 import javax.jcr.RepositoryException;
 import javax.jcr.RangeIterator;
 import java.util.NoSuchElementException;
+import java.util.List;
+import java.util.ArrayList;
 
 /**
  * <code>QueryInfoImpl</code> implements a <code>QueryInfo</code> based on a
@@ -67,29 +72,26 @@
     /**
      * The names of the columns in the query result.
      */
-    private final Name[] columnNames;
+    private final String[] columnNames;
 
     /**
-     * The resolved name of the jcr:score column.
+     * The names of the selectors in the query result.
      */
-    private final String scoreName;
-
-    /**
-     * The resolved name of the jcr:path column.
-     */
-    private final String pathName;
+    private final Name[] selectorNames;
 
     /**
      * Creates a new query info based on a given <code>result</code>.
      *
+     * @param query         the JCR query.
      * @param result        the JCR query result.
      * @param idFactory     the id factory.
-     * @param resolver
+     * @param resolver      the name path resolver.
      * @param qValueFactory the QValue factory.
      * @throws RepositoryException if an error occurs while reading from
      *                             <code>result</code>.
      */
-    public QueryInfoImpl(QueryResult result,
+    public QueryInfoImpl(Query query,
+                         QueryResult result,
                          IdFactoryImpl idFactory,
                          NamePathResolver resolver,
                          QValueFactory qValueFactory)
@@ -98,17 +100,8 @@
         this.idFactory = idFactory;
         this.resolver = resolver;
         this.qValueFactory = qValueFactory;
-        String[] jcrNames = result.getColumnNames();
-        this.columnNames = new Name[jcrNames.length];
-        try {
-            for (int i = 0; i < jcrNames.length; i++) {
-                columnNames[i] = resolver.getQName(jcrNames[i]);
-            }
-            this.scoreName = resolver.getJCRName(NameConstants.JCR_SCORE);
-            this.pathName = resolver.getJCRName(NameConstants.JCR_PATH);
-        } catch (NameException e) {
-            throw new RepositoryException(e.getMessage(), e);
-        }
+        this.columnNames = result.getColumnNames();
+        this.selectorNames = getSelectorNames(query, result, resolver);
     }
 
     /**
@@ -116,13 +109,12 @@
      */
     public RangeIterator getRows() {
         try {
-            final String[] columnJcrNames = result.getColumnNames();
             return new RangeIteratorDecorator(result.getRows()) {
                 public Object next() {
                     try {
                         return new QueryResultRowImpl(
-                                (Row) super.next(), columnJcrNames, scoreName,
-                                pathName, idFactory, resolver, qValueFactory);
+                                (Row) super.next(), columnNames, selectorNames,
+                                idFactory, resolver, qValueFactory);
                     } catch (RepositoryException e) {
                         log.warn("Exception when creating QueryResultRowImpl: " +
                                 e.getMessage(), e);
@@ -138,9 +130,45 @@
     /**
      * {@inheritDoc}
      */
-    public Name[] getColumnNames() {
-        Name[] names = new Name[columnNames.length];
+    public String[] getColumnNames() {
+        String[] names = new String[columnNames.length];
         System.arraycopy(columnNames, 0, names, 0, columnNames.length);
         return names;
     }
+
+    private static Name[] getSelectorNames(Query query,
+                                           QueryResult result,
+                                           NamePathResolver resolver)
+            throws RepositoryException {
+        List<String> sn = new ArrayList<String>();
+        if (query instanceof QueryObjectModel) {
+            QueryObjectModel qom = (QueryObjectModel) query;
+            collectSelectorNames(qom.getSource(), sn);
+        } else {
+            // TODO
+            // sn.addAll(Arrays.asList(result.getSelectorNames()));
+        }
+        Name[] selectorNames = new Name[sn.size()];
+        for (int i = 0; i < sn.size(); i++) {
+            selectorNames[i] = resolver.getQName(sn.get(i));
+        }
+        return selectorNames;
+    }
+
+    private static void collectSelectorNames(Source source, List<String> sn) {
+        if (source instanceof Join) {
+            collectSelectorNames((Join) source, sn);
+        } else {
+            collectSelectorNames((Selector) source, sn);
+        }
+    }
+
+    private static void collectSelectorNames(Join join, List<String> sn) {
+        collectSelectorNames(join.getLeft(), sn);
+        collectSelectorNames(join.getRight(), sn);
+    }
+
+    private static void collectSelectorNames(Selector s, List<String> sn) {
+        sn.add(s.getSelectorName());
+    }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryResultRowImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryResultRowImpl.java?rev=792142&r1=792141&r2=792142&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryResultRowImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/QueryResultRowImpl.java Wed Jul  8 13:57:13 2009
@@ -16,18 +16,24 @@
  */
 package org.apache.jackrabbit.spi2jcr;
 
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
 import org.apache.jackrabbit.spi.QueryResultRow;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.QValueFactory;
-import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.value.ValueFormat;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.commons.conversion.NameException;
 
 import javax.jcr.query.Row;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.Node;
 
 /**
  * <code>QueryResultRowImpl</code> implements a <code>QueryResultRow</code>
@@ -36,14 +42,14 @@
 class QueryResultRowImpl implements QueryResultRow {
 
     /**
-     * The node id of the underlying row.
+     * The node ids of the underlying row.
      */
-    private final NodeId nodeId;
+    private final Map<Name, NodeId> nodeIds = new HashMap<Name, NodeId>();
 
     /**
-     * The score value for this row.
+     * The score values for this row.
      */
-    private final double score;
+    private final Map<Name, Double> scores = new HashMap<Name, Double>();
 
     /**
      * The QValues for this row.
@@ -55,30 +61,19 @@
      *
      * @param row           the JCR row.
      * @param columnNames   the resolved names of the columns.
-     * @param scoreName     the name of the jcr:score column.
-     * @param pathName      the name of the jcr:path column
+     * @param selectorNames the selector names.
      * @param idFactory     the id factory.
-     * @param resolver
+     * @param resolver      the name path resolver.
      * @param qValueFactory the QValue factory.
      * @throws RepositoryException if an error occurs while reading from
      *                             <code>row</code>.
      */
     public QueryResultRowImpl(Row row,
                               String[] columnNames,
-                              String scoreName,
-                              String pathName,
+                              Name[] selectorNames,
                               IdFactoryImpl idFactory,
                               NamePathResolver resolver,
                               QValueFactory qValueFactory) throws RepositoryException {
-        String jcrPath = row.getValue(pathName).getString();
-        Path path;
-        try {
-            path = resolver.getQPath(jcrPath);
-        } catch (NameException e) {
-            throw new RepositoryException(e.getMessage(), e);
-        }
-        this.nodeId = idFactory.createNodeId((String) null, path);
-        this.score = row.getValue(scoreName).getDouble();
         this.values = new QValue[columnNames.length];
         for (int i = 0; i < columnNames.length; i++) {
             Value v = row.getValue(columnNames[i]);
@@ -88,20 +83,59 @@
                 values[i] = ValueFormat.getQValue(v, resolver, qValueFactory);
             }
         }
+        List<Name> selNames = new ArrayList<Name>();
+        selNames.addAll(Arrays.asList(selectorNames));
+        if (selNames.isEmpty()) {
+            selNames.add(null); // default selector
+        }
+        for (Name sn : selNames) {
+            Node n;
+            double score;
+            if (sn == null) {
+                n = row.getNode();
+                score = row.getScore();
+            } else {
+                String selName = resolver.getJCRName(sn);
+                n = row.getNode(selName);
+                score = row.getScore(selName);
+            }
+            NodeId id = null;
+            if (n != null) {
+                id = idFactory.fromJcrIdentifier(n.getIdentifier());
+            }
+            nodeIds.put(sn, id);
+            scores.put(sn, score);
+        }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public NodeId getNodeId() {
-        return nodeId;
+    public NodeId getNodeId(Name selectorName) {
+        if (nodeIds.containsKey(selectorName)) {
+            return nodeIds.get(selectorName);
+        } else {
+            if (nodeIds.size() == 1) {
+                return nodeIds.values().iterator().next();
+            } else {
+                throw new IllegalArgumentException(selectorName + " is not a valid selectorName");
+            }
+        }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public double getScore() {
-        return score;
+    public double getScore(Name selectorName) {
+        Double score;
+        if (scores.containsKey(selectorName)) {
+            score = scores.get(selectorName);
+        } else {
+            if (scores.size() == 1) {
+                score = scores.values().iterator().next();
+            } else {
+                throw new IllegalArgumentException(selectorName + " is not a valid selectorName");
+            }
+        }
+        if (score == null) {
+            return Double.NaN;
+        } else {
+            return score;
+        }
     }
 
     /**



Mime
View raw message