You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2020/07/26 10:36:43 UTC

[jackrabbit-filevault] branch master updated: JCRVLT-426 fix handling of node types defined in other files

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git


The following commit(s) were added to refs/heads/master by this push:
     new 2df4989  JCRVLT-426 fix handling of node types defined in other files
2df4989 is described below

commit 2df498954d708addb027d0d1395a2af2f76b5642
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sun Jul 26 12:36:33 2020 +0200

    JCRVLT-426 fix handling of node types defined in other files
    
    improve handling of unknown node types
---
 .../spi/impl/nodetype/NodeNameAndType.java         | 47 ++++++++++++++++--
 .../spi/impl/nodetype/NodeTypeValidator.java       | 55 ++++++++++++++--------
 .../impl/nodetype/NodeTypeValidatorFactory.java    |  2 +-
 .../spi/impl/nodetype/NodeTypeValidatorTest.java   |  2 +-
 4 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeNameAndType.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeNameAndType.java
index e71a523..c1cf249 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeNameAndType.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeNameAndType.java
@@ -40,19 +40,45 @@ import org.jetbrains.annotations.Nullable;
  * In addition stores references to the child node names and types.
  */
 final class NodeNameAndType {
-    private final @NotNull Name name;
-    private final @NotNull EffectiveNodeType effectiveNodeType;
+    private final Name name;
+    private final EffectiveNodeType effectiveNodeType;
     private final @NotNull List<NodeNameAndType> children;
     private final @Nullable NodeNameAndType parent;
 
+    public static NodeNameAndType createUnknownNodeNameAndType(@Nullable NodeNameAndType parent) {
+        return new NodeNameAndType(parent);
+    }
+
+    private NodeNameAndType(@Nullable NodeNameAndType parent) {
+        this.parent = parent;
+        if (parent != null) {
+            parent.addChild(this);
+        }
+        this.effectiveNodeType = null;
+        children = new LinkedList<>();
+        this.name = null;
+    }
+    
     @SuppressWarnings("null")
     public NodeNameAndType(@Nullable NodeNameAndType parent, @NotNull NameResolver nameResolver, @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider, @NotNull DocViewNode node) throws IllegalNameException, NamespaceException, ConstraintViolationException, NoSuchNodeTypeException {
-        this.name = nameResolver.getQName(node.name);
+        try {
+            this.name = nameResolver.getQName(node.name);
+        } catch (IllegalNameException|NamespaceException e) {
+            throw new IllegalNameException("Invalid node name " + node.name + ": '" + e.getMessage() + "'", e);
+        }
         Collection<Name> types = new LinkedList<>();
-        types.add(nameResolver.getQName(node.primary));
+        try {
+            types.add(nameResolver.getQName(node.primary));
+        } catch (IllegalNameException|NamespaceException e) {
+            throw new IllegalNameException("Invalid primary type " + node.primary + ": '" + e.getMessage() + "'", e);
+        }
         if (node.mixins != null) {
             for (String mixin : node.mixins) {
-                types.add(nameResolver.getQName(mixin));
+                try {
+                    types.add(nameResolver.getQName(mixin));
+                } catch (IllegalNameException|NamespaceException e) { 
+                    throw new IllegalNameException("Invalid mixin type " + mixin + ": '" + e.getMessage() + "'", e);
+                }
             }
         }
         effectiveNodeType = effectiveNodeTypeProvider.getEffectiveNodeType(types.toArray(new Name[0]));
@@ -63,6 +89,10 @@ final class NodeNameAndType {
         this.parent = parent;
     }
 
+    public boolean isUnknown() {
+        return this.effectiveNodeType == null && this.name == null;
+    }
+
     public boolean fulfillsNodeDefinition(QNodeDefinition nodeDefinition) {
         // name must match
         if (!nodeDefinition.getName().equals(NameConstants.ANY_NAME) && !nodeDefinition.getName().equals(name)) {
@@ -97,4 +127,11 @@ final class NodeNameAndType {
     public NodeNameAndType getParent() {
         return parent;
     }
+
+    @Override
+    public String toString() {
+        return "NodeNameAndType [" + (name != null ? "name=" + name + ", " : "")
+                + (effectiveNodeType != null ? "effectiveNodeType=" + effectiveNodeType + ", " : "")
+                + (children != null ? "children=" + children + ", " : "") + (parent != null ? "parent=" + parent : "") + "]";
+    }
 }
\ No newline at end of file
diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidator.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidator.java
index 287f39a..2e76064 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidator.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidator.java
@@ -75,7 +75,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
 
     static final String MESSAGE_MANDATORY_CHILD_NODE_MISSING = "Mandatory child node missing: %s";
     static final String MESSAGE_PROPERTY_ERROR = "Error while retrieving property '%s': %s";
-    static final String MESSAGE_UNKNOWN_NODE_TYPE_OR_NAMESPACE = "Unknown node type or namespace: %s";
+    static final String MESSAGE_UNKNOWN_NODE_TYPE_OR_NAMESPACE = "%s. Skip validation of nodes with that type";
     static final String MESSAGE_MISSING_PRIMARY_TYPE = "Mandatory jcr:primaryType missing on node '%s'";
     static final String MESSAGE_PROPERTY_NOT_ALLOWED = "Property '%s' is not allowed in node with types '[%s]': %s";
     static final String MESSAGE_MANDATORY_PROPERTY_MISSING = "Mandatory property '%s' missing in node with types [%s]";
@@ -162,24 +162,29 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
                 if (currentNodeNameAndType == null || !filter.contains(parentNodePath)) {
                     parentNodeType = defaultType;
                     useDefaultNodeType = true;
-                } else {
+                } else if (!currentNodeNameAndType.isUnknown()) {
                     parentNodeType = currentNodeNameAndType.getEffectiveNodeType();
                     useDefaultNodeType = false;
+                } else {
+                    parentNodeType = null;
+                    useDefaultNodeType = false;
                 }
 
-                String constraintViolation = getChildNodeConstraintViolation(node, parentNodeType,
-                        ntManagerProvider.getNodeTypeDefinitionProvider(),
-                        ntManagerProvider.getNameResolver(), ntManagerProvider.getItemDefinitionProvider(),
-                        allowProtectedSubNodesAndProperties);
-                if (constraintViolation != null) {
-                    messages.add(new ValidationMessage(defaultSeverity,
-                            String.format(
-                                    useDefaultNodeType ? MESSAGE_CHILD_NODE_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED
-                                            : MESSAGE_CHILD_NODE_NOT_ALLOWED,
-                                    getDocViewNodeLabel(node),
-                                    effectiveNodeTypeToString(ntManagerProvider.getNameResolver(), parentNodeType),
-                                    constraintViolation)));
-
+                if (parentNodeType != null) {
+                    String constraintViolation = getChildNodeConstraintViolation(node, parentNodeType,
+                            ntManagerProvider.getNodeTypeDefinitionProvider(),
+                            ntManagerProvider.getNameResolver(), ntManagerProvider.getItemDefinitionProvider(),
+                            allowProtectedSubNodesAndProperties);
+                    if (constraintViolation != null) {
+                        messages.add(new ValidationMessage(defaultSeverity,
+                                String.format(
+                                        useDefaultNodeType ? MESSAGE_CHILD_NODE_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED
+                                                : MESSAGE_CHILD_NODE_NOT_ALLOWED,
+                                        getDocViewNodeLabel(node),
+                                        effectiveNodeTypeToString(ntManagerProvider.getNameResolver(), parentNodeType),
+                                        constraintViolation)));
+    
+                    }
                 }
             }
 
@@ -226,6 +231,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
                         String.format(MESSAGE_UNKNOWN_NODE_TYPE_OR_NAMESPACE, e.getMessage()), e));
                 loggedUnknownNodeTypeMessages.add(e.getMessage());
             }
+            currentNodeNameAndType = NodeNameAndType.createUnknownNodeNameAndType(currentNodeNameAndType);
         } catch (RepositoryException e) {
             throw new IllegalStateException("Could not validate nodes/properties against node types: " + e.getMessage(), e);
         }
@@ -241,7 +247,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
         }
 
         try {
-            if (currentNodeNameAndType != null) {
+            if (currentNodeNameAndType != null && !currentNodeNameAndType.isUnknown()) {
                 Collection<ValidationMessage> messages = new LinkedList<>();
                 for (QNodeDefinition mandatoryNodeType : currentNodeNameAndType.getEffectiveNodeType().getMandatoryQNodeDefinitions()) {
                     boolean foundRequiredChildNode = currentNodeNameAndType.getChildren().stream()
@@ -260,7 +266,8 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
                 return null;
             }
         } finally {
-            if (currentNodeNameAndType != null) {
+            // do not leave root 
+            if (currentNodeNameAndType != null && !isRoot) {
                 currentNodeNameAndType = currentNodeNameAndType.getParent();
             }
         }
@@ -391,8 +398,18 @@ public class NodeTypeValidator implements DocumentViewXmlValidator {
             NodeTypeDefinitionProvider nodeTypeDefinitionProvider,
             NameResolver nameResolver, ItemDefinitionProvider itemDefinitionProvider, boolean allowProtected)
             throws RepositoryException {
-        Name nodeName = nameResolver.getQName(node.name);
-        QNodeTypeDefinition nodeTypeDefinition = nodeTypeDefinitionProvider.getNodeTypeDefinition(nameResolver.getQName(node.primary));
+        final Name nodeName;
+        try {
+            nodeName = nameResolver.getQName(node.name);
+        } catch (IllegalNameException|NamespaceException e) {
+            throw new IllegalNameException("Invalid node name " + node.name+ ": '" + e.getMessage()+ "'", e);
+        }
+        QNodeTypeDefinition nodeTypeDefinition;
+        try {
+            nodeTypeDefinition = nodeTypeDefinitionProvider.getNodeTypeDefinition(nameResolver.getQName(node.primary));
+        } catch (IllegalNameException|NamespaceException e) {
+            throw new IllegalNameException("Invalid primary type " + node.primary + ": '" + e.getMessage() + "'", e);
+        }
         if (nodeTypeDefinition.isAbstract()) {
             return "Not allowed to add node with abstract node type as primary type";
         }
diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorFactory.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorFactory.java
index be0ebb9..f3a7f0e 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorFactory.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorFactory.java
@@ -88,7 +88,7 @@ public class NodeTypeValidatorFactory implements ValidatorFactory {
             ntManagerProvider = new NodeTypeManagerProvider();
             for (String cndUrl : resolveJarUrls(cndUrls.split(","))) {
                 try (Reader reader = new InputStreamReader(URLFactory.createURL(cndUrl).openStream(), StandardCharsets.US_ASCII)) {
-                    LOGGER.info("Register additional node types from {}", cndUrl);
+                    LOGGER.info("Register node types from {}", cndUrl);
                     ntManagerProvider.registerNodeTypes(reader);
                 } catch (RepositoryException | IOException | ParseException e) {
                     throw new IllegalArgumentException("Error loading node types from CND at " + cndUrl, e);
diff --git a/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorTest.java b/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorTest.java
index b0a7220..fb5af86 100644
--- a/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorTest.java
+++ b/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/NodeTypeValidatorTest.java
@@ -172,7 +172,7 @@ public class NodeTypeValidatorTest {
         ValidationExecutorTest.assertViolation(validator.validate(node, nodeContext, false),
                 new ValidationMessage(ValidationMessageSeverity.WARN,
                         String.format(NodeTypeValidator.MESSAGE_UNKNOWN_NODE_TYPE_OR_NAMESPACE,
-                                "sling: is not a registered namespace prefix.")));
+                                "Invalid primary type sling:Folder: 'sling: is not a registered namespace prefix.'")));
     }
 
     @Test