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 ju...@apache.org on 2012/09/05 21:08:08 UTC

svn commit: r1381300 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/core/ main/java/org/apache/jackrabbit/oak/osgi/ main/java/org/apache/jackrabbit/oak/plugins/identifier/ main/java/org/apache/jackrabbit/oak/plugins/index/...

Author: jukka
Date: Wed Sep  5 19:08:07 2012
New Revision: 1381300

URL: http://svn.apache.org/viewvc?rev=1381300&view=rev
Log:
OAK-270: Enforce uniqueness of jcr:uuid

Connect the jcr:uuid unique index to the query mechanism.
Also add uniqueness checks for rep:authorizableId and rep:principalName

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java   (with props)
Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/UUIDValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/UUIDValidatorProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/commit/UniquePropertyValidator.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Indexer.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndexValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndexProvider.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java Wed Sep  5 19:08:07 2012
@@ -33,6 +33,7 @@ import org.apache.jackrabbit.oak.query.Q
 import org.apache.jackrabbit.oak.security.authentication.LoginContextProviderImpl;
 import org.apache.jackrabbit.oak.spi.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
 import org.apache.jackrabbit.oak.spi.commit.CompositeValidatorProvider;
 import org.apache.jackrabbit.oak.spi.commit.ValidatingHook;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
@@ -65,9 +66,11 @@ public class ContentRepositoryImpl imple
      * test cases only.
      */
     public ContentRepositoryImpl() {
-        this(new MicroKernelImpl(), new CompositeQueryIndexProvider(),
-                new ValidatingHook(new CompositeValidatorProvider(
-                        Collections.<ValidatorProvider> emptyList())));
+        this(new CompositeHook());
+    }
+
+    public ContentRepositoryImpl(CommitHook hook) {
+        this(new MicroKernelImpl(), new CompositeQueryIndexProvider(), hook);
     }
 
     /**
@@ -127,7 +130,7 @@ public class ContentRepositoryImpl imple
             microKernel.commit("/", "^\"jcr:primaryType\":\"nam:rep:root\"" +
                 "+\"jcr:system\":{" +
                     "\"jcr:primaryType\"    :\"nam:rep:system\"," +
-                    "\":unique\"            :{\"jcr:uuid\":{}}," +
+                    "\":unique\"            :{\"jcr:uuid\":{},\"rep:authorizableId\":{},\"rep:principalName\":{}}," +
                     "\"jcr:versionStorage\" :{\"jcr:primaryType\":\"nam:rep:versionStorage\"}," +
                     "\"jcr:nodeTypes\"      :{\"jcr:primaryType\":\"nam:rep:nodeTypes\"}," +
                     "\"jcr:activities\"     :{\"jcr:primaryType\":\"nam:rep:Activities\"}," +

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexProvider.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiIndexProvider.java Wed Sep  5 19:08:07 2012
@@ -80,7 +80,7 @@ public class OsgiIndexProvider implement
     }
 
     @Override
-    public List<QueryIndex> getQueryIndexes(MicroKernel mk) {
+    public List<? extends QueryIndex> getQueryIndexes(MicroKernel mk) {
         if (providers.isEmpty()) {
             return Collections.emptyList();
         } else if (providers.size() == 1) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Indexer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Indexer.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Indexer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Indexer.java Wed Sep  5 19:08:07 2012
@@ -33,6 +33,7 @@ import org.apache.jackrabbit.mk.simple.N
 import org.apache.jackrabbit.mk.simple.NodeMap;
 import org.apache.jackrabbit.mk.util.SimpleLRUCache;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.unique.UniqueIndex;
 import org.apache.jackrabbit.oak.query.index.PrefixContentIndex;
 import org.apache.jackrabbit.oak.query.index.PropertyContentIndex;
 import org.apache.jackrabbit.oak.spi.QueryIndex;
@@ -685,6 +686,7 @@ public class Indexer implements QueryInd
                 }
                 queryIndexList.add(qi);
             }
+            queryIndexList.add(new UniqueIndex());
         }
         return queryIndexList;
     }

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java?rev=1381300&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java Wed Sep  5 19:08:07 2012
@@ -0,0 +1,107 @@
+/*
+ * 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.unique;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.query.index.IndexRowImpl;
+import org.apache.jackrabbit.oak.spi.Cursor;
+import org.apache.jackrabbit.oak.spi.Filter;
+import org.apache.jackrabbit.oak.spi.Filter.PropertyRestriction;
+import org.apache.jackrabbit.oak.spi.IndexRow;
+import org.apache.jackrabbit.oak.spi.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
+
+public class UniqueIndex implements QueryIndex {
+
+    @Override
+    public String getIndexName() {
+        return "jcr:uuid";
+    }
+
+    @Override
+    public double getCost(Filter filter) {
+        PropertyRestriction pr = filter.getPropertyRestriction("jcr:uuid");
+        if (pr != null
+                && "/".equals(filter.getPath())
+                && filter.getPathRestriction() == Filter.PathRestriction.ALL_CHILDREN
+                && filter.getFulltextConditions().isEmpty()
+                && filter.getPropertyRestrictions().size() == 1) {
+            return 1.0;
+        } else {
+            return Double.MAX_VALUE;
+        }
+    }
+
+    @Override
+    public String getPlan(Filter filter) {
+        return "jcr:uuid";
+    }
+
+    @Override
+    public Cursor query(Filter filter, String revisionId, NodeState root) {
+        NodeState state = root.getChildNode("jcr:system");
+        if (state != null) {
+            state = state.getChildNode(":unique");
+        }
+        if (state != null) {
+            state = state.getChildNode("jcr:uuid");
+        }
+        if (state == null) {
+            state = MemoryNodeState.EMPTY_NODE;
+        }
+
+        List<String> paths = Lists.newArrayList();
+        PropertyRestriction pr = filter.getPropertyRestriction("jcr:uuid");
+        String value = pr.first.getString();
+        try {
+            value = URLEncoder.encode(value, Charsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            // ignore
+        }
+        PropertyState property = state.getProperty(pr.first.getString());
+        if (property != null && !property.isArray()) {
+            paths.add(property.getValue().getString());
+        }
+        final Iterator<String> iterator = paths.iterator();
+        return new Cursor() {
+            private String currentPath = null;
+            @Override
+            public boolean next() {
+                if (iterator.hasNext()) {
+                    currentPath = "/" + iterator.next();
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+            @Override
+            public IndexRow currentRow() {
+                return new IndexRowImpl(currentPath);
+            }
+        };
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndex.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndexValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndexValidator.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndexValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/unique/UniqueIndexValidator.java Wed Sep  5 19:08:07 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.plugins.unique;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.util.Map;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -27,6 +29,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
 
+import com.google.common.base.Charsets;
 import com.google.common.collect.Maps;
 
 public class UniqueIndexValidator implements Validator {
@@ -93,7 +96,11 @@ public class UniqueIndexValidator implem
     }
 
     private String encode(String value) {
-        return value; // TODO: escape to valid name
+        try {
+            return URLEncoder.encode(value, Charsets.UTF_8.name());
+        } catch (UnsupportedEncodingException e) {
+            return value;
+        }
     }
 
     private void insert(Iterable<CoreValue> values)

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java Wed Sep  5 19:08:07 2012
@@ -126,7 +126,7 @@ public class QueryEngineImpl {
         return best;
     }
 
-    private List<QueryIndex> getIndexes() {
+    private List<? extends QueryIndex> getIndexes() {
         return indexProvider.getQueryIndexes(mk);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/UserValidator.java Wed Sep  5 19:08:07 2012
@@ -16,14 +16,11 @@
  */
 package org.apache.jackrabbit.oak.security.user;
 
