You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by tm...@apache.org on 2017/09/15 08:27:59 UTC

svn commit: r1808431 - in /sling/trunk/bundles: extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/ extensions/repoinit/parser/src/main/javacc/ extensions/repoinit/parser/src/test/resources/testcases/ jcr/repoinit/src/...

Author: tmaret
Date: Fri Sep 15 08:27:58 2017
New Revision: 1808431

URL: http://svn.apache.org/viewvc?rev=1808431&view=rev
Log:
SLING-7066 - Support mixins in repoinit "create path" statements

* Add parser support for creating paths with mixins
* Add JCR implementation

Modified:
    sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/CreatePath.java
    sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/PathSegmentDefinition.java
    sling/trunk/bundles/extensions/repoinit/parser/src/main/javacc/RepoInitGrammar.jjt
    sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20-output.txt
    sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20.txt
    sling/trunk/bundles/jcr/repoinit/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java
    sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java
    sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java

Modified: sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/CreatePath.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/CreatePath.java?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/CreatePath.java (original)
+++ sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/CreatePath.java Fri Sep 15 08:27:58 2017
@@ -44,8 +44,12 @@ public class CreatePath extends Operatio
     public void accept(OperationVisitor v) {
         v.visitCreatePath(this);
     }
-    
+
     public void addSegment(String path, String primaryType) {
+        addSegment(path, primaryType, null);
+    }
+
+    public void addSegment(String path, String primaryType, List<String> mixins) {
         // We might get a path like /var/discovery, in which case
         // the specified primary type applies to the last
         // segment only
@@ -55,10 +59,16 @@ public class CreatePath extends Operatio
                 continue;
             }
             String pt = defaultPrimaryType;
-            if(i == segments.length -1 && primaryType != null) {
-                pt = primaryType;
+            List<String> ms = null;
+            if(i == segments.length -1) {
+                if (primaryType != null) {
+                    pt = primaryType;
+                }
+                if (mixins != null && ! mixins.isEmpty()) {
+                    ms = mixins;
+                }
             }
-            pathDef.add(new PathSegmentDefinition(segments[i], pt));
+            pathDef.add(new PathSegmentDefinition(segments[i], pt, ms));
         }
     }
     

Modified: sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/PathSegmentDefinition.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/PathSegmentDefinition.java?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/PathSegmentDefinition.java (original)
+++ sling/trunk/bundles/extensions/repoinit/parser/src/main/java/org/apache/sling/repoinit/parser/operations/PathSegmentDefinition.java Fri Sep 15 08:27:58 2017
@@ -17,23 +17,44 @@
 
 package org.apache.sling.repoinit.parser.operations;
 
