SLING-6659 detect modification to validator.id, service.ranking and/or validator.severity a run-time
Also did some major refactoring to hold references to validator services only from the ValidationServiceImpl
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1787945 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/validation/impl/ResourceToValidationResultAdapterFactory.java b/src/main/java/org/apache/sling/validation/impl/ResourceToValidationResultAdapterFactory.java
index 0873a7e..c83d883 100644
--- a/src/main/java/org/apache/sling/validation/impl/ResourceToValidationResultAdapterFactory.java
+++ b/src/main/java/org/apache/sling/validation/impl/ResourceToValidationResultAdapterFactory.java
@@ -22,7 +22,6 @@
import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.validation.ValidationFailure;
import org.apache.sling.validation.ValidationResult;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
diff --git a/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java b/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java
index 4742f23..fb25a7c 100644
--- a/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java
+++ b/src/main/java/org/apache/sling/validation/impl/ValidationModelRetrieverImpl.java
@@ -21,9 +21,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.SortedMap;
-import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -35,12 +33,9 @@
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.validation.impl.model.MergedValidationModel;
import org.apache.sling.validation.model.ValidationModel;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
import org.apache.sling.validation.model.spi.ValidationModelProvider;
import org.apache.sling.validation.model.spi.ValidationModelRetriever;
-import org.apache.sling.validation.spi.Validator;
import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.FieldOption;
import org.osgi.service.component.annotations.Reference;
@@ -64,13 +59,6 @@
@Reference(policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY, fieldOption = FieldOption.REPLACE)
protected volatile List<ValidationModelProvider> modelProviders;
- /** List of all known validators (key=id of validator) */
- @Nonnull
- Map<String, ValidatorAndSeverity<?>> validators = new ConcurrentHashMap<>();
-
- @Nonnull
- Map<String, ServiceReference<Validator<?>>> validatorServiceReferences = new ConcurrentHashMap<>();
-
@Reference
ResourceResolverFactory resourceResolverFactory;
@@ -145,7 +133,7 @@
// lowest ranked model provider inserts first (i.e. higher ranked should overwrite)
for (ValidationModelProvider modelProvider : modelProviders) {
LOG.debug("Retrieving validation models with resource type {} from provider {}...", resourceType, modelProvider.getClass().getName());
- List<ValidationModel> models = modelProvider.getModels(resourceType, validators);
+ List<ValidationModel> models = modelProvider.getModels(resourceType);
for (ValidationModel model : models) {
for (String applicablePath : model.getApplicablePaths()) {
LOG.debug("Found validation model for resource type {} for applicable path {}", resourceType, applicablePath);
@@ -159,70 +147,4 @@
return modelsForResourceType;
}
- @Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY)
- protected void addValidator(@Nonnull Validator<?> validator, Map<String, Object> properties, ServiceReference<Validator<?>> serviceReference) {
- String validatorId = getValidatorIdFromServiceProperties(properties, validator, serviceReference);
- Integer severity = getValidatorSeverityFromServiceProperties(properties, validator, serviceReference);
- if (validators.containsKey(validatorId)) {
- ServiceReference<Validator<?>> existingServiceReference = validatorServiceReferences.get(validatorId);
- if (existingServiceReference == null) {
- throw new IllegalStateException("Could not find service reference for validator with id " + validatorId);
- }
- if (serviceReference.compareTo(existingServiceReference) == 1) {
- LOG.info("Overwriting already existing validator {} from bundle {} with validator {} from bundle {},"
- + " because it has the same id '{}' and a higher service ranking",
- validators.get(validatorId), existingServiceReference.getBundle().getBundleId(), validator,
- serviceReference.getBundle().getBundleId(), validatorId);
- validators.put(validatorId, new ValidatorAndSeverity<>(validator, severity));
- validatorServiceReferences.put(validatorId, serviceReference);
- } else {
- LOG.info(
- "A Validator for the same id '{}' is already registered with class '{}' from bundle {} and has a higher service ranking",
- validatorId, validators.get(validatorId), existingServiceReference.getBundle().getBundleId());
- }
- } else {
- validators.put(validatorId, new ValidatorAndSeverity<>(validator, severity));
- validatorServiceReferences.put(validatorId, serviceReference);
- }
- }
-
- // no need for an unbind method for validators, as those are static, i.e. component is deactivated first
- @Activate
- protected void activate() {
- LOG.info("Starting service...");
- }
-
- private String getValidatorIdFromServiceProperties(Map<String, Object> properties, Validator<?> validator,
- ServiceReference<Validator<?>> serviceReference) {
- Object id = properties.get(Validator.PROPERTY_VALIDATOR_ID);
- if (id == null) {
- throw new IllegalArgumentException("Validator '" + validator.getClass().getName() + "' provided from bundle "
- + serviceReference.getBundle().getBundleId() +
- " is lacking the mandatory service property " + Validator.PROPERTY_VALIDATOR_ID);
- }
- if (!(id instanceof String)) {
- throw new IllegalArgumentException("Validator '" + validator.getClass().getName() + "' provided from bundle "
- + serviceReference.getBundle().getBundleId() +
- " is providing the mandatory service property " + Validator.PROPERTY_VALIDATOR_ID + " with the wrong type "
- + id.getClass() + " (must be of type String)");
- }
- return (String) id;
- }
-
- private Integer getValidatorSeverityFromServiceProperties(Map<String, Object> properties, Validator<?> validator,
- ServiceReference<Validator<?>> serviceReference) {
- Object severity = properties.get(Validator.PROPERTY_VALIDATOR_SEVERITY);
- if (severity == null) {
- LOG.debug("Validator '{}' is not setting an explicit severity via the OSGi service property {}", validator.getClass().getName(), Validator.PROPERTY_VALIDATOR_SEVERITY);
- return null;
- }
- if (!(severity instanceof Integer)) {
- throw new IllegalArgumentException("Validator '" + validator.getClass().getName() + "' provided from bundle "
- + serviceReference.getBundle().getBundleId() +
- " is providing the optional service property " + Validator.PROPERTY_VALIDATOR_SEVERITY + " with the wrong type "
- + severity.getClass() + " (must be of type Integer)");
- }
- return (Integer) severity;
- }
-
}
diff --git a/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java b/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java
index 764a83e..edf6649 100644
--- a/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java
+++ b/src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java
@@ -23,6 +23,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.ResourceBundle;
import java.util.function.Predicate;
import java.util.regex.Matcher;
@@ -44,7 +45,7 @@
import org.apache.sling.validation.ValidationResult;
import org.apache.sling.validation.ValidationService;
import org.apache.sling.validation.model.ChildResource;
-import org.apache.sling.validation.model.ParameterizedValidator;
+import org.apache.sling.validation.model.ValidatorInvocation;
import org.apache.sling.validation.model.ResourceProperty;
import org.apache.sling.validation.model.ValidationModel;
import org.apache.sling.validation.model.spi.ValidationModelRetriever;
@@ -78,6 +79,10 @@
@Reference
ValidationModelRetriever modelRetriever;
+ /** List of all known validators (key=id of validator) */
+ @Nonnull
+ ValidatorMap validatorMap;
+
Collection<String> searchPaths;
ValidationServiceConfiguration configuration;
@@ -98,7 +103,8 @@
private ServiceUserMapped serviceUserMapped;
@Activate
- public void activate(ValidationServiceConfiguration configuration) {
+ protected void activate(ValidationServiceConfiguration configuration) {
+ this.validatorMap = new ValidatorMap();
this.configuration = configuration;
ResourceResolver rr = null;
try {
@@ -113,6 +119,28 @@
}
}
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, policyOption = ReferencePolicyOption.GREEDY, policy=ReferencePolicy.DYNAMIC)
+ protected void addValidator(@Nonnull Validator<?> validator, Map<String, Object> properties, ServiceReference<Validator<?>> serviceReference) {
+ validatorMap.put(properties, validator, serviceReference);
+ }
+
+ protected void removeValidator(@Nonnull Validator<?> validator, Map<String, Object> properties, ServiceReference<Validator<?>> serviceReference) {
+ validatorMap.remove(properties, validator, serviceReference);
+ }
+
+ /**
+ * Necessary to deal with property changes which do not lead to service restarts (when a modified method is provided)
+ *
+ * @param validator
+ * @param properties
+ * @param serviceReference
+ */
+ protected void updatedValidator(@Nonnull Validator<?> validator, Map<String, Object> properties, ServiceReference<Validator<?>> serviceReference) {
+ validatorMap.update(properties, validator, serviceReference);
+ }
+
+
+
// ValidationService ###################################################################################################################
public @CheckForNull ValidationModel getValidationModel(@Nonnull String validatedResourceType, String resourcePath, boolean considerResourceSuperTypeModels) {
@@ -173,13 +201,14 @@
throw new IllegalStateException("There is no resource provider in the system, providing a resource bundle for locale");
}
- private int getSeverityForValidator(ParameterizedValidator validator) {
- Integer validatorSeverity = validator.getSeverity();
- if (validatorSeverity == null) {
- return configuration.defaultSeverity();
- } else {
- return validatorSeverity;
+ private int getSeverityForValidator(Integer severityFromModel, Integer severityFromValidator) {
+ if (severityFromModel != null) {
+ return severityFromModel;
}
+ if (severityFromValidator != null) {
+ return severityFromValidator;
+ }
+ return configuration.defaultSeverity();
}
protected @Nonnull ValidationResult validate(@Nonnull Resource resource, @Nonnull ValidationModel model, @Nonnull String relativePath) {
@@ -306,7 +335,7 @@
}
return;
}
- List<ParameterizedValidator> validators = resourceProperty.getValidators();
+ List<ValidatorInvocation> validatorInvocations = resourceProperty.getValidatorInvocations();
if (resourceProperty.isMultiple()) {
if (!fieldValues.getClass().isArray()) {
result.addFailure(relativePath + property, configuration.defaultSeverity(), defaultResourceBundle, I18N_KEY_EXPECTED_MULTIVALUE_PROPERTY);
@@ -314,10 +343,16 @@
}
}
- for (ParameterizedValidator validator : validators) {
- int severity = getSeverityForValidator(validator);
+ for (ValidatorInvocation validatorInvocation : validatorInvocations) {
+ // lookup validator by id
+ ValidatorMap.ValidatorMetaData validatorMetaData = validatorMap.get(validatorInvocation.getValidatorId());
+ if (validatorMetaData == null) {
+ throw new IllegalStateException("Could not find validator with id '" + validatorInvocation.getValidatorId() + "'");
+ }
+ int severity = getSeverityForValidator(validatorInvocation.getSeverity(), validatorMetaData.getSeverity());
+
// convert the type always to an array
- Class<?> type = validator.getType();
+ Class<?> type = validatorMetaData.getType();
if (!type.isArray()) {
try {
// https://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getName%28%29 has some hints on class names
@@ -331,23 +366,23 @@
// see https://issues.apache.org/jira/browse/SLING-4178 for why the second check is necessary
if (typedValue == null || (typedValue.length > 0 && typedValue[0] == null)) {
// here the missing required property case was already treated in validateValueMap
- result.addFailure(relativePath + property, severity, defaultResourceBundle, I18N_KEY_WRONG_PROPERTY_TYPE, validator.getType());
+ result.addFailure(relativePath + property, severity, defaultResourceBundle, I18N_KEY_WRONG_PROPERTY_TYPE, validatorMetaData.getType());
return;
}
// see https://issues.apache.org/jira/browse/SLING-662 for a description on how multivalue properties are treated with ValueMap
- if (validator.getType().isArray()) {
+ if (validatorMetaData.getType().isArray()) {
// ValueMap already returns an array in both cases (property is single value or multivalue)
- validateValue(result, typedValue, property, relativePath, valueMap, resource, validator, defaultResourceBundle, severity);
+ validateValue(result, typedValue, property, relativePath, valueMap, resource, validatorMetaData.getValidator(), validatorInvocation.getParameters(), defaultResourceBundle, severity);
} else {
// call validate for each entry in the array (supports both singlevalue and multivalue)
@Nonnull Object[] array = (Object[])typedValue;
if (array.length == 1) {
- validateValue(result, array[0], property, relativePath, valueMap, resource, validator, defaultResourceBundle, severity);
+ validateValue(result, array[0], property, relativePath, valueMap, resource, validatorMetaData.getValidator(), validatorInvocation.getParameters(), defaultResourceBundle, severity);
} else {
int n = 0;
for (Object item : array) {
- validateValue(result, item, property + "[" + n++ + "]", relativePath, valueMap, resource, validator, defaultResourceBundle, severity);
+ validateValue(result, item, property + "[" + n++ + "]", relativePath, valueMap, resource, validatorMetaData.getValidator(), validatorInvocation.getParameters(), defaultResourceBundle, severity);
}
}
}
@@ -355,10 +390,10 @@
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private void validateValue(CompositeValidationResult result, @Nonnull Object value, String property, String relativePath, @Nonnull ValueMap valueMap, Resource resource, ParameterizedValidator validator, @Nonnull ResourceBundle defaultResourceBundle, int severity) {
+ private void validateValue(CompositeValidationResult result, @Nonnull Object value, String property, String relativePath, @Nonnull ValueMap valueMap, Resource resource, @Nonnull Validator validator, ValueMap validatorParameters, @Nonnull ResourceBundle defaultResourceBundle, int severity) {
try {
ValidationContext validationContext = new ValidationContextImpl(relativePath + property, severity, valueMap, resource, defaultResourceBundle);
- ValidationResult validatorResult = ((Validator)validator.getValidator()).validate(value, validationContext, validator.getParameters());
+ ValidationResult validatorResult = ((Validator)validator).validate(value, validationContext, validatorParameters);
result.addValidationResult(validatorResult);
} catch (SlingValidationException e) {
// wrap in another SlingValidationException to include information about the property
diff --git a/src/main/java/org/apache/sling/validation/impl/ValidatorMap.java b/src/main/java/org/apache/sling/validation/impl/ValidatorMap.java
new file mode 100644
index 0000000..bc00177
--- /dev/null
+++ b/src/main/java/org/apache/sling/validation/impl/ValidatorMap.java
@@ -0,0 +1,236 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.sling.validation.impl.util.ValidatorTypeUtil;
+import org.apache.sling.validation.spi.Validator;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class which encapsulates a map of {@link Validator}s with their meta information.
+ *
+ */
+public class ValidatorMap {
+
+ final static class ValidatorMetaData implements Comparable<ValidatorMetaData> {
+ protected final @Nonnull Validator<?> validator;
+ // default severity of the validator
+ protected final Integer severity;
+ protected final @Nonnull Class<?> type;
+ /** used for comparison, to sort by service ranking and id */
+ protected final @Nonnull ServiceReference<Validator<?>> serviceReference;
+
+ public ValidatorMetaData(Validator<?> validator, ServiceReference<Validator<?>> serviceReference, Integer severity) {
+ this.validator = validator;
+ this.severity = severity;
+ this.serviceReference = serviceReference;
+ // cache validator's type (as this is using reflection)
+ type = ValidatorTypeUtil.getValidatorType(validator);
+ }
+
+ @Override
+ public int compareTo(ValidatorMetaData o) {
+ return serviceReference.compareTo(o.serviceReference);
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((serviceReference == null) ? 0 : serviceReference.hashCode());
+ result = prime * result + ((severity == null) ? 0 : severity.hashCode());
+ result = prime * result + ((validator == null) ? 0 : validator.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ValidatorMetaData other = (ValidatorMetaData) obj;
+ if (serviceReference == null) {
+ if (other.serviceReference != null)
+ return false;
+ } else if (!serviceReference.equals(other.serviceReference))
+ return false;
+ if (severity == null) {
+ if (other.severity != null)
+ return false;
+ } else if (!severity.equals(other.severity))
+ return false;
+ if (validator == null) {
+ if (other.validator != null)
+ return false;
+ } else if (!validator.equals(other.validator))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry [validator=" + validator + ", severity=" + severity + ", type=" + type + ", from bundle '" + serviceReference.getBundle().getSymbolicName() + "'"
+ + "]";
+ }
+
+ public @Nonnull Validator<?> getValidator() {
+ return validator;
+ }
+
+ public @CheckForNull Integer getSeverity() {
+ return severity;
+ }
+
+ public @Nonnull Class<?> getType() {
+ return type;
+ }
+
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValidationServiceImpl.class);
+ private final Map<String, ValidatorMetaData> validatorMap;
+
+ public ValidatorMap() {
+ validatorMap = new ConcurrentHashMap<>();
+ }
+
+ private String getValidatorIdFromServiceProperties(Map<String, Object> properties, @SuppressWarnings("rawtypes") Class<? extends Validator> validatorClass,
+ ServiceReference<Validator<?>> serviceReference) {
+ Object id = properties.get(Validator.PROPERTY_VALIDATOR_ID);
+ if (id == null) {
+ throw new IllegalArgumentException("Validator '" + validatorClass.getName() + "' provided from bundle "
+ + serviceReference.getBundle().getBundleId() +
+ " is lacking the mandatory service property " + Validator.PROPERTY_VALIDATOR_ID);
+ }
+ if (!(id instanceof String)) {
+ throw new IllegalArgumentException("Validator '" + validatorClass.getName() + "' provided from bundle "
+ + serviceReference.getBundle().getBundleId() +
+ " is providing the mandatory service property " + Validator.PROPERTY_VALIDATOR_ID + " with the wrong type "
+ + id.getClass() + " (must be of type String)");
+ }
+ return (String) id;
+ }
+
+ private Integer getValidatorSeverityFromServiceProperties(Map<String, Object> properties, Validator<?> validator,
+ ServiceReference<Validator<?>> serviceReference) {
+ Object severity = properties.get(Validator.PROPERTY_VALIDATOR_SEVERITY);
+ if (severity == null) {
+ LOG.debug("Validator '{}' is not setting an explicit severity via the OSGi service property {}", validator.getClass().getName(), Validator.PROPERTY_VALIDATOR_SEVERITY);
+ return null;
+ }
+ if (!(severity instanceof Integer)) {
+ throw new IllegalArgumentException("Validator '" + validator.getClass().getName() + "' provided from bundle "
+ + serviceReference.getBundle().getBundleId() +
+ " is providing the optional service property " + Validator.PROPERTY_VALIDATOR_SEVERITY + " with the wrong type "
+ + severity.getClass() + " (must be of type Integer)");
+ }
+ return (Integer) severity;
+ }
+
+ public void put(@Nonnull Map<String, Object> properties, @Nonnull Validator<?> validator, ServiceReference<Validator<?>> serviceReference) {
+ String validatorId = getValidatorIdFromServiceProperties(properties, validator.getClass(), serviceReference);
+ Integer severity = getValidatorSeverityFromServiceProperties(properties, validator, serviceReference);
+ put(validatorId, validator, serviceReference, severity);
+ }
+
+ void put(@Nonnull String id, @Nonnull Validator<?> validator, ServiceReference<Validator<?>> serviceReference, Integer severity) {
+ // create new entry
+ ValidatorMetaData entry = new ValidatorMetaData(validator, serviceReference, severity);
+ if (validatorMap.containsKey(id)) {
+ ValidatorMetaData existingEntry = validatorMap.get(id);
+ if (entry.compareTo(existingEntry) > 0) {
+ LOG.info("Overwriting already existing validator {} with {}, because it has the same id '{}' and a higher service ranking",
+ existingEntry, entry, id);
+ } else {
+ LOG.info(
+ "A Validator for the same id '{}' is already registered {} and it has a higher service ranking, therefore ignoring {}",
+ id, existingEntry, entry);
+ return;
+ }
+ } else {
+ LOG.debug("New validator with id '{}' added: {}", id, entry);
+ }
+ validatorMap.put(id, entry);
+ }
+
+ public void update(@Nonnull Map<String, Object> properties, @Nonnull Validator<?> validator, ServiceReference<Validator<?>> serviceReference) {
+ String validatorId = getValidatorIdFromServiceProperties(properties, validator.getClass(), serviceReference);
+ Integer severity = getValidatorSeverityFromServiceProperties(properties, validator, serviceReference);
+ update(validatorId, validator, serviceReference, severity);
+ }
+
+ void update(@Nonnull String id, @Nonnull Validator<?> validator, ServiceReference<Validator<?>> serviceReference, Integer severity) {
+ LOG.info("Updating validator with id '{}'", id);
+ // the id might have been changed, therefore remove old entry by looking up the service reference!
+ remove(serviceReference);
+ put(id, validator, serviceReference, severity);
+ }
+
+ private boolean remove(ServiceReference<Validator<?>> serviceReference) {
+ for (java.util.Iterator<ValidatorMetaData> iterator = validatorMap.values().iterator(); iterator.hasNext();) {
+ ValidatorMetaData value = iterator.next();
+ if (value.serviceReference.equals(serviceReference)) {
+ iterator.remove();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean remove(@Nonnull Map<String, Object> properties, @Nonnull Validator<?> validator, ServiceReference<Validator<?>> serviceReference) {
+ String validatorId = getValidatorIdFromServiceProperties(properties, validator.getClass(), serviceReference);
+ return remove(validatorId, serviceReference);
+ }
+
+ public boolean remove(String id, ServiceReference<Validator<?>> serviceReference) {
+ // only actually remove if the service reference is equal
+ if (id == null) {
+ // find by service reference
+ }
+ ValidatorMetaData entry = validatorMap.get(id);
+ if (entry == null) {
+ LOG.warn("Could not remove validator with id '{}' from map, because it is not there!", id);
+ return false;
+ } else {
+ // only actually remove if the service reference is equal
+ if (entry.serviceReference.equals(serviceReference)) {
+ return true;
+ } else {
+ LOG.warn("Could not remove validator with id '{}' from map because it is only contained with a different service reference!", id);
+ return false;
+ }
+ }
+ }
+
+ public ValidatorMetaData get(String id) {
+ return validatorMap.get(id);
+ }
+}
diff --git a/src/main/java/org/apache/sling/validation/impl/model/ParameterizedValidatorImpl.java b/src/main/java/org/apache/sling/validation/impl/model/ParameterizedValidatorImpl.java
index e51a395..1dbceb2 100644
--- a/src/main/java/org/apache/sling/validation/impl/model/ParameterizedValidatorImpl.java
+++ b/src/main/java/org/apache/sling/validation/impl/model/ParameterizedValidatorImpl.java
@@ -25,15 +25,11 @@
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
-import org.apache.sling.validation.impl.util.ValidatorTypeUtil;
-import org.apache.sling.validation.model.ParameterizedValidator;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
-import org.apache.sling.validation.spi.Validator;
+import org.apache.sling.validation.model.ValidatorInvocation;
-public class ParameterizedValidatorImpl implements ParameterizedValidator {
- private final @Nonnull Validator<?> validator;
+public class ParameterizedValidatorImpl implements ValidatorInvocation {
+ private final @Nonnull String id;
private final @Nonnull Map<String, Object> parameters;
- private final @Nonnull Class<?> type;
private final Integer severity;
/**
@@ -43,27 +39,20 @@
* @param parameters
* @param severity
*/
- public ParameterizedValidatorImpl(@Nonnull ValidatorAndSeverity<?> validator, @Nonnull Map<String, Object> parameters, Integer severity) {
+ public ParameterizedValidatorImpl(@Nonnull String id, @Nonnull Map<String, Object> parameters, Integer severity) {
super();
- this.validator = validator.getValidator();
+ this.id = id;
this.parameters = parameters;
- // cache type information as this is using reflection
- this.type = ValidatorTypeUtil.getValidatorType(this.validator);
- if (severity == null) {
- this.severity = validator.getSeverity();
- } else {
- this.severity = severity;
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.sling.validation.impl.ParameterizedValidator#getValidator()
- */
- @Override
- public @Nonnull Validator<?> getValidator() {
- return validator;
+ this.severity = severity;
}
+
+ @Override
+ public String getValidatorId() {
+ return id;
+ }
+
+
/* (non-Javadoc)
* @see org.apache.sling.validation.impl.ParameterizedValidator#getParameters()
*/
@@ -71,14 +60,6 @@
public @Nonnull ValueMap getParameters() {
return new ValueMapDecorator(parameters);
}
-
- /* (non-Javadoc)
- * @see org.apache.sling.validation.impl.ParameterizedValidator#getType()
- */
- @Override
- public @Nonnull Class<?> getType() {
- return type;
- }
@Override
@CheckForNull
@@ -86,23 +67,18 @@
return severity;
}
- @Override
- public String toString() {
- return "ParameterizedValidatorImpl [validator=" + validator + ", parameters=" + parameters + ", type=" + type
- + ", severity=" + severity + "]";
- }
- @Override
+ @Override
public int hashCode() {
final int prime = 31;
int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
- result = prime * result + ((type == null) ? 0 : type.hashCode());
- result = prime * result + ((validator == null) ? 0 : validator.hashCode());
result = prime * result + ((severity == null) ? 0 : severity.hashCode());
return result;
}
+
@Override
public boolean equals(Object obj) {
if (this == obj)
@@ -112,19 +88,28 @@
if (getClass() != obj.getClass())
return false;
ParameterizedValidatorImpl other = (ParameterizedValidatorImpl) obj;
- if (!parameters.equals(other.parameters))
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
return false;
- if (!type.equals(other.type))
+ if (parameters == null) {
+ if (other.parameters != null)
+ return false;
+ } else if (!parameters.equals(other.parameters))
return false;
- if (!validator.getClass().getName().equals(other.validator.getClass().getName()))
+ if (severity == null) {
+ if (other.severity != null)
+ return false;
+ } else if (!severity.equals(other.severity))
return false;
- if (severity == null && other.severity != null) {
- return false;
- } else if (severity != null && other.severity == null) {
- return false;
- } else if (severity != null && other.severity != null && !severity.equals(other.severity)) {
- return false;
- }
return true;
}
+
+
+ @Override
+ public String toString() {
+ return "ParameterizedValidatorImpl [id=" + id + ", parameters=" + parameters + ", severity=" + severity + "]";
+ }
+
}
diff --git a/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyBuilder.java b/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyBuilder.java
index d4a0dbe..1c121b9 100644
--- a/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyBuilder.java
+++ b/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyBuilder.java
@@ -25,19 +25,18 @@
import javax.annotation.Nonnull;
-import org.apache.sling.validation.model.ParameterizedValidator;
+import org.apache.sling.validation.model.ValidatorInvocation;
import org.apache.sling.validation.model.ResourceProperty;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
public class ResourcePropertyBuilder {
private boolean optional;
private boolean multiple;
private String nameRegex;
- private final @Nonnull List<ParameterizedValidator> validators;
+ private final @Nonnull List<ValidatorInvocation> validators;
public ResourcePropertyBuilder() {
- validators = new ArrayList<ParameterizedValidator>();
+ validators = new ArrayList<ValidatorInvocation>();
this.nameRegex = null;
this.optional = false;
this.multiple = false;
@@ -51,15 +50,7 @@
/**
* should only be used from test classes
*/
- public @Nonnull ResourcePropertyBuilder validator(@Nonnull ValidatorAndSeverity<?> validator) {
- validators.add(new ParameterizedValidatorImpl(validator, new HashMap<String, Object>(), null));
- return this;
- }
-
- /**
- * should only be used from test classes
- */
- public @Nonnull ResourcePropertyBuilder validator(@Nonnull ValidatorAndSeverity<?> validator, Integer severity, String... parametersNamesAndValues) {
+ public @Nonnull ResourcePropertyBuilder validator(@Nonnull String id, Integer severity, String... parametersNamesAndValues) {
if (parametersNamesAndValues.length % 2 != 0) {
throw new IllegalArgumentException("array parametersNamesAndValues must be even! (first specify name then value, separated by comma)");
}
@@ -68,11 +59,11 @@
for (int i=0; i<parametersNamesAndValues.length; i=i+2) {
parameterMap.put(parametersNamesAndValues[i], parametersNamesAndValues[i+1]);
}
- return validator(validator, severity, parameterMap);
+ return validator(id, severity, parameterMap);
}
- public @Nonnull ResourcePropertyBuilder validator(@Nonnull ValidatorAndSeverity<?> validator, Integer severity, @Nonnull Map<String, Object> parameters) {
- validators.add(new ParameterizedValidatorImpl(validator, parameters, severity));
+ public @Nonnull ResourcePropertyBuilder validator(@Nonnull String id, Integer severity, @Nonnull Map<String, Object> parameters) {
+ validators.add(new ParameterizedValidatorImpl(id, parameters, severity));
return this;
}
diff --git a/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java b/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java
index 74c5a66..e3b13a4 100644
--- a/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java
+++ b/src/main/java/org/apache/sling/validation/impl/model/ResourcePropertyImpl.java
@@ -24,7 +24,7 @@
import javax.annotation.Nonnull;
-import org.apache.sling.validation.model.ParameterizedValidator;
+import org.apache.sling.validation.model.ValidatorInvocation;
import org.apache.sling.validation.model.ResourceProperty;
public class ResourcePropertyImpl implements ResourceProperty {
@@ -32,7 +32,7 @@
private final @Nonnull String name;
private final boolean isMultiple;
private final boolean isRequired;
- private final @Nonnull List<ParameterizedValidator> validators;
+ private final @Nonnull List<ValidatorInvocation> validators;
private final Pattern namePattern;
/**
@@ -45,7 +45,7 @@
* @throws IllegalArgumentException
*/
protected ResourcePropertyImpl(@Nonnull String name, String nameRegex, boolean isMultiple, boolean isRequired,
- @Nonnull List<ParameterizedValidator> validators) throws IllegalArgumentException {
+ @Nonnull List<ValidatorInvocation> validators) throws IllegalArgumentException {
if (nameRegex != null) {
try {
this.namePattern = Pattern.compile(nameRegex);
@@ -82,7 +82,7 @@
}
@Override
- public @Nonnull List<ParameterizedValidator> getValidators() {
+ public @Nonnull List<ValidatorInvocation> getValidatorInvocations() {
return validators;
}
diff --git a/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java b/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java
index ff0e9d2..f931bcc 100644
--- a/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java
+++ b/src/main/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImpl.java
@@ -46,9 +46,7 @@
import org.apache.sling.validation.model.ChildResource;
import org.apache.sling.validation.model.ResourceProperty;
import org.apache.sling.validation.model.ValidationModel;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
import org.apache.sling.validation.model.spi.ValidationModelProvider;
-import org.apache.sling.validation.spi.Validator;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
@@ -215,14 +213,13 @@
/*
* (non-Javadoc)
*
- * @see org.apache.sling.validation.model.spi.ValidationModelProvider#getModels(java.lang.String, java.util.Map)
+ * @see org.apache.sling.validation.model.spi.ValidationModelProvider#getModels(java.lang.String)
*/
@Override
- public @Nonnull List<ValidationModel> getModels(@Nonnull String relativeResourceType,
- @Nonnull Map<String, ValidatorAndSeverity<?>> validatorsMap) {
+ public @Nonnull List<ValidationModel> getModels(@Nonnull String relativeResourceType) {
List<ValidationModel> cacheEntry = validationModelCacheByResourceType.get(relativeResourceType);
if (cacheEntry == null) {
- cacheEntry = doGetModels(relativeResourceType, validatorsMap);
+ cacheEntry = doGetModels(relativeResourceType);
validationModelCacheByResourceType.put(relativeResourceType, cacheEntry);
} else {
LOG.debug("Found entry in cache for resource type {}", relativeResourceType);
@@ -233,13 +230,11 @@
/** Searches for validation models bound to a specific resource type through a search query.
*
* @param relativeResourceType the resource type to look for
- * @param validatorsMap all known validators in a map (key=id of validator). Only one of those should be used in the returned validation
- * models.
* @return a List of {@link ValidationModel}s. Never {@code null}, but might be empty collection in case no model for the given resource
* type could be found. Returns the models below "/apps" before the models below "/libs".
* @throws IllegalStateException in case a validation model is found but it is invalid */
@Nonnull
- private List<ValidationModel> doGetModels(@Nonnull String relativeResourceType, @Nonnull Map<String, ValidatorAndSeverity<?>> validatorsMap) {
+ private List<ValidationModel> doGetModels(@Nonnull String relativeResourceType) {
List<ValidationModel> validationModels = new ArrayList<ValidationModel>();
ResourceResolver resourceResolver = null;
try {
@@ -258,8 +253,8 @@
ValueMap validationModelProperties = model.getValueMap();
modelBuilder.addApplicablePaths(validationModelProperties.get(ResourceValidationModelProviderImpl.APPLICABLE_PATHS, new String[] {}));
Resource propertiesResource = model.getChild(ResourceValidationModelProviderImpl.PROPERTIES);
- modelBuilder.resourceProperties(buildProperties(validatorsMap, propertiesResource));
- modelBuilder.childResources(buildChildren(model, model, validatorsMap));
+ modelBuilder.resourceProperties(buildProperties(propertiesResource));
+ modelBuilder.childResources(buildChildren(model, model));
ValidationModel vm = modelBuilder.build(relativeResourceType, resourcePath);
validationModels.add(vm);
} catch (IllegalArgumentException e) {
@@ -286,11 +281,10 @@
/** Creates a set of the properties that a resource is expected to have, together with the associated validators.
*
- * @param validatorsMap a map containing {@link Validator}s as values and their id's as keys
* @param propertiesResource the resource identifying the properties node from a validation model's structure (might be {@code null})
* @return a set of properties or an empty set if no properties are defined
* @see ResourceProperty */
- private @Nonnull List<ResourceProperty> buildProperties(@Nonnull Map<String, ValidatorAndSeverity<?>> validatorsMap, Resource propertiesResource) {
+ private @Nonnull List<ResourceProperty> buildProperties(@Nonnull Resource propertiesResource) {
List<ResourceProperty> properties = new ArrayList<ResourceProperty>();
if (propertiesResource != null) {
for (Resource propertyResource : propertiesResource.getChildren()) {
@@ -318,10 +312,7 @@
"Could not adapt resource at '" + validatorResource.getPath() + "' to ValueMap");
}
String validatorId = validatorResource.getName();
- ValidatorAndSeverity<?> validator = validatorsMap.get(validatorId);
- if (validator == null) {
- throw new IllegalArgumentException("Could not find validator with id '" + validatorId + "'");
- }
+
// get arguments for validator
String[] validatorArguments = validatorProperties.get(ResourceValidationModelProviderImpl.VALIDATOR_ARGUMENTS,
String[].class);
@@ -357,7 +348,7 @@
}
// get severity
Integer severity = validatorProperties.get(SEVERITY, Integer.class);
- resourcePropertyBuilder.validator(validator, severity, validatorArgumentsMap);
+ resourcePropertyBuilder.validator(validatorId, severity, validatorArgumentsMap);
}
}
properties.add(resourcePropertyBuilder.build(fieldName));
@@ -372,10 +363,8 @@
* @param modelResource the resource describing a {@link org.apache.sling.validation.api.ValidationModel}
* @param rootResource the model's resource from which to search for children (this resource has to have a
* {@link ResourceValidationModelProviderImpl#CHILDREN} node directly underneath it)
- * @param validatorsMap a map containing {@link Validator}s as values and their class names as values
* @return a list of all the children resources; the list will be empty if there are no children resources */
- private @Nonnull List<ChildResource> buildChildren(@Nonnull Resource modelResource, @Nonnull Resource rootResource,
- @Nonnull Map<String, ValidatorAndSeverity<?>> validatorsMap) {
+ private @Nonnull List<ChildResource> buildChildren(@Nonnull Resource modelResource, @Nonnull Resource rootResource) {
List<ChildResource> children = new ArrayList<ChildResource>();
Resource childrenResource = rootResource.getChild(ResourceValidationModelProviderImpl.CHILDREN);
if (childrenResource != null) {
@@ -395,8 +384,8 @@
}
boolean isRequired = !childrenProperties.get(ResourceValidationModelProviderImpl.OPTIONAL, false);
ChildResource childResource = new ChildResourceImpl(name, nameRegex, isRequired,
- buildProperties(validatorsMap, child.getChild(ResourceValidationModelProviderImpl.PROPERTIES)),
- buildChildren(modelResource, child, validatorsMap));
+ buildProperties(child.getChild(ResourceValidationModelProviderImpl.PROPERTIES)),
+ buildChildren(modelResource, child));
children.add(childResource);
}
}
diff --git a/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java b/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java
index a2dcbfc..0a93d14 100644
--- a/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java
+++ b/src/test/java/org/apache/sling/validation/impl/ValidationModelRetrieverImplTest.java
@@ -21,7 +21,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -36,11 +35,8 @@
import org.apache.sling.validation.impl.model.ResourcePropertyBuilder;
import org.apache.sling.validation.impl.model.ValidationModelBuilder;
import org.apache.sling.validation.impl.util.ResourcePropertyNameMatcher;
-import org.apache.sling.validation.impl.util.examplevalidators.DateValidator;
-import org.apache.sling.validation.impl.util.examplevalidators.StringValidator;
import org.apache.sling.validation.model.ResourceProperty;
import org.apache.sling.validation.model.ValidationModel;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
import org.apache.sling.validation.model.spi.ValidationModelProvider;
import org.apache.sling.validation.spi.Validator;
import org.hamcrest.Matchers;
@@ -51,14 +47,11 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
@RunWith(MockitoJUnitRunner.class)
public class ValidationModelRetrieverImplTest {
private ValidationModelRetrieverImpl validationModelRetriever;
- private Validator<Date> dateValidator;
private MultiValuedMap<String, String> applicablePathPerResourceType;
private TestModelProvider modelProvider;
@@ -66,15 +59,9 @@
private ResourceResolver resourceResolver;
@Mock
private ResourceResolverFactory resourceResolverFactory;
- @Mock
- private ServiceReference<Validator<?>> validatorServiceReference;
- @Mock
- private ServiceReference<Validator<?>> newValidatorServiceReference;
- @Mock
- private Bundle providingBundle;
-
- private static final String DATE_VALIDATOR_ID = "DateValidator";
+
+ private static final String DATE_VALIDATOR_ID = "DateValidator";
/**
* 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.
@@ -87,12 +74,7 @@
}
@Override
- public @Nonnull List<ValidationModel> getModels(@Nonnull String relativeResourceType,
- @Nonnull Map<String, ValidatorAndSeverity<?>> validatorsMap) {
- // make sure the date validator is passed along
- Assert.assertThat(validatorsMap,
- Matchers.<String, ValidatorAndSeverity<?>> hasEntry(DATE_VALIDATOR_ID, new ValidatorAndSeverity<Date>(dateValidator, 1)));
-
+ public @Nonnull List<ValidationModel> getModels(@Nonnull String relativeResourceType) {
List<ValidationModel> models = new ArrayList<ValidationModel>();
Collection<String> applicablePaths = applicablePathPerResourceType.get(relativeResourceType);
if (applicablePaths != null) {
@@ -111,60 +93,19 @@
@Before
public void setup() throws LoginException {
- dateValidator = new DateValidator();
applicablePathPerResourceType = new ArrayListValuedHashMap<>();
validationModelRetriever = new ValidationModelRetrieverImpl();
modelProvider = new TestModelProvider("source1");
validationModelRetriever.modelProviders = new ArrayList<>();
validationModelRetriever.modelProviders.add(modelProvider);
- Mockito.doReturn(1l).when(providingBundle).getBundleId();
- Mockito.doReturn(providingBundle).when(validatorServiceReference).getBundle();
- Mockito.doReturn(providingBundle).when(newValidatorServiceReference).getBundle();
+
Map<String, Object> validatorProperties = new HashMap<>();
validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, DATE_VALIDATOR_ID);
validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 1);
- validationModelRetriever.addValidator(dateValidator, validatorProperties, validatorServiceReference);
validationModelRetriever.resourceResolverFactory = resourceResolverFactory;
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyObject())).thenReturn(resourceResolver);
}
- @Test(expected=IllegalArgumentException.class)
- public void testAddValidatorWithoutValidatorIdProperty() {
- Map<String, Object> validatorProperties = new HashMap<>();
- validationModelRetriever.addValidator(dateValidator, validatorProperties, validatorServiceReference);
- }
-
- @Test(expected=IllegalArgumentException.class)
- public void testAddValidatorWithWronglyTypedValidatorId() {
- Map<String, Object> validatorProperties = new HashMap<>();
- validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, new String[]{"some", "value"});
- validationModelRetriever.addValidator(dateValidator, validatorProperties, validatorServiceReference);
- }
-
- @Test
- public void testAddOverloadingValidatorWithSameValidatorIdAndHigherRanking() {
- Map<String, Object> validatorProperties = new HashMap<>();
- validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, DATE_VALIDATOR_ID);
- validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 2);
- Mockito.doReturn(1).when(newValidatorServiceReference).compareTo(Mockito.anyObject());
- Validator<String> stringValidator = new StringValidator();
- validationModelRetriever.addValidator(stringValidator, validatorProperties, newValidatorServiceReference);
- Assert.assertEquals(new ValidatorAndSeverity<>(stringValidator, 2), validationModelRetriever.validators.get(DATE_VALIDATOR_ID));
- Assert.assertEquals(newValidatorServiceReference, validationModelRetriever.validatorServiceReferences.get(DATE_VALIDATOR_ID));
- }
-
- @Test
- public void testAddOverloadingValidatorWithSameValidatorIdAndLowerRanking() {
- Map<String, Object> validatorProperties = new HashMap<>();
- validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, DATE_VALIDATOR_ID);
- validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 2);
- Mockito.doReturn(-1).when(newValidatorServiceReference).compareTo(Mockito.anyObject());
- Validator<String> stringValidator = new StringValidator();
- validationModelRetriever.addValidator(stringValidator, validatorProperties, newValidatorServiceReference);
- Assert.assertEquals(new ValidatorAndSeverity<>(dateValidator, 1), validationModelRetriever.validators.get(DATE_VALIDATOR_ID));
- Assert.assertEquals(validatorServiceReference, validationModelRetriever.validatorServiceReferences.get(DATE_VALIDATOR_ID));
- }
-
@Test
public void testGetModel() {
applicablePathPerResourceType.put("test/type", "/content/site1");
diff --git a/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java b/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java
index b2198e7..232b88b 100644
--- a/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java
+++ b/src/test/java/org/apache/sling/validation/impl/ValidationServiceImplTest.java
@@ -1,20 +1,20 @@
/*
-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
+ * 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
+ * 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.
+ * 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;
@@ -44,9 +44,9 @@
import org.apache.sling.i18n.ResourceBundleProvider;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.validation.SlingValidationException;
import org.apache.sling.validation.ValidationFailure;
import org.apache.sling.validation.ValidationResult;
-import org.apache.sling.validation.SlingValidationException;
import org.apache.sling.validation.impl.model.ChildResourceImpl;
import org.apache.sling.validation.impl.model.ResourcePropertyBuilder;
import org.apache.sling.validation.impl.model.ValidationModelBuilder;
@@ -55,7 +55,6 @@
import org.apache.sling.validation.model.ChildResource;
import org.apache.sling.validation.model.ResourceProperty;
import org.apache.sling.validation.model.ValidationModel;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
import org.apache.sling.validation.model.spi.ValidationModelRetriever;
import org.apache.sling.validation.spi.DefaultValidationFailure;
import org.apache.sling.validation.spi.DefaultValidationResult;
@@ -70,6 +69,8 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
@RunWith(MockitoJUnitRunner.class)
public class ValidationServiceImplTest {
@@ -94,27 +95,75 @@
@Mock
private ResourceBundleProvider resourceBundleProvider;
-
+
+ @Mock
+ private ValidationModelRetriever modelRetriever;
+ private Validator<Date> dateValidator;
+
+ @Mock
+ private ServiceReference<Validator<?>> validatorServiceReference;
+ @Mock
+ private ServiceReference<Validator<?>> newValidatorServiceReference;
+ @Mock
+ private Bundle providingBundle;
+
+ private static final String DATE_VALIDATOR_ID = "DateValidator";
+ private static final String REGEX_VALIDATOR_ID = "RegexValidator";
+
@Before
public void setUp() throws LoginException, PersistenceException, RepositoryException {
validationService = new ValidationServiceImpl();
validationService.searchPaths = Arrays.asList(context.resourceResolver().getSearchPath());
validationService.configuration = configuration;
+ validationService.validatorMap = new ValidatorMap();
Mockito.doReturn(20).when(configuration).defaultSeverity();
validationService.resourceBundleProviders = Collections.singletonList(resourceBundleProvider);
Mockito.doReturn(defaultResourceBundle).when(resourceBundleProvider).getResourceBundle(Mockito.anyObject());
modelBuilder = new ValidationModelBuilder();
propertyBuilder = new ResourcePropertyBuilder();
+ dateValidator = new DateValidator();
+ Mockito.doReturn(1l).when(providingBundle).getBundleId();
+ Mockito.doReturn(providingBundle).when(validatorServiceReference).getBundle();
+ Mockito.doReturn(providingBundle).when(newValidatorServiceReference).getBundle();
+ validationService.validatorMap.put(DATE_VALIDATOR_ID, dateValidator, validatorServiceReference, 10);
+ validationService.validatorMap.put(REGEX_VALIDATOR_ID, new RegexValidator(), validatorServiceReference, 10);
+ validationService.modelRetriever = modelRetriever;
}
@Test
- public void testGetValidationModel() throws Exception {
+ public void testGetValidationModelWithAbsolutePath() throws Exception {
+ // check conversion to relative resource type
+ validationService.getValidationModel("/libs/some/type", "some path", true);
+ Mockito.verify(modelRetriever).getModel("some/type", "some path", true);
+ }
+ @Test
+ public void testGetValidationModelWithRelativePath() throws Exception {
+ // check conversion to relative resource type
+ validationService.getValidationModel("some/type", "some path", true);
+ Mockito.verify(modelRetriever).getModel("some/type", "some path", true);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testGetValidationModelWithAbsolutePathOutsideSearchPath() throws Exception {
+ // check conversion to relative resource type
+ validationService.getValidationModel("/content/some/type", "some path", true);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testValidateWithInvalidValidatorId() throws Exception {
+ propertyBuilder.validator("invalidid", 10);
+ modelBuilder.resourceProperty(propertyBuilder.build("field1"));
+ ValidationModel vm = modelBuilder.build("sling/validation/test", "some source");
+
+ HashMap<String, Object> hashMap = new HashMap<String, Object>();
+ hashMap.put("field1", "1");
+ validationService.validate(new ValueMapDecorator(hashMap), vm);
}
@Test()
public void testValueMapWithWrongDataType() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<Date>(new DateValidator(), 10));
+ propertyBuilder.validator(DATE_VALIDATOR_ID, 10);
modelBuilder.resourceProperty(propertyBuilder.build("field1"));
ValidationModel vm = modelBuilder.build("sling/validation/test", "some source");
@@ -138,7 +187,8 @@
return DefaultValidationResult.VALID;
}
};
- propertyBuilder.validator(new ValidatorAndSeverity<String>(myValidator, 10));
+ validationService.validatorMap.put("someId", myValidator, validatorServiceReference, 10);
+ propertyBuilder.validator("someId", 20);
modelBuilder.resourceProperty(propertyBuilder.build("field1"));
ValidationModel vm = modelBuilder.build("sling/validation/test", "some source");
@@ -182,7 +232,7 @@
@Test()
public void testValueMapWithEmptyOptionalValue() throws Exception {
propertyBuilder.optional();
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), null, RegexValidator.REGEX_PARAM, "abc");
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, null, RegexValidator.REGEX_PARAM, "abc");
modelBuilder.resourceProperty(propertyBuilder.build("field1"));
ValidationModel vm = modelBuilder.build("sling/validation/test", "some source");
@@ -190,17 +240,17 @@
hashMap.put("field1", "");
ValidationResult vr = validationService.validate(new ValueMapDecorator(hashMap), vm);
- Assert.assertFalse(vr.isValid()); // check for correct error message Map<String, List<String>>
- Assert.assertThat(vr.getFailures(), Matchers.<ValidationFailure>contains(new DefaultValidationFailure("field1", 2, defaultResourceBundle, RegexValidator.I18N_KEY_PATTERN_DOES_NOT_MATCH, "abc")));
+ Assert.assertFalse(vr.isValid());
+ Assert.assertThat(vr.getFailures(), Matchers.<ValidationFailure>contains(new DefaultValidationFailure("field1", 10, defaultResourceBundle, RegexValidator.I18N_KEY_PATTERN_DOES_NOT_MATCH, "abc")));
}
@Test
public void testValueMapWithCorrectDataType() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "abc");
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "abc");
modelBuilder.resourceProperty(propertyBuilder.build("field1"));
propertyBuilder = new ResourcePropertyBuilder();
final String TEST_REGEX = "^test$";
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, TEST_REGEX);
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, TEST_REGEX);
modelBuilder.resourceProperty(propertyBuilder.build("field2"));
ValidationModel vm = modelBuilder.build("sling/validation/test", "some source");
@@ -217,7 +267,7 @@
// see https://issues.apache.org/jira/browse/SLING-5674
@Test
public void testNonExistingResource() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
modelBuilder.resourceProperty(property);
@@ -241,7 +291,7 @@
// see https://issues.apache.org/jira/browse/SLING-5749
@Test
public void testSyntheticResource() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
modelBuilder.resourceProperty(property);
@@ -264,7 +314,7 @@
@Test
public void testResourceWithMissingGrandChildProperty() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
modelBuilder.resourceProperty(property);
@@ -296,7 +346,7 @@
@Test
public void testResourceWithMissingOptionalChildResource() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
ChildResource child = new ChildResourceImpl("child", null, false, Collections.singletonList(property),
@@ -316,7 +366,7 @@
@Test
public void testResourceWithNestedChildren() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
ChildResource modelGrandChild = new ChildResourceImpl("grandchild", null, true,
@@ -342,7 +392,7 @@
@Test
public void testResourceWithValidatorLeveragingTheResource() throws Exception {
- ValidatorAndSeverity<String> extendedValidator = new ValidatorAndSeverity<String>(new Validator<String>() {
+ Validator<String> extendedValidator = new Validator<String>() {
@Override
@Nonnull
public ValidationResult validate(@Nonnull String data, @Nonnull ValidationContext context, @Nonnull ValueMap arguments)
@@ -356,8 +406,10 @@
return DefaultValidationResult.VALID;
}
- }, 0);
- propertyBuilder.validator(extendedValidator); // accept any digits
+ };
+ // register validator
+ validationService.validatorMap.put("myid", extendedValidator, newValidatorServiceReference, null);
+ propertyBuilder.validator("myid", null); // accept any digits
modelBuilder.resourceProperty(propertyBuilder.build("field1"));
ValidationModel vm = modelBuilder.build("sometype", "some source");
@@ -373,7 +425,7 @@
@Test
public void testResourceWithNestedChildrenAndPatternMatching() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
ResourceProperty property = propertyBuilder.build("field1");
ChildResource modelGrandChild = new ChildResourceImpl("grandchild", "grandchild.*", true,
@@ -398,7 +450,7 @@
// child2 is lacking its mandatory sub resource
rr.create(testResource, "child2", properties);
rr.create(testResource, "child3", null);
- // siblingchild is not there at all (although mandatory)
+ // sibling child is not there at all (although mandatory)
ValidationResult vr = validationService.validate(testResource, vm);
Assert.assertFalse("resource should have been considered invalid", vr.isValid());
@@ -412,7 +464,7 @@
@Test
public void testResourceWithPropertyPatternMatching() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 1, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 1, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
propertyBuilder.nameRegex("field.*");
modelBuilder.resourceProperty(propertyBuilder.build("field"));
propertyBuilder.nameRegex("otherfield.*");
@@ -441,7 +493,7 @@
@Test
public void testResourceWithMultivalueProperties() throws Exception {
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
+ propertyBuilder.validator(REGEX_VALIDATOR_ID, 0, RegexValidator.REGEX_PARAM, "\\d"); // accept any digits
propertyBuilder.multiple();
modelBuilder.resourceProperty(propertyBuilder.build("field"));
ValidationModel vm = modelBuilder.build("type", "some source");
diff --git a/src/test/java/org/apache/sling/validation/impl/ValidatorMapTest.java b/src/test/java/org/apache/sling/validation/impl/ValidatorMapTest.java
new file mode 100644
index 0000000..3bbed54
--- /dev/null
+++ b/src/test/java/org/apache/sling/validation/impl/ValidatorMapTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.validation.impl.util.examplevalidators.DateValidator;
+import org.apache.sling.validation.impl.util.examplevalidators.StringValidator;
+import org.apache.sling.validation.spi.Validator;
+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.Bundle;
+import org.osgi.framework.ServiceReference;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ValidatorMapTest {
+
+ private ValidatorMap validatorMap;
+ private DateValidator dateValidator;
+
+ @Mock
+ private ServiceReference<Validator<?>> validatorServiceReference;
+ @Mock
+ private ServiceReference<Validator<?>> newValidatorServiceReference;
+ @Mock
+ private Bundle providingBundle;
+
+ private static final String DATE_VALIDATOR_ID = "DateValidator";
+
+ @Before
+ public void setUp() {
+ validatorMap = new ValidatorMap();
+ dateValidator = new DateValidator();
+ Mockito.doReturn("some name").when(providingBundle).getSymbolicName();
+ Mockito.doReturn(providingBundle).when(validatorServiceReference).getBundle();
+ Mockito.doReturn(providingBundle).when(newValidatorServiceReference).getBundle();
+ validatorMap.put(DATE_VALIDATOR_ID, dateValidator, validatorServiceReference, 10);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPutWithoutValidatorIdProperty() {
+ Map<String, Object> validatorProperties = new HashMap<>();
+ validatorMap.put(validatorProperties, dateValidator, validatorServiceReference);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPutWithWronglyTypedValidatorId() {
+ Map<String, Object> validatorProperties = new HashMap<>();
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, new String[]{"some", "value"});
+ validatorMap.put(validatorProperties, dateValidator, validatorServiceReference);
+ }
+
+ @Test
+ public void testPutValidatorWithSameValidatorIdAndHigherRanking() {
+ Map<String, Object> validatorProperties = new HashMap<>();
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, DATE_VALIDATOR_ID);
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 2);
+ Mockito.doReturn(1).when(newValidatorServiceReference).compareTo(Mockito.anyObject());
+ Validator<String> stringValidator = new StringValidator();
+ validatorMap.put(validatorProperties,stringValidator, newValidatorServiceReference);
+ Assert.assertEquals(new ValidatorMap.ValidatorMetaData(stringValidator, newValidatorServiceReference, 2), validatorMap.get(DATE_VALIDATOR_ID));
+ }
+
+ @Test
+ public void testPutValidatorWithSameValidatorIdAndLowerRanking() {
+ Map<String, Object> validatorProperties = new HashMap<>();
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, DATE_VALIDATOR_ID);
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 2);
+ Mockito.doReturn(-1).when(newValidatorServiceReference).compareTo(Mockito.anyObject());
+ Validator<String> stringValidator = new StringValidator();
+ validatorMap.put(validatorProperties, stringValidator, newValidatorServiceReference);
+ Assert.assertEquals(new ValidatorMap.ValidatorMetaData(dateValidator, validatorServiceReference, 10), validatorMap.get(DATE_VALIDATOR_ID));
+ }
+
+ @Test
+ public void testUpdateChangingValidatorId() {
+ Map<String, Object> validatorProperties = new HashMap<>();
+ String newId = "newId";
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_ID, newId);
+ validatorProperties.put(Validator.PROPERTY_VALIDATOR_SEVERITY, 1);
+ Mockito.doReturn(-1).when(newValidatorServiceReference).compareTo(Mockito.anyObject());
+ validatorMap.update(validatorProperties, dateValidator, validatorServiceReference);
+ Assert.assertEquals(new ValidatorMap.ValidatorMetaData(dateValidator, validatorServiceReference, 1), validatorMap.get(newId));
+ // make sure that the old validator id is no longer in the list
+ Assert.assertNull(validatorMap.get(DATE_VALIDATOR_ID));
+ }
+}
diff --git a/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java b/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java
index 514d6f5..6a3fe61 100644
--- a/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java
+++ b/src/test/java/org/apache/sling/validation/impl/resourcemodel/ResourceValidationModelProviderImplTest.java
@@ -54,10 +54,9 @@
import org.apache.sling.validation.impl.model.ValidationModelBuilder;
import org.apache.sling.validation.impl.validators.RegexValidator;
import org.apache.sling.validation.model.ChildResource;
-import org.apache.sling.validation.model.ParameterizedValidator;
+import org.apache.sling.validation.model.ValidatorInvocation;
import org.apache.sling.validation.model.ResourceProperty;
import org.apache.sling.validation.model.ValidationModel;
-import org.apache.sling.validation.model.ValidatorAndSeverity;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Assert;
@@ -130,7 +129,6 @@
private ResourceResolverFactory resourceResolverFactory;
private MockQueryResultHandler prefixBasedResultHandler;
private Map<PrefixAndResourceType, List<Node>> validatorModelNodesPerPrefixAndResourceType;
- private Map<String, ValidatorAndSeverity<?>> validatorMap;
private ValidationModelBuilder modelBuilder;
// extract resource type from strings like
@@ -146,14 +144,12 @@
primaryTypeUnstructuredMap.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
modelProvider = new ResourceValidationModelProviderImpl();
- validatorMap = new HashMap<>();
- validatorMap.put("org.apache.sling.validation.impl.validators.RegexValidator", new ValidatorAndSeverity<String>(new RegexValidator(), 2));
// one default model
modelBuilder = new ValidationModelBuilder();
modelBuilder.setApplicablePath("/content/site1");
ResourcePropertyBuilder propertyBuilder = new ResourcePropertyBuilder();
- propertyBuilder.validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 10, RegexValidator.REGEX_PARAM, "prefix.*");
+ propertyBuilder.validator("validatorId", 10, RegexValidator.REGEX_PARAM, "prefix.*");
ResourceProperty property = propertyBuilder.build("field1");
modelBuilder.resourceProperty(property);
@@ -230,7 +226,7 @@
createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel2", model2);
// check that both models are returned
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.containsInAnyOrder(model1, model2));
}
@@ -247,7 +243,7 @@
properties.remove("applicablePaths");
// check that both models are returned
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.containsInAnyOrder(model1));
}
@@ -262,7 +258,7 @@
createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// check that both models are returned
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.containsInAnyOrder(model1));
}
@@ -278,7 +274,7 @@
createValidationModelResource(rr, contentValidatorsRoot.getPath(), "testValidationModel1", model1);
// check that no model is found
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat("Model was placed outside resource resolver search path but still found", models, Matchers.empty());
} finally {
rr.delete(contentValidatorsRoot);
@@ -300,7 +296,7 @@
createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// compare both models
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model1));
}
@@ -316,7 +312,7 @@
createValidationModelResource(rr, appsValidatorsRoot.getPath(), "testValidationModel1", model2);
// only the apps model should be returned
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model2));
}
@@ -331,18 +327,7 @@
Resource resource = createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// make created model invalid by removing the properties sub resource
rr.delete(resource.getChild("properties"));
- modelProvider.getModels("sling/validation/test", validatorMap);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testGetValidationModelsWithInvalidValidatorId() throws Exception {
- // create one default model
- ValidationModel model1 = modelBuilder.build("sling/validation/test", libsValidatorsRoot.getPath() + "/testValidationModel1");
- createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
-
- // clear validator map to make the referenced validator unknown
- validatorMap.clear();
- modelProvider.getModels("sling/validation/test", validatorMap);
+ modelProvider.getModels("sling/validation/test");
}
@Test
@@ -355,11 +340,11 @@
validatorArguments.put("key2", "value1");
validatorArguments.put("key3", "value1=value2");
modelBuilder = new ValidationModelBuilder();
- modelBuilder.resourceProperty(new ResourcePropertyBuilder().validator(new ValidatorAndSeverity<String>(new RegexValidator(), 2), 10, validatorArguments).build("field1"));
+ modelBuilder.resourceProperty(new ResourcePropertyBuilder().validator("validatorId", 10, validatorArguments).build("field1"));
modelBuilder.addApplicablePath("content/site1");
ValidationModel model1 = modelBuilder.build("sling/validation/test", libsValidatorsRoot.getPath() + "/testValidationModel1");
createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model1));
}
@@ -370,10 +355,10 @@
// create valid model first
Resource modelResource = createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// and make parametrization of validator invalid afterwards
- Resource validatorResource = modelResource.getChild("properties/field1/validators/" + RegexValidator.class.getName());
+ Resource validatorResource = modelResource.getChild("properties/field1/validators/validatorId");
ModifiableValueMap validatorArguments = validatorResource.adaptTo(ModifiableValueMap.class);
validatorArguments.put("validatorArguments", "key1"); // value without "="
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model1));
}
@@ -384,10 +369,10 @@
// create valid model first
Resource modelResource = createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// and make parametrization of validator invalid afterwards
- Resource validatorResource = modelResource.getChild("properties/field1/validators/" + RegexValidator.class.getName());
+ Resource validatorResource = modelResource.getChild("properties/field1/validators/validatorId");
ModifiableValueMap validatorArguments = validatorResource.adaptTo(ModifiableValueMap.class);
validatorArguments.put("validatorArguments", "=value2"); // starting with "="
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model1));
}
@@ -398,10 +383,10 @@
// create valid model first
Resource modelResource = createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// and make parametrization of validator invalid afterwards
- Resource validatorResource = modelResource.getChild("properties/field1/validators/" + RegexValidator.class.getName());
+ Resource validatorResource = modelResource.getChild("properties/field1/validators/validatorId");
ModifiableValueMap validatorArguments = validatorResource.adaptTo(ModifiableValueMap.class);
validatorArguments.put("validatorArguments", "key1="); // ending with "="
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.contains(model1));
}
@@ -416,11 +401,11 @@
createValidationModelResource(rr, libsValidatorsRoot.getPath(), "testValidationModel1", model1);
// check that both models are returned
- Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models = modelProvider.getModels("sling/validation/test");
Assert.assertThat(models, Matchers.containsInAnyOrder(model1));
// the 2nd time the same instance should be returned
- Collection<ValidationModel> models2 = modelProvider.getModels("sling/validation/test", validatorMap);
+ Collection<ValidationModel> models2 = modelProvider.getModels("sling/validation/test");
Assert.assertEquals("Due to caching both models should be actually the same instance", System.identityHashCode(models), System.identityHashCode(models2));
}
@@ -485,22 +470,21 @@
Resource validators = ResourceUtil.getOrCreateResource(rr, propertyResource.getPath() + "/"
+ ResourceValidationModelProviderImpl.VALIDATORS, JcrConstants.NT_UNSTRUCTURED, null, true);
if (validators != null) {
- for (ParameterizedValidator validator : property.getValidators()) {
+ for (ValidatorInvocation validatorIncovation : property.getValidatorInvocations()) {
Map<String, Object> validatorProperties = new HashMap<String, Object>();
validatorProperties.put(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED);
- ValueMap parameters = validator.getParameters();
+ ValueMap parameters = validatorIncovation.getParameters();
if (!parameters.isEmpty()) {
// convert to right format
validatorProperties.put(ResourceValidationModelProviderImpl.VALIDATOR_ARGUMENTS,
convertMapToJcrValidatorArguments(parameters));
}
- Integer severity = validator.getSeverity();
+ Integer severity = validatorIncovation.getSeverity();
if (severity != null) {
validatorProperties.put(ResourceValidationModelProviderImpl.SEVERITY, severity);
}
- // TODO: get real validator id here!
ResourceUtil.getOrCreateResource(rr, validators.getPath() + "/"
- + validator.getValidator().getClass().getName(), validatorProperties, null, true);
+ + validatorIncovation.getValidatorId(), validatorProperties, null, true);
}
}
}