You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2015/07/29 09:22:47 UTC

svn commit: r1693191 - in /sling/trunk/bundles/extensions/validation: api/src/main/java/org/apache/sling/validation/ api/src/main/java/org/apache/sling/validation/model/ api/src/main/java/org/apache/sling/validation/spi/ core/src/main/java/org/apache/s...

Author: kwin
Date: Wed Jul 29 07:22:46 2015
New Revision: 1693191

URL: http://svn.apache.org/r1693191
Log:
SLING-4876 support resource type inheritance for validator models

This closes #100

Added:
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceBuilder.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/MergedValidationModel.java
    sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/
    sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/MergedValidationModelTest.java
Modified:
    sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/ValidationService.java
    sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ChildResource.java
    sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ResourceProperty.java
    sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ValidationModel.java
    sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/spi/ValidationModelProvider.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetriever.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationResourceVisitor.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceImpl.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java
    sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java
    sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java
    sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java
    sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java
    sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/models/UserModel.java
    sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/servlets/ModifyUserServlet.java
    sling/trunk/bundles/extensions/validation/test-services/src/main/java/org/apache/sling/validation/testservices/ValidationPostOperation.java

Modified: sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/ValidationService.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/ValidationService.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/ValidationService.java (original)
+++ sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/ValidationService.java Wed Jul 29 07:22:46 2015
@@ -39,11 +39,12 @@ public interface ValidationService {
      * @param validatedResourceType the type of {@code Resources} the model validates, should be either relative 
      *                              (i.e. not start with a "/") or starting with one of the resource resolver's search paths
      * @param resourcePath        the path of the validated resource, may be {@code null} or empty. Must match the applicablePath property of the model
+     * @param considerResourceSuperTypeModels if {@code true} will also consider the validation model of the resource super type (recursively), otherwise not.
      * @return a {@code ValidationModel} if one is found, {@code null} otherwise
      * @throws IllegalStateException in case an invalid validation model was found
-     * @throws IllegalArgumentException in case validatedResourceType was blank, {@code null} or absolute but outside of the search paths
+     * @throws IllegalArgumentException in case validatedResourceType was blank, {@code null} or absolute but outside of the search paths or some other error occurred while retrieving the models.
      */
-    @CheckForNull ValidationModel getValidationModel(@Nonnull String validatedResourceType, String resourcePath) throws IllegalStateException, IllegalArgumentException;
+    @CheckForNull ValidationModel getValidationModel(@Nonnull String validatedResourceType, String resourcePath, boolean considerResourceSuperTypeModels) throws IllegalStateException, IllegalArgumentException;
 
     /**
      * Tries to obtain a {@link ValidationModel} that is able to validate the given {@code resource}.
@@ -51,9 +52,9 @@ public interface ValidationService {
      * @param resource the resource for which to obtain a validation model
      * @return a {@code ValidationModel} if one is found, {@code null} otherwise
      * @throws IllegalStateException in case an invalid validation model was found
-     * @throws IllegalArgumentException in case resourceType being set on the given resource is blank, not set or absolute but outside of the search paths.
+     * @throws IllegalArgumentException in case resourceType being set on the given resource is blank, not set or absolute but outside of the search paths or some other error occurred while retrieving the models.
      */
-    @CheckForNull ValidationModel getValidationModel(@Nonnull Resource resource) throws IllegalStateException, IllegalArgumentException;
+    @CheckForNull ValidationModel getValidationModel(@Nonnull Resource resource, boolean considerResourceSuperTypeModels) throws IllegalStateException, IllegalArgumentException;
 
     /**
      * Validates a {@link Resource} using a specific {@link ValidationModel}. If the {@code model} describes a resource tree,
@@ -62,6 +63,7 @@ public interface ValidationService {
      *
      * @param resource the resource to validate
      * @param model    the model with which to perform the validation
+     * @param considerResourceSuperTypeModels if {@code true} will also consider the validation model of the resource super type (recursively), otherwise not.
      * @return a {@link ValidationResult} that provides the necessary information
      * @throws SlingValidationException if one validator was called with invalid arguments
      */
@@ -85,11 +87,12 @@ public interface ValidationService {
      * @param enforceValidation if {@code true} will throw an {@link IllegalArgumentException} in case a validation model could not be found for a (not-ignored) resource 
      * @param filter a {@link Predicate} on a resource which is evaluated to determine whether a given resource should be validated. May be {@code null} in which case all resources are validated. 
      * Children of ignored resources are still validated (if this predicate applies to them).
+     * @param considerResourceSuperTypeModels if {@code true} will also consider the validation model of the resource super type (recursively), otherwise not.
      * @return the aggregated {@link ValidationResult} over all child resource validations
      * @throws IllegalStateException in case an invalid validation model was found
      * @throws IllegalArgumentException in case resourceType is absolute but outside of the search paths or if no validation model could be found (and enforceValidation is {@code true}).
      * @throws SlingValidationException if one validator was called with invalid arguments
      */
-    @Nonnull ValidationResult validateResourceRecursively(@Nonnull Resource resource, boolean enforceValidation, Predicate filter) throws IllegalStateException, IllegalArgumentException, SlingValidationException;
+    @Nonnull ValidationResult validateResourceRecursively(@Nonnull Resource resource, boolean enforceValidation, Predicate filter, boolean considerResourceSuperTypeModels) throws IllegalStateException, IllegalArgumentException, SlingValidationException;
 
 }

Modified: sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ChildResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ChildResource.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ChildResource.java (original)
+++ sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ChildResource.java Wed Jul 29 07:22:46 2015
@@ -18,7 +18,7 @@
  */
 package org.apache.sling.validation.model;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.regex.Pattern;
 
 import javax.annotation.CheckForNull;
@@ -32,14 +32,14 @@ public interface ChildResource {
 
     /**
      * Return this resource's name. This must match the name of the child resource which is validated through this section of the validation model.
-     * Either this method or {@link getNamePattern} must not return {@code null}
+     * In case {@link getNamePattern} is not {@code null} this name is not relevant for matching the content resource.
      *
-     * @return the name (if one is set) or {@code null)
+     * @return the name
      */
-    @CheckForNull String getName();
+     String getName();
     
     /**
-     * Returns this resource's name pattern. Either this method or {@link getName} must not return {@code null}
+     * Returns this resource's name pattern. In case this is not returning {@code null}, this pattern is used for finding the child resources which should be validated.
      *
      * @return the name pattern (if one is set) or {@code null)
      */
@@ -57,11 +57,11 @@ public interface ChildResource {
      *
      * @return the properties list. Never {@code null}.
      */
-    @Nonnull List<ResourceProperty> getProperties();
+    @Nonnull Collection<ResourceProperty> getProperties();
     
     /**
      * Returns the child resources of this part of the Validation Model
      * @return child resources. Never {@code null}.
      */
-    @Nonnull List<ChildResource> getChildren();
+    @Nonnull Collection<ChildResource> getChildren();
 }

Modified: sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ResourceProperty.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ResourceProperty.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ResourceProperty.java (original)
+++ sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ResourceProperty.java Wed Jul 29 07:22:46 2015
@@ -30,15 +30,15 @@ import javax.annotation.Nonnull;
 public interface ResourceProperty {
 
     /**
-     * Returns the name of this property.
-     * Either this method or {@link getNamePattern} must not return {@code null}
+     * Returns the name of this property. This must match the name of the property which is validated through this section of the validation model.
+     * In case {@link getNamePattern} is not {@code null} this name is not relevant for matching the property.
      *
-     * @return the name or {@code null}
+     * @return the name
      */
-    @CheckForNull String getName();
+    String getName();
     
     /**
-     * Returns the name pattern for this property. Either this method or {@link getName} must not return {@code null}
+     * Returns the name pattern for this property. In case this is not returning {@code null}, this pattern is used for finding the properties which should be validated.
      *
      * @return the name pattern (if one is set) or {@code null)
      */

Modified: sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ValidationModel.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ValidationModel.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ValidationModel.java (original)
+++ sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/model/ValidationModel.java Wed Jul 29 07:22:46 2015
@@ -18,7 +18,7 @@
  */
 package org.apache.sling.validation.model;
 
-import java.util.List;
+import java.util.Collection;
 
 import javax.annotation.Nonnull;
 
@@ -32,7 +32,7 @@ public interface ValidationModel {
      *
      * @return the properties list (never {@code null}, but might be empty list)
      */
-    @Nonnull List<ResourceProperty> getResourceProperties();
+    @Nonnull Collection<ResourceProperty> getResourceProperties();
 
     /**
      * Returns the type of resource this model validates.
@@ -55,6 +55,6 @@ public interface ValidationModel {
      *
      * @return the children list (can be empty if there are no children), never {@code null}
      */
-    @Nonnull List<ChildResource> getChildren();
+    @Nonnull Collection<ChildResource> getChildren();
 
 }

Modified: sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/spi/ValidationModelProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/spi/ValidationModelProvider.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/spi/ValidationModelProvider.java (original)
+++ sling/trunk/bundles/extensions/validation/api/src/main/java/org/apache/sling/validation/spi/ValidationModelProvider.java Wed Jul 29 07:22:46 2015
@@ -23,22 +23,32 @@ import java.util.Map;
 
 import javax.annotation.Nonnull;
 
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.validation.Validator;
 import org.apache.sling.validation.model.ValidationModel;
 
 /**
- * All providers of {@link ValidationModel}s must implement this interface.
- * In addition if the model might become invalid after some time it is also the obligatation of the provider implementation to invalidate the cache
- * via the {@link ValidationModelCache} OSGi service.
+ * All providers of {@link ValidationModel}s must implement this interface. In addition if the model might become
+ * invalid after some time it is also the obligatation of the provider implementation to invalidate the cache via the
+ * {@link ValidationModelCache} OSGi service.
  */
 public interface ValidationModelProvider {
 
     /**
      * Retrieves the model responsible for validating the given resourceType.
+     * 
      * @param relativeResourceType
-     * @param all known validators in a map (key=name of validator)
-     * @return a Collection of {@link ValidationModel}s. Never {@code null} but might be empty collection.
-     * @throws IllegalStateException in case a validation model was found but it is invalid
+     * @param validatorsMap
+     *            all known validators in a map (key=name of validator). Only one of those should be used in the
+     *            returned validation models.
+     * @param resourceResolver
+     *            the resource resolver which should be used by the provider (if one is necessary).
+     * @return a Collection of {@link ValidationModel}s. Never {@code null}, but might be empty collection in case no
+     *         model for the given resource type could be found.
+     * @throws IllegalStateException
+     *             in case a validation model was found but it is invalid
      */
-    public @Nonnull Collection<ValidationModel> getModel(@Nonnull String relativeResourceType,  @Nonnull Map<String, Validator<?>> validatorsMap) throws IllegalStateException;
+    public @Nonnull Collection<ValidationModel> getModel(@Nonnull String relativeResourceType,
+            @Nonnull Map<String, Validator<?>> validatorsMap, @Nonnull ResourceResolver resourceResolver)
+            throws IllegalStateException;
 }

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetriever.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetriever.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetriever.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetriever.java Wed Jul 29 07:22:46 2015
@@ -29,6 +29,7 @@ public interface ValidationModelRetrieve
      * @param resourceType
      * @param resourcePath may be {@code null} or empty
      * @return a model which should be used for validation or null, if no validation model could be found
+     * @throws IllegalStateException in case some error occurred during looking up models
      */
-    public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath);
+    public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath, boolean considerResourceSuperTypeModels);
 }

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java Wed Jul 29 07:22:46 2015
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.validation.impl;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -30,8 +32,12 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.ReferencePolicy;
 import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.osgi.RankedServices;
 import org.apache.sling.validation.Validator;
