You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by kw...@apache.org on 2022/02/14 18:00:24 UTC
[jackrabbit-oak] 01/01: OAK-9695 correctly evaluate property type from definition while check if protected
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch bugfix/consider-type-for-residual-property-type-definition
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 51d0147ce5f2e6490a4462d137c5509b915a0e0c
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Feb 14 19:00:12 2022 +0100
OAK-9695 correctly evaluate property type from definition while check if
protected
---
.../jackrabbit/oak/jcr/delegate/NodeDelegate.java | 39 ++++++++++++++--------
.../oak/jcr/delegate/PropertyDelegate.java | 2 +-
.../apache/jackrabbit/oak/jcr/PropertyTest.java | 30 +++++++++++++++++
3 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
index b851892..5403e7c 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/NodeDelegate.java
@@ -193,14 +193,14 @@ public class NodeDelegate extends ItemDelegate {
return false;
}
- boolean isProtected(String property) throws InvalidItemStateException {
+ boolean isProtected(String propertyName, Type<?> propertyType) throws InvalidItemStateException {
Tree tree = getTree();
Tree typeRoot = sessionDelegate.getRoot().getTree(NODE_TYPES_PATH);
List<Tree> types = TreeUtil.getEffectiveType(tree, typeRoot);
boolean protectedResidual = false;
for (Tree type : types) {
- if (contains(TreeUtil.getNames(type, REP_PROTECTED_PROPERTIES), property)) {
+ if (contains(TreeUtil.getNames(type, REP_PROTECTED_PROPERTIES), propertyName)) {
return true;
} else if (!protectedResidual) {
protectedResidual = TreeUtil.getBoolean(
@@ -209,18 +209,15 @@ public class NodeDelegate extends ItemDelegate {
}
// Special case: There are one or more protected *residual*
- // child node definitions. Iterate through them to check whether
+ // property definitions. Iterate through them to check whether
// there's a matching, protected one.
if (protectedResidual) {
- for (Tree type : types) {
- Tree definitions = type.getChild(REP_RESIDUAL_PROPERTY_DEFINITIONS);
- for (Tree definition : definitions.getChildren()) {
- // TODO: check for matching property type?
- if (TreeUtil.getBoolean(definition, JCR_PROTECTED)) {
- return true;
- }
+ Tree definition = findMatchingResidualPropertyDefinition(null, types, propertyType, true);
+ if (definition != null) {
+ if (TreeUtil.getBoolean(definition, JCR_PROTECTED)) {
+ return true;
}
- }
+ }
}
return false;
@@ -617,7 +614,20 @@ public class NodeDelegate extends ItemDelegate {
}
// Then look through any residual property definitions
- for (Tree type : types) {
+ return findMatchingResidualPropertyDefinition(fuzzyMatch, types, propertyType.isArray(), definedType, undefinedType, exactTypeMatch);
+ }
+
+ private Tree findMatchingResidualPropertyDefinition(Tree fuzzyMatch, List<Tree> types, Type<?> propertyType, boolean exactTypeMatch) {
+ String definedType = propertyType.toString();
+ String undefinedType = UNDEFINED.toString();
+ if (propertyType.isArray()) {
+ undefinedType = UNDEFINEDS.toString();
+ }
+ return findMatchingResidualPropertyDefinition(fuzzyMatch, types, propertyType.isArray(), definedType, undefinedType, exactTypeMatch);
+ }
+
+ private Tree findMatchingResidualPropertyDefinition(Tree fuzzyMatch, List<Tree> types, boolean isMultiValue, String definedType, String undefinedType, boolean exactTypeMatch) {
+ for (Tree type : types) {
Tree definitions = type.getChild(REP_RESIDUAL_PROPERTY_DEFINITIONS);
Tree definition = definitions.getChild(definedType);
if (definition.exists()) {
@@ -629,7 +639,7 @@ public class NodeDelegate extends ItemDelegate {
}
if (!exactTypeMatch && fuzzyMatch == null) {
for (Tree def : definitions.getChildren()) {
- if (propertyType.isArray() == TreeUtil.getBoolean(def, JCR_MULTIPLE)) {
+ if (isMultiValue == TreeUtil.getBoolean(def, JCR_MULTIPLE)) {
fuzzyMatch = def;
break;
}
@@ -639,7 +649,8 @@ public class NodeDelegate extends ItemDelegate {
return fuzzyMatch;
}
-
+
+
private Tree findMatchingChildNodeDefinition(
List<Tree> types, String childNodeName, Set<String> typeNames) {
// First look for a matching named property definition
diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
index 45b49e8..1376cf2 100644
--- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
+++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/PropertyDelegate.java
@@ -92,7 +92,7 @@ public class PropertyDelegate extends ItemDelegate {
@Override
public boolean isProtected() throws InvalidItemStateException {
- return getParent().isProtected(name);
+ return getParent().isProtected(name, state.getType());
}
@NotNull
diff --git a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/PropertyTest.java b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/PropertyTest.java
index 1218a6e..aef92cf 100644
--- a/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/PropertyTest.java
+++ b/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/PropertyTest.java
@@ -20,16 +20,21 @@ import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.NodeTypeTemplate;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.PropertyDefinitionTemplate;
+import javax.jcr.version.VersionException;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.apache.jackrabbit.value.ValueFactoryImpl;
public class PropertyTest extends AbstractJCRTest {
@@ -58,6 +63,12 @@ public class PropertyTest extends AbstractJCRTest {
pdt.setRequiredType(PropertyType.LONG);
template.getPropertyDefinitionTemplates().add(pdt);
+ pdt = ntMgr.createPropertyDefinitionTemplate();
+ pdt.setName("*"); // residual property type
+ pdt.setRequiredType(PropertyType.URI);
+ pdt.setProtected(true);
+ template.getPropertyDefinitionTemplates().add(pdt);
+
ntMgr.registerNodeType(template, true);
node = testRootNode.addNode(nodeName2, NT_NAME);
@@ -274,4 +285,23 @@ public class PropertyTest extends AbstractJCRTest {
assertEquals(3, pitr.getSize());
assertEquals(3, Iterators.size(pitr));
}
+
+ public void testSetAndRemoveUnprotectedProperty() throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+ Property property = node.setProperty(BOOLEAN_PROP_NAME, true);
+ assertNotNull(property);
+ property.setValue(false);
+ superuser.save();
+ property.remove();
+ superuser.save();
+ }
+
+ public void testSetProtectedResidualProperty() throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
+ Value uriValue = ValueFactoryImpl.getInstance().createValue("http://example.com", PropertyType.URI);
+ try {
+ node.setProperty("test", uriValue);
+ fail("Setting protected property (according to residual propery type definition) must throw ConstraintViolationException");
+ } catch (ConstraintViolationException e) {
+ // success
+ }
+ }
}
\ No newline at end of file