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/21 12:13:39 UTC

[jackrabbit-filevault] branch feature/JCRVLT-536-warn-for-default-type-violations created (now 3f06f38)

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

kwin pushed a change to branch feature/JCRVLT-536-warn-for-default-type-violations
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git.


      at 3f06f38  JCRVLT-536 only emit "WARN" by default for violations against default type

This branch includes the following new commits:

     new 3f06f38  JCRVLT-536 only emit "WARN" by default for violations against default type

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-536 only emit "WARN" by default for violations against default type

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-536-warn-for-default-type-violations
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git

commit 3f06f38b0194eb3d21fc0a60dcf968d0405c31a9
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Jun 21 14:13:28 2021 +0200

    JCRVLT-536 only emit "WARN" by default for violations against default
    type
---
 src/site/markdown/validation.md                    |   2 +-
 .../spi/impl/nodetype/JcrNodeTypeMetaData.java     |   7 +-
 .../spi/impl/nodetype/JcrNodeTypeMetaDataImpl.java |  55 +++++-----
 .../spi/impl/nodetype/NodeTypeValidator.java       |  10 +-
 .../impl/nodetype/NodeTypeValidatorFactory.java    |  19 +++-
 .../impl/nodetype/JcrNodeTypeMetaDataImplTest.java | 121 ++++++++++-----------
 .../spi/impl/nodetype/NodeTypeValidatorTest.java   |  16 +--
 7 files changed, 121 insertions(+), 109 deletions(-)

