jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alexparvule...@apache.org
Subject svn commit: r1439331 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/index/p2/ test/java/org/apache/jackrabbit/oak/plugins/index/p2/
Date Mon, 28 Jan 2013 10:23:43 GMT
Author: alexparvulescu
Date: Mon Jan 28 10:23:43 2013
New Revision: 1439331

URL: http://svn.apache.org/viewvc?rev=1439331&view=rev
Log:
OAK-396

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2Index.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexDiff.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexUpdate.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2Index.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2Index.java?rev=1439331&r1=1439330&r2=1439331&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2Index.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2Index.java
Mon Jan 28 10:23:43 2013
@@ -38,7 +38,7 @@ import com.google.common.base.Charsets;
  * <p>
  * To define a property index on a subtree you have to add an <code>oak:index</code>
node.
  * 
- * Under it follows the index definition node that:
+ * Next (as a child node) follows the index definition node that:
  * <ul>
  * <li>must be of type <code>oak:queryIndexDefinition</code></li>
  * <li>must have the <code>type</code> property set to <b><code>p2</code></b></li>
@@ -46,10 +46,12 @@ import com.google.common.base.Charsets;
  * </ul>
  * </p>
  * <p>
- * Optionally you can specify the uniqueness constraint on a property index by
- * setting the <code>unique</code> flag to <code>true</code>.
+ * Optionally you can specify
+ * <ul> 
+ * <li> a uniqueness constraint on a property index by setting the <code>unique</code>
flag to <code>true</code></li>
+ * <li> that the property index only applies to a certain node type by setting the
<code>declaringNodeTypes</code> property</li>
+ * </ul>
  * </p>
- * 
  * <p>
  * Note: <code>propertyNames</code> can be a list of properties, and it is optional.in
case it is missing, the node name will be used as a property name reference value
  * </p>
@@ -66,6 +68,7 @@ import com.google.common.base.Charsets;
  *         .setProperty("jcr:primaryType", "oak:queryIndexDefinition", Type.NAME)
  *         .setProperty("type", "p2")
  *         .setProperty("propertyNames", "jcr:uuid")
+ *         .setProperty("declaringNodeTypes", "mix:referenceable")
  *         .setProperty("unique", true)
  *         .setProperty("reindex", true);
  * }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexDiff.java?rev=1439331&r1=1439330&r2=1439331&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexDiff.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexDiff.java
