private void validatePropertyValue()

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);
                    }
                }
            }
        }
    }