diff --git a/src/site/markdown/validation.md b/src/site/markdown/validation.md
index 7a5d31d..83c0eb9 100644
--- a/src/site/markdown/validation.md
+++ b/src/site/markdown/validation.md
@@ -59,7 +59,7 @@ ID  |  Description | Options | Incremental Execution Limitations
 `jackrabbit-mergelimitations` | Checks for the limitation of import mode=merge outlined at [JCRVLT-255][jcrvlt-255]. | none | none
 `jackrabbit-oakindex` |  Checks if the package (potentially) modifies/creates an OakIndexDefinition. This is done by evaluating both the filter.xml for potential matches as well as the actual content for nodes with jcr:primaryType  `oak:indexDefinition`. | none | none
 `jackrabbit-packagetype` | Checks if the package type is correctly set for this package, i.e. is compliant with all rules outlined at [Package Types](packagetypes.html). | *jcrInstallerNodePathRegex*: the regex of the node paths which all OSGi bundles and configurations within packages must match ([JCR Installer](https://sling.apache.org/documentation/bundles/jcr-installer-provider.html)) (default=`/([^/]*/){0,4}?(install|config)(\\.[^/]*)*/(\\d{1,3}/)?.+?\\.`).<br/>*additionalJcrInstall [...]
-`jackrabbit-nodetypes` | Checks if all non empty elements within [DocView files](docview.html) have the mandatory property `jcr:primaryType` set and follow the [node type definition of their given type](https://jackrabbit.apache.org/jcr/node-types.html). | *cnds*: A URI pointing to one or multiple [CNDs](https://jackrabbit.apache.org/jcr/node-type-notation.html) (separated by `,`) which define the additional namespaces and nodetypes used apart from the [default ones defined in JCR 2.0](h [...]
+`jackrabbit-nodetypes` | Checks if all non empty elements within [DocView files](docview.html) have the mandatory property `jcr:primaryType` set and follow the [node type definition of their given type](https://jackrabbit.apache.org/jcr/node-types.html). | *cnds*: A URI pointing to one or multiple [CNDs](https://jackrabbit.apache.org/jcr/node-type-notation.html) (separated by `,`) which define the additional namespaces and nodetypes used apart from the [default ones defined in JCR 2.0](h [...]
 `jackrabbit-accesscontrol` | Checks that [access control list nodes (primary type `rep:ACL`, `rep:CugPolicy` and `rep:PrincipalPolicy`)](https://jackrabbit.apache.org/oak/docs/security/accesscontrol/default.html#Representation_in_the_Repository) are only used when the [package property's](./properties.html) `acHandling` is set to something but `ignore` or `clear` and also that there is at least one access control list node otherwise | none | Validation message in case no access control l [...]
 
 ### Custom Validators
diff --git a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaData.java b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaData.java
index d30e8e4..d0f2369 100644
--- a/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaData.java
+++ b/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/impl/nodetype/JcrNodeTypeMetaData.java
@@ -44,14 +44,14 @@ public interface JcrNodeTypeMetaData {
 
     Collection<ValidationMessage> addProperty(@NotNull NodeContext nodeContext, @NotNull NamePathResolver namePathResolver, @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider,
             @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, String name, boolean isMultiValue, Value... values) throws RepositoryException;
+            @NotNull ValidationMessageSeverity severity, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations, String name, boolean isMultiValue, Value... values) throws RepositoryException;
     @NotNull JcrNodeTypeMetaData addImplicitChildNode(@NotNull NameResolver nameResolver,
             @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider, @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider,
             @NotNull ItemDefinitionProvider itemDefinitionProvider, @NotNull NodeContext nodeContext, @NotNull Name implicitNodeType)
             throws RepositoryException;
     @NotNull JcrNodeTypeMetaData addChildNode(@NotNull NameResolver nameResolver, @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider,
             @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, @NotNull NodeContext nodeContext, @NotNull String primaryType, String... mixinTypes)
+            @NotNull NodeContext nodeContext, @NotNull String primaryType, String... mixinTypes)
                     throws RepositoryException, NamespaceExceptionInNodeName;
     @NotNull JcrNodeTypeMetaData addUnknownChildNode(@NotNull NameResolver nameResolver, @NotNull NodeContext nodeContext, @NotNull String name) throws IllegalNameException, NamespaceException;
     
@@ -62,7 +62,8 @@ public interface JcrNodeTypeMetaData {
     @NotNull JcrNodeTypeMetaData getOrCreateNode(NamePathResolver nameResolver, @NotNull NodeContext nodeContext, String path) throws RepositoryException;
     
     @NotNull Collection<ValidationMessage> finalizeValidation(@NotNull NamePathResolver nameResolver,
-            @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider, @NotNull ValidationMessageSeverity severity, @NotNull WorkspaceFilter filter) throws NamespaceException;
+            @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider, @NotNull ValidationMessageSeverity severity, 
+            @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations, @NotNull WorkspaceFilter filter) throws NamespaceException;
     @NotNull Name getPrimaryNodeType();
     String getQualifiedPath(NamePathResolver resolver) throws NamespaceException;
     void setNodeTypes(@NotNull NameResolver nameResolver, @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider,
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 bd675f8..22bfe95 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
@@ -78,14 +78,12 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     static final String CONSTRAINT_ABSTRACT_TYPE_AS_PRIMARY_TYPE = "Given node type is abstract and cannot be used as primary node type.";
     static final String CONSTRAINT_CHILD_NODE_NOT_ALLOWED = "Node type does not allow arbitrary child nodes and does not allow this specific name and node type either!";
 
-    static final String MESSAGE_CHILD_NODE_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED = "Node '%s [%s]' is not allowed as child of not contained node with potential default types '[%s]': %s";
-    static final String MESSAGE_CHILD_NODE_NOT_ALLOWED = "Node '%s [%s]' is not allowed as child of node with types [%s]: %s";
-    static final String MESSAGE_PROPERTY_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED = "Property '%s' [%s] is not allowed in node with potential default types [%s]: %s";;
-    static final String MESSAGE_PROPERTY_NOT_ALLOWED = "Property '%s' [%s] is not allowed in node with types [%s]: %s";
-    static final String MESSAGE_MANDATORY_CHILD_NODE_MISSING = "Mandatory child node missing: %s inside node with types [%s]";
+    static final String MESSAGE_CHILD_NODE_NOT_ALLOWED = "Node '%s [%s]' is not allowed as child of node with %s: %s";
+    static final String MESSAGE_PROPERTY_NOT_ALLOWED = "Property '%s' [%s] is not allowed in node with %s: %s";
+    static final String MESSAGE_MANDATORY_CHILD_NODE_MISSING = "Mandatory child node missing: %s inside node with %s";
     static final String MESSAGE_MANDATORY_UNCONTAINED_CHILD_NODE_MISSING = "Mandatory child node missing: %s inside node with types [%s] (outside of filter rules)";
-    static final String MESSAGE_MANDATORY_PROPERTY_MISSING = "Mandatory property '%s' missing in node with types [%s]";
-    static final String MESSAGE_MANDATORY_PROPERTY_WITH_WRONG_TYPE = "Mandatory property '%s' has type '%s' while it should have '%s' in node with types [%s]";
+    static final String MESSAGE_MANDATORY_PROPERTY_MISSING = "Mandatory property '%s' missing in node with %s";
+    static final String MESSAGE_MANDATORY_PROPERTY_WITH_WRONG_TYPE = "Mandatory property '%s' has type '%s' while it should have '%s' in node with %s";
 
     // do not validate protected JCR system properties that are handled by FileVault specially in https://github.com/apache/jackrabbit-filevault/blob/f785fcb24d4cbd01c734e9273310a925c29ae15b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java#L123 and 
     // https://github.com/apache/jackrabbit-filevault/blob/f785fcb24d4cbd01c734e9273310a925c29ae15b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java#L140
@@ -238,8 +236,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     public @NotNull JcrNodeTypeMetaData addChildNode(@NotNull NameResolver nameResolver,
             @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider,
             @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, @NotNull NodeContext nodeContext, @NotNull String primaryType,
-            String... mixinTypes)
+            @NotNull NodeContext nodeContext, @NotNull String primaryType, String... mixinTypes)
             throws IllegalNameException, RepositoryException, NamespaceExceptionInNodeName {
 
         List<Name> types = getTypes(nameResolver, primaryType, mixinTypes);
@@ -338,15 +335,15 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
 
     @Override
     public @NotNull Collection<ValidationMessage> finalizeValidation(@NotNull NamePathResolver namePathResolver,  @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, @NotNull WorkspaceFilter filter) throws NamespaceException {
+            @NotNull ValidationMessageSeverity severity, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations, @NotNull WorkspaceFilter filter) throws NamespaceException {
         if (!isValidationDone) {
             Collection<ValidationMessage> messages = new LinkedList<>();
             // 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 children and mandatory properties of " + getQualifiedPath(namePathResolver)));
-                messages.addAll(validateChildNodes(namePathResolver, nodeTypeDefinitionProvider, itemDefinitionProvider, severity, filter));
-                messages.addAll(validateMandatoryProperties(namePathResolver, severity));
+                messages.addAll(validateChildNodes(namePathResolver, nodeTypeDefinitionProvider, itemDefinitionProvider, severity, severityForDefaultNodeTypeViolations, filter));
+                messages.addAll(validateMandatoryProperties(namePathResolver, severity, severityForDefaultNodeTypeViolations));
             }
             // only remove child nodes on 2nd level to be able to validate mandatory properties of parent
             childNodesByName.clear();
@@ -361,7 +358,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     }
 
     private Collection<ValidationMessage> validateChildNodes(@NotNull NamePathResolver namePathResolver,  @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, @NotNull WorkspaceFilter filter) {
+            @NotNull ValidationMessageSeverity severity, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations, @NotNull WorkspaceFilter filter) {
         if (effectiveNodeType == null) {
             return Collections.emptyList();
         }
@@ -374,10 +371,9 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
                 constraintViolation = childNode.validateAgainstParentNodeType(effectiveNodeType, nodeTypeDefinitionProvider,
                         itemDefinitionProvider);
                 if (constraintViolation.isPresent()) {
-                    messages.add(new ValidationMessage(severity,
+                    messages.add(new ValidationMessage(isImplicit ? severityForDefaultNodeTypeViolations : severity,
                             String.format(
-                                    isImplicit ? MESSAGE_CHILD_NODE_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED
-                                            : MESSAGE_CHILD_NODE_NOT_ALLOWED,
+                                    MESSAGE_CHILD_NODE_NOT_ALLOWED,
                                     namePathResolver.getJCRName(childNode.name), namePathResolver.getJCRName(childNode.primaryNodeType),
                                     getEffectiveNodeTypeLabel(namePathResolver, effectiveNodeType),
                                     constraintViolation.get()), childNode.context));
@@ -405,7 +401,8 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
                 pathBuilder.addLast(mandatoryNodeType.getName());
                 try {
                     if (filter.contains(namePathResolver.getJCRPath(pathBuilder.getPath()))) {
-                        messages.add(new ValidationMessage(severity, String.format(MESSAGE_MANDATORY_CHILD_NODE_MISSING,
+                        messages.add(new ValidationMessage(isImplicit ? severityForDefaultNodeTypeViolations : severity,
+                                String.format(MESSAGE_MANDATORY_CHILD_NODE_MISSING,
                                 getNodeDefinitionLabel(namePathResolver, mandatoryNodeType),
                                 getEffectiveNodeTypeLabel(namePathResolver, effectiveNodeType))));
                     } else {
@@ -423,8 +420,15 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
         return messages;
     }
 
-    private static String getEffectiveNodeTypeLabel(NameResolver nameResolver, EffectiveNodeType nodeType) throws NamespaceException {
-        return joinAsQualifiedJcrName(nameResolver, nodeType.getMergedNodeTypes());
+    private String getEffectiveNodeTypeLabel(NameResolver nameResolver, EffectiveNodeType nodeType) throws NamespaceException {
+        String label;
+        String types = joinAsQualifiedJcrName(nameResolver, nodeType.getMergedNodeTypes());
+        if (isImplicit) 
+            label = String.format("potential default types [%s]", types);
+        else {
+            label =  String.format("types [%s]", types);
+        }
+        return label;
     }
 
     private static String getNodeDefinitionLabel(NameResolver nameResolver, QNodeDefinition nodeDefinition) throws NamespaceException {
@@ -499,7 +503,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     }
 
     private Collection<ValidationMessage> validateMandatoryProperties(@NotNull NamePathResolver nameResolver,
-            @NotNull ValidationMessageSeverity severity) {
+            @NotNull ValidationMessageSeverity severity, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations) {
 
         if (effectiveNodeType == null) {
             return Collections.emptyList();
@@ -517,7 +521,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
             }
             try {
                 if (!propertyTypesByName.containsKey(mandatoryPropertyDefinition.getName())) {
-                    messages.add(new ValidationMessage(severity,
+                    messages.add(new ValidationMessage(isImplicit ? severityForDefaultNodeTypeViolations : severity,
                             String.format(MESSAGE_MANDATORY_PROPERTY_MISSING,
                                     nameResolver.getJCRName(mandatoryPropertyDefinition.getName()),
                                     getEffectiveNodeTypeLabel(nameResolver, effectiveNodeType)), context));
@@ -526,7 +530,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
                     int actualPropertyType = propertyTypesByName.get(mandatoryPropertyDefinition.getName());
                     if (mandatoryPropertyDefinition.getRequiredType() != actualPropertyType) {
                         // check type
-                        messages.add(new ValidationMessage(severity,
+                        messages.add(new ValidationMessage(isImplicit ? severityForDefaultNodeTypeViolations : severity,
                                 String.format(MESSAGE_MANDATORY_PROPERTY_WITH_WRONG_TYPE,
                                         nameResolver.getJCRName(mandatoryPropertyDefinition.getName()),
                                         PropertyType.nameFromValue(actualPropertyType),
@@ -546,7 +550,7 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
     public Collection<ValidationMessage> addProperty(@NotNull NodeContext nodeContext, @NotNull NamePathResolver namePathResolver,
             @NotNull EffectiveNodeTypeProvider effectiveNodeTypeProvider,
             @NotNull NodeTypeDefinitionProvider nodeTypeDefinitionProvider, @NotNull ItemDefinitionProvider itemDefinitionProvider,
-            @NotNull ValidationMessageSeverity severity, String name, boolean isMultiValue, Value... values) throws RepositoryException {
+            @NotNull ValidationMessageSeverity severity, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations, String name, boolean isMultiValue, Value... values) throws RepositoryException {
         Collection<ValidationMessage> messages = new ArrayList<>();
         // some sanity checks on multivalue
         if (!isMultiValue && values.length > 1) {
@@ -572,10 +576,9 @@ public class JcrNodeTypeMetaDataImpl implements JcrNodeTypeMetaData {
                 nodeTypeDefinitionProvider, itemDefinitionProvider, qName, values, isAuthenticationOrAuthorizationContext,
                 isMultiValue);
         if (constraintViolation.isPresent()) {
-            messages.add(new ValidationMessage(severity,
+            messages.add(new ValidationMessage(isImplicit ? severityForDefaultNodeTypeViolations : severity,
                     String.format(
-                            isImplicit ? MESSAGE_PROPERTY_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED
-                                    : MESSAGE_PROPERTY_NOT_ALLOWED,
+                            MESSAGE_PROPERTY_NOT_ALLOWED,
                             namePathResolver.getJCRName(qName), PropertyType.nameFromValue(values[0].getType()),
                             getEffectiveNodeTypeLabel(namePathResolver, effectiveNodeType),
                             constraintViolation.get()),
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 4add3c5..8d3d02f 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
@@ -73,6 +73,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
     private final WorkspaceFilter filter;
     private final ValidationMessageSeverity defaultSeverity;
     private final ValidationMessageSeverity severityForUnknownNodeTypes;
+    private final ValidationMessageSeverity severityForDefaultNodeTypeViolations;
     private final DocViewPropertyValueFactory docViewPropertyValueFactory;
     private final NodeTypeManagerProvider ntManagerProvider;
     private final Set<String> loggedUnknownNodeTypeMessages;
@@ -82,13 +83,14 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
 
     public NodeTypeValidator(boolean isIncremental, @NotNull WorkspaceFilter filter, @NotNull NodeTypeManagerProvider ntManagerProvider,
             @NotNull Name defaultPrimaryNodeType, @NotNull ValidationMessageSeverity defaultSeverity,
-            @NotNull ValidationMessageSeverity severityForUnknownNodeTypes)
+            @NotNull ValidationMessageSeverity severityForUnknownNodeTypes, @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations)
             throws IllegalNameException, ConstraintViolationException, NoSuchNodeTypeException {
         this.filter = filter;
         this.ntManagerProvider = ntManagerProvider;
         this.defaultType = defaultPrimaryNodeType;
         this.defaultSeverity = defaultSeverity;
         this.severityForUnknownNodeTypes = severityForUnknownNodeTypes;
+        this.severityForDefaultNodeTypeViolations = severityForDefaultNodeTypeViolations;
         this.docViewPropertyValueFactory = new DocViewPropertyValueFactory();
         this.loggedUnknownNodeTypeMessages = new HashSet<>();
 
@@ -145,7 +147,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
         try {
             messages.addAll(currentNodeTypeMetaData.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(),
                     ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                    ntManagerProvider.getItemDefinitionProvider(), defaultSeverity, propertyName, isMultiValue, values));
+                    ntManagerProvider.getItemDefinitionProvider(), defaultSeverity, severityForDefaultNodeTypeViolations, propertyName, isMultiValue, values));
         } catch (NoSuchNodeTypeException | NamespaceException e) {
             // log each unknown node type/namespace only once!
             if (!loggedUnknownNodeTypeMessages.contains(e.getMessage())) {
@@ -221,7 +223,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
                 } else {
                     currentNodeTypeMetaData = parentNode.addChildNode(ntManagerProvider.getNameResolver(),
                             ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                            ntManagerProvider.getItemDefinitionProvider(), defaultSeverity, nodeContext, primaryType, mixinTypes);
+                            ntManagerProvider.getItemDefinitionProvider(), nodeContext, primaryType, mixinTypes);
                     
                 }
             } catch (NoSuchNodeTypeException | NamespaceException e) {
@@ -288,7 +290,7 @@ public class NodeTypeValidator implements DocumentViewXmlValidator, JcrPathValid
         for (JcrNodeTypeMetaData child : node.getChildren()) {
             messages.addAll(finalizeValidationForSubtree(child, nodeContext));
             messages.addAll(child.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                    ntManagerProvider.getItemDefinitionProvider(), defaultSeverity, filter));
+                    ntManagerProvider.getItemDefinitionProvider(), defaultSeverity, severityForDefaultNodeTypeViolations, filter));
         }
         return messages;
     }
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 e5d3faf..4818fa9 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
@@ -52,13 +52,18 @@ public class NodeTypeValidatorFactory implements ValidatorFactory {
     public static final String OPTION_CNDS = "cnds";
     /** The default node type to assume if no other node type is given */
     public static final String OPTION_DEFAULT_NODE_TYPES = "defaultNodeType";
+    static final @NotNull String DEFAULT_DEFAULT_NODE_TYPE = JcrConstants.NT_FOLDER;
+
     public static final String OPTION_SEVERITY_FOR_UNKNOWN_NODETYPES = "severityForUnknownNodetypes";
+    static final @NotNull ValidationMessageSeverity DEFAULT_SEVERITY_FOR_UNKNOWN_NODETYPE = ValidationMessageSeverity.WARN;
+    
+    public static final String OPTION_SEVERITY_FOR_DEFAULT_NODE_TYPE_VIOLATIONS = "severityForDefaultNodeTypeViolations";
+    static final @NotNull ValidationMessageSeverity DEFAULT_SEVERITY_FOR_DEFAULT_NODE_TYPE_VIOLATIONS = ValidationMessageSeverity.WARN;
+    
     /** Comma-separated list of name spaces that are known as valid (even if not defined in the CND files). Use syntax "prefix1=ns-uri1,prefix2=nsuri2,...". */
     public static final String OPTION_VALID_NAMESPACES = "validNameSpaces";
 
-    static final @NotNull String DEFAULT_DEFAULT_NODE_TYPE = JcrConstants.NT_FOLDER;
 
-    static final @NotNull ValidationMessageSeverity DEFAULT_SEVERITY_FOR_UNKNOWN_NODETYPE = ValidationMessageSeverity.WARN;
 
     private static final Logger LOGGER = LoggerFactory.getLogger(NodeTypeValidatorFactory.class);
 
@@ -87,6 +92,14 @@ public class NodeTypeValidatorFactory implements ValidatorFactory {
             severityForUnknownNodetypes = DEFAULT_SEVERITY_FOR_UNKNOWN_NODETYPE;
         }
 
+        final @NotNull ValidationMessageSeverity severityForDefaultNodeTypeViolations;
+        if (settings.getOptions().containsKey(OPTION_SEVERITY_FOR_DEFAULT_NODE_TYPE_VIOLATIONS)) {
+            String optionValue = settings.getOptions().get(OPTION_SEVERITY_FOR_DEFAULT_NODE_TYPE_VIOLATIONS);
+            severityForDefaultNodeTypeViolations = ValidationMessageSeverity.valueOf(optionValue.toUpperCase());
+        } else {
+            severityForDefaultNodeTypeViolations = DEFAULT_SEVERITY_FOR_DEFAULT_NODE_TYPE_VIOLATIONS;
+        }
+
         Map<String,String> validNameSpaces; 
         if (settings.getOptions().containsKey(OPTION_VALID_NAMESPACES)) {
             validNameSpaces = parseNamespaces(settings.getOptions().get(OPTION_VALID_NAMESPACES));
@@ -110,7 +123,7 @@ public class NodeTypeValidatorFactory implements ValidatorFactory {
                 ntManagerProvider.registerNamespace(entry.getKey(), entry.getValue());
             }
             return new NodeTypeValidator(context.isIncremental(), context.getFilter(), ntManagerProvider, ntManagerProvider.getNameResolver().getQName(defaultNodeType), settings.getDefaultSeverity(),
-                    severityForUnknownNodetypes);
+                    severityForUnknownNodetypes, severityForDefaultNodeTypeViolations);
         } catch (IOException | RepositoryException | ParseException e) {
             throw new IllegalArgumentException("Error loading default node type " + defaultNodeType, e);
         }
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 0eef044..fb5879d 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
@@ -72,19 +72,18 @@ public class JcrNodeTypeMetaDataImplTest {
 
     @Test
     public void testGetNode() throws RepositoryException {
-        ValidationMessageSeverity severity = ValidationMessageSeverity.ERROR;
         JcrNodeTypeMetaData child = root.addChildNode(ntManagerProvider.getNameResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
-                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(), severity,
+                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
                 createSimpleNodeContext("my"),
                 NodeType.NT_FOLDER);
         JcrNodeTypeMetaData grandChild = child.addChildNode(ntManagerProvider.getNameResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(),
-                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(), severity,
+                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
                 createSimpleNodeContext("test"),
                 NodeType.NT_FOLDER);
         JcrNodeTypeMetaData child2 = root.addChildNode(ntManagerProvider.getNameResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(),
-                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(), severity,
+                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
                 createSimpleNodeContext("test2"),
                 NodeType.NT_FOLDER);
         Assert.assertEquals(child2,
@@ -94,14 +93,13 @@ public class JcrNodeTypeMetaDataImplTest {
     public void testGetNodeWithNonExistingPath() throws MalformedPathException, NamespaceException, IllegalArgumentException,
             PathNotFoundException, RepositoryException {
 
-        ValidationMessageSeverity severity = ValidationMessageSeverity.ERROR;
         JcrNodeTypeMetaData child = root.addChildNode(ntManagerProvider.getNameResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
-                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(), severity,
+                ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
                 createSimpleNodeContext("my"),
                 NodeType.NT_FOLDER);
         JcrNodeTypeMetaData grandChild = child.addChildNode(ntManagerProvider.getNameResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), severity, createSimpleNodeContext("test"), NodeType.NT_FOLDER);
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("test"), NodeType.NT_FOLDER);
         Assert.assertFalse(grandChild.getNode(ntManagerProvider.getNamePathResolver(), "/test2").isPresent());
     }
 
@@ -109,7 +107,6 @@ public class JcrNodeTypeMetaDataImplTest {
     public void testAddChildNodeWithUndeclaredNamespaceInName() throws RepositoryException {
         root.addChildNode(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 createSimpleNodeContext("invalid:name"), NodeTypeConstants.NT_FOLDER);
     }
 
@@ -117,7 +114,6 @@ public class JcrNodeTypeMetaDataImplTest {
     public void testAddChildNodeWithUndeclaredNamespaceInType() throws RepositoryException {
         root.addChildNode(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 createSimpleNodeContext("myname"), "my:nodeType1");
     }
 
@@ -125,7 +121,6 @@ public class JcrNodeTypeMetaDataImplTest {
     public void testAddChildNodeWithUndeclaredType() throws RepositoryException {
         root.addChildNode(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 createSimpleNodeContext("myname"), "jcr:nodeType1");
     }
 
@@ -144,79 +139,76 @@ public class JcrNodeTypeMetaDataImplTest {
         
         JcrNodeTypeMetaData node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext,
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext,
                 "mix:mimeType");
         ValidationExecutorTest.assertViolation(root.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
                 ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR, filter),
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "mix:mimeType", ROOT_NODE_TYPES,
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "mix:mimeType", "types [" + ROOT_NODE_TYPES +"]",
                         JcrNodeTypeMetaDataImpl.CONSTRAINT_MIXIN_TYPE_AS_PRIMARY_TYPE), nodeContext));
 
         // add node with abstract type
         root = JcrNodeTypeMetaDataImpl.createRoot(false, ntManagerProvider.getEffectiveNodeTypeProvider());
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext,
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext,
                 "nt:hierarchyNode");
         ValidationExecutorTest.assertViolation(root.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
                 ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR, filter),
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "nt:hierarchyNode", ROOT_NODE_TYPES,
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "nt:hierarchyNode", "types [" + ROOT_NODE_TYPES +"]",
                         JcrNodeTypeMetaDataImpl.CONSTRAINT_ABSTRACT_TYPE_AS_PRIMARY_TYPE), nodeContext));
 
         // add node for version storage
         root = JcrNodeTypeMetaDataImpl.createRoot(false, ntManagerProvider.getEffectiveNodeTypeProvider());
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 createSimpleNodeContext("versionedNode"), "rep:versionStorage");
         // add child node with protected node which is ACL (i.e. accepted)
         node.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 createSimpleNodeContext("rep:policy"), "rep:Policy");
         // add child node with protected node which is not ACL (i.e. not accepted)
         root = JcrNodeTypeMetaDataImpl.createRoot(false, ntManagerProvider.getEffectiveNodeTypeProvider());
         node.addChildNode(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
                 nodeContext, "nt:versionHistory");
         ValidationExecutorTest.assertViolation(node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
                 ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR, filter), new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "nt:versionHistory", "rep:versionStorage",
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter), new ValidationMessage(ValidationMessageSeverity.ERROR,
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name", "nt:versionHistory", "types [rep:versionStorage]",
                         JcrNodeTypeMetaDataImpl.CONSTRAINT_CHILD_NODE_PROTECTED), nodeContext));
 
         // add valid child node
         root = JcrNodeTypeMetaDataImpl.createRoot(false, ntManagerProvider.getEffectiveNodeTypeProvider());
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("name"),
                 "my:nodeType1");
         // below that add auto-created child node
         nodeContext = createSimpleNodeContext("my:autoCreatedChild1");
         node.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR,
+                ntManagerProvider.getItemDefinitionProvider(), 
                 nodeContext, "my:nodeType2");
         // and next to it a child node which is not allowed
         NodeContext nodeContext2 = createSimpleNodeContext("name2");
         node.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext2,
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext2,
                 "my:nodeType1");
         ValidationExecutorTest.assertViolation(node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
                 ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR, filter), 
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter), 
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
                         String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "my:autoCreatedChild1", "my:nodeType2",
-                                "my:nodeType1",
+                                "types [my:nodeType1]",
                                 JcrNodeTypeMetaDataImpl.CONSTRAINT_CHILD_NODE_AUTO_CREATED), nodeContext),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name2", "my:nodeType1", "my:nodeType1",
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED, "name2", "my:nodeType1", "types [my:nodeType1]",
                         JcrNodeTypeMetaDataImpl.CONSTRAINT_CHILD_NODE_NOT_ALLOWED), nodeContext2));
     }
 
@@ -231,7 +223,7 @@ public class JcrNodeTypeMetaDataImplTest {
         // add valid node
         JcrNodeTypeMetaData node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("name"),
                 "my:nodeType1");
 
         DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
@@ -239,71 +231,72 @@ public class JcrNodeTypeMetaDataImplTest {
         // mandatory child node missing outside filter
         Collection<ValidationMessage> messages = root.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
                 ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR, filter);
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
 
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name2"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("name2"),
                 "my:nodeType1");
         
         // mandatory child node missing inside filter
         filter.add(new PathFilterSet("/"));
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(),ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(),ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         ValidationExecutorTest.assertViolation(messages, new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_CHILD_NODE_MISSING, "my:namedChild1 [my:nodeType1]", "my:nodeType1",
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_CHILD_NODE_MISSING, "my:namedChild1 [my:nodeType1]", "types [my:nodeType1]",
                         "/name2")));
 
         // calling a second time will not lead to anything
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
         
         // now add mandatory child node
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name3"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("name3"),
                 "my:nodeType1");
         
         node.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("my:namedChild1"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("my:namedChild1"),
                 "my:nodeType1");
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR,
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 new DefaultWorkspaceFilter());
         MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
 
         // add arbitrary property to root
         MatcherAssert.assertThat(root.addProperty(createSimpleNodeContext("/"), ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, "property", false,
+                ntManagerProvider.getItemDefinitionProvider(),ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR,  "property", false,
                 ValueFactoryImpl.getInstance().createValue("foo")), AnyValidationMessageMatcher.noValidationInCollection());
         
         NodeContext nodeContext = createSimpleNodeContext("nodeForMandatoryProperties");
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext, "my:nodeType2");
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext, "my:nodeType2");
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(),ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         ValidationExecutorTest.assertViolation(messages, new ValidationMessage(ValidationMessageSeverity.ERROR,
-                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_PROPERTY_MISSING, "my:mandatoryProperty", "my:nodeType2",
+                String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_PROPERTY_MISSING, "my:mandatoryProperty", "types [my:nodeType2]",
                         "/nodeForMandatoryProperties"), nodeContext));
 
         nodeContext = createSimpleNodeContext("nodeForMandatoryProperties2");
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, nodeContext, "my:nodeType2");
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext, "my:nodeType2");
+        // TODO: assert return value
         node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "my:mandatoryProperty", false, ValueFactoryImpl.getInstance().createValue("foo"));
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         ValidationExecutorTest.assertViolation(messages, new ValidationMessage(ValidationMessageSeverity.ERROR,
                 String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_PROPERTY_WITH_WRONG_TYPE, "my:mandatoryProperty", "String", "Date",
-                        "my:nodeType2"), nodeContext));
+                        "types [my:nodeType2]"), nodeContext));
     }
 
     @Test