-import java.util.Set;
-import javax.annotation.Nonnull;
 import javax.jcr.nodetype.ConstraintViolationException;
 
-import com.google.common.collect.ImmutableSet;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.spi.commit.UniquePropertyValidator;
+import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
 import org.apache.jackrabbit.oak.spi.commit.Validator;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfig;
@@ -34,11 +31,7 @@ import org.apache.jackrabbit.util.Text;
 /**
  * UserValidator... TODO
  */
-class UserValidator extends UniquePropertyValidator implements UserConstants {
-
-    private final static Set<String> PROPERTY_NAMES = ImmutableSet.copyOf(new String[] {
-            REP_AUTHORIZABLE_ID, REP_PRINCIPAL_NAME
-    });
+class UserValidator extends DefaultValidator implements UserConstants {
 
     private final UserValidatorProvider provider;
 
@@ -52,23 +45,10 @@ class UserValidator extends UniqueProper
         this.provider = provider;
     }
 
-    @Nonnull
-    @Override
-    protected Set<String> getPropertyNames() {
-        // TODO: make configurable
-        return PROPERTY_NAMES;
-    }
-
     //----------------------------------------------------------< Validator >---
-    @Override
-    public void propertyAdded(PropertyState after) throws CommitFailedException {
-        super.propertyAdded(after);
-    }
 
     @Override
     public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
-        super.propertyChanged(before, after);
-
         String name = before.getName();
         if (REP_PRINCIPAL_NAME.equals(name) || REP_AUTHORIZABLE_ID.equals(name)) {
             throw new CommitFailedException("Authorizable property " + name + " may not be altered after user/group creation.");
@@ -76,11 +56,6 @@ class UserValidator extends UniqueProper
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) throws CommitFailedException {
-        // nothing to do
-    }
-
-    @Override
     public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
         NodeUtil node = parentAfter.getChild(name);
         String authRoot = null;
@@ -101,12 +76,6 @@ class UserValidator extends UniqueProper
         return new UserValidator(parentBefore.getChild(name), parentAfter.getChild(name), provider);
     }
 
-    @Override
-    public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
-        // nothing to do
-        return null;
-    }
-
     //------------------------------------------------------------< private >---
 
     /**

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndexProvider.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndexProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/QueryIndexProvider.java Wed Sep  5 19:08:07 2012
@@ -34,6 +34,6 @@ public interface QueryIndexProvider {
      * @param mk the MicroKernel instance
      * @return the list of indexes
      */
-    List<QueryIndex> getQueryIndexes(MicroKernel mk);
+    List<? extends QueryIndex> getQueryIndexes(MicroKernel mk);
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java?rev=1381300&r1=1381299&r2=1381300&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/user/UserProviderImplTest.java Wed Sep  5 19:08:07 2012
@@ -29,7 +29,9 @@ import org.apache.jackrabbit.oak.api.Con
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.ContentRepositoryImpl;
 import org.apache.jackrabbit.oak.core.DefaultConflictHandler;
+import org.apache.jackrabbit.oak.plugins.unique.UniqueIndexHook;
 import org.apache.jackrabbit.oak.spi.security.user.Type;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfig;
 import org.apache.jackrabbit.oak.spi.security.user.UserConstants;
@@ -102,7 +104,7 @@ public class UserProviderImplTest extend
 
     @Override
     protected ContentRepository createRepository() {
-        return createEmptyRepository();
+        return new ContentRepositoryImpl(new UniqueIndexHook());
     }
 
     private UserProvider createUserProvider() {