You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2022/12/14 18:57:30 UTC

[sling-org-apache-sling-jcr-repoinit] 01/01: SLING-11735 separate node from ACL operations

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/separate-acls-and-node-visitor
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git

commit b4eda7c107cc0c84a4b0af11a2d3f3251183b03e
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Wed Dec 14 19:57:22 2022 +0100

    SLING-11735 separate node from ACL operations
---
 .../apache/sling/jcr/repoinit/impl/AclVisitor.java | 115 ---------------
 .../repoinit/impl/JcrRepoInitOpsProcessorImpl.java |   1 +
 .../jcr/repoinit/impl/NodePropertiesVisitor.java   |   1 +
 .../sling/jcr/repoinit/impl/NodeVisitor.java       | 160 +++++++++++++++++++++
 .../org/apache/sling/jcr/repoinit/MixinsTest.java  |   4 +-
 5 files changed, 164 insertions(+), 117 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java
index 09e0293..b69dd24 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/AclVisitor.java
@@ -23,29 +23,20 @@ import static org.apache.sling.repoinit.parser.operations.AclLine.PROP_PRIVILEGE
 import java.util.Collections;
 import java.util.List;
 
-import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.nodetype.ConstraintViolationException;
 
 import org.apache.sling.repoinit.parser.operations.AclLine;
-import org.apache.sling.repoinit.parser.operations.AddMixins;
-import org.apache.sling.repoinit.parser.operations.CreatePath;
 import org.apache.sling.repoinit.parser.operations.DeleteAclPrincipalBased;
 import org.apache.sling.repoinit.parser.operations.DeleteAclPrincipals;
-import org.apache.sling.repoinit.parser.operations.PathSegmentDefinition;
-import org.apache.sling.repoinit.parser.operations.PropertyLine;
 import org.apache.sling.repoinit.parser.operations.DeleteAclPaths;
 import org.apache.sling.repoinit.parser.operations.RemoveAcePaths;
 import org.apache.sling.repoinit.parser.operations.RemoveAcePrincipalBased;
 import org.apache.sling.repoinit.parser.operations.RemoveAcePrincipals;
-import org.apache.sling.repoinit.parser.operations.RemoveMixins;
 import org.apache.sling.repoinit.parser.operations.RestrictionClause;
 import org.apache.sling.repoinit.parser.operations.SetAclPaths;
 import org.apache.sling.repoinit.parser.operations.SetAclPrincipalBased;
 import org.apache.sling.repoinit.parser.operations.SetAclPrincipals;
-import org.apache.sling.repoinit.parser.operations.SetProperties;
-import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -180,112 +171,6 @@ class AclVisitor extends DoNothingVisitor {
         }
     }
 