@@ -317,29 +310,29 @@ public class JcrNodeTypeMetaDataImplTest {
         // add valid node
         JcrNodeTypeMetaData node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("name"),
                 "my:nodeType1");
 
         DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
 
         node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("name2"),
+                ntManagerProvider.getItemDefinitionProvider(), 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(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(),  ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(),  ValidationMessageSeverity.ERROR, 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");
+                ntManagerProvider.getItemDefinitionProvider(), nodeContext, "my:nodeType2");
         messages = node.finalizeValidation(ntManagerProvider.getNamePathResolver(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, filter);
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, filter);
         MatcherAssert.assertThat(messages, AnyValidationMessageMatcher.noValidationInCollection());
     }
     
@@ -348,7 +341,7 @@ public class JcrNodeTypeMetaDataImplTest {
         root.addProperty(createSimpleNodeContext("/"), ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "invalid:property", false, ValueFactoryImpl.getInstance().createValue("foo"));
     }
 
@@ -364,65 +357,65 @@ public class JcrNodeTypeMetaDataImplTest {
         // add arbitrary property to root
         MatcherAssert.assertThat(root.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, "property", false,
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, "property", false,
                 ValueFactoryImpl.getInstance().createValue("foo")), AnyValidationMessageMatcher.noValidationInCollection());
 
         JcrNodeTypeMetaData node = root.addChildNode(ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, createSimpleNodeContext("child"),
+                ntManagerProvider.getItemDefinitionProvider(), createSimpleNodeContext("child"),
                 "my:nodeType3");
 
         // not allowed (wrong type)
         ValidationExecutorTest.assertViolation( node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, "property", false,
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR,  "property", false,
                 ValueFactoryImpl.getInstance().createValue("foo")),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
                         String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED, "property",
