You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by an...@apache.org on 2021/05/20 09:42:08 UTC
[sling-org-apache-sling-jcr-repoinit] 01/01: SLING-10406 :
AclVisitor.visitCreatePath: retry if no default primary type can be found
This is an automated email from the ASF dual-hosted git repository.
angela pushed a commit to branch SLING-10406
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git
commit e28553cafe4c896cd40fd94ce30d8bb0d33e8a2e
Author: angela <an...@adobe.com>
AuthorDate: Thu May 20 11:41:50 2021 +0200
SLING-10406 : AclVisitor.visitCreatePath: retry if no default primary type can be found
---
.../apache/sling/jcr/repoinit/impl/AclVisitor.java | 89 ++++++++++++++--------
.../apache/sling/jcr/repoinit/CreatePathsTest.java | 15 ++++
2 files changed, 72 insertions(+), 32 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 45659f6..9e363ef 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
@@ -26,6 +26,7 @@ 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.CreatePath;
@@ -37,16 +38,24 @@ 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.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-/** OperationVisitor which processes only operations related to ACLs.
+/**
+ * OperationVisitor which processes only operations related to ACLs.
* Having several such specialized visitors
* makes it easy to control the execution order.
*/
class AclVisitor extends DoNothingVisitor {
- /** Create a visitor using the supplied JCR Session.
+ private static final Logger log = LoggerFactory.getLogger(AclVisitor.class);
+
+ /**
+ * Create a visitor using the supplied JCR Session.
+ *
* @param s must have sufficient rights to create users
- * and set ACLs.
+ * and set ACLs.
*/
public AclVisitor(Session s) {
super(s);
@@ -54,7 +63,7 @@ class AclVisitor extends DoNothingVisitor {
private List<String> require(AclLine line, String propertyName) {
final List<String> result = line.getProperty(propertyName);
- if(result == null) {
+ if (result == null) {
throw new IllegalStateException("Missing property " + propertyName + " on " + line);
}
return result;
@@ -72,7 +81,7 @@ class AclVisitor extends DoNothingVisitor {
List<RestrictionClause> restrictions = line.getRestrictions();
AclUtil.setAcl(s, principals, paths, privileges, isAllow, restrictions);
}
- } catch(Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to set ACL (" + e.toString() + ") " + line, e);
}
}
@@ -89,7 +98,7 @@ class AclVisitor extends DoNothingVisitor {
List<RestrictionClause> restrictions = line.getRestrictions();
AclUtil.setRepositoryAcl(s, principals, privileges, isAllow, restrictions);
}
- } catch(Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to set repository level ACL (" + e.toString() + ") " + line, e);
}
}
@@ -99,13 +108,13 @@ class AclVisitor extends DoNothingVisitor {
final List<String> principals = s.getPrincipals();
for (AclLine line : s.getLines()) {
final List<String> paths = line.getProperty(PROP_PATHS);
- if (paths != null && ! paths.isEmpty()) {
+ if (paths != null && !paths.isEmpty()) {
setAcl(line, session, principals, paths, require(line, PROP_PRIVILEGES), line.getAction());
} else {
setRepositoryAcl(line, session, principals, require(line, PROP_PRIVILEGES), line.getAction());
}
}
- }
+ }
@Override
public void visitSetAclPaths(SetAclPaths s) {
@@ -121,7 +130,7 @@ class AclVisitor extends DoNothingVisitor {
try {
log.info("Adding principal-based access control entry for {}", principalName);
AclUtil.setPrincipalAcl(session, principalName, s.getLines());
- } catch(Exception e) {
+ } catch (Exception e) {
throw new RuntimeException("Failed to set principal-based ACL (" + e.getMessage() + ")", e);
}
}
@@ -130,35 +139,51 @@ class AclVisitor extends DoNothingVisitor {
@Override
public void visitCreatePath(CreatePath cp) {
String parentPath = "";
- for(PathSegmentDefinition psd : cp.getDefinitions()) {
- final String fullPath = 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 = 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);
- }
+ for (PathSegmentDefinition psd : cp.getDefinitions()) {
+ final String fullPath = 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) {
- throw new RuntimeException("CreatePath execution failed at " + psd + ": " + e, e);
}
- parentPath += "/" + psd.getSegment();
+ } catch (Exception e) {
+ throw new RuntimeException("CreatePath execution failed at " + psd + ": " + e, e);
}
+ parentPath += "/" + psd.getSegment();
+ }
try {
session.save();
- } catch(Exception e) {
- throw new RuntimeException("Session.save failed: "+ e, e);
+ } catch (Exception e) {
+ throw new RuntimeException("Session.save failed: " + e, 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
+ log.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()) {
@@ -166,7 +191,7 @@ class AclVisitor extends DoNothingVisitor {
log.info("Removing access control policy for {}", principalName);
AclUtil.removePolicy(session, principalName);
} catch (RepositoryException e) {
- throw new RuntimeException("Failed to remove ACL ("+e.getMessage()+")");
+ throw new RuntimeException("Failed to remove ACL (" + e.getMessage() + ")");
}
}
}
@@ -176,7 +201,7 @@ class AclVisitor extends DoNothingVisitor {
try {
AclUtil.removePolicies(session, s.getPaths());
} catch (RepositoryException e) {
- throw new RuntimeException("Failed to remove ACL ("+e.getMessage()+")");
+ throw new RuntimeException("Failed to remove ACL (" + e.getMessage() + ")");
}
}
@@ -187,7 +212,7 @@ class AclVisitor extends DoNothingVisitor {
log.info("Removing principal-based access control policy for {}", principalName);
AclUtil.removePrincipalPolicy(session, principalName);
} catch (RepositoryException e) {
- throw new RuntimeException("Failed to remove principal-based ACL ("+e.getMessage()+")");
+ throw new RuntimeException("Failed to remove principal-based ACL (" + e.getMessage() + ")");
}
}
}
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java b/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java
index 38b33e6..cb356d9 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/CreatePathsTest.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
+import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.apache.sling.commons.testing.jcr.RepositoryUtil;
@@ -30,6 +31,8 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/** Test the creation of paths with specific node types */
public class CreatePathsTest {
@@ -124,4 +127,16 @@ public class CreatePathsTest {
U.assertNodeExists("/thirteen/fourteen", "nt:unstructured", Collections.singletonList("mix:lockable"));
U.assertNodeExists("/thirteen/fourteen/fifteen", "nt:unstructured", Collections.singletonList("mix:lockable"));
}
+
+ @Test
+ public void createPathNoDefaultPrimaryType() throws Exception {
+ U.adminSession.getRootNode().addNode("folder", "nt:folder");
+ U.parseAndExecute("create path /folder/subfolder/subfolder2");
+
+ Node subFolder = U.adminSession.getNode("/folder/subfolder");
+ assertEquals("sling:Folder", subFolder.getPrimaryNodeType().getName());
+
+ Node subFolder2 = subFolder.getNode("subfolder2");
+ assertEquals("sling:Folder", subFolder2.getPrimaryNodeType().getName());
+ }
}