in src/main/java/org/apache/sling/validation/impl/ValidationServiceImpl.java [329:389]
private void validatePropertyValue(@NotNull String property, ValueMap valueMap, Resource resource, @NotNull String relativePath, @NotNull ResourceProperty resourceProperty, @NotNull CompositeValidationResult result, @NotNull ResourceBundle defaultResourceBundle) {
Object fieldValues = valueMap.get(property);
if (fieldValues == null) {
if (resourceProperty.isRequired()) {
result.addFailure(relativePath, configuration.defaultSeverity(), defaultResourceBundle, I18N_KEY_MISSING_REQUIRED_PROPERTY_WITH_NAME, property);
}
return;
}
List<ValidatorInvocation> validatorInvocations = resourceProperty.getValidatorInvocations();
if (resourceProperty.isMultiple()) {
if (!fieldValues.getClass().isArray()) {
result.addFailure(relativePath + property, configuration.defaultSeverity(), defaultResourceBundle, I18N_KEY_EXPECTED_MULTIVALUE_PROPERTY);
return;
}
}
for (ValidatorInvocation validatorInvocation : validatorInvocations) {
// lookup validator by id
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 = 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
type = Class.forName("[L"+type.getName()+";", false, type.getClassLoader());
} catch (ClassNotFoundException e) {
throw new SlingValidationException("Could not generate array class for type " + type, e);
}
}
// it is already validated here that the property exists in the value map
Object[] typedValue = (Object[])valueMap.get(property, type);
// 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, validatorMetadata.getType());
return;
}
// see https://issues.apache.org/jira/browse/SLING-662 for a description on how multivalue properties are treated with ValueMap
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, validatorMetadata.getValidator(), validatorInvocation.getParameters(), defaultResourceBundle, severity);
} else {
// call validate for each entry in the array (supports both singlevalue and multivalue)
@NotNull Object[] array = (Object[])typedValue;
if (array.length == 1) {
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, validatorMetadata.getValidator(), validatorInvocation.getParameters(), defaultResourceBundle, severity);
}
}
}
}
}