-                                "String", "my:nodeType3", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_NOT_ALLOWED),
+                                "String", "types [my:nodeType3]", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_NOT_ALLOWED),
                         nodeContext));
 
         // protected but nevertheless allowed
         MatcherAssert.assertThat(node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, "jcr:primaryType", false,
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, "jcr:primaryType", false,
                 ValueFactoryImpl.getInstance().createValue("foo")), AnyValidationMessageMatcher.noValidationInCollection());
 
         // protected
         ValidationExecutorTest.assertViolation(node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "my:protected", false, ValueFactoryImpl.getInstance().createValue("foo")),
-                new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED,
-                        "my:protected", "String", "my:nodeType3", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_PROTECTED), nodeContext));
+                new ValidationMessage(ValidationMessageSeverity.ERROR,  String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED,
+                        "my:protected", "String", "types [my:nodeType3]", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_PROTECTED), nodeContext));
 
         // multi value where single value is required
         ValidationExecutorTest.assertViolation(node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(),
                 ntManagerProvider.getEffectiveNodeTypeProvider(), ntManagerProvider.getNodeTypeDefinitionProvider(),
-                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, "my:property1", true,
+                ntManagerProvider.getItemDefinitionProvider(), ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, "my:property1", true,
                 ValueFactoryImpl.getInstance().createValue("foo"), ValueFactoryImpl.getInstance().createValue("bar")),
                 new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED,
