You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by en...@apache.org on 2022/09/10 19:42:21 UTC
[sling-org-apache-sling-jcr-repoinit] branch master updated: SLING-11571 repoinit: allow add or remove mixin types (#36)
This is an automated email from the ASF dual-hosted git repository.
enorman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git
The following commit(s) were added to refs/heads/master by this push:
new f7361d4 SLING-11571 repoinit: allow add or remove mixin types (#36)
f7361d4 is described below
commit f7361d46183b21acaa0a2e54bad6d401c6d43287
Author: Eric Norman <en...@apache.org>
AuthorDate: Sat Sep 10 12:42:16 2022 -0700
SLING-11571 repoinit: allow add or remove mixin types (#36)
---
bnd.bnd | 2 +-
pom.xml | 2 +-
.../apache/sling/jcr/repoinit/impl/AclVisitor.java | 54 ++++++++-
.../sling/jcr/repoinit/impl/DoNothingVisitor.java | 13 ++
.../org/apache/sling/jcr/repoinit/MixinsTest.java | 131 +++++++++++++++++++++
5 files changed, 199 insertions(+), 3 deletions(-)
diff --git a/bnd.bnd b/bnd.bnd
index e49236d..7b85d6c 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -3,4 +3,4 @@ Import-Package:\
org.apache.jackrabbit.oak.spi.security.principal;version="[1.5,3)",\
*
Provide-Capability: osgi.implementation;osgi.implementation="org.apache.sling.jcr.repoinit";version:Version="8.1"
-Require-Capability: org.apache.sling.repoinit.language;filter:="(version>=8.5)"
+Require-Capability: org.apache.sling.repoinit.language;filter:="(version>=8.6)"
diff --git a/pom.xml b/pom.xml
index b1a7aea..7af451e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -225,7 +225,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.repoinit.parser</artifactId>
- <version>1.7.0</version>
+ <version>1.7.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
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 705edf7..09e0293 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
@@ -29,6 +29,7 @@ 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;
@@ -38,6 +39,7 @@ 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;
@@ -217,7 +219,57 @@ class AclVisitor extends DoNothingVisitor {
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();
diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
index 18ae6fa..4594130 100644
--- a/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
+++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java
@@ -19,6 +19,7 @@ package org.apache.sling.jcr.repoinit.impl;
import javax.jcr.Session;
import org.apache.sling.repoinit.parser.operations.AddGroupMembers;
+import org.apache.sling.repoinit.parser.operations.AddMixins;
import org.apache.sling.repoinit.parser.operations.CreateGroup;
import org.apache.sling.repoinit.parser.operations.CreatePath;
import org.apache.sling.repoinit.parser.operations.CreateServiceUser;
@@ -38,6 +39,7 @@ 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.RemoveGroupMembers;
+import org.apache.sling.repoinit.parser.operations.RemoveMixins;
import org.apache.sling.repoinit.parser.operations.SetAclPaths;
import org.apache.sling.repoinit.parser.operations.SetAclPrincipalBased;
import org.apache.sling.repoinit.parser.operations.SetAclPrincipals;
@@ -192,4 +194,15 @@ class DoNothingVisitor implements OperationVisitor {
public void visitSetProperties(SetProperties sp) {
// no-op
}
+
+ @Override
+ public void visitAddMixins(AddMixins s) {
+ // no-op
+ }
+
+ @Override
+ public void visitRemoveMixins(RemoveMixins s) {
+ // no-op
+ }
+
}
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java b/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java
new file mode 100644
index 0000000..9137493
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/repoinit/MixinsTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+
+import org.apache.sling.jcr.repoinit.impl.TestUtil;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/** Test the creation of paths with specific node types */
+public class MixinsTest {
+
+ @Rule
+ public final SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK);
+
+ private TestUtil U;
+
+ @Before
+ public void setup() throws RepositoryException, IOException {
+ U = new TestUtil(context);
+ }
+
+ @Test
+ public void addOneMixinOnOnePath() throws Exception {
+ U.parseAndExecute("create path /addOneMixinOnOnePath(nt:unstructured)");
+ U.assertNodeExists("/addOneMixinOnOnePath", "nt:unstructured", Collections.emptyList());
+
+ U.parseAndExecute("add mixin mix:lockable to /addOneMixinOnOnePath");
+ U.assertNodeExists("/addOneMixinOnOnePath", "nt:unstructured", Collections.singletonList("mix:lockable"));
+ }
+
+ @Test
+ public void addTwoMixinsOnTwoPaths() throws Exception {
+ U.parseAndExecute("create path /addTwoMixinsOnOnePath1(nt:unstructured)\n"
+ + "create path /addTwoMixinsOnOnePath2(nt:unstructured)");
+ U.assertNodeExists("/addTwoMixinsOnOnePath1", "nt:unstructured", Collections.emptyList());
+ U.assertNodeExists("/addTwoMixinsOnOnePath1", "nt:unstructured", Collections.emptyList());
+
+ U.parseAndExecute("add mixin mix:lockable,mix:referenceable to /addTwoMixinsOnOnePath1,/addTwoMixinsOnOnePath2");
+ U.assertNodeExists("/addTwoMixinsOnOnePath1", "nt:unstructured", Arrays.asList("mix:lockable","mix:referenceable"));
+ U.assertNodeExists("/addTwoMixinsOnOnePath1", "nt:unstructured", Arrays.asList("mix:lockable","mix:referenceable"));
+ }
+
+ @Test
+ public void removeOneMixinFromOnePath() throws Exception {
+ U.parseAndExecute("create path /removeOneMixinOnOnePath(nt:unstructured mixin mix:lockable)");
+ U.assertNodeExists("/removeOneMixinOnOnePath", "nt:unstructured", Collections.singletonList("mix:lockable"));
+
+ U.parseAndExecute("remove mixin mix:lockable from /removeOneMixinOnOnePath");
+ U.assertNodeExists("/removeOneMixinOnOnePath", "nt:unstructured", Collections.emptyList());
+ }
+
+ @Test
+ public void removeTwoMixinsFromTwoPaths() throws Exception {
+ U.parseAndExecute("create path /removeTwoMixinsOnOnePath1(nt:unstructured mixin mix:lockable,mix:referenceable)\n"
+ + "create path /removeTwoMixinsOnOnePath2(nt:unstructured mixin mix:lockable,mix:referenceable)");
+ U.assertNodeExists("/removeTwoMixinsOnOnePath1", "nt:unstructured", Arrays.asList("mix:lockable","mix:referenceable"));
+ U.assertNodeExists("/removeTwoMixinsOnOnePath2", "nt:unstructured", Arrays.asList("mix:lockable","mix:referenceable"));
+
+ U.parseAndExecute("remove mixin mix:lockable,mix:referenceable from /removeTwoMixinsOnOnePath1,/removeTwoMixinsOnOnePath2");
+ U.assertNodeExists("/removeTwoMixinsOnOnePath1", "nt:unstructured", Collections.emptyList());
+ U.assertNodeExists("/removeTwoMixinsOnOnePath2", "nt:unstructured", Collections.emptyList());
+ }
+
+ @Test
+ public void addMixinOnNotExistingPath() throws Exception {
+ // this should just log a warning and continue
+ U.parseAndExecute("add mixin mix:lockable to /addMixinOnNotExistingPath");
+ assertNodeNotExists("/addMixinOnNotExistingPath");
+ }
+
+ @Test
+ public void removeMixinFromNotExistingPath() throws Exception {
+ // this should just log a warning and continue
+ U.parseAndExecute("remove mixin mix:lockable from /removeMixinFromNotExistingPath");
+ assertNodeNotExists("/removeMixinFromNotExistingPath");
+ }
+
+ @Test
+ public void addNonExistingMixinToPath() throws Exception {
+ U.parseAndExecute("create path /addNonExistingMixinToPath(nt:unstructured)");
+ try {
+ U.parseAndExecute("add mixin mix:invalid to /addNonExistingMixinToPath");
+ } catch (Exception e) {
+ assertTrue("Expected NoSuchNodeTypeException", e.getCause() instanceof NoSuchNodeTypeException);
+ }
+ }
+
+ @Test
+ public void removeNonExistingMixinFromPath() throws Exception {
+ U.parseAndExecute("create path /removeNonExistingMixinFromPath(nt:unstructured)");
+ try {
+ U.parseAndExecute("remove mixin mix:invalid from /removeNonExistingMixinFromPath");
+ } catch (Exception e) {
+ assertTrue("Expected NoSuchNodeTypeException", e.getCause() instanceof NoSuchNodeTypeException);
+ }
+ }
+
+ protected void assertNodeNotExists(String path) throws RepositoryException {
+ Session adminSession = context.resourceResolver().adaptTo(Session.class);
+ assertFalse("Node should not exist", adminSession.nodeExists(path));
+ }
+
+}