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 md...@apache.org on 2012/08/31 18:32:19 UTC
svn commit: r1379497 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type:
TypeValidator.java TypeValidatorProvider.java
Author: mduerig
Date: Fri Aug 31 16:32:18 2012
New Revision: 1379497
URL: http://svn.apache.org/viewvc?rev=1379497&view=rev
Log:
OAK-66: JCR Node Type Management
node type validation (WIP)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidatorProvider.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java?rev=1379497&r1=1379496&r2=1379497&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidator.java Fri Aug 31 16:32:18 2012
@@ -16,25 +16,47 @@
*/
package org.apache.jackrabbit.oak.plugins.type;
+import java.util.List;
+
+import javax.annotation.Nonnull;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeManager;
+import com.google.common.collect.Lists;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.CoreValue;
import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.ReadOnlyTree;
import org.apache.jackrabbit.oak.spi.commit.Validator;
import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
class TypeValidator implements Validator {
+ private static final Logger log = LoggerFactory.getLogger(TypeValidator.class);
+
private final NodeTypeManager ntm;
+ private final Tree parent;
+
+ private EffectiveNodeType parentType;
+
+ @Nonnull
+ private EffectiveNodeType getParentType() throws CommitFailedException {
+ if (parentType == null) {
+ parentType = getEffectiveNodeType(parent);
+ }
+ return parentType;
+ }
- public TypeValidator(NodeTypeManager ntm) {
+ public TypeValidator(NodeTypeManager ntm, Tree parent) {
this.ntm = ntm;
+ this.parent = parent;
}
//-------------------------------------------------------< NodeValidator >
@@ -42,39 +64,58 @@ class TypeValidator implements Validator
@Override
public void propertyAdded(PropertyState after) throws CommitFailedException {
validateType(after);
- // TODO: validate added property
+ if (!getParentType().canAddProperty(after)) {
+ throwConstraintViolationException(
+ "Can't add property " + after.getName() + " at " + parent.getPath());
+ }
}
@Override
public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
validateType(after);
+ if (!getParentType().canSetProperty(after)) {
+ throwConstraintViolationException(
+ "Can't set property " + after.getName() + " at " + parent.getPath());
+ }
}
@Override
public void propertyDeleted(PropertyState before) throws CommitFailedException {
- // TODO: validate removed property
+ if (!getParentType().canRemoveProperty(before)) {
+ throwConstraintViolationException(
+ "Can't delete property " + before.getName() + " at " + parent.getPath());
+ }
}
@Override
public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
- // TODO: validate added child node
- // TODO: get the type for validating the child contents
- return this;
+ if (!getParentType().canAddChildNode(name, after)) {
+ throwConstraintViolationException(
+ "Can't add node " + name + " at " + parent.getPath());
+ }
+ return new TypeValidator(ntm, new ReadOnlyTree(after));
}
@Override
public Validator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
- // TODO: validate changed child node
- // TODO: get the type to validating the child contents
- return this;
+ if (!getParentType().canChangeChildNode(name, after)) {
+ throwConstraintViolationException(
+ "Can't modify node " + name + " at " + parent.getPath());
+ }
+ return new TypeValidator(ntm, new ReadOnlyTree(after));
}
@Override
- public Validator childNodeDeleted(String name, NodeState before) {
- // TODO: validate removed child node
- return null;
+ public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+ if (!getParentType().canRemoveNode(name, before)) {
+ throwConstraintViolationException(
+ "Can't delete node " + name + " at " + parent.getPath());
+ }
+ return new TypeValidator(ntm, new ReadOnlyTree(before));
}
+ //------------------------------------------------------------< private >---
+
private void validateType(PropertyState after) throws CommitFailedException {
boolean primaryType = JCR_PRIMARYTYPE.equals(after.getName());
boolean mixinType = JCR_MIXINTYPES.equals(after.getName());
@@ -95,13 +136,99 @@ class TypeValidator implements Validator
}
}
catch (RepositoryException e) {
- throw new CommitFailedException(e);
+ throwConstraintViolationException(e);
+ }
+ }
+ }
+
+ private NodeType getPrimaryType(Tree tree) throws CommitFailedException {
+ try {
+ PropertyState jcrPrimaryType = tree.getProperty(JCR_PRIMARYTYPE);
+ if (jcrPrimaryType != null) {
+ for (CoreValue typeName : jcrPrimaryType.getValues()) {
+ String ntName = typeName.getString();
+ NodeType type = ntm.getNodeType(ntName);
+ if (type == null) {
+ log.warn("Could not find node type {} for item at {}", ntName, tree.getPath());
+ }
+ return type;
+ }
+ }
+ log.warn("Item at {} has no primary type", tree.getPath());
+ return null;
+ }
+ catch (RepositoryException e) {
+ return throwConstraintViolationException(e);
+ }
+ }
+
+ private List<NodeType> getMixinTypes(Tree tree) throws CommitFailedException {
+ try {
+ List<NodeType> types = Lists.newArrayList();
+ PropertyState jcrMixinType = tree.getProperty(JCR_MIXINTYPES);
+ if (jcrMixinType != null) {
+ for (CoreValue typeName : jcrMixinType.getValues()) {
+ String ntName = typeName.getString();
+ NodeType type = ntm.getNodeType(ntName);
+ if (type == null) {
+ log.warn("Could not find mixin type {} for item at {}", ntName, tree.getPath());
+ }
+ else {
+ types.add(type);
+ }
+ }
}
+ return types;
}
+ catch (RepositoryException e) {
+ return throwConstraintViolationException(e);
+ }
+ }
+
+ private EffectiveNodeType getEffectiveNodeType(Tree tree) throws CommitFailedException {
+ return new EffectiveNodeType(getPrimaryType(tree), getMixinTypes(tree));
}
- private static void throwConstraintViolationException(String message) throws CommitFailedException {
+ private static <T> T throwConstraintViolationException(String message) throws CommitFailedException {
throw new CommitFailedException(new ConstraintViolationException(message));
}
+ private static <T> T throwConstraintViolationException(RepositoryException cause) throws CommitFailedException {
+ throw new CommitFailedException(cause);
+ }
+
+ private class EffectiveNodeType {
+ private final NodeType primaryType;
+ private final List<NodeType> mixinTypes;
+
+ public EffectiveNodeType(NodeType primaryType, List<NodeType> mixinTypes) {
+ this.primaryType = primaryType;
+ this.mixinTypes = mixinTypes;
+ }
+
+ public boolean canAddProperty(PropertyState property) {
+ return true; // todo implement canAddProperty
+ }
+
+ public boolean canSetProperty(PropertyState property) {
+ return true; // todo implement canSetProperty
+ }
+
+ public boolean canRemoveProperty(PropertyState property) {
+ return true; // todo implement canRemoveProperty
+ }
+
+ public boolean canAddChildNode(String name, NodeState node) {
+ return true; // todo implement canAddChildNode
+ }
+
+ public boolean canChangeChildNode(String name, NodeState node) {
+ return true; // todo implement canChangeChildNode
+ }
+
+ public boolean canRemoveNode(String name, NodeState node) {
+ return true; // todo implement canRemoveNode
+ }
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidatorProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidatorProvider.java?rev=1379497&r1=1379496&r2=1379497&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidatorProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/type/TypeValidatorProvider.java Fri Aug 31 16:32:18 2012
@@ -33,7 +33,7 @@ public class TypeValidatorProvider imple
@Override
public Validator getRootValidator(NodeState before, final NodeState after) {
- return new TypeValidator(new AbstractNodeTypeManager() {
+ AbstractNodeTypeManager ntm = new AbstractNodeTypeManager() {
private final Tree types = getTypes(after);
@Override
@@ -53,7 +53,9 @@ public class TypeValidatorProvider imple
}
return tree;
}
- });
+ };
+
+ return new TypeValidator(ntm, new ReadOnlyTree(after));
}
}