-                        "my:property1", "String", "my:nodeType3", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_NOT_ALLOWED), nodeContext));
+                        "my:property1", "String", "types [my:nodeType3]", JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_NOT_ALLOWED), nodeContext));
 
         // constrained property
         MatcherAssert.assertThat(node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "my:constrainedStringProperty", false, ValueFactoryImpl.getInstance().createValue("prefix1foo")),
                 AnyValidationMessageMatcher.noValidationInCollection());
 
         MatcherAssert.assertThat(node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "my:constrainedStringProperty", false, ValueFactoryImpl.getInstance().createValue("foosuffix1")),
                 AnyValidationMessageMatcher.noValidationInCollection());
 
         ValidationExecutorTest.assertViolation( node.addProperty(nodeContext, ntManagerProvider.getNamePathResolver(), ntManagerProvider.getEffectiveNodeTypeProvider(),
                 ntManagerProvider.getNodeTypeDefinitionProvider(), ntManagerProvider.getItemDefinitionProvider(),
-                ValidationMessageSeverity.ERROR,
+                ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, 
                 "my:constrainedStringProperty", false, ValueFactoryImpl.getInstance().createValue("foo")),
                 new ValidationMessage(ValidationMessageSeverity.ERROR, String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED,
-                        "my:constrainedStringProperty", "String", "my:nodeType3",
+                        "my:constrainedStringProperty", "String", "types [my:nodeType3]",
                         String.format(JcrNodeTypeMetaDataImpl.CONSTRAINT_PROPERTY_VALUE,
                                 "'foo' does not satisfy the constraint '.*suffix1'")),
                         nodeContext));
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 382649e..81afbb1 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
@@ -79,7 +79,7 @@ public class NodeTypeValidatorTest {
             }
         }
         return new NodeTypeValidator(false, filter, ntManagerProvider, defaultNodeType, ValidationMessageSeverity.ERROR,
-                ValidationMessageSeverity.WARN);
+                ValidationMessageSeverity.WARN, ValidationMessageSeverity.WARN);
     }
 
     @Test