-/** Defines a segment of a path to be created, 
- *  with its name and an optional primary type
+import java.util.List;
+
+/** Defines a segment of a path to be created,
+ *  with its name and an optional primary type and optional mixins
  */
 public class PathSegmentDefinition {
     private final String segment;
     private final String primaryType;
+    private final List<String> mixins;
     
     public PathSegmentDefinition(String segment, String primaryType) {
+        this(segment, primaryType, null);
+    }
+
+    public PathSegmentDefinition(String segment, String primaryType, List<String> mixins) {
         this.segment = segment;
         this.primaryType = primaryType;
+        this.mixins = mixins;
     }
 
     public String toString() {
         final StringBuilder sb = new StringBuilder();
         sb.append(segment);
-        if(primaryType != null) {
-            sb.append("(").append(primaryType).append(")");
+        boolean hasPrimaryType = primaryType != null;
+        boolean hasMixin = mixins != null && ! mixins.isEmpty();
+        if (hasPrimaryType || hasMixin) {
+            sb.append("(");
+            if (hasPrimaryType) {
+                sb.append(primaryType);
+            }
+            if (hasPrimaryType && hasMixin) {
+                sb.append(" ");
+            }
+            if (hasMixin) {
+                sb.append("mixin ");
+                sb.append(mixins.toString());
+            }
+            sb.append(")");
         }
         return sb.toString();
     }
@@ -45,4 +66,8 @@ public class PathSegmentDefinition {
     public String getPrimaryType() {
         return primaryType;
     }
+
+    public List<String> getMixins() {
+        return mixins;
+    }
 }

Modified: sling/trunk/bundles/extensions/repoinit/parser/src/main/javacc/RepoInitGrammar.jjt
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/repoinit/parser/src/main/javacc/RepoInitGrammar.jjt?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/repoinit/parser/src/main/javacc/RepoInitGrammar.jjt (original)
+++ sling/trunk/bundles/extensions/repoinit/parser/src/main/javacc/RepoInitGrammar.jjt Fri Sep 15 08:27:58 2017
@@ -65,6 +65,7 @@ TOKEN:
 |   < DELETE: "delete" >
 |   < DISABLE: "disable" >
 |   < SERVICE: "service" >
+|   < MIXIN: "mixin" >
 |   < PATH: "path" >
 |   < END: "end" >
 |   < USER: "user" >
@@ -207,18 +208,22 @@ void createPathStatement(List<Operation>
     String defaultPrimaryType = null;
     Token t1 = null;
     Token t2 = null;
+    List<String> t3 = null;
 }
 {
     <CREATE> <PATH> 
     ( <LPAREN> t1 = <NAMESPACED_ITEM> <RPAREN> { defaultPrimaryType = t1.image; } ) ?
     
     ( t1 = <PATH_STRING> ( <LPAREN> t2 = <NAMESPACED_ITEM> <RPAREN> ) ?
+                         ( <LPAREN> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ?
+                         ( <LPAREN> t2 = <NAMESPACED_ITEM> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ?
         {
             if(cp == null) {
                 cp = new CreatePath(defaultPrimaryType);
             } 
-            cp.addSegment(t1.image, t2 == null ? null : t2.image); 
-            t2 = null; 
+            cp.addSegment(t1.image, t2 == null ? null : t2.image, t3);
+            t2 = null;
+            t3 = null;
         }
     ) +
     

Modified: sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20-output.txt
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20-output.txt?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20-output.txt (original)
+++ sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20-output.txt Fri Sep 15 08:27:58 2017
@@ -1,4 +1,9 @@
 CreatePath [var(sling:Folder), discovery(nt:unstructured), somefolder(sling:Folder)]
 CreatePath [one, two, three]
 CreatePath [three, four(nt:folk), five(nt:jazz), six]
-CreatePath [seven(nt:x), eight(nt:x), nine(nt:x)]
\ No newline at end of file
+CreatePath [seven(nt:x), eight(nt:x), nine(nt:x)]
+CreatePath [one(mixin [nt:art]), step(mixin [nt:dance]), two, steps]
+CreatePath [one(nt:foxtrot), step(nt:foxtrot mixin [nt:dance]), two(nt:foxtrot), steps(nt:foxtrot)]
+CreatePath [one, step(mixin [nt:dance, nt:art]), two, steps]
+CreatePath [one, step(nt:foxtrot mixin [nt:dance]), two, steps]
+CreatePath [one, step(nt:foxtrot mixin [nt:dance, nt:art]), two, steps]
\ No newline at end of file

Modified: sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20.txt
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20.txt?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20.txt (original)
+++ sling/trunk/bundles/extensions/repoinit/parser/src/test/resources/testcases/test-20.txt Fri Sep 15 08:27:58 2017
@@ -3,3 +3,8 @@ create path (sling:Folder) /var/discover
 create path /one/two/three
 create path /three/four(nt:folk)/five(nt:jazz)/six
 create path (nt:x) /seven/eight/nine
+create path /one(mixin nt:art)/step(mixin nt:dance)/two/steps
+create path (nt:foxtrot) /one/step(mixin nt:dance)/two/steps
+create path /one/step(mixin nt:dance,nt:art)/two/steps
+create path /one/step(nt:foxtrot mixin nt:dance)/two/steps
+create path /one/step(nt:foxtrot mixin nt:dance,nt:art)/two/steps
\ No newline at end of file

Modified: sling/trunk/bundles/jcr/repoinit/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/repoinit/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/repoinit/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java (original)
+++ sling/trunk/bundles/jcr/repoinit/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java Fri Sep 15 08:27:58 2017
@@ -91,9 +91,16 @@ class AclVisitor extends DoNothingVisito
                     if(session.itemExists(fullPath)) {
                         log.info("Path already exists, nothing to do (and not checking its primary type for now): {}", fullPath);
                     } else {
-                        final Node n = parentPath.equals("") ? session.getRootNode() : session.getNode(parentPath);
+                        final Node parent = parentPath.equals("") ? session.getRootNode() : session.getNode(parentPath);
                         log.info("Creating node {} with primary type {}", fullPath, psd.getPrimaryType());
-                        n.addNode(psd.getSegment(), psd.getPrimaryType());
+                        Node node = parent.addNode(psd.getSegment(), psd.getPrimaryType());
+                        List<String> mixins = psd.getMixins();
+                        if (mixins != null) {
+                            log.info("Adding mixins {} to node {}", mixins, fullPath);
+                            for (String mixin : mixins) {
+                                node.addMixin(mixin);
+                            }
+                        }
                     }
                 } catch(Exception e) {
                     throw new RuntimeException("CreatePath execution failed at " + psd + ": " + e, e);

Modified: sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java (original)
+++ sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java Fri Sep 15 08:27:58 2017
@@ -17,6 +17,8 @@
 package org.apache.sling.jcr.repoinit;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
 
 import javax.jcr.RepositoryException;
 
@@ -75,4 +77,30 @@ public class CreatePathsTest {
         U.assertNodeExists("/ten/eleven", "sling:Folder");
         U.assertNodeExists("/ten/eleven/twelve", "sling:Folder");
     }
+
+    @Test
+    public void createPathWithMixins() throws Exception {
+        final String path = "/eleven(mixin mix:lockable)/twelve(mixin mix:referenceable,mix:shareable)/thirteen";
+        U.parseAndExecute("create path " + path);
+        U.assertNodeExists("/eleven", Collections.singletonList("mix:lockable"));
+        U.assertNodeExists("/eleven/twelve", Arrays.asList("mix:shareable", "mix:referenceable"));
+    }
+
+    @Test
+    public void createPathWithJcrDefaultTypeAndMixins() throws Exception {
+        final String path = "/twelve/thirteen(mixin mix:lockable)/fourteen";
+        U.parseAndExecute("create path (nt:unstructured)" + path);
+        U.assertNodeExists("/twelve", "nt:unstructured", Collections.<String>emptyList());
+        U.assertNodeExists("/twelve/thirteen", "nt:unstructured", Collections.singletonList("mix:lockable"));
+        U.assertNodeExists("/twelve/thirteen/fourteen", "nt:unstructured", Collections.<String>emptyList());
+    }
+
+    @Test
+    public void createPathWithJcrTypeAndMixins() throws Exception {
+        final String path = "/thirteen(nt:unstructured)/fourteen(nt:unstructured mixin mix:lockable)/fifteen(mixin mix:lockable)";
+        U.parseAndExecute("create path " + path);
+        U.assertNodeExists("/thirteen", "nt:unstructured", Collections.<String>emptyList());
+        U.assertNodeExists("/thirteen/fourteen", "nt:unstructured", Collections.singletonList("mix:lockable"));
+        U.assertNodeExists("/thirteen/fourteen/fifteen", "nt:unstructured", Collections.singletonList("mix:lockable"));
+    }
 }

Modified: sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java?rev=1808431&r1=1808430&r2=1808431&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java (original)
+++ sling/trunk/bundles/jcr/repoinit/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java Fri Sep 15 08:27:58 2017
@@ -31,6 +31,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.api.security.user.Authorizable;
@@ -86,10 +87,18 @@ public class TestUtil {
     }
 
     public void assertNodeExists(String path) throws RepositoryException {
-        assertNodeExists(path, null);
+        assertNodeExists(path, null, null);
     }
 
     public void assertNodeExists(String path, String primaryType) throws RepositoryException {
+        assertNodeExists(path, primaryType, null);
+    }
+
+    public void assertNodeExists(String path, List<String> mixins) throws RepositoryException {
+        assertNodeExists(path, null, mixins);
+    }
+
+    public void assertNodeExists(String path, String primaryType, List<String> mixins) throws RepositoryException {
         if(!adminSession.nodeExists(path)) {
             fail("Node does not exist:" + path);
         }
@@ -103,6 +112,18 @@ public class TestUtil {
                 fail("Primary type mismatch for " + path + ", expected " + primaryType + " but got " + actual);
             }
         }
+        if (mixins != null) {
+            final Node n = adminSession.getNode(path);
+            NodeType[] mixinNodeTypes = n.getMixinNodeTypes();
+            if (mixinNodeTypes.length != mixins.size()) {
+                fail("Number of mixin node types does not match, expected " + mixins.size() + " but got " + mixinNodeTypes.length);
+            }
+            for (NodeType mixinNodeType : mixinNodeTypes) {
+                if (! mixins.contains(mixinNodeType.getName())) {
+                    fail("Node contains the unexpected mixin node type " + mixinNodeType.getName());
+                }
+            }
+        }
     }
 
     public void parseAndExecute(String input) throws RepositoryException, RepoInitParsingException {