You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/08/14 14:35:35 UTC

svn commit: r1372860 - in /jackrabbit/oak/trunk: oak-core/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/ oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/ oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/ oak-jcr/...

Author: angela
Date: Tue Aug 14 12:35:34 2012
New Revision: 1372860

URL: http://svn.apache.org/viewvc?rev=1372860&view=rev
Log:
OAK-101 : implement identifier handling (byUUID, byIdentifier, etc)

move identifier related code to oak (plugins/identifier) in order to have
- functionality available in oak
- avoid distributing hardcoded identifier handing all over the place

TODO:
- former todos from oak-jcr have not yet been addressed
- getReferences and getWeakReferences are not yet implemented
- check for tree being referenceable is not correct yet (missing effective node type utility in oak)

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/CoreValueFactoryTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/value/ValueFactoryImpl.java

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Tue Aug 14 12:35:34 2012
@@ -43,6 +43,7 @@
               org.apache.jackrabbit.oak.core,
               org.apache.jackrabbit.oak.util,
               org.apache.jackrabbit.oak.namepath,
+              org.apache.jackrabbit.oak.plugins.identifier,
               org.apache.jackrabbit.oak.plugins.name,
               org.apache.jackrabbit.oak.plugins.type,
               org.apache.jackrabbit.oak.plugins.value,

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java?rev=1372860&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java Tue Aug 14 12:35:34 2012
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.identifier;
+
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.query.Query;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Result;
+import org.apache.jackrabbit.oak.api.ResultRow;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * IdentifierManager...
+ */
+public class IdentifierManager {
+
+    private static final Logger log = LoggerFactory.getLogger(IdentifierManager.class);
+
+    private final ContentSession contentSession;
+    private final Root root;
+
+    public IdentifierManager(ContentSession contentSession, Root root) {
+        this.contentSession = contentSession;
+        this.root = root;
+    }
+
+    @Nonnull
+    public static String generateUUID() {
+        return UUID.randomUUID().toString();
+    }
+
+    public static boolean isValidUUID(String uuid) {
+        try {
+            UUID.fromString(uuid);
+            return true;
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    /**
+     *
+     * @param uuid
+     * @throws IllegalArgumentException If the specified uuid has an invalid format.
+     */
+    public static void checkUUIDFormat(String uuid) throws IllegalArgumentException {
+        UUID.fromString(uuid);
+    }
+
+    @Nonnull
+    public String getIdentifier(Tree tree) {
+        PropertyState property = tree.getProperty(JcrConstants.JCR_UUID);
+        if (property == null) {
+            // TODO calculate the identifier from closest referenceable parent
+            // TODO and a relative path irrespective of the accessibility of the parent node(s)
+            return tree.getPath();
+        } else {
+            return property.getValue().getString();
+        }
+    }
+
+    @CheckForNull
+    public Tree getTree(String identifier) {
+        if (isValidUUID(identifier)) {
+            return findByJcrUuid(identifier);
+        } else {
+            // TODO as stated in NodeDelegate#getIdentifier() a non-uuid ID should
+            // TODO consisting of closest referenceable parent and a relative path
+            // TODO irrespective of the accessibility of the parent node(s)
+            return root.getTree(identifier);
+        }
+    }
+
+    @Nonnull
+    public Set<String> getReferences(Tree tree, String name) {
+        if (!isReferenceable(tree)) {
+            return Collections.emptySet();
+        } else {
+            String uuid = getIdentifier(tree);
+            // TODO execute query.
+            throw new UnsupportedOperationException("TODO: Node.getReferences");
+        }
+    }
+
+    @Nonnull
+    public Set<String> getWeakReferences(Tree tree, String name) {
+        if (!isReferenceable(tree)) {
+            return Collections.emptySet();
+        } else {
+            String uuid = getIdentifier(tree);
+            // TODO execute query.
+            throw new UnsupportedOperationException("TODO: Node.getWeakReferences");
+        }
+    }
+
+    public boolean isReferenceable(Tree tree) {
+        // TODO add proper implementation include node type eval
+        return tree.hasProperty(JcrConstants.JCR_UUID);
+    }
+
+    @CheckForNull
+    private Tree findByJcrUuid(String id) {
+        try {
+            Map<String, CoreValue> bindings = Collections.singletonMap("id", contentSession.getCoreValueFactory().createValue(id));
+
+            Result result = contentSession.getQueryEngine().executeQuery("SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2,
+                    contentSession, Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default());
+
+            String path = null;
+            for (ResultRow rr : result.getRows()) {
+                if (path != null) {
+                    log.error("multiple results for identifier lookup: " + path + " vs. " + rr.getPath());
+                    return null;
+                } else {
+                    path = rr.getPath();
+                }
+            }
+            return path == null ? null : root.getTree(path);
+        } catch (ParseException ex) {
+            log.error("query failed", ex);
+            return null;
+        }
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/CoreValueFactoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/CoreValueFactoryTest.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/CoreValueFactoryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/kernel/CoreValueFactoryTest.java Tue Aug 14 12:35:34 2012
@@ -16,16 +16,6 @@
  */
 package org.apache.jackrabbit.oak.kernel;
 
-import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.mk.core.MicroKernelImpl;
-import org.apache.jackrabbit.mk.json.JsopReader;
-import org.apache.jackrabbit.mk.json.JsopTokenizer;
-import org.apache.jackrabbit.oak.api.CoreValue;
-import org.apache.jackrabbit.oak.api.CoreValueFactory;
-import org.junit.Before;
-import org.junit.Test;
-
-import javax.jcr.PropertyType;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
@@ -34,7 +24,17 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.core.MicroKernelImpl;
+import org.apache.jackrabbit.mk.json.JsopReader;
+import org.apache.jackrabbit.mk.json.JsopTokenizer;
+import org.apache.jackrabbit.oak.api.CoreValue;
+import org.apache.jackrabbit.oak.api.CoreValueFactory;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.junit.Before;
+import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 
@@ -77,7 +77,7 @@ public class CoreValueFactoryTest {
 
         singleValueMap.put(valueFactory.createValue("http://jackrabbit.apache.org", PropertyType.URI), "\"uri:http://jackrabbit.apache.org\"");
 
-        String uuid = UUID.randomUUID().toString();
+        String uuid = IdentifierManager.generateUUID();
         singleValueMap.put(valueFactory.createValue(uuid, PropertyType.REFERENCE), "\"ref:" +uuid+ '\"');
         singleValueMap.put(valueFactory.createValue(uuid, PropertyType.WEAKREFERENCE), "\"wea:" +uuid+ '\"');
 

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java Tue Aug 14 12:35:34 2012
@@ -16,13 +16,13 @@
  */
 package org.apache.jackrabbit.oak.namepath;
 
-import org.junit.Test;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
+
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -34,9 +34,10 @@ public class NamePathMapperImplTest {
 
     @Test
     public void testInvalidIdentifierPath() {
+        String uuid = IdentifierManager.generateUUID();
         List<String> invalid = new ArrayList<String>();
-        invalid.add('[' + UUID.randomUUID().toString() + "]abc");
-        invalid.add('[' + UUID.randomUUID().toString() + "]/a/b/c");
+        invalid.add('[' + uuid + "]abc");
+        invalid.add('[' + uuid + "]/a/b/c");
 
         for (String jcrPath : invalid) {
             assertNull(npMapper.getOakPath(jcrPath));

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeDelegate.java Tue Aug 14 12:35:34 2012
@@ -97,15 +97,7 @@ public class NodeDelegate extends ItemDe
 
     @Nonnull
     public String getIdentifier() throws InvalidItemStateException {
-        PropertyDelegate pd = getProperty(JcrConstants.JCR_UUID);
-        if (pd == null) {
-            // TODO delegated to the OAK-API to calculate the identifier
-            // TODO consisting of closest referenceable parent and a relative path
-            // TODO irrespective of the accessibility of the parent node(s)
-            return getPath();
-        } else {
-            return pd.getValue().toString();
-        }
+        return sessionDelegate.getIdManager().getIdentifier(getTree());
     }
 
     /**
@@ -336,7 +328,7 @@ public class NodeDelegate extends ItemDe
         return sessionDelegate.getTree(absPath);
     }
 
-    private synchronized Tree getTree() throws InvalidItemStateException {
+    synchronized Tree getTree() throws InvalidItemStateException {
         resolve();
         if (tree == null) {
             throw new InvalidItemStateException("Node is stale");

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Tue Aug 14 12:35:34 2012
@@ -23,10 +23,10 @@ import java.util.Calendar;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.UUID;
-
+import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Binary;
 import javax.jcr.InvalidItemStateException;
@@ -53,7 +53,10 @@ import javax.jcr.nodetype.NodeTypeManage
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionHistory;
 
-import org.apache.jackrabbit.JcrConstants;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
 import org.apache.jackrabbit.commons.ItemNameMatcher;
 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
 import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
@@ -67,14 +70,11 @@ import org.apache.jackrabbit.oak.api.Tre
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.core.DefaultConflictHandler;
 import org.apache.jackrabbit.oak.jcr.value.ValueConverter;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
 import org.apache.jackrabbit.value.ValueHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-
 import static javax.jcr.Property.JCR_LOCK_IS_DEEP;
 import static javax.jcr.Property.JCR_LOCK_OWNER;
 
@@ -728,19 +728,9 @@ public class NodeImpl extends ItemImpl<N
 
     @Override
     @Nonnull
-    public PropertyIterator getReferences(String name) throws RepositoryException {
+    public PropertyIterator getReferences(final String name) throws RepositoryException {
         checkStatus();
-
-        return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
-            @Override
-            public PropertyIterator perform() throws RepositoryException {
-                if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
-                    return PropertyIteratorAdapter.EMPTY;
-                } else {
-                    throw new UnsupportedRepositoryOperationException("TODO: Node.getReferences");
-                }
-            }
-        });
+        return internalGetReferences(name, false);
     }
 
     /**
@@ -756,15 +746,46 @@ public class NodeImpl extends ItemImpl<N
     @Nonnull
     public PropertyIterator getWeakReferences(String name) throws RepositoryException {
         checkStatus();
+        return internalGetReferences(name, true);
+    }
+
+    private PropertyIterator internalGetReferences(String name, boolean weak) throws RepositoryException {
+        final Set<String> propertyOakPaths;
+        if (weak) {
+            propertyOakPaths = sessionDelegate.getIdManager().getWeakReferences(dlg.getTree(), name);
+        } else {
+            propertyOakPaths = sessionDelegate.getIdManager().getReferences(dlg.getTree(), name);
+        }
+
+        final Iterable<Property> properties = Iterables.transform(
+                propertyOakPaths,
+                new Function<String, Property>() {
+                    @Override
+                    public Property apply(String oakPath) {
+                        // FIXME: should use sessionDelegate.getProperty(oakPath)
+                        // FIXME: avoid converting oak-path to jcr-path and back and to avoid
+                        // FIXME: using jcr-api calls internally.
+                        try {
+                            return sessionDelegate.getSession().getProperty(sessionDelegate.getNamePathMapper().getJcrPath(oakPath));
+                        } catch (RepositoryException e) {
+                            log.debug(e.getMessage());
+                            return null;
+                        }
+                    }
+                }
+        );
+
+        final Predicate ignoreNull = new Predicate() {
+            @Override
+            public boolean apply(@Nullable Object o) {
+                return o != null;
+            }
+        };
 
         return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
             @Override
-            public PropertyIterator perform() throws RepositoryException {
-                if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
-                    return PropertyIteratorAdapter.EMPTY;
-                } else {
-                    throw new UnsupportedRepositoryOperationException("TODO: Node.getWeakReferences");
-                }
+            public PropertyIterator perform() {
+                return new PropertyIteratorAdapter(Iterables.filter(properties, ignoreNull).iterator(), propertyOakPaths.size());
             }
         });
     }
@@ -955,7 +976,8 @@ public class NodeImpl extends ItemImpl<N
                 // TODO: hack -- make sure we assign a UUID
                 if (nodeModified && nt.isNodeType(NodeType.MIX_REFERENCEABLE)) {
                     String jcrUuid = sessionDelegate.getOakPathOrThrow(Property.JCR_UUID);
-                    dlg.setProperty(jcrUuid, ValueConverter.toCoreValue(UUID.randomUUID().toString(), PropertyType.STRING, sessionDelegate));
+                    String uuid = IdentifierManager.generateUUID();
+                    dlg.setProperty(jcrUuid, ValueConverter.toCoreValue(uuid, PropertyType.STRING, sessionDelegate));
                 }
                 return null;
             }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Tue Aug 14 12:35:34 2012
@@ -17,11 +17,7 @@
 package org.apache.jackrabbit.oak.jcr;
 
 import java.io.IOException;
-import java.text.ParseException;
-import java.util.Collections;
-import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
-
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.ItemExistsException;
@@ -34,7 +30,6 @@ import javax.jcr.Workspace;
 import javax.jcr.lock.LockManager;
 import javax.jcr.nodetype.NodeTypeManager;
 import javax.jcr.observation.ObservationManager;
-import javax.jcr.query.Query;
 import javax.jcr.query.QueryManager;
 import javax.jcr.version.VersionManager;
 
@@ -44,10 +39,7 @@ import org.apache.jackrabbit.oak.api.Cha
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.ConflictHandler;
 import org.apache.jackrabbit.oak.api.ContentSession;
-import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.QueryEngine;
-import org.apache.jackrabbit.oak.api.Result;
-import org.apache.jackrabbit.oak.api.ResultRow;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -58,6 +50,7 @@ import org.apache.jackrabbit.oak.jcr.val
 import org.apache.jackrabbit.oak.namepath.AbstractNameMapper;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
 import org.apache.jackrabbit.oak.plugins.value.AnnotatingConflictHandler;
 import org.apache.jackrabbit.oak.util.TODO;
 import org.slf4j.Logger;
@@ -77,6 +70,8 @@ public class SessionDelegate {
     private final ConflictHandler conflictHandler;
     private final boolean autoRefresh;
 
+    private final IdentifierManager idManager;
+
     private ObservationManagerImpl observationManager;
     private boolean isAlive = true;
     private int sessionOpCount;
@@ -97,6 +92,7 @@ public class SessionDelegate {
         this.root = contentSession.getCurrentRoot();
         this.conflictHandler = new AnnotatingConflictHandler(contentSession.getCoreValueFactory());
         this.autoRefresh = autoRefresh;
+        this.idManager = new IdentifierManager(contentSession, root);
     }
 
     /**
@@ -187,17 +183,8 @@ public class SessionDelegate {
 
     @CheckForNull
     public NodeDelegate getNodeByIdentifier(String id) {
-        // TODO delegate identifier handling  to the OAK-API (or oak-utility)
-        // TODO as stated in NodeDelegate#getIdentifier() a non-uuid ID shoud
-        // TODO consisting of closest referenceable parent and a relative path
-        // TODO irrespective of the accessibility of the parent node(s)
-        if (id.startsWith("/")) {
-            Tree tree = getTree(id);
-            return tree == null ? null : new NodeDelegate(this, tree);
-        } else {
-            // referenceable
-            return findByJcrUuid(id);
-        }
+        Tree tree = idManager.getTree(id);
+        return (tree == null) ? null : new NodeDelegate(this, tree);
     }
 
     @Nonnull
@@ -448,37 +435,14 @@ public class SessionDelegate {
         return root.getTree(path);
     }
 
-    @CheckForNull
-    NodeDelegate findByJcrUuid(String id) {
-        try {
-            Map<String, CoreValue> bindings = Collections.singletonMap("id", getValueFactory().getCoreValueFactory()
-                    .createValue(id));
-
-            Result result = getQueryEngine().executeQuery("SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2,
-                    getContentSession(), Long.MAX_VALUE, 0, bindings, namePathMapper);
-
-            String path = null;
-
-            for (ResultRow rr : result.getRows()) {
-                if (path != null) {
-                    log.error("multiple results for identifier lookup: " + path + " vs. " + rr.getPath());
-                    return null;
-                } else {
-                    path = rr.getPath();
-                }
-            }
-
-            return path == null ? null : getNode(path);
-        } catch (ParseException ex) {
-            log.error("query failed", ex);
-            return null;
-        }
-    }
-
     UserManager getUserManager() throws UnsupportedRepositoryOperationException {
         return TODO.unimplemented().returnValue(new UserManagerImpl(this, root, null));
     }
 
+    IdentifierManager getIdManager() {
+        return idManager;
+    }
+
     //--------------------------------------------------< SessionNameMapper >---
 
     private class SessionNameMapper extends AbstractNameMapper {

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/value/ValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/value/ValueFactoryImpl.java?rev=1372860&r1=1372859&r2=1372860&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/value/ValueFactoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/value/ValueFactoryImpl.java Tue Aug 14 12:35:34 2012
@@ -22,7 +22,6 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.math.BigDecimal;
 import java.util.Calendar;
-import java.util.UUID;
 import javax.jcr.Binary;
 import javax.jcr.Node;
 import javax.jcr.PropertyType;
@@ -34,6 +33,7 @@ import javax.jcr.ValueFormatException;
 import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.CoreValueFactory;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
 import org.apache.jackrabbit.util.ISO8601;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -187,11 +187,8 @@ public class ValueFactoryImpl implements
 
                 case PropertyType.REFERENCE:
                 case PropertyType.WEAKREFERENCE:
-                    // TODO: move to identifier/uuid management utility instead of relying on impl specific uuid-format here.
-                    try {
-                        UUID.fromString(value);
-                    } catch (IllegalArgumentException e) {
-                        throw new ValueFormatException(e);
+                    if (!IdentifierManager.isValidUUID(value)) {
+                        throw new ValueFormatException("Invalid reference value " + value);
                     }
                     cv = factory.createValue(value, type);
                     break;