Mon Jan 28 10:23:43 2013
@@ -22,14 +22,16 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.p2.Property2Index.TYPE;
+import static com.google.common.collect.Lists.newArrayList;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
+
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
@@ -54,6 +56,11 @@ import org.apache.jackrabbit.oak.spi.sta
  */
 class Property2IndexDiff implements IndexHook {
 
+    protected static String propertyNames = "propertyNames";
+
+    protected static String declaringNodeTypes = "declaringNodeTypes";
+
+    
     private final IndexStoreStrategy store = new ContentMirrorStoreStrategy();
 
     /**
@@ -138,21 +145,45 @@ class Property2IndexDiff implements Inde
      */
     private Iterable<Property2IndexUpdate> getIndexes(String name) {
         List<Property2IndexUpdate> indexes = updates.get(name);
-        if (indexes != null) {
-            return indexes;
-        } else {
+        if (indexes == null) {
             return ImmutableList.of();
         }
+        List<Property2IndexUpdate> filtered = new ArrayList<Property2IndexUpdate>();
+        for (Property2IndexUpdate pi : indexes) {
+            if (pi.getNodeTypeNames() == null
+                    || pi.getNodeTypeNames().isEmpty()) {
+                filtered.add(pi);
+                continue;
+            }
+            PropertyState ps = node.getProperty(JCR_PRIMARYTYPE);
+            String type = ps != null && !ps.isArray() ? ps
+                    .getValue(Type.STRING) : null;
+            if (type != null) {
+                for (String typeName : pi.getNodeTypeNames()) {
+                    if (typeName.equals(type)) {
+                        filtered.add(pi);
+                        break;
+                    }
+                }
+            }
+        }
+        return filtered;
     }
 
     private void update(NodeBuilder builder, String indexName) {
-        PropertyState ps = builder.getProperty("propertyNames");
+        List<String> typeNames = ImmutableList.of();
+        PropertyState appliesTo = builder.getProperty(declaringNodeTypes);
+        if (appliesTo != null) {
+            typeNames = newArrayList(appliesTo.getValue(Type.STRINGS));
+        }
+        PropertyState ps = builder.getProperty(propertyNames);
+
         Iterable<String> propertyNames = ps != null ? ps.getValue(Type.STRINGS)
                 : ImmutableList.of(indexName);
         for (String pname : propertyNames) {
             List<Property2IndexUpdate> list = this.updates.get(pname);
             if (list == null) {
-                list = Lists.newArrayList();
+                list = newArrayList();
                 this.updates.put(pname, list);
             }
             boolean exists = false;
@@ -163,7 +194,7 @@ class Property2IndexDiff implements Inde
                 }
             }
             if (!exists) {
-                list.add(new Property2IndexUpdate(getPath(), builder, store));
+                list.add(new Property2IndexUpdate(getPath(), builder, store, typeNames));
             }
         }
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexUpdate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexUpdate.java?rev=1439331&r1=1439330&r2=1439331&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexUpdate.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexUpdate.java
Mon Jan 28 10:23:43 2013
@@ -51,6 +51,13 @@ class Property2IndexUpdate {
     private final String path;
 
     /**
+     * The node types that this index applies to. If <code>null</code> or
+     * <code>empty</code> then the node type of the indexed node is ignored
+     * 
+     */
+    private final List<String> nodeTypeNames;
+
+    /**
      * The node where the index definition is stored.
      */
     private final NodeBuilder node;
@@ -69,18 +76,29 @@ class Property2IndexUpdate {
      */
     private final Map<String, Set<String>> remove;
 
-    public Property2IndexUpdate(String path, NodeBuilder node, IndexStoreStrategy store)
{
+    public Property2IndexUpdate(String path, NodeBuilder node,
+            IndexStoreStrategy store) {
+        this(path, node, store, null);
+    }
+
+    public Property2IndexUpdate(String path, NodeBuilder node,
+            IndexStoreStrategy store, List<String> nodeTypeNames) {
         this.path = path;
         this.node = node;
         this.store = store;
         this.insert = Maps.newHashMap();
         this.remove = Maps.newHashMap();
+        this.nodeTypeNames = nodeTypeNames;
     }
 
     String getPath() {
         return path;
     }
 
+    public List<String> getNodeTypeNames() {
+        return nodeTypeNames;
+    }
+
     /**
      * A property value was added at the given path.
      * 

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexTest.java?rev=1439331&r1=1439330&r2=1439331&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/p2/Property2IndexTest.java
Mon Jan 28 10:23:43 2013
@@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
 import java.util.Arrays;
 import java.util.Set;
 
+import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.index.IndexHook;
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
@@ -130,8 +131,105 @@ public class Property2IndexTest {
         } catch (IllegalArgumentException e) {
             // expected: no index for "pqr"
         }
+    }
+
+    @Test
+    public void testUnique() throws Exception {
+
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        // Add index definition
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index")
+                .child("fooIndex")
+                .setProperty("jcr:primaryType", "oak:queryIndexDefinition",
+                        Type.NAME)
+                .setProperty("type", "p2")
+                .setProperty("unique", "true")
+                .setProperty("propertyNames", Arrays.asList("foo"),
+                        Type.STRINGS);
+
+        NodeState before = builder.getNodeState();
+        builder = before.builder();
+        builder.child("a").setProperty("foo", "abc");
+        builder.child("b").setProperty("foo", Arrays.asList("abc", "def"),
+                Type.STRINGS);
+        NodeState after = builder.getNodeState();
 
+        IndexHook p = new Property2IndexDiff(builder);
+        after.compareAgainstBaseState(before, p);
+        try {
+            p.apply();
+            fail("Unique constraint should be respected");
+        } catch (CommitFailedException e) {
+            // expected
+        } finally {
+            p.close();
+        }
     }
 
+    @Test
+    public void testUniqueByTypeOK() throws Exception {
+
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        // Add index definition
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("fooIndex")
+                .setProperty("jcr:primaryType", "oak:queryIndexDefinition", Type.NAME)
+                .setProperty("type", "p2")
+                .setProperty("unique", "true")
+                .setProperty("propertyNames", Arrays.asList("foo"), Type.STRINGS)
+                .setProperty(Property2IndexDiff.declaringNodeTypes, Arrays.asList("typeFoo"),
Type.STRINGS);
+        NodeState before = builder.getNodeState();
+        builder = before.builder();
+        builder.child("a")
+                .setProperty("jcr:primaryType", "typeFoo", Type.NAME)
+                .setProperty("foo", "abc");
+        builder.child("b")
+                .setProperty("jcr:primaryType", "typeBar", Type.NAME)
+                .setProperty("foo", "abc");
+        NodeState after = builder.getNodeState();
+
+        IndexHook p = new Property2IndexDiff(builder);
+        after.compareAgainstBaseState(before, p);
+        p.apply();
+        p.close();
+    }
+
+    @Test
+    public void testUniqueByTypeKO() throws Exception {
+
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        // Add index definition
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("fooIndex")
+                .setProperty("jcr:primaryType", "oak:queryIndexDefinition", Type.NAME)
+                .setProperty("type", "p2")
+                .setProperty("unique", "true")
+                .setProperty("propertyNames", Arrays.asList("foo"), Type.STRINGS)
+                .setProperty(Property2IndexDiff.declaringNodeTypes, Arrays.asList("typeFoo"),
Type.STRINGS);
+        NodeState before = builder.getNodeState();
+        builder = before.builder();
+        builder.child("a")
+                .setProperty("jcr:primaryType", "typeFoo", Type.NAME)
+                .setProperty("foo", "abc");
+        builder.child("b")
+                .setProperty("jcr:primaryType", "typeFoo", Type.NAME)
+                .setProperty("foo", "abc");
+        NodeState after = builder.getNodeState();
+
+        IndexHook p = new Property2IndexDiff(builder);
+        after.compareAgainstBaseState(before, p);
+        try {
+            p.apply();
+            fail("Unique constraint should be respected");
+        } catch (CommitFailedException e) {
+            // expected
+        } finally {
+            p.close();
+        }
+    }
 
 }



Mime
View raw message