+import org.apache.sling.validation.impl.model.MergedValidationModel;
 import org.apache.sling.validation.impl.util.Trie;
 import org.apache.sling.validation.model.ValidationModel;
 import org.apache.sling.validation.spi.ValidationModelProvider;
@@ -42,17 +48,17 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Retrieves the most appropriate (the one with the longest matching applicablePath) model from any of the {@link ValidationModelProvider}s.
- * Also implements a cache of all previously retrieved models.
+ * Retrieves the most appropriate model (the one with the longest matching applicablePath) from any of the
+ * {@link ValidationModelProvider}s. Also implements a cache of all previously retrieved models.
  *
  */
 @Service
 @Component
 public class ValidationModelRetrieverImpl implements ValidationModelRetriever, EventHandler {
 
-    @Property(name=EventConstants.EVENT_TOPIC)
+    @Property(name = EventConstants.EVENT_TOPIC)
     public static final String CACHE_INVALIDATION_EVENT_TOPIC = "org/apache/sling/validation/cache/INVALIDATE";
-    
+
     /**
      * Map of known validation models (key=validated resourceType, value=trie of ValidationModels sorted by their
      * allowed paths)
@@ -69,28 +75,73 @@ public class ValidationModelRetrieverImp
     @Reference(name = "validator", referenceInterface = Validator.class, policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE)
     Map<String, Validator<?>> validators = new ConcurrentHashMap<String, Validator<?>>();
 
+    @Reference
+    private ResourceResolverFactory resourceResolverFactory;
+
     private static final Logger LOG = LoggerFactory.getLogger(ValidationModelRetrieverImpl.class);
 
     /*
      * (non-Javadoc)
+     * 
      * @see org.apache.sling.validation.impl.ValidationModelRetriever#getModel(java.lang.String, java.lang.String)
      */
     @Override
-    public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath) {
+    public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath,
+            boolean considerResourceSuperTypeModels) {
+        try {
+            ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+            try {
+                return getModel(resourceType, resourcePath, considerResourceSuperTypeModels, resourceResolver);
+            } finally {
+                resourceResolver.close();
+            }
+        } catch (LoginException e) {
+            throw new IllegalStateException(
+                    "Could not retrieve models, because the administrative resource resolver could not be acquired", e);
+        }
+    }
+
+    @CheckForNull
+    ValidationModel getModel(@Nonnull String resourceType, String resourcePath,
+            boolean considerResourceSuperTypeModels, @Nonnull ResourceResolver resourceResolver) {
+        // first get model for exactly the requested resource type
+        ValidationModel baseModel = getModel(resourceType, resourcePath, resourceResolver);
+        String currentResourceType = resourceType;
+        if (considerResourceSuperTypeModels) {
+            Collection<ValidationModel> modelsToMerge = new ArrayList<ValidationModel>();
+            while ((currentResourceType = resourceResolver.getParentResourceType(currentResourceType)) != null) {
+                ValidationModel modelToMerge = getModel(currentResourceType, resourcePath, resourceResolver);
+                if (baseModel == null) {
+                    baseModel = modelToMerge;
+                } else {
+                    modelsToMerge.add(modelToMerge);
+                }
+            }
+            if (!modelsToMerge.isEmpty()) {
+                return new MergedValidationModel(baseModel, modelsToMerge.toArray(new ValidationModel[modelsToMerge
+                        .size()]));
+            }
+        }
+        return baseModel;
+    }
+
+    private @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath,
+            @Nonnull ResourceResolver resourceResolver) {
         ValidationModel model = null;
         Trie<ValidationModel> modelsForResourceType = validationModelsCache.get(resourceType);
         if (modelsForResourceType == null) {
-            modelsForResourceType = fillTrieForResourceType(resourceType);
+            modelsForResourceType = fillTrieForResourceType(resourceType, resourceResolver);
         }
         model = modelsForResourceType.getElementForLongestMatchingKey(resourcePath).getValue();
         if (model == null && !modelsForResourceType.isEmpty()) {
-            LOG.warn("Although model for resource type {} is available, it is not allowed for path {}",
-                    resourceType, resourcePath);
+            LOG.warn("Although model for resource type {} is available, it is not allowed for path {}", resourceType,
+                    resourcePath);
         }
         return model;
     }
