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 2021/06/10 09:34:48 UTC

[jackrabbit-filevault] branch feature/JCRVLT-532-relaxed-nodetype-validator-for-incremental created (now feebfd2)

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

kwin pushed a change to branch feature/JCRVLT-532-relaxed-nodetype-validator-for-incremental
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git.


      at feebfd2  JCRVLT-532 use relaxed node type validation during incremental runs

This branch includes the following new commits:

     new feebfd2  JCRVLT-532 use relaxed node type validation during incremental runs

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[jackrabbit-filevault] 01/01: JCRVLT-532 use relaxed node type validation during incremental runs

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch feature/JCRVLT-532-relaxed-nodetype-validator-for-incremental
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit feebfd2f81ee372805d060dfb814efaedf5de18b
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Thu Jun 10 11:34:33 2021 +0200

    JCRVLT-532 use relaxed node type validation during incremental runs
---
 .../vault/validation/spi/ValidationContext.java    |  8 +++++
 .../spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java | 23 +++++++-----
 .../spi/impl/nodetype/NodeTypeValidator.java       |  4 +--
 .../impl/nodetype/NodeTypeValidatorFactory.java    |  5 +--
 .../vault/validation/spi/package-info.java         |  2 +-
 .../impl/nodetype/JcrNodeTypeMetaDataImplTest.java | 41 ++++++++++++++++++++--
 .../spi/impl/nodetype/NodeTypeValidatorTest.java   |  2 +-
 7 files changed, 66 insertions(+), 19 deletions(-)

diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/ValidationContext.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/ValidationContext.java
index 607aa1e..0b09161 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/ValidationContext.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/ValidationContext.java
@@ -64,4 +64,12 @@ public interface ValidationContext {
      * @return the package info of all resolved package dependencies (i.e. the ones for which an artifact was found).
      */
     @NotNull Collection<PackageInfo> getDependenciesPackageInfo();
+    
+    /**
+     * 
+     * @return {@code true} in case the validation is incremental (i.e. does not cover all files in a package). This should relax some validations.
+     */
+    default boolean isIncremental() {
+        return false;
+    }
 }
diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java
index 0745420..144bc43 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java
@@ -110,8 +110,9 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     private final boolean isImplicit; // if this is true, the node type is set implicitly (not explicitly set in package, used as is in the
                                       // repository)
     private boolean isValidationDone;
+    private final boolean isIncremental;
 
-    private JcrNodeTypeMetaDataImpl(@NotNull Name name, @Nullable Name primaryNodeType, @Nullable EffectiveNodeType effectiveNodeType,
+    private JcrNodeTypeMetaDataImpl(boolean isIncremental, @NotNull Name name, @Nullable Name primaryNodeType, @Nullable EffectiveNodeType effectiveNodeType,
             JcrNodeTypeMetaDataImpl parentNode, boolean isAuthenticationOrAuthorizationContext, boolean isImplicit) {
         super();
         this.name = name; // fully namespaced (taking into account local namespace declaration for Docview XML)
@@ -124,6 +125,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
         this.isAuthenticationOrAuthorizationContext = isAuthenticationOrAuthorizationContext;
         this.isImplicit = isImplicit;
         this.isValidationDone = false;
+        this.isIncremental = isIncremental;
     }
 
     @Override
@@ -228,7 +230,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     }
 
     private @NotNull JcrNodeTypeMetaDataImpl addUnknownChildNode(@NotNull Name name) throws IllegalNameException {
-        JcrNodeTypeMetaDataImpl childNode = new JcrNodeTypeMetaDataImpl(name, null, null, this, false, false);
+        JcrNodeTypeMetaDataImpl childNode = new JcrNodeTypeMetaDataImpl(this.isIncremental, name, null, null, this, false, false);
         childNodesByName.put(name, childNode);
         return childNode;
     }
@@ -299,7 +301,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
         if (!isAuthenticationOrAuthorizationContext) {
             isAuthenticationOrAuthorizationContext = this.isAuthenticationOrAuthorizationContext;
         }