-    @Override
-    public void visitCreatePath(CreatePath cp) {
-        StringBuilder parentPathBuilder = new StringBuilder();
-        for (PathSegmentDefinition psd : cp.getDefinitions()) {
-            String parentPath = parentPathBuilder.toString();
-            final String fullPath = String.format("%s/%s", parentPath, psd.getSegment());
-            try {
-                if (session.itemExists(fullPath)) {
-                    log.info("Path already exists, nothing to do (and not checking its primary type for now): {}", fullPath);
-                } else {
-                    final Node parent = parentPath.equals("") ? session.getRootNode() : session.getNode(parentPath);
-                    log.info("Creating node {} with primary type {}", fullPath, psd.getPrimaryType());
-                    Node node = addChildNode(parent, psd);
-                    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) {
-                report(e, "CreatePath execution failed at " + psd + ": " + e);
-            }
-            parentPathBuilder.append("/").append(psd.getSegment());
-        }
-        List<PropertyLine> propertyLines = cp.getPropertyLines();
-        if (!propertyLines.isEmpty()) {
-            // delegate to the NodePropertiesVisitor to set the properties
-            SetProperties sp = new SetProperties(Collections.singletonList(parentPathBuilder.toString()), propertyLines);
-            NodePropertiesVisitor npv = new NodePropertiesVisitor(session);
-            npv.visitSetProperties(sp);
-        }
-        try {
-            session.save();
-        } catch (Exception e) {
-            report(e, "Session.save failed: " + e);
-        }
-    }
-
-    @Override
-    public void visitAddMixins(AddMixins am) {
-        List<String> paths = am.getPaths();
-        if (paths != null) {
-            for (String absPath : paths) {
-                try {
-                    if (!session.itemExists(absPath)) {
-                        log.warn("Path does not exist, not adding mixins: {}", absPath);
-                    } else {
-                        List<String> mixins = am.getMixins();
-                        if (mixins != null) {
-                            Node node = session.getNode(absPath);
-                            log.info("Adding mixins {} to node {}", mixins, absPath);
-                            for (String mixin : mixins) {
-                                node.addMixin(mixin);
-                            }
-                        }
-                    }
-                } catch (Exception e) {
-                    report(e, "AddMixins execution failed at " + absPath + ": " + e);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void visitRemoveMixins(RemoveMixins rm) {
-        List<String> paths = rm.getPaths();
-        if (paths != null) {
-            for (String absPath : paths) {
-                try {
-                    if (!session.itemExists(absPath)) {
-                        log.warn("Path does not exist, not removing mixins: {}", absPath);
-                    } else {
-                        List<String> mixins = rm.getMixins();
-                        if (mixins != null) {
-                            Node node = session.getNode(absPath);
-                            log.info("Removing mixins {} from node {}", mixins, absPath);
-                            for (String mixin : mixins) {
-                                node.removeMixin(mixin);
-                            }
-                        }
-                    }
-                } catch (Exception e) {
-                    report(e, "RemoveMixins execution failed at " + absPath + ": " + e);
-                }
-            }
-        }
-    }
-
-    @NotNull
-    private static Node addChildNode(@NotNull Node parent, @NotNull PathSegmentDefinition psd) throws RepositoryException {
-        String primaryType = psd.getPrimaryType();
-        if (primaryType == null) {
-            try {
-                return parent.addNode(psd.getSegment());
-            } catch (ConstraintViolationException e) {
-                // assume that no default primary type could be detected -> retry with a default
-                slog.info("Adding Node without node type failed ('{}'), retry with sling:Folder", e.getMessage());
-                return parent.addNode(psd.getSegment(), "sling:Folder");
-            }
-        } else {
-            return parent.addNode(psd.getSegment(), psd.getPrimaryType());
-        }
-    }
-
     @Override
     public void visitDeleteAclPrincipals(DeleteAclPrincipals s) {
         for (String principalName : s.getPrincipals()) {
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java
index be30809..ddd8b8b 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java
@@ -46,6 +46,7 @@ public class JcrRepoInitOpsProcessorImpl implements JcrRepoInitOpsProcessor {
                 new NodetypesVisitor(session),
                 new PrivilegeVisitor(session),
                 new UserVisitor(session),
+                new NodeVisitor(session),
                 new AclVisitor(session),
                 new GroupMembershipVisitor(session),
                 new NodePropertiesVisitor(session)
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/NodePropertiesVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodePropertiesVisitor.java
index e9f4a23..73d056e 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/NodePropertiesVisitor.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodePropertiesVisitor.java
@@ -51,6 +51,7 @@ import org.jetbrains.annotations.Nullable;
  * OperationVisitor which processes only operations related to setting node
  * properties. Having several such specialized visitors makes it easy to control
  * the execution order.
+ * @see NodeVisitor NodeVisitor, for operations related to nodes and their types
  */
 class NodePropertiesVisitor extends DoNothingVisitor {
     /**
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/NodeVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodeVisitor.java
new file mode 100644
index 0000000..8c4c0b9
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodeVisitor.java
@@ -0,0 +1,160 @@
+/*
+ * 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.sling.jcr.repoinit.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.ConstraintViolationException;
+
+import org.apache.sling.repoinit.parser.operations.AddMixins;
+import org.apache.sling.repoinit.parser.operations.CreatePath;
+import org.apache.sling.repoinit.parser.operations.PathSegmentDefinition;
+import org.apache.sling.repoinit.parser.operations.PropertyLine;
+import org.apache.sling.repoinit.parser.operations.RemoveMixins;
+import org.apache.sling.repoinit.parser.operations.SetProperties;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OperationVisitor which processes only operations related to nodes (but not its properties)
+ * @see NodePropertiesVisitor NodePropertiesVisitor, for operations related to node properties
+ */
+public class NodeVisitor extends DoNothingVisitor {
+    private static final Logger slog = LoggerFactory.getLogger(NodeVisitor.class);
+
+    /**
+     * Create a visitor using the supplied JCR Session.
+     *
+     * @param s must have sufficient rights to create nodes
+     */
+    protected NodeVisitor(Session s) {
+        super(s);
+    }
+
+    @Override
+    public void visitCreatePath(CreatePath cp) {
+        StringBuilder parentPathBuilder = new StringBuilder();
+        for (PathSegmentDefinition psd : cp.getDefinitions()) {
+            String parentPath = parentPathBuilder.toString();
+            final String fullPath = String.format("%s/%s", parentPath, psd.getSegment());
+            try {
+                if (session.itemExists(fullPath)) {
+                    log.info("Path already exists, nothing to do (and not checking its primary type for now): {}", fullPath);
+                } else {
+                    final Node parent = parentPath.equals("") ? session.getRootNode() : session.getNode(parentPath);
+                    log.info("Creating node {} with primary type {}", fullPath, psd.getPrimaryType());
+                    Node node = addChildNode(parent, psd);
+                    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) {
+                report(e, "CreatePath execution failed at " + psd + ": " + e);
+            }
+            parentPathBuilder.append("/").append(psd.getSegment());
+        }
+        List<PropertyLine> propertyLines = cp.getPropertyLines();
+        if (!propertyLines.isEmpty()) {
+            // delegate to the NodePropertiesVisitor to set the properties
+            SetProperties sp = new SetProperties(Collections.singletonList(parentPathBuilder.toString()), propertyLines);
+            NodePropertiesVisitor npv = new NodePropertiesVisitor(session);
+            npv.visitSetProperties(sp);
+        }
+        try {
+            session.save();
+        } catch (Exception e) {
+            report(e, "Session.save failed: " + e);
+        }
+    }
+
+    @Override
+    public void visitAddMixins(AddMixins am) {
+        List<String> paths = am.getPaths();
+        if (paths != null) {
+            for (String absPath : paths) {
+                try {
+                    if (!session.itemExists(absPath)) {
+                        log.warn("Path does not exist, not adding mixins: {}", absPath);
+                    } else {
+                        List<String> mixins = am.getMixins();
+                        if (mixins != null) {
+                            Node node = session.getNode(absPath);
+                            log.info("Adding mixins {} to node {}", mixins, absPath);
+                            for (String mixin : mixins) {
+                                node.addMixin(mixin);
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    report(e, "AddMixins execution failed at " + absPath + ": " + e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void visitRemoveMixins(RemoveMixins rm) {
+        List<String> paths = rm.getPaths();
+        if (paths != null) {
+            for (String absPath : paths) {
+                try {
+                    if (!session.itemExists(absPath)) {
+                        log.warn("Path does not exist, not removing mixins: {}", absPath);
+                    } else {
+                        List<String> mixins = rm.getMixins();
+                        if (mixins != null) {
+                            Node node = session.getNode(absPath);
+                            log.info("Removing mixins {} from node {}", mixins, absPath);
+                            for (String mixin : mixins) {
+                                node.removeMixin(mixin);
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    report(e, "RemoveMixins execution failed at " + absPath + ": " + e);
+                }
+            }
+        }
+    }
+
+    @NotNull
+    private static Node addChildNode(@NotNull Node parent, @NotNull PathSegmentDefinition psd) throws RepositoryException {
+        String primaryType = psd.getPrimaryType();
+        if (primaryType == null) {
+            try {
+                return parent.addNode(psd.getSegment());
+            } catch (ConstraintViolationException e) {
+                // assume that no default primary type could be detected -> retry with a default
+                slog.info("Adding Node without node type failed ('{}'), retry with sling:Folder", e.getMessage());
+                return parent.addNode(psd.getSegment(), "sling:Folder");
+            }
+        } else {
+            return parent.addNode(psd.getSegment(), psd.getPrimaryType());
+        }
+    }
+
+
+}
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java b/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java
index ff423c4..735468e 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java
@@ -96,7 +96,7 @@ public class MixinsTest {
 
     @Test
     public void addMixinOnNotExistingPath() throws Exception {
-        try (LogCapture capture = new LogCapture("org.apache.sling.jcr.repoinit.impl.AclVisitor", true)) {
+        try (LogCapture capture = new LogCapture("org.apache.sling.jcr.repoinit.impl.NodeVisitor", true)) {
             // this should just log a warning and continue
             U.parseAndExecute("add mixin mix:lockable to /addMixinOnNotExistingPath");
             assertNodeNotExists("/addMixinOnNotExistingPath");
@@ -108,7 +108,7 @@ public class MixinsTest {
 
     @Test
     public void removeMixinFromNotExistingPath() throws Exception {
-        try (LogCapture capture = new LogCapture("org.apache.sling.jcr.repoinit.impl.AclVisitor", true)) {
+        try (LogCapture capture = new LogCapture("org.apache.sling.jcr.repoinit.impl.NodeVisitor", true)) {
             // this should just log a warning and continue
             U.parseAndExecute("remove mixin mix:lockable from /removeMixinFromNotExistingPath");
             assertNodeNotExists("/removeMixinFromNotExistingPath");