-    
-    private synchronized @Nonnull Trie<ValidationModel> fillTrieForResourceType(@Nonnull String resourceType) {
+
+    private synchronized @Nonnull Trie<ValidationModel> fillTrieForResourceType(@Nonnull String resourceType,
+            @Nonnull ResourceResolver resourceResolver) {
         Trie<ValidationModel> modelsForResourceType = validationModelsCache.get(resourceType);
         // use double-checked locking (http://en.wikipedia.org/wiki/Double-checked_locking)
         if (modelsForResourceType == null) {
@@ -98,9 +149,10 @@ public class ValidationModelRetrieverImp
             modelsForResourceType = new Trie<ValidationModel>();
             validationModelsCache.put(resourceType, modelsForResourceType);
 
-            // fill trie with data from model providers (all models for the given resource type, independent of resource path)
+            // fill trie with data from model providers (all models for the given resource type, independent of resource
+            // path)
             for (ValidationModelProvider modelProvider : modelProviders) {
-                for (ValidationModel model : modelProvider.getModel(resourceType, validators)) {
+                for (ValidationModel model : modelProvider.getModel(resourceType, validators, resourceResolver)) {
                     for (String applicablePath : model.getApplicablePaths()) {
                         modelsForResourceType.insert(applicablePath, model);
                     }

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationResourceVisitor.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationResourceVisitor.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationResourceVisitor.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationResourceVisitor.java Wed Jul 29 07:22:46 2015
@@ -33,16 +33,18 @@ import org.apache.sling.validation.model
 public class ValidationResourceVisitor extends AbstractResourceVisitor {
 
     private final ValidationServiceImpl validationService;
+    private final String rootResourcePath;
     private final boolean enforceValidation;
+    private final boolean considerResourceSuperTypeModels;
     private final @Nonnull ValidationResultImpl result;
     private final Predicate filter;
-    private final String rootResourcePath;
 
-    public ValidationResourceVisitor(ValidationServiceImpl validationService, String rootResourcePath, boolean enforceValidation, Predicate filter) {
+    public ValidationResourceVisitor(ValidationServiceImpl validationService, String rootResourcePath, boolean enforceValidation, Predicate filter,  boolean considerResourceSuperTypeModels) {
         super();
         this.validationService = validationService;
         this.rootResourcePath = rootResourcePath + "/";
         this.enforceValidation = enforceValidation;
+        this.considerResourceSuperTypeModels = considerResourceSuperTypeModels;
         this.filter = filter;
         this.result = new ValidationResultImpl();
     }
@@ -50,9 +52,8 @@ public class ValidationResourceVisitor e
     @Override
     protected void visit(Resource resource) {
         if (isValidSubResource(resource)) {
-            // JCR will return then primary type instead!!
             @SuppressWarnings("null")
-            ValidationModel model = validationService.getValidationModel(resource);
+            ValidationModel model = validationService.getValidationModel(resource, considerResourceSuperTypeModels);
             if (model == null) {
                 if (enforceValidation) {
                     throw new IllegalArgumentException("No model for resource type " + resource.getResourceType() + " found.");

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java Wed Jul 29 07:22:46 2015
@@ -83,14 +83,14 @@ public class ValidationServiceImpl imple
     // ValidationService ###################################################################################################################
     
     @SuppressWarnings("unused")
-    public @CheckForNull ValidationModel getValidationModel(@Nonnull String validatedResourceType, String resourcePath) {
+    public @CheckForNull ValidationModel getValidationModel(@Nonnull String validatedResourceType, String resourcePath, boolean considerResourceSuperTypeModels) {
         // https://bugs.eclipse.org/bugs/show_bug.cgi?id=459256
         if (validatedResourceType == null) {
             throw new IllegalArgumentException("ValidationService.getValidationModel - cannot accept null as resource type. Resource path was: " + resourcePath);
         }
         // convert to relative resource types, see https://issues.apache.org/jira/browse/SLING-4262
         validatedResourceType = getRelativeResourceType(validatedResourceType);
-        return modelRetriever.getModel(validatedResourceType, resourcePath);
+        return modelRetriever.getModel(validatedResourceType, resourcePath,  considerResourceSuperTypeModels);
     }
     
     
@@ -121,8 +121,8 @@ public class ValidationServiceImpl imple
 
     @SuppressWarnings("null")
     @Override
-    public @CheckForNull ValidationModel getValidationModel(@Nonnull Resource resource) {
-        return getValidationModel(resource.getResourceType(), resource.getPath());
+    public @CheckForNull ValidationModel getValidationModel(@Nonnull Resource resource, boolean considerResourceSuperTypeModels) {
+        return getValidationModel(resource.getResourceType(), resource.getPath(), considerResourceSuperTypeModels);
     }
 
     @Override
@@ -153,7 +153,7 @@ public class ValidationServiceImpl imple
      * @param result
      * @param childResources
      */
-    private void validateChildren(Resource resource, String relativePath, List<ChildResource> childResources, ValidationResultImpl result) {
+    private void validateChildren(Resource resource, String relativePath, Collection<ChildResource> childResources, ValidationResultImpl result) {
         // validate children resources, if any
         for (ChildResource childResource : childResources) {
             // if a pattern is set we validate all children matching that pattern
@@ -197,14 +197,14 @@ public class ValidationServiceImpl imple
     }    
 
     @Override
-    public @Nonnull ValidationResult validateResourceRecursively(@Nonnull Resource resource, boolean enforceValidation, Predicate filter) 
+    public @Nonnull ValidationResult validateResourceRecursively(@Nonnull Resource resource, boolean enforceValidation, Predicate filter,  boolean considerResourceSuperTypeModels) 
             throws IllegalStateException, IllegalArgumentException, SlingValidationException {
-        ValidationResourceVisitor visitor = new ValidationResourceVisitor(this, resource.getPath(), enforceValidation, filter);
+        ValidationResourceVisitor visitor = new ValidationResourceVisitor(this, resource.getPath(), enforceValidation, filter, considerResourceSuperTypeModels);
         visitor.accept(resource);
         return visitor.getResult();
     }
 
-    private void validateValueMap(ValueMap valueMap, String relativePath, List<ResourceProperty> resourceProperties,
+    private void validateValueMap(ValueMap valueMap, String relativePath, Collection<ResourceProperty> resourceProperties,
             ValidationResultImpl result) {
         if (valueMap == null) {
             throw new IllegalArgumentException("ValueMap may not be null");

Added: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceBuilder.java?rev=1693191&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceBuilder.java (added)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceBuilder.java Wed Jul 29 07:22:46 2015
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.validation.impl.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.apache.sling.validation.model.ChildResource;
+import org.apache.sling.validation.model.ResourceProperty;
+
+public class ChildResourceBuilder {
+
+    public boolean optional;
+    public boolean multiple;
+    String nameRegex;
+    private final List<ResourceProperty> resourceProperties;
+    private final List<ChildResource> children;
+
+    public ChildResourceBuilder() {
+        this.nameRegex = null;
+        this.optional = false;
+        resourceProperties = new ArrayList<ResourceProperty>();
+        children = new ArrayList<ChildResource>();
+    }
+
+    public @Nonnull ChildResourceBuilder nameRegex(String nameRegex) {
+        this.nameRegex = nameRegex;
+        return this;
+    }
+
+    public @Nonnull ChildResourceBuilder optional() {
+        this.optional = true;
+        return this;
+    }
+
+    public @Nonnull ChildResource build(@Nonnull String name) {
+        return new ChildResourceImpl(name, nameRegex, !optional, resourceProperties, children);
+    }
+}

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceImpl.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceImpl.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ChildResourceImpl.java Wed Jul 29 07:22:46 2015
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.validation.impl.model;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
@@ -38,22 +39,17 @@ public class ChildResourceImpl implement
     private final @Nonnull List<ChildResource> children;
     private final boolean isRequired;
 
-    public ChildResourceImpl(String name, String nameRegex, boolean isRequired, @Nonnull List<ResourceProperty> properties, @Nonnull List<ChildResource> children) {
+    public ChildResourceImpl(@Nonnull String name, String nameRegex, boolean isRequired, @Nonnull List<ResourceProperty> properties, @Nonnull List<ChildResource> children) {
         if (nameRegex != null) {
             try {
                 this.namePattern = Pattern.compile(nameRegex);
             } catch (PatternSyntaxException e) {
                 throw new IllegalArgumentException("Invalid regex given", e);
             }
-            this.name = null;
         } else {
-            if (name == null) {
-                throw new IllegalArgumentException("Either name or nameRegex must be set!");
-            }
-            this.name = name;
             this.namePattern = null;
-           
-        } 
+        }
+        this.name = name;
         this.isRequired = isRequired;
         this.properties = properties;
         this.children = children;
@@ -65,7 +61,7 @@ public class ChildResourceImpl implement
     }
 
     @Override
-    public @Nonnull List<ResourceProperty> getProperties() {
+    public @Nonnull Collection<ResourceProperty> getProperties() {
         return properties;
     }
 
@@ -74,7 +70,7 @@ public class ChildResourceImpl implement
         return namePattern;
     }
     
-    public @Nonnull List<ChildResource> getChildren() {
+    public @Nonnull Collection<ChildResource> getChildren() {
         return children;
     }
 

Added: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/MergedValidationModel.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/MergedValidationModel.java?rev=1693191&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/MergedValidationModel.java (added)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/MergedValidationModel.java Wed Jul 29 07:22:46 2015
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.validation.impl.model;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.validation.model.ChildResource;
+import org.apache.sling.validation.model.ResourceProperty;
+import org.apache.sling.validation.model.ValidationModel;
+
+/**
+ * Generates a merged validation model out of one base {@link ValidationModel} and 1 or more models to merge.
+ * The resource properties and children are basically concatenated with the exception that
+ * if a resource property/child with the same name is already defined in the baseModel it is not added again.
+ * 
+ * That way you can overwrite and even remove validation rules from the model to merge.
+ *
+ */
+public class MergedValidationModel implements ValidationModel {
+
+    private final ValidationModel baseModel;
+    private final Map<String, ResourceProperty> resourcePropertiesMap;
+    private final Map<String, ChildResource> childResourceMap;
+    
+    public MergedValidationModel(ValidationModel baseModel, ValidationModel... modelsToMerge) {
+        this.baseModel = baseModel;
+        
+        // merge resource properties and child resources: all the ones from the base + different ones from the model to merge
+        resourcePropertiesMap = new HashMap<String, ResourceProperty>();
+        for (ResourceProperty resourceProperty : baseModel.getResourceProperties()) {
+            resourcePropertiesMap.put(resourceProperty.getName(), resourceProperty);
+        }
+        childResourceMap = new HashMap<String, ChildResource>();
+        for (ChildResource childResource : baseModel.getChildren()) {
+            childResourceMap.put(childResource.getName(), childResource);
+        }
+        
+        for (ValidationModel modelToMerge : modelsToMerge) {
+            for (ResourceProperty resourceProperty : modelToMerge.getResourceProperties()) {
+                // only if name is not already used, the resource property should be considered
+                if (!resourcePropertiesMap.containsKey(resourceProperty.getName())) {
+                    resourcePropertiesMap.put(resourceProperty.getName(), resourceProperty);
+                }
+            }
+            for (ChildResource childResource : modelToMerge.getChildren()) {
+                // only if name is not already used, the child resource should be considered
+                if (!childResourceMap.containsKey(childResource.getName())) {
+                    childResourceMap.put(childResource.getName(), childResource);
+                }
+            }
+            // throw exception if the applicable path is restricted in the modelToMerge in comparison to baseModel
+            for (String path : modelToMerge.getApplicablePaths()) {
+                if (isPathRestricted(path, baseModel.getApplicablePaths())) {
+                    String msg = String.format("The path '%s' from one of the models to merge is more specific than any of the base paths (%s)", path, StringUtils.join(baseModel.getApplicablePaths(), ","));
+                    throw new IllegalArgumentException(msg);
+                }
+            }
+        }
+    }
+    
+    /**
+     * 
+     * @param path
+     * @param pathsToCompareWith
+     * @return {@code true} in case the given path is either more specific or not at all overlapping with one of the pathsToCompareWith
+     */
+    private boolean isPathRestricted(String path, String[] pathsToCompareWith) {
+        for (String basePath : pathsToCompareWith) {
+            if (basePath.startsWith(path)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    @Override
+    @Nonnull
+    public Collection<ResourceProperty> getResourceProperties() {
+        return resourcePropertiesMap.values();
+    }
+
+    @Override
+    @Nonnull
+    public String getValidatedResourceType() {
+        return baseModel.getValidatedResourceType();
+    }
+
+    @Override
+    @Nonnull
+    public String[] getApplicablePaths() {
+        return baseModel.getApplicablePaths();
+    }
+
+    @Override
+    @Nonnull
+    public Collection<ChildResource> getChildren() {
+        return childResourceMap.values();
+    }
+
+}

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java Wed Jul 29 07:22:46 2015
@@ -35,22 +35,18 @@ public class ResourcePropertyImpl implem
     private final @Nonnull List<ParameterizedValidator> validators;
     private final Pattern namePattern;
 
-    public ResourcePropertyImpl(String name, String nameRegex, boolean isMultiple, boolean isRequired,
+    public ResourcePropertyImpl(@Nonnull String name, String nameRegex, boolean isMultiple, boolean isRequired,
             @Nonnull List<ParameterizedValidator> validators) throws IllegalArgumentException {
         if (nameRegex != null) {
-            this.name = null;
             try {
                 this.namePattern = Pattern.compile(nameRegex);
             } catch (PatternSyntaxException e) {
                 throw new IllegalArgumentException("Invalid regex given", e);
             }
         } else {
-            if (name == null) {
-                throw new IllegalArgumentException("Either name or nameRegex must be not null!");
-            }
-            this.name = name;
             this.namePattern = null;
         }
+        this.name = name;
         this.isMultiple = isMultiple;
         this.isRequired = isRequired;
         this.validators = validators;

Modified: sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java Wed Jul 29 07:22:46 2015
@@ -179,25 +179,10 @@ public class ResourceValidationModelProv
      * @return {@inheritDoc}
      * @throws {@inheritDoc}
      */
-    @Override
-    public @Nonnull Collection<ValidationModel> getModel(@Nonnull String relativeResourceType,
-            @Nonnull Map<String, Validator<?>> validatorsMap) {
-        ResourceResolver rr = null;
-        try {
-            rr = rrf.getAdministrativeResourceResolver(null);
-            return getModel(rr, relativeResourceType, validatorsMap);
-        } catch (LoginException e) {
-            throw new IllegalStateException("Unable to obtain a resource resolver.", e);
-        } finally {
-            if (rr != null) {
-                rr.close();
-            }
-        }
-    }
 
+    @Override
     @Nonnull
-    Collection<ValidationModel> getModel(@Nonnull ResourceResolver resourceResolver,
-            @Nonnull String relativeResourceType, @Nonnull Map<String, Validator<?>> validatorsMap) {
+    public Collection<ValidationModel> getModel(@Nonnull String relativeResourceType, @Nonnull Map<String, Validator<?>> validatorsMap, @Nonnull ResourceResolver resourceResolver) {
         ValidationModelImpl vm;
         Collection<ValidationModel> validationModels = new ArrayList<ValidationModel>();
         String[] searchPaths = resourceResolver.getSearchPath();
@@ -312,14 +297,12 @@ public class ResourceValidationModelProv
                 if (childrenProperties == null) {
                     throw new IllegalStateException("Could not adapt resource " + child.getPath() + " to ValueMap");
                 }
-                final String name;
+                final String name = child.getName();
                 final String nameRegex;
                 if (childrenProperties.containsKey(Constants.NAME_REGEX)) {
-                    name = null;
                     nameRegex = childrenProperties.get(Constants.NAME_REGEX, String.class);
                 } else {
                     // otherwise fall back to the name
-                    name = child.getName();
                     nameRegex = null;
                 }
                 boolean isRequired = !PropertiesUtil.toBoolean(childrenProperties.get(Constants.OPTIONAL), false);

Modified: sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java Wed Jul 29 07:22:46 2015
@@ -19,12 +19,18 @@
 package org.apache.sling.validation.impl;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
 
 import javax.annotation.Nonnull;
 
+import org.apache.commons.collections.MultiHashMap;
+import org.apache.commons.collections.MultiMap;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.validation.Validator;
 import org.apache.sling.validation.impl.model.ResourcePropertyBuilder;
 import org.apache.sling.validation.impl.model.ValidationModelBuilder;
@@ -32,42 +38,55 @@ import org.apache.sling.validation.impl.
 import org.apache.sling.validation.model.ResourceProperty;
 import org.apache.sling.validation.model.ValidationModel;
 import org.apache.sling.validation.spi.ValidationModelProvider;
+import org.hamcrest.Description;
 import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
 import org.osgi.framework.Constants;
 import org.osgi.service.event.Event;
 
+@RunWith(MockitoJUnitRunner.class)
 public class ValidationModelRetrieverImplTest {
 
     private ValidationModelRetrieverImpl validationModelRetriever;
     private Validator<?> dateValidator;
-    private Map<String, String> propertyNamePerApplicablePath;
+    private MultiMap applicablePathPerResourceType;
     private TestModelProvider modelProvider;
+    
+    @Mock
+    private ResourceResolver resourceResolver;
 
     /**
-     * Test model provider which only provides models for resource types starting with "test"
+     * Test model provider which only provides models for all resource types in map applicablePathPerResourceType with their according applicablePath!
+     * In addition those models have an (empty) resource property with a name equal to validated resource type.
      *
      */
     class TestModelProvider implements ValidationModelProvider {
         int counter = 0;
 
         @Override
-        public @Nonnull Collection<ValidationModel> getModel(@Nonnull String relativeResourceType, @Nonnull Map<String, Validator<?>> validatorsMap) {
+        public @Nonnull Collection<ValidationModel> getModel(@Nonnull String relativeResourceType,
+                @Nonnull Map<String, Validator<?>> validatorsMap, @Nonnull ResourceResolver resourceResolver) {
             // make sure the date validator is passed along
-            Assert.assertThat(validatorsMap, Matchers.<String, Validator<?>>hasEntry(DateValidator.class.getName(), dateValidator));
+            Assert.assertThat(validatorsMap,
+                    Matchers.<String, Validator<?>> hasEntry(DateValidator.class.getName(), dateValidator));
 
             Collection<ValidationModel> models = new ArrayList<ValidationModel>();
-            if (relativeResourceType.startsWith("test")) {
-                for (Map.Entry<String, String> entry : propertyNamePerApplicablePath.entrySet()) {
+            Collection<String> applicablePaths = (Collection<String>) applicablePathPerResourceType
+                    .get(relativeResourceType);
+            if (applicablePaths != null) {
+                for (String applicablePath : applicablePaths) {
                     ValidationModelBuilder modelBuilder = new ValidationModelBuilder();
-                    ResourcePropertyBuilder propertyBuilder = new ResourcePropertyBuilder();
-                    modelBuilder.resourceProperty(propertyBuilder.build(entry.getValue()));
-                    String applicablePath = entry.getKey();
                     if (applicablePath != null) {
                         modelBuilder.addApplicablePath(applicablePath);
                     }
+                    modelBuilder.resourceProperty(new ResourcePropertyBuilder().build(relativeResourceType));
                     models.add(modelBuilder.build(relativeResourceType));
                 }
             }
@@ -76,10 +95,32 @@ public class ValidationModelRetrieverImp
         }
     }
 
+    /**
+     * Custom Hamcrest matcher which matches Resource Properties based on the equality only on their name.
+     */
+    private static final class ResourcePropertyNameMatcher extends TypeSafeMatcher<ResourceProperty> {
+
+        private final String expectedName;
+
+        public ResourcePropertyNameMatcher(String name) {
+            expectedName = name;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("ResourceProperty with name=" + expectedName);
+        }
+
+        @Override
+        protected boolean matchesSafely(ResourceProperty resourceProperty) {
+           return expectedName.equals(resourceProperty.getName());
+        }
+    }
+
     @Before
     public void setup() {
         dateValidator = new DateValidator();
-        propertyNamePerApplicablePath = new HashMap<String, String>();
+        applicablePathPerResourceType = new MultiHashMap();
         validationModelRetriever = new ValidationModelRetrieverImpl();
         modelProvider = new TestModelProvider();
         // service id must be set (even if service ranking is not set)
@@ -91,58 +132,70 @@ public class ValidationModelRetrieverImp
 
     @Test
     public void testGetModel() {
-        propertyNamePerApplicablePath.put("/content/site1", "somename");
-        propertyNamePerApplicablePath.put("/content/site1/subnode/test", "somename2");
-        propertyNamePerApplicablePath.put("/content/site1/subnode", "somename3");
-        
-        ValidationModel model = validationModelRetriever.getModel("test/type", "/content/site1/subnode/test/somepage");
-        Assert.assertNotNull(model);
-        Assert.assertThat(model.getResourceProperties(), Matchers.hasSize(1));
-        ResourceProperty resourceProperty = model.getResourceProperties().get(0);
-        Assert.assertEquals("somename2", resourceProperty.getName());
+        applicablePathPerResourceType.put("test/type", "/content/site1");
+        applicablePathPerResourceType.put("test/type", "/content/site1/subnode/test");
+        applicablePathPerResourceType.put("test/type", "/content/site1/subnode");
+
+        ValidationModel model = validationModelRetriever.getModel("test/type", "/content/site1/subnode/test/somepage",
+                false, resourceResolver);
+        Assert.assertNotNull(model);
+        Assert.assertThat(Arrays.asList(model.getApplicablePaths()), Matchers.contains("/content/site1/subnode/test"));
     }
 
     @Test
-    public void testGetModelWithNoResourcePath() {
-        propertyNamePerApplicablePath.put("/content/site1", "somename");
-        propertyNamePerApplicablePath.put(null, "somename2");
-        propertyNamePerApplicablePath.put("/content/site1/subnode", "somename3");
-        
-        ValidationModel model = validationModelRetriever.getModel("test/type", null);
-        Assert.assertNotNull(model);
-        Assert.assertThat(model.getResourceProperties(), Matchers.hasSize(1));
-        ResourceProperty resourceProperty = model.getResourceProperties().get(0);
-        Assert.assertEquals("somename2", resourceProperty.getName());
+    public void testGetModelWithNullApplicablePathPath() {
+        applicablePathPerResourceType.put("test/type", "/content/site1");
+        applicablePathPerResourceType.put("test/type", null);
+        applicablePathPerResourceType.put("test/type", "/content/site1/subnode");
+
+        ValidationModel model = validationModelRetriever.getModel("test/type", null, false, resourceResolver);
+        Assert.assertNotNull(model);
+        Assert.assertThat(Arrays.asList(model.getApplicablePaths()), Matchers.contains(""));
     }
 
     @Test
     public void testGetCachedModel() {
-        propertyNamePerApplicablePath.put("/content/site1", "somename");
+        applicablePathPerResourceType.put("test/type", "/content/site1");
         // call two times, the second time the counter must be the same (because provider is not called)
-        ValidationModel model = validationModelRetriever.getModel("test/type", "/content/site1");
+        ValidationModel model = validationModelRetriever.getModel("test/type", "/content/site1", false, resourceResolver);
         Assert.assertNotNull(model);
         Assert.assertEquals(1, modelProvider.counter);
-        model = validationModelRetriever.getModel("test/type", "/content/site1");
+        model = validationModelRetriever.getModel("test/type", "/content/site1", false, resourceResolver);
         Assert.assertNotNull(model);
         Assert.assertEquals(1, modelProvider.counter);
-        
-        model = validationModelRetriever.getModel("invalid/type", "/content/site1");
+
+        model = validationModelRetriever.getModel("invalid/type", "/content/site1", false, resourceResolver);
         Assert.assertNull(model);
         Assert.assertEquals(2, modelProvider.counter);
-        model = validationModelRetriever.getModel("invalid/type", "/content/site1");
+        model = validationModelRetriever.getModel("invalid/type", "/content/site1", false, resourceResolver);
         Assert.assertNull(model);
         Assert.assertEquals(2, modelProvider.counter);
     }
 
     @Test
     public void testGetCachedInvalidation() {
-        propertyNamePerApplicablePath.put("/content/site1", "somename");
-        validationModelRetriever.getModel("test/type", "/content/site1");
+        applicablePathPerResourceType.put("test/type", "/content/site1");
+        validationModelRetriever.getModel("test/type", "/content/site1", false, resourceResolver);
         Assert.assertEquals(1, modelProvider.counter);
-        validationModelRetriever.handleEvent(new Event(ValidationModelRetrieverImpl.CACHE_INVALIDATION_EVENT_TOPIC, null));
+        validationModelRetriever.handleEvent(new Event(ValidationModelRetrieverImpl.CACHE_INVALIDATION_EVENT_TOPIC,
+                null));
         // after cache invalidation the provider is called again
-        validationModelRetriever.getModel("test/type", "/content/site1");
+        validationModelRetriever.getModel("test/type", "/content/site1", false, resourceResolver);
         Assert.assertEquals(2, modelProvider.counter);
-        
+    }
+
+    @Test
+    public void testGetModelWithResourceInheritance() {
+        // in case no super type is known, just return model
+        applicablePathPerResourceType.put("test/type", "/content/site1");
+        ValidationModel model = validationModelRetriever.getModel("test/type", "/content/site1", true, resourceResolver);
+        Assert.assertNotNull(model);
+        Assert.assertThat(model.getResourceProperties(), Matchers.contains(new ResourcePropertyNameMatcher("test/type")));
+        // in case there is one super type make sure the merged model is returned!
+        Mockito.when(resourceResolver.getParentResourceType("test/type")).thenReturn("test/supertype");
+        applicablePathPerResourceType.put("test/supertype", "/content/site1");
+        model = validationModelRetriever.getModel("test/type", "/content/site1", true, resourceResolver);
+        Assert.assertNotNull(model);
+        Assert.assertThat(model.getResourceProperties(), Matchers.containsInAnyOrder(new ResourcePropertyNameMatcher("test/type"), new ResourcePropertyNameMatcher("test/supertype")));
     }
 }

Modified: sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java Wed Jul 29 07:22:46 2015
@@ -21,7 +21,6 @@ package org.apache.sling.validation.impl
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -373,7 +372,7 @@ public class ValidationServiceImplTest {
         validationService.modelRetriever = new ValidationModelRetriever() {
 
             @Override
-            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath) {
+            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath, boolean considerResourceSuperTypeModels) {
                 if (resourceType.equals("resourcetype1")) {
                     return vm1;
                 } else if (resourceType.equals("resourcetype2")) {
@@ -416,7 +415,7 @@ public class ValidationServiceImplTest {
             }
         };
         
-        ValidationResult vr = validationService.validateResourceRecursively(testResource, true, ignoreResourceType3Filter);
+        ValidationResult vr = validationService.validateResourceRecursively(testResource, true, ignoreResourceType3Filter, false);
         Assert.assertFalse("resource should have been considered invalid", vr.isValid());
         Assert.assertThat(vr.getFailureMessages(),
                 Matchers.hasEntry("field1", Arrays.asList("Missing required property.")));
@@ -430,7 +429,7 @@ public class ValidationServiceImplTest {
         // set model retriever which never retrieves anything
         validationService.modelRetriever = new ValidationModelRetriever() {
             @Override
-            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath) {
+            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath, boolean considerResourceSuperTypeModels) {
                 return null;
             }
         };
@@ -440,7 +439,7 @@ public class ValidationServiceImplTest {
         Resource testResource = ResourceUtil.getOrCreateResource(rr, "/content/validation/1/resource", "resourcetype1",
                 JcrConstants.NT_UNSTRUCTURED, true);
 
-        ValidationResult vr = validationService.validateResourceRecursively(testResource, true, null);
+        ValidationResult vr = validationService.validateResourceRecursively(testResource, true, null, false);
     }
 
     @Test()
@@ -448,7 +447,7 @@ public class ValidationServiceImplTest {
         // set model retriever which never retrieves anything
         validationService.modelRetriever = new ValidationModelRetriever() {
             @Override
-            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath) {
+            public @CheckForNull ValidationModel getModel(@Nonnull String resourceType, String resourcePath, boolean considerResourceSuperTypeModels) {
                 return null;
             }
         };
@@ -458,7 +457,7 @@ public class ValidationServiceImplTest {
         Resource testResource = ResourceUtil.getOrCreateResource(rr, "/content/validation/1/resource", "resourcetype1",
                 JcrConstants.NT_UNSTRUCTURED, true);
 
-        ValidationResult vr = validationService.validateResourceRecursively(testResource, false, null);
+        ValidationResult vr = validationService.validateResourceRecursively(testResource, false, null, false);
         Assert.assertTrue(vr.isValid());
     }
 

Added: sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/MergedValidationModelTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/MergedValidationModelTest.java?rev=1693191&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/MergedValidationModelTest.java (added)
+++ sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/model/MergedValidationModelTest.java Wed Jul 29 07:22:46 2015
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.validation.impl.model;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.apache.sling.validation.model.ChildResource;
+import org.apache.sling.validation.model.ResourceProperty;
+import org.apache.sling.validation.model.ValidationModel;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MergedValidationModelTest {
+
+    private ValidationModelBuilder modelBuilder;
+    private ResourcePropertyBuilder propertyBuilder;
+    private ChildResourceBuilder childResourceBuilder;
+
+    @Before
+    public void setup() {
+        modelBuilder = new ValidationModelBuilder();
+        propertyBuilder = new ResourcePropertyBuilder();
+        childResourceBuilder = new ChildResourceBuilder();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testMoreSpecificApplicationPathInModelToMerge() {
+        modelBuilder.addApplicablePath("/base/path").addApplicablePath("/base/path2");
+        ValidationModel baseValidationModel = modelBuilder.build("base");
+        modelBuilder.setApplicablePath("/base/path3");
+        new MergedValidationModel(baseValidationModel, modelBuilder.build("superType"));
+    }
+
+    @Test
+    public void testLessSpecificApplicationPathInModelToMerge() {
+        modelBuilder.addApplicablePath("/base/path").addApplicablePath("/base/path2");
+        ValidationModel baseValidationModel = modelBuilder.build("base");
+        modelBuilder.setApplicablePath("/base");
+        ValidationModel mergedModel = new MergedValidationModel(baseValidationModel, modelBuilder.build("superType"));
+        Assert.assertThat(Arrays.asList(mergedModel.getApplicablePaths()),
+                Matchers.contains("/base/path", "/base/path2"));
+    }
+
+    @Test
+    public void testOverwritingChildrenAndResourceProperties() {
+        modelBuilder.resourceProperty(propertyBuilder.nameRegex("overwrittenNameToOverwrite").build("nameToOverwrite"));
+        modelBuilder.childResource(childResourceBuilder.nameRegex("overwrittenNameToOverwrite")
+                .build("nameToOverwrite"));
+        ValidationModel baseValidationModel = modelBuilder.build("base");
+        modelBuilder = new ValidationModelBuilder();
+        modelBuilder.resourceProperty(propertyBuilder.nameRegex("originalNameToOverwrite").build("nameToOverwrite"));
+        modelBuilder.childResource(childResourceBuilder.nameRegex("originalNameToOverwrite").build("nameToOverwrite"));
+        modelBuilder.resourceProperty(propertyBuilder.nameRegex("originalNameNotOverwritten").build(
+                "nameNotOverwritten"));
+        modelBuilder.childResource(childResourceBuilder.nameRegex("originalNameNotOverwritten").build(
+                "nameNotOverwritten"));
+        ValidationModel mergedModel = new MergedValidationModel(baseValidationModel, modelBuilder.build("superType"));
+        Assert.assertThat(mergedModel.getResourceProperties(), Matchers.containsInAnyOrder(
+                new ResourcePropertyNameRegexMatcher("overwrittenNameToOverwrite"),
+                new ResourcePropertyNameRegexMatcher("originalNameNotOverwritten")));
+        Assert.assertThat(mergedModel.getChildren(), Matchers.containsInAnyOrder(new ChildResourceNameRegexMatcher(
+                "overwrittenNameToOverwrite"), new ChildResourceNameRegexMatcher("originalNameNotOverwritten")));
+    }
+
+    @Test
+    public void testValidatedResourceTypes() {
+        ValidationModel mergedModel = new MergedValidationModel(modelBuilder.build("base"),
+                modelBuilder.build("superType"));
+        Assert.assertThat(mergedModel.getValidatedResourceType(), Matchers.equalTo("base"));
+    }
+
+    /**
+     * Custom Hamcrest matcher which matches Resource Properties based on the equality only on their namePatterns.
+     */
+    private static final class ResourcePropertyNameRegexMatcher extends TypeSafeMatcher<ResourceProperty> {
+
+        private final String expectedNameRegex;
+
+        public ResourcePropertyNameRegexMatcher(String nameRegex) {
+            expectedNameRegex = nameRegex;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("ResourceProperty with namePattern=" + expectedNameRegex);
+        }
+
+        @Override
+        protected boolean matchesSafely(ResourceProperty resourceProperty) {
+            Pattern namePattern = resourceProperty.getNamePattern();
+            if (namePattern == null) {
+                return false;
+            } else {
+                return expectedNameRegex.equals(namePattern.toString());
+            }
+        }
+
+    }
+
+    /**
+     * Custom Hamcrest matcher which matches ChildResource based on the equality only on their namePatterns.
+     */
+    private static final class ChildResourceNameRegexMatcher extends TypeSafeMatcher<ChildResource> {
+
+        private final String expectedNameRegex;
+
+        public ChildResourceNameRegexMatcher(String nameRegex) {
+            expectedNameRegex = nameRegex;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("ChildResource with namePattern=" + expectedNameRegex);
+        }
+
+        @Override
+        protected boolean matchesSafely(ChildResource childResource) {
+            Pattern namePattern = childResource.getNamePattern();
+            if (namePattern == null) {
+                return false;
+            } else {
+                return expectedNameRegex.equals(namePattern.toString());
+            }
+        }
+    }
+}

Modified: sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java (original)
+++ sling/trunk/bundles/extensions/validation/core/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java Wed Jul 29 07:22:46 2015
@@ -215,7 +215,7 @@ public class ResourceValidationModelProv
         createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel2", model2);
 
         // check that both models are returned
-        Collection<ValidationModel> models = modelProvider.getModel(rr, "sling/validation/test", validatorMap);
+        Collection<ValidationModel> models = modelProvider.getModel("sling/validation/test", validatorMap, rr);
         Assert.assertThat(models, Matchers.containsInAnyOrder(model1, model2));
     }
 
@@ -234,7 +234,7 @@ public class ResourceValidationModelProv
         createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
 
         // compare both models
-        Collection<ValidationModel> models = modelProvider.getModel(rr, "sling/validation/test", validatorMap);
+        Collection<ValidationModel> models = modelProvider.getModel("sling/validation/test", validatorMap, rr);
         Assert.assertThat(models, Matchers.contains(model1));
     }
 
@@ -250,7 +250,7 @@ public class ResourceValidationModelProv
         createValidationModelResource(rr, appsValidatorsRoot.getPath(), "testValidationModel1", model2);
 
         // only the apps model should be returned
-        Collection<ValidationModel> models = modelProvider.getModel(rr, "sling/validation/test", validatorMap);
+        Collection<ValidationModel> models = modelProvider.getModel("sling/validation/test", validatorMap, rr);
         Assert.assertThat(models, Matchers.contains(model2));
     }
 
@@ -262,7 +262,7 @@ public class ResourceValidationModelProv
 
         // clear validator map to make the referenced validator unknown
         validatorMap.clear();
-        modelProvider.getModel(rr, "sling/validation/test", validatorMap);
+        modelProvider.getModel("sling/validation/test", validatorMap, rr);
     }
     
     @Test(expected = IllegalStateException.class)
@@ -274,7 +274,7 @@ public class ResourceValidationModelProv
         
         createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
 
-        modelProvider.getModel(rr, "sling/validation/test", validatorMap);
+        modelProvider.getModel("sling/validation/test", validatorMap, rr);
     }
 
     private Resource createValidationModelResource(ResourceResolver rr, String root, String name, ValidationModel model)
@@ -307,7 +307,7 @@ public class ResourceValidationModelProv
         return modelResource;
     }
 
-    private void createValidationModelProperties(Resource model, @Nonnull List<ResourceProperty> properties)
+    private void createValidationModelProperties(Resource model, @Nonnull Collection<ResourceProperty> properties)
             throws PersistenceException {
         ResourceResolver rr = model.getResourceResolver();
         if (properties.isEmpty()) {

Modified: sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/models/UserModel.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/models/UserModel.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/models/UserModel.java (original)
+++ sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/models/UserModel.java Wed Jul 29 07:22:46 2015
@@ -80,7 +80,7 @@ public class UserModel {
 
     @PostConstruct
     protected void validate() {
-        ValidationModel model = validationService.getValidationModel(resource);
+        ValidationModel model = validationService.getValidationModel(resource, false);
         if (model != null) {
             ValidationResult result = validationService.validate(resource, model);
             if (!result.isValid()) {

Modified: sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/servlets/ModifyUserServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/servlets/ModifyUserServlet.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/servlets/ModifyUserServlet.java (original)
+++ sling/trunk/bundles/extensions/validation/examples/src/main/java/org/apache/sling/validation/examples/servlets/ModifyUserServlet.java Wed Jul 29 07:22:46 2015
@@ -58,7 +58,7 @@ public class ModifyUserServlet extends S
         }
         if (resourceType != null && !"".equals(resourceType)) {
             String resourcePath = request.getRequestPathInfo().getResourcePath();
-            ValidationModel vm = validationService.getValidationModel(resourceType, resourcePath);
+            ValidationModel vm = validationService.getValidationModel(resourceType, resourcePath, false);
             if (vm != null) {
                 ValidationResult vr = validationService.validate(requestParameters, vm);
                 if (vr.isValid()) {

Modified: sling/trunk/bundles/extensions/validation/test-services/src/main/java/org/apache/sling/validation/testservices/ValidationPostOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/validation/test-services/src/main/java/org/apache/sling/validation/testservices/ValidationPostOperation.java?rev=1693191&r1=1693190&r2=1693191&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/validation/test-services/src/main/java/org/apache/sling/validation/testservices/ValidationPostOperation.java (original)
+++ sling/trunk/bundles/extensions/validation/test-services/src/main/java/org/apache/sling/validation/testservices/ValidationPostOperation.java Wed Jul 29 07:22:46 2015
@@ -64,7 +64,7 @@ public class ValidationPostOperation ext
             }
             if (resourceType != null && !"".equals(resourceType)) {
                 String resourcePath = request.getRequestPathInfo().getResourcePath();
-                ValidationModel vm = validationService.getValidationModel(resourceType, resourcePath);
+                ValidationModel vm = validationService.getValidationModel(resourceType, resourcePath, false);
                 if (vm != null) {
                     ValidationResult vr = validationService.validate(requestParameters, vm);
                     vpr.setValidationResult(vr);