@@ -101,7 +101,7 @@ public class NodeTypeValidatorTest {
         node = new DocViewNode("test", "test", null, props, null, "nt:folder");
         ValidationExecutorTest.assertViolation(validator.validate(node, nodeContext, false),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
-                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED, "prop1", "String", "nt:folder",
+                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED, "prop1", "String", "types [nt:folder]",
                                 "No applicable property definition found for name and type!"), nodeContext));
     }
 
@@ -137,9 +137,9 @@ public class NodeTypeValidatorTest {
         DocViewNode node = new DocViewNode("jcr:root", "jcr:root", null, props, null, JcrConstants.NT_UNSTRUCTURED);
         MatcherAssert.assertThat(validator.validate(node, nodeContext, false), AnyValidationMessageMatcher.noValidationInCollection());
         ValidationExecutorTest.assertViolation(validator.done(),
-                new ValidationMessage(ValidationMessageSeverity.ERROR,
-                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_OF_NOT_CONTAINED_PARENT_POTENTIALLY_NOT_ALLOWED,
-                                "test", "nt:unstructured", JcrConstants.NT_FOLDER,
+                new ValidationMessage(ValidationMessageSeverity.WARN,
+                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_CHILD_NODE_NOT_ALLOWED,
+                                "test", "nt:unstructured", "potential default types ["+JcrConstants.NT_FOLDER + "]",
                                 "Node type does not allow arbitrary child nodes and does not allow this specific name and node type either!"), nodeContext));
     }
 
