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 544823a SLING-10192 Add option to set/edit properties on users and
groups (#13)
544823a is described below
commit 544823a8f748943887a820058c9150c58ce4ec8e
Author: Eric Norman <[email protected]>
AuthorDate: Fri Mar 26 10:37:40 2021 -0700
SLING-10192 Add option to set/edit properties on users and groups (#13)
---
.../jcr/repoinit/impl/NodePropertiesVisitor.java | 166 +++++++++++++++++---
.../sling/jcr/repoinit/SetPropertiesTest.java | 169 +++++++++++++++++++++
.../apache/sling/jcr/repoinit/impl/TestUtil.java | 26 ++++
.../sling/jcr/repoinit/it/RepoInitTextIT.java | 129 +++++++++++++++-
.../java/org/apache/sling/jcr/repoinit/it/U.java | 25 +++
src/test/resources/repoinit.txt | 32 +++-
6 files changed, 520 insertions(+), 27 deletions(-)
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 d04c4c4..3483d69 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
@@ -16,24 +16,27 @@
*/
package org.apache.sling.jcr.repoinit.impl;
-import java.util.List;
+import java.util.ArrayList;
import java.util.Calendar;
+import java.util.List;
-import javax.jcr.Session;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
-import javax.jcr.Value;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.value.BooleanValue;
import org.apache.jackrabbit.value.DateValue;
import org.apache.jackrabbit.value.DoubleValue;
import org.apache.jackrabbit.value.LongValue;
import org.apache.jackrabbit.value.StringValue;
-
import org.apache.sling.repoinit.parser.operations.PropertyLine;
import org.apache.sling.repoinit.parser.operations.SetProperties;
+import org.jetbrains.annotations.NotNull;
/**
* OperationVisitor which processes only operations related to setting node
@@ -41,6 +44,16 @@ import
org.apache.sling.repoinit.parser.operations.SetProperties;
* the execution order.
*/
class NodePropertiesVisitor extends DoNothingVisitor {
+ /**
+ * The repoinit.parser transforms the authorizable(ids)[/relative_path]
path
+ * syntax from the original source into ":authorizable:ids#/relative_path"
in the
+ * values provided from {@link SetProperties#getPaths()}
+ *
+ * These constants are used to unwind those values into the parts for
processing
+ */
+ private static final String PATH_AUTHORIZABLE = ":authorizable:";
+ private static final char ID_DELIMINATOR = ',';
+ private static final char SUBTREE_DELIMINATOR = '#';
/**
* Create a visitor using the supplied JCR Session.
@@ -70,30 +83,135 @@ class NodePropertiesVisitor extends DoNothingVisitor {
return(!n.hasProperty(name) || n.getProperty(name) == null);
}
+ /**
+ * True if the property needs to be set - if false, it is not touched. This
+ * handles the "default" repoinit instruction, which means "do not change
the
+ * property if already set"
+ *
+ * @throws RepositoryException
+ * @throws PathNotFoundException
+ */
+ private static boolean needToSetProperty(Authorizable a, String pRelPath,
boolean isDefault) throws RepositoryException {
+ if (!isDefault) {
+ // It's a "set" line -> overwrite existing value if any
+ return true;
+ }
+
+ // Otherwise set the property only if not set yet
+ return(!a.hasProperty(pRelPath) || a.getProperty(pRelPath) == null);
+ }
+
+ /**
+ * Build relative property path from a subtree path and a property name
+ * @param subTreePath the subtree path (may be null or empty)
+ * @param name the property name
+ * @return the relative path of the property
+ */
+ private static String toRelPath(String subTreePath, final String name) {
+ final String pRelPath;
+ if (subTreePath == null || subTreePath.isEmpty()) {
+ pRelPath = name;
+ } else {
+ if (subTreePath.startsWith("/")) {
+ subTreePath = subTreePath.substring(1);
+ }
+ pRelPath = String.format("%s/%s", subTreePath, name);
+ }
+ return pRelPath;
+ }
+
+ /**
+ * Lookup the authorizables for the given ids
+ * @param session the jcr session
+ * @param ids delimited list of authorizable ids
+ * @return iterator over the found authorizables
+ */
+ @NotNull
+ private static Iterable<Authorizable> getAuthorizables(@NotNull Session
session, @NotNull String ids) throws RepositoryException {
+ List<Authorizable> authorizables = new ArrayList<>();
+ for (String id : Text.explode(ids, ID_DELIMINATOR)) {
+ Authorizable a = UserUtil.getAuthorizable(session, id);
+ if (a == null) {
+ throw new PathNotFoundException("Cannot resolve path of
authorizable with id '" + id + "'.");
+ }
+ authorizables.add(a);
+ }
+ return authorizables;
+ }
+
+ /**
+ * Set properties on a user or group
+ *
+ * @param nodePath the target path
+ * @param propertyLines the property lines to process to set the properties
+ */
+ private void setAuthorizableProperties(String nodePath, List<PropertyLine>
propertyLines) throws RepositoryException {
+ int lastHashIndex = nodePath.lastIndexOf(SUBTREE_DELIMINATOR);
+ if (lastHashIndex == -1) {
+ throw new IllegalStateException("Invalid format of authorizable
path: # deliminator expected.");
+ }
+ String ids = nodePath.substring(PATH_AUTHORIZABLE.length(),
lastHashIndex);
+ String subTreePath = nodePath.substring(lastHashIndex + 1);
+ for (Authorizable a : getAuthorizables(session, ids)) {
+ log.info("Setting properties on authorizable '{}'", a.getID());
+ for (PropertyLine pl : propertyLines) {
+ final String pName = pl.getPropertyName();
+ final String pRelPath = toRelPath(subTreePath, pName);
+ if (needToSetProperty(a, pRelPath, pl.isDefault())) {
+ final List<Object> values = pl.getPropertyValues();
+ if (values.size() > 1) {
+ Value[] pValues = convertToValues(values);
+ a.setProperty(pRelPath, pValues);
+ } else {
+ Value pValue = convertToValue(values.get(0));
+ a.setProperty(pRelPath, pValue);
+ }
+ } else {
+ log.info("Property '{}' already set on authorizable '{}',
existing value will not be overwritten in 'default' mode",
+ pRelPath, a.getID());
+ }
+ }
+ }
+ }
+
+ /**
+ * Set properties on a JCR node
+ *
+ * @param nodePath the target path
+ * @param propertyLines the property lines to process to set the properties
+ */
+ private void setNodeProperties(String nodePath, List<PropertyLine>
propertyLines) throws RepositoryException {
+ log.info("Setting properties on nodePath '{}'", nodePath);
+ Node n = session.getNode(nodePath);
+ for (PropertyLine pl : propertyLines) {
+ final String pName = pl.getPropertyName();
+ if (needToSetProperty(n, pl)) {
+ final PropertyLine.PropertyType pType = pl.getPropertyType();
+ final int type = PropertyType.valueFromName(pType.name());
+ final List<Object> values = pl.getPropertyValues();
+ if (values.size() > 1) {
+ Value[] pValues = convertToValues(values);
+ n.setProperty(pName, pValues, type);
+ } else {
+ Value pValue = convertToValue(values.get(0));
+ n.setProperty(pName, pValue, type);
+ }
+ } else {
+ log.info("Property '{}' already set on path '{}', existing
value will not be overwritten in 'default' mode",
+ pName, nodePath);
+ }
+ }
+ }
+
@Override
public void visitSetProperties(SetProperties sp) {
for (String nodePath : sp.getPaths()) {
try {
- log.info("Setting properties on nodePath '{}'", nodePath);
- Node n = session.getNode(nodePath);
- for (PropertyLine pl : sp.getPropertyLines()) {
- final String pName = pl.getPropertyName();
- final PropertyLine.PropertyType pType =
pl.getPropertyType();
- final List<Object> values = pl.getPropertyValues();
- final int type = PropertyType.valueFromName(pType.name());
- if (needToSetProperty(n, pl)) {
- if (values.size() > 1) {
- Value[] pValues = convertToValues(values);
- n.setProperty(pName, pValues, type);
- } else {
- Value pValue = convertToValue(values.get(0));
- n.setProperty(pName, pValue, type);
- }
- } else {
- log.info(
- "Property '{}' already set on path '{}', existing
value will not be overwritten in 'default' mode",
- pName, nodePath);
- }
+ if (nodePath.startsWith(PATH_AUTHORIZABLE)) {
+ // special case for setting properties on authorizable
+ setAuthorizableProperties(nodePath, sp.getPropertyLines());
+ } else {
+ setNodeProperties(nodePath, sp.getPropertyLines());
}
} catch (RepositoryException e) {
report(e, "Unable to set properties on path [" + nodePath +
"]:" + e);
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/SetPropertiesTest.java
b/src/test/java/org/apache/sling/jcr/repoinit/SetPropertiesTest.java
index 67a886a..2914b5b 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/SetPropertiesTest.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/SetPropertiesTest.java
@@ -128,4 +128,173 @@ public class SetPropertiesTest {
U.assertSVPropertyExists(path3, "one", vf.createValue("oneB"));
U.assertSVPropertyExists(path3, "two", vf.createValue("twoA"));
}
+
+ @Test
+ public void setUserProperties() throws Exception {
+ String userid = "user" + UUID.randomUUID();
+
+ U.assertUser("before creating user", userid, false);
+ U.parseAndExecute("create user " + userid);
+ U.assertUser("after creating user", userid, true);
+
+ assertAuthorizableProperties(userid);
+ assertAuthorizablePropertiesAgain(userid);
+ }
+
+ @Test
+ public void setSubTreeUserProperties() throws Exception {
+ String userid = "user" + UUID.randomUUID();
+
+ U.assertUser("before creating user", userid, false);
+ U.parseAndExecute("create user " + userid);
+ U.assertUser("after creating user", userid, true);
+
+ assertAuthorizableSubTreeProperties(userid);
+ assertAuthorizableSubTreePropertiesAgain(userid);
+ }
+
+ @Test
+ public void setGroupProperties() throws Exception {
+ String groupid = "group" + UUID.randomUUID();
+
+ U.assertGroup("before creating group", groupid, false);
+ U.parseAndExecute("create group " + groupid);
+ U.assertGroup("after creating group", groupid, true);
+
+ assertAuthorizableProperties(groupid);
+ assertAuthorizablePropertiesAgain(groupid);
+ }
+
+ @Test
+ public void setSubTreeGroupProperties() throws Exception {
+ String groupid = "group" + UUID.randomUUID();
+
+ U.assertGroup("before creating group", groupid, false);
+ U.parseAndExecute("create group " + groupid);
+ U.assertGroup("after creating group", groupid, true);
+
+ assertAuthorizableSubTreeProperties(groupid);
+ assertAuthorizableSubTreePropertiesAgain(groupid);
+ }
+
+ /**
+ * Set properties on an authorizable and then verify that the values were
set
+ */
+ protected void assertAuthorizableProperties(String id) throws
RepositoryException, RepoInitParsingException {
+ final String setPropsA =
+ "set properties on authorizable(" +id + ")\n"
+ + "set one to oneA\n"
+ + "default two to twoA\n"
+ + "set nested/one to oneA\n"
+ + "default nested/two to twoA\n"
+ + "set three to threeA, \"threeB\", threeC\n"
+ + "default four to fourA, \"fourB\"\n"
+ + "set nested/three to threeA, \"threeB\", threeC\n"
+ + "default nested/four to fourA, \"fourB\"\n"
+ + "end";
+
+ U.parseAndExecute(setPropsA);
+
+ U.assertAuthorizableSVPropertyExists(id, "one",
vf.createValue("oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/one",
vf.createValue("oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "two",
vf.createValue("twoA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/two",
vf.createValue("twoA"));
+ U.assertAuthorizableMVPropertyExists(id, "three", new Value[] {
+ vf.createValue("threeA"),
+ vf.createValue("threeB"),
+ vf.createValue("threeC")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "nested/three", new Value[] {
+ vf.createValue("threeA"),
+ vf.createValue("threeB"),
+ vf.createValue("threeC")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "four", new Value[] {
+ vf.createValue("fourA"),
+ vf.createValue("fourB")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "nested/four", new Value[] {
+ vf.createValue("fourA"),
+ vf.createValue("fourB")
+ });
+ }
+
+ /**
+ * Change values for existing properties on an authorizable and then
verify that the values were set
+ * or not as appropriate
+ */
+ protected void assertAuthorizablePropertiesAgain(String id) throws
RepositoryException, RepoInitParsingException {
+ final String setPropsA =
+ "set properties on authorizable(" + id + ")\n"
+ + "set one to changed_oneA\n"
+ + "default two to changed_twoA\n"
+ + "set nested/one to changed_oneA\n"
+ + "default nested/two to changed_twoA\n"
+ + "set three to changed_threeA, \"changed_threeB\",
changed_threeC\n"
+ + "default four to changed_fourA, \"changed_fourB\"\n"
+ + "set nested/three to changed_threeA,
\"changed_threeB\", changed_threeC\n"
+ + "default nested/four to changed_fourA,
\"changed_fourB\"\n"
+ + "end";
+
+ U.parseAndExecute(setPropsA);
+
+ U.assertAuthorizableSVPropertyExists(id, "one",
vf.createValue("changed_oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/one",
vf.createValue("changed_oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "two",
vf.createValue("twoA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/two",
vf.createValue("twoA"));
+ U.assertAuthorizableMVPropertyExists(id, "three", new Value[] {
+ vf.createValue("changed_threeA"),
+ vf.createValue("changed_threeB"),
+ vf.createValue("changed_threeC")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "nested/three", new Value[] {
+ vf.createValue("changed_threeA"),
+ vf.createValue("changed_threeB"),
+ vf.createValue("changed_threeC")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "four", new Value[] {
+ vf.createValue("fourA"),
+ vf.createValue("fourB")
+ });
+ U.assertAuthorizableMVPropertyExists(id, "nested/four", new Value[] {
+ vf.createValue("fourA"),
+ vf.createValue("fourB")
+ });
+ }
+
+ /**
+ * Set properties on a subtree of an authorizable and then verify that the
values were set
+ */
+ protected void assertAuthorizableSubTreeProperties(String id)
+ throws RepositoryException, RepoInitParsingException {
+ final String setPropsA =
+ "set properties on authorizable(" + id + ")/nested\n"
+ + "set one to oneA\n"
+ + "default two to twoA\n"
+ + "end";
+
+ U.parseAndExecute(setPropsA);
+
+ U.assertAuthorizableSVPropertyExists(id, "nested/one",
vf.createValue("oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/two",
vf.createValue("twoA"));
+ }
+
+ /**
+ * Change values for existing properties on a subtree of an authorizable
and then verify
+ * that the values were set or not as appropriate
+ */
+ protected void assertAuthorizableSubTreePropertiesAgain(String id)
+ throws RepositoryException, RepoInitParsingException {
+ final String setPropsA =
+ "set properties on authorizable(" + id + ")/nested\n"
+ + "set one to changed_oneA\n"
+ + "default two to changed_twoA\n"
+ + "end";
+
+ U.parseAndExecute(setPropsA);
+
+ U.assertAuthorizableSVPropertyExists(id, "nested/one",
vf.createValue("changed_oneA"));
+ U.assertAuthorizableSVPropertyExists(id, "nested/two",
vf.createValue("twoA"));
+ }
+
}
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
index fb7e201..306c877 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java
@@ -197,6 +197,32 @@ public class TestUtil {
assertEquals(message + " to be member of " + groupId,
expectToBeMember, isMember);
}
+ public void assertAuthorizableSVPropertyExists(String id, String
propertyName, Value expectedValue) throws RepositoryException {
+ final Authorizable a = UserUtil.getAuthorizable(adminSession, id);
+ assertNotNull("failed to get authorizable for " + id, a);
+ if (!a.hasProperty(propertyName)) {
+ fail("No " + propertyName + " property for " + a.getID());
+ } else {
+ Value[] property = a.getProperty(propertyName);
+ assertNotNull("Expected non-null value for property: " +
propertyName, property);
+ assertEquals("Expected one value for property: " + propertyName,
1, property.length);
+ Value actualValue = property[0];
+ assertEquals("Value mismatch for property: " + propertyName,
expectedValue, actualValue);
+ }
+ }
+
+ public void assertAuthorizableMVPropertyExists(String id, String
propertyName, Value[] expectedValues) throws RepositoryException {
+ final Authorizable a = UserUtil.getAuthorizable(adminSession, id);
+ assertNotNull("failed to get authorizable for " + id, a);
+ if (!a.hasProperty(propertyName)) {
+ fail("No " + propertyName + " property for " + a.getID());
+ } else {
+ Value[] actualValues = a.getProperty(propertyName);
+ assertNotNull("Expected non-null value for property: " +
propertyName, actualValues);
+ assertArrayEquals("Values mismatch for property: " + propertyName,
expectedValues, actualValues);
+ }
+ }
+
public void assertSVPropertyExists(String path, String propertyName, Value
expectedValue) throws RepositoryException {
final Node n = adminSession.getNode(path);
if(!n.hasProperty(propertyName)) {
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/it/RepoInitTextIT.java
b/src/test/java/org/apache/sling/jcr/repoinit/it/RepoInitTextIT.java
index 11e2e2b..3bebc3c 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/it/RepoInitTextIT.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/it/RepoInitTextIT.java
@@ -24,11 +24,14 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.UUID;
+import javax.inject.Inject;
import javax.jcr.PropertyType;
-import javax.jcr.ValueFactory;
import javax.jcr.Value;
-import javax.inject.Inject;
+import javax.jcr.ValueFactory;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
import org.apache.sling.repoinit.parser.RepoInitParser;
import org.junit.Before;
@@ -211,4 +214,126 @@ public class RepoInitTextIT extends RepoInitTestSupport {
}
};
}
+
+ @Test
+ public void setAuthorizableProperties() throws Exception {
+ new Retry() {
+ @Override
+ public Void call() throws Exception {
+ if(!(session instanceof JackrabbitSession)) {
+ throw new IllegalArgumentException("Session is not a
JackrabbitSession");
+ }
+ UserManager um = ((JackrabbitSession)session).getUserManager();
+
+ Authorizable [] authorizables = new Authorizable[] {
+ um.getAuthorizable(ALICE),
+ um.getAuthorizable(GROUP_A)
+ };
+
+ for (Authorizable authorizable : authorizables) {
+ assertNotNull("Expected authorizable to not be null",
authorizable);
+ ValueFactory vf = session.getValueFactory();
+ Value[] expectedValues1 = new Value[2];
+ expectedValues1[0] = vf.createValue("/d/e/f/*");
+ expectedValues1[1] = vf.createValue("m/n/*");
+ assertTrue("Expecting array type property " + PROP_A + "
to be present ", U.hasProperty(authorizable, PROP_A, expectedValues1));
+
+ Value expectedValue2 = vf.createValue("42",
PropertyType.valueFromName("Long"));
+ assertTrue("Expecting Long type default property " +
PROP_B + " to be present ", U.hasProperty(authorizable, PROP_B,
expectedValue2));
+
+ Value expectedValue3 = vf.createValue("true",
PropertyType.valueFromName("Boolean"));
+ assertTrue("Expecting bool type property " + PROP_C + " to
be present ", U.hasProperty(authorizable, PROP_C, expectedValue3));
+
+ Value expectedValue4 =
vf.createValue("2020-03-19T11:39:33.437+05:30",
PropertyType.valueFromName("Date"));
+ assertTrue("Expecting date type property " + PROP_D + " to
be present " , U.hasProperty(authorizable, PROP_D, expectedValue4));
+
+ Value expectedValue5 = vf.createValue("test");
+ assertTrue("Expecting string type property " + PROP_E + "
to be present " , U.hasProperty(authorizable, PROP_E, expectedValue5));
+
+ Value expectedValue6 = vf.createValue("hello, you!");
+ assertTrue("Expecting quoted string type property " +
PROP_F + " to be present " , U.hasProperty(authorizable, PROP_F,
expectedValue6));
+
+ Value[] expectedValues7 = new Value[2];
+ expectedValues7[0] = vf.createValue("test1");
+ expectedValues7[1] = vf.createValue("test2");
+ assertTrue("Expecting string array type property " +
PROP_G + " to be present " , U.hasProperty(authorizable, PROP_G,
expectedValues7));
+
+ Value expectedValue8 = vf.createValue("Here's a \"double
quoted string\" with suffix");
+ assertTrue("Expecting quoted string type property " +
PROP_H + " to be present " , U.hasProperty(authorizable, PROP_H,
expectedValue8));
+
+ Value[] expectedValues9 = new Value[3];
+ expectedValues9[0] = vf.createValue("quoted");
+ expectedValues9[1] = vf.createValue("non-quoted");
+ expectedValues9[2] = vf.createValue("the last \" one");
+ assertTrue("Expecting string array type property " +
PROP_I + " to be present " , U.hasProperty(authorizable, PROP_I,
expectedValues9));
+
+ Value nestedExpectedValue = vf.createValue("42",
PropertyType.valueFromName("Long"));
+ assertTrue("Expecting Long type default property nested/"
+ PROP_B + " to be present ", U.hasProperty(authorizable, "nested/" +PROP_B,
nestedExpectedValue));
+ }
+
+ return null;
+ }
+ };
+ }
+
+ @Test
+ public void setAuthorizableSubTreeProperties() throws Exception {
+ new Retry() {
+ @Override
+ public Void call() throws Exception {
+ if(!(session instanceof JackrabbitSession)) {
+ throw new IllegalArgumentException("Session is not a
JackrabbitSession");
+ }
+ UserManager um = ((JackrabbitSession)session).getUserManager();
+
+ Authorizable [] authorizables = new Authorizable[] {
+ um.getAuthorizable(BOB),
+ um.getAuthorizable(GROUP_B)
+ };
+
+ for (Authorizable authorizable : authorizables) {
+ assertNotNull("Expected authorizable to not be null",
authorizable);
+ ValueFactory vf = session.getValueFactory();
+ Value[] expectedValues1 = new Value[2];
+ expectedValues1[0] = vf.createValue("/d/e/f/*");
+ expectedValues1[1] = vf.createValue("m/n/*");
+ assertTrue("Expecting array type property nested/" +
PROP_A + " to be present ", U.hasProperty(authorizable, "nested/" + PROP_A,
expectedValues1));
+
+ Value expectedValue2 = vf.createValue("42",
PropertyType.valueFromName("Long"));
+ assertTrue("Expecting Long type default property nested/"
+ PROP_B + " to be present ", U.hasProperty(authorizable, "nested/" + PROP_B,
expectedValue2));
+
+ Value expectedValue3 = vf.createValue("true",
PropertyType.valueFromName("Boolean"));
+ assertTrue("Expecting bool type property nested/" + PROP_C
+ " to be present ", U.hasProperty(authorizable, "nested/" + PROP_C,
expectedValue3));
+
+ Value expectedValue4 =
vf.createValue("2020-03-19T11:39:33.437+05:30",
PropertyType.valueFromName("Date"));
+ assertTrue("Expecting date type property nested/" + PROP_D
+ " to be present " , U.hasProperty(authorizable, "nested/" + PROP_D,
expectedValue4));
+
+ Value expectedValue5 = vf.createValue("test");
+ assertTrue("Expecting string type property nested/" +
PROP_E + " to be present " , U.hasProperty(authorizable, "nested/" + PROP_E,
expectedValue5));
+
+ Value expectedValue6 = vf.createValue("hello, you!");
+ assertTrue("Expecting quoted string type property nested/"
+ PROP_F + " to be present " , U.hasProperty(authorizable, "nested/" + PROP_F,
expectedValue6));
+
+ Value[] expectedValues7 = new Value[2];
+ expectedValues7[0] = vf.createValue("test1");
+ expectedValues7[1] = vf.createValue("test2");
+ assertTrue("Expecting string array type property nested/"
+ PROP_G + " to be present " , U.hasProperty(authorizable, "nested/" + PROP_G,
expectedValues7));
+
+ Value expectedValue8 = vf.createValue("Here's a \"double
quoted string\" with suffix");
+ assertTrue("Expecting quoted string type property nested/"
+ PROP_H + " to be present " , U.hasProperty(authorizable, "nested/" + PROP_H,
expectedValue8));
+
+ Value[] expectedValues9 = new Value[3];
+ expectedValues9[0] = vf.createValue("quoted");
+ expectedValues9[1] = vf.createValue("non-quoted");
+ expectedValues9[2] = vf.createValue("the last \" one");
+ assertTrue("Expecting string array type property nested/"
+ PROP_I + " to be present " , U.hasProperty(authorizable, "nested/" + PROP_I,
expectedValues9));
+
+ Value nestedExpectedValue = vf.createValue("42",
PropertyType.valueFromName("Long"));
+ assertTrue("Expecting Long type default property
nested/nested/" + PROP_B + " to be present ", U.hasProperty(authorizable,
"nested/nested/" +PROP_B, nestedExpectedValue));
+ }
+
+ return null;
+ }
+ };
+ }
}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/jcr/repoinit/it/U.java
b/src/test/java/org/apache/sling/jcr/repoinit/it/U.java
index 1a404ff..381d2a9 100644
--- a/src/test/java/org/apache/sling/jcr/repoinit/it/U.java
+++ b/src/test/java/org/apache/sling/jcr/repoinit/it/U.java
@@ -135,4 +135,29 @@ public class U {
}
return false;
}
+
+ public static boolean hasProperty(Authorizable a, String propertyName,
Value propertyValue) throws RepositoryException {
+ if (a != null) {
+ boolean isPropertyPresent = a.hasProperty(propertyName);
+ if (isPropertyPresent) {
+ Value[] values = a.getProperty(propertyName);
+ if (values != null && values.length == 1) {
+ Value v = values[0];
+ return v.equals(propertyValue);
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean hasProperty(Authorizable a, String propertyName,
Value[] propertyValues) throws RepositoryException {
+ if (a != null) {
+ boolean isPropertyPresent = a.hasProperty(propertyName);
+ if (isPropertyPresent) {
+ Value[] v = a.getProperty(propertyName);
+ return Arrays.equals(v, propertyValues);
+ }
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/src/test/resources/repoinit.txt b/src/test/resources/repoinit.txt
index d6fd943..2dbbe24 100644
--- a/src/test/resources/repoinit.txt
+++ b/src/test/resources/repoinit.txt
@@ -81,4 +81,34 @@ set properties on /proptest/X/Y
default someInteger{Long} to 65
set quotedA to "Here's a \"double quoted string\" with suffix"
set quotedMix to "quoted", non-quoted, "the last \" one"
-end
\ No newline at end of file
+end
+
+# SLING-10192 set properties on user or group profile
+set properties on authorizable(alice),authorizable(grpA)
+ set pathArray to /d/e/f/*, m/n/*
+ default someInteger{Long} to 42
+ set someFlag{Boolean} to true
+ default someDate{Date} to "2020-03-19T11:39:33.437+05:30"
+ set customSingleValueStringProp to test
+ set customSingleValueQuotedStringProp to "hello, you!"
+ set stringArray to test1, test2
+ default someInteger{Long} to 65
+ set quotedA to "Here's a \"double quoted string\" with suffix"
+ set quotedMix to "quoted", non-quoted, "the last \" one"
+ set nested/someInteger{Long} to 42
+end
+
+# SLING-10192 set properties on a subtree of the user or group profile
+set properties on authorizable(bob)/nested,authorizable(grpB)/nested
+ set pathArray to /d/e/f/*, m/n/*
+ default someInteger{Long} to 42
+ set someFlag{Boolean} to true
+ default someDate{Date} to "2020-03-19T11:39:33.437+05:30"
+ set customSingleValueStringProp to test
+ set customSingleValueQuotedStringProp to "hello, you!"
+ set stringArray to test1, test2
+ default someInteger{Long} to 65
+ set quotedA to "Here's a \"double quoted string\" with suffix"
+ set quotedMix to "quoted", non-quoted, "the last \" one"
+ set nested/someInteger{Long} to 42
+end