-        JcrNodeTypeMetaDataImpl newNode = new JcrNodeTypeMetaDataImpl(qName, newPrimaryNodeType, newEffectiveNodeType, this,
+        JcrNodeTypeMetaDataImpl newNode = new JcrNodeTypeMetaDataImpl(this.isIncremental, qName, newPrimaryNodeType, newEffectiveNodeType, this,
                 isAuthenticationOrAuthorizationContext, isImplicit);
         childNodesByName.put(qName, newNode);
         return newNode;
@@ -350,10 +352,13 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
             @NotNull ValidationMessageSeverity severity, @NotNull WorkspaceFilter filter) throws NamespaceException {
         if (!isValidationDone) {
             Collection<ValidationMessage> messages = new LinkedList<>();
-            messages.add(new ValidationMessage(ValidationMessageSeverity.DEBUG,
-                    "Validate mandatory children and properties of " + getQualifiedPath(namePathResolver)));
-            messages.addAll(validateMandatoryChildNodes(namePathResolver, severity, filter));
-            messages.addAll(validateMandatoryProperties(namePathResolver, severity));
+            // in incremental validations ignore missing mandatory properties and child nodes (as they might not be visible to the validator)
+            if (!isIncremental) {
+                messages.add(new ValidationMessage(ValidationMessageSeverity.DEBUG,
+                        "Validate mandatory children and properties of " + getQualifiedPath(namePathResolver)));
+                messages.addAll(validateMandatoryChildNodes(namePathResolver, severity, filter));
+                messages.addAll(validateMandatoryProperties(namePathResolver, severity));
+            }
             // only remove child nodes on 2nd level to be able to validate mandatory properties of parent
             childNodesByName.clear();
             isValidationDone = true;
@@ -624,9 +629,9 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
         return true;
     }
 
-    public static @NotNull JcrNodeTypeMetaDataImpl createRoot(@NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider)
+    public static @NotNull JcrNodeTypeMetaDataImpl createRoot(boolean isIncremental, @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider)
             throws ConstraintViolationException, NoSuchNodeTypeException {
-        return new JcrNodeTypeMetaDataImpl(NameConstants.ROOT, NameConstants.REP_ROOT, effectiveNodeTypeProvider.getEffectiveNodeType(
+        return new JcrNodeTypeMetaDataImpl(isIncremental, NameConstants.ROOT, NameConstants.REP_ROOT, effectiveNodeTypeProvider.getEffectiveNodeType(
                 new Name[] {
                         NameConstants.REP_ROOT,
                         NameConstants.REP_ACCESS_CONTROLLABLE,
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 1a013a4..2bacdcf 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
@@ -80,7 +80,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
     private final @NotNull Name defaultType;
     private JcrNodeTypeMetaData currentNodeTypeMetaData;
 
-    public NodeTypeValidator(@NotNull WorkspaceFilter filter, @NotNull NodeTypeManagerProvider ntManagerProvider,
+    public NodeTypeValidator(boolean isIncremental, @NotNull WorkspaceFilter filter, @NotNull NodeTypeManagerProvider ntManagerProvider,
             @NotNull Name defaultPrimaryNodeType, @NotNull ValidationMessageSeverity defaultSeverity,
             @NotNull ValidationMessageSeverity severityForUnknownNodeTypes)
             throws IllegalNameException, ConstraintViolationException, NoSuchNodeTypeException {
@@ -92,7 +92,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
         this.docViewPropertyValueFactory = new DocViewPropertyValueFactory();
         this.loggedUnknownNodeTypeMessages = new HashSet<>();
 
-        this.currentNodeTypeMetaData = JcrNodeTypeMetaDataImpl.createRoot(ntManagerProvider.getEffectiveNodeTypeProvider());
+        this.currentNodeTypeMetaData = JcrNodeTypeMetaDataImpl.createRoot(isIncremental, ntManagerProvider.getEffectiveNodeTypeProvider());
     }
 
     static String getDocViewNodeLabel(DocViewNode node) {
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 71ed2ca..e5d3faf 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
@@ -22,14 +22,11 @@ import java.io.Reader;
 import java.net.JarURLConnection;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.jar.Manifest;
 
 import javax.jcr.RepositoryException;
@@ -112,7 +109,7 @@ public class NodeTypeValidatorFactory implements ValidatorFactory {
             for (Map.Entry<String, String> entry : validNameSpaces.entrySet()) {
                 ntManagerProvider.registerNamespace(entry.getKey(), entry.getValue());
             }
-            return new NodeTypeValidator(context.getFilter(), ntManagerProvider, ntManagerProvider.getNameResolver().getQName(defaultNodeType), settings.getDefaultSeverity(),
+            return new NodeTypeValidator(context.isIncremental(), context.getFilter(), ntManagerProvider, ntManagerProvider.getNameResolver().getQName(defaultNodeType), settings.getDefaultSeverity(),
                     severityForUnknownNodetypes);
         } catch (IOException | RepositoryException | ParseException e) {
             throw new IllegalArgumentException("Error loading default node type " + defaultNodeType, e);
diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/package-info.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/package-info.java
index 0dfdeae..e36d16b 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/package-info.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/package-info.java
@@ -18,7 +18,7 @@
 /**
  * The FileVault validation framework SPI. Provides classes/interfaces to implement validators on FileVault packages.
  */
-@Version("1.3.0")
+@Version("1.4.0")
 package org.apache.jackrabbit.vault.validation.spi;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImplTest.java b/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImplTest.java
index b2d472b..f69d870 100644
--- a/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImplTest.java
+++ b/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaDataImplTest.java
@@ -65,7 +65,7 @@ public class JcrNodeTypeMetaDataImplTest {
     @Before
     public void setUp() throws IOException, RepositoryException, ParseException {
         ntManagerProvider = new NodeTypeManagerProvider();
-        root = JcrNodeTypeMetaDataImpl.createRoot(ntManagerProvider.getEffectiveNodeTypeProvider());
+        root = JcrNodeTypeMetaDataImpl.createRoot(false, ntManagerProvider.getEffectiveNodeTypeProvider());
     }
 
     static NodeContext createSimpleNodeContext(String nodePath) {
@@ -220,7 +220,7 @@ public class JcrNodeTypeMetaDataImplTest {
     }
 
     @Test
-    public void testValidateMandatoryChildNode() throws IllegalNameException, NoSuchNodeTypeException, RepositoryException,
+    public void testValidateMandatoryChildNodesAndProperties() throws IllegalNameException, NoSuchNodeTypeException, RepositoryException,
             IOException, ParseException {
         try (InputStream input = this.getClass().getResourceAsStream("/simple-restricted-nodetypes.cnd");
                 Reader reader = new InputStreamReader(input, StandardCharsets.US_ASCII)) {
@@ -305,6 +305,43 @@ public class JcrNodeTypeMetaDataImplTest {
                         "my:nodeType2", "/nodeForMandatoryProperties2")));
     }
 
+    @Test
+    public void testValidateMandatoryChildNodesAndPropertiesDuringIncrementalBuild() throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, UnsupportedRepositoryOperationException, ParseException, RepositoryException, IOException {
+        try (InputStream input = this.getClass().getResourceAsStream("/simple-restricted-nodetypes.cnd");
+                Reader reader = new InputStreamReader(input, StandardCharsets.US_ASCII)) {
+            ntManagerProvider.registerNodeTypes(reader);
+        }
+        // enable incremental validation
+        root = JcrNodeTypeMetaDataImpl.createRoot(true, ntManagerProvider.getEffectiveNodeTypeProvider());
+        // add valid node
+        JcrNodeTypeMetaData node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
+                ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name"),
+                "my:nodeType1");
+        assertNoValidationErrors(node);
+
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+
+        node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
+                ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name2"),
+                "my:nodeType1");
+        
+        // mandatory child node missing but not reported due to incremental validation
+        filter.add(new PathFilterSet("/"));
+        Collection<ValidationMessage> messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ValidationMessageSeverity.ERROR, filter);
+        MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
+
+        // mandatory property missing but not reported due to incremental validation
+        NodeContext nodeContext = createSimpleNodeContext("nodeForMandatoryProperties");
+        node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
+                ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext, "my:nodeType2");
+        assertNoValidationErrors(node);
+        messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ValidationMessageSeverity.ERROR, filter);
+        MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
+    }
+    
     @Test(expected = IllegalNameException.class)
     public void testAddPropertyWithUndeclaredNamespace() throws RepositoryException {
         root.addProperty(createSimpleNodeContext("/"), ntManagerProvider.getNamePathResolver(),
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 54c5913..3790f3c 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
@@ -80,7 +80,7 @@ public class NodeTypeValidatorTest {
                 throw new IllegalArgumentException("Error loading node types from CND at " + cndUrl, e);
             }
         }
-        return new NodeTypeValidator(filter, ntManagerProvider, defaultNodeType, ValidationMessageSeverity.ERROR,
+        return new NodeTypeValidator(false, filter, ntManagerProvider, defaultNodeType, ValidationMessageSeverity.ERROR,
                 ValidationMessageSeverity.WARN);
     }