@@ -184,7 +184,7 @@ public class NodeTypeValidatorTest {
         ValidationExecutorTest.assertViolation(validator.done(),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
                         String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_PROPERTY_MISSING,
-                                "rep:principalName", "rep:SystemUser", nodeContext.getNodePath()), nodeContext));
+                                "rep:principalName", "types [rep:SystemUser]", nodeContext.getNodePath()), nodeContext));
     }
 
     @Test
@@ -200,7 +200,7 @@ public class NodeTypeValidatorTest {
         ValidationExecutorTest.assertViolation(validator.done(),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
                         String.format(JcrNodeTypeMetaDataImpl.MESSAGE_MANDATORY_CHILD_NODE_MISSING,
-                                "jcr:content [nt:base]", "nt:file", "/apps/test/node4")));
+                                "jcr:content [nt:base]", "types [nt:file]", "/apps/test/node4")));
         MatcherAssert.assertThat(validator.done(), AnyValidationMessageMatcher.noValidationInCollection());
     }
 
@@ -217,7 +217,7 @@ public class NodeTypeValidatorTest {
         DocViewNode node = new DocViewNode("jcr:root", "jcr:root", null, props, null, JcrConstants.NT_FILE);
         ValidationExecutorTest.assertViolation(validator.validate(node, nodeContext, false),
                 new ValidationMessage(ValidationMessageSeverity.ERROR,
-                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED, "invalid-prop", "String", JcrConstants.NT_FILE,
+                        String.format(JcrNodeTypeMetaDataImpl.MESSAGE_PROPERTY_NOT_ALLOWED, "invalid-prop", "String", "types [" + JcrConstants.NT_FILE + "]",
                                 "No applicable property definition found for name and type!"), nodeContext));
     }