Example usage for org.springframework.validation Errors getNestedPath

List of usage examples for org.springframework.validation Errors getNestedPath

Introduction

In this page you can find the example usage for org.springframework.validation Errors getNestedPath.

Prototype

String getNestedPath();

Source Link

Document

Return the current nested path of this Errors object.

Usage

From source file:org.sakaiproject.metaobj.utils.mvc.impl.ValidatorBase.java

protected void pushNestedPath(String newPath, Errors errors) {
    String currentPath = errors.getNestedPath();

    nestedPathStack.push(currentPath);//from ww  w.  jav a 2  s . co m

    errors.setNestedPath(currentPath + newPath);
}

From source file:com.epam.ta.reportportal.ws.validation.JaskonRequiredPropertiesValidator.java

@Override
public void validate(Object object, Errors errors) {
    for (Field field : collectFields(object.getClass())) {
        if (AnnotationUtils.isAnnotationDeclaredLocally(JsonInclude.class, field.getType())) {
            try {
                Object innerObject = Accessible.on(object).field(field).getValue();
                if (null != innerObject) {
                    errors.pushNestedPath(field.getName());
                    validate(innerObject, errors);
                }/* www.  j a  v a2s  .c  o m*/
            } catch (Exception e) {
                LOGGER.error("JaskonRequiredPropertiesValidator error: " + e.getMessage(), e);
                // do nothing
            }

        }
        if (field.isAnnotationPresent(JsonProperty.class)
                && field.getAnnotation(JsonProperty.class).required()) {
            String errorCode = new StringBuilder("NotNull.").append(field.getName()).toString();
            ValidationUtils.rejectIfEmpty(errors, field.getName(), errorCode, new Object[] { errorCode });
        }
    }
    if (errors.getNestedPath() != null && errors.getNestedPath().length() != 0) {
        errors.popNestedPath();
    }
}

From source file:org.springmodules.validation.bean.BeanValidator.java

/**
 * Applies the global validation rules as listed in the given validation configuration on the given object, and
 * registering all global validation errors with the given {@link Errors}.
 *
 * @param configuration The bean validation configuration that holds all the global validation rules.
 * @param obj The validated object.// ww w  . ja v a  2  s  . co m
 * @param errors The {@link Errors} instance where all global validation errors will be registered.
 */
protected void applyGlobalValidationRules(BeanValidationConfiguration configuration, Object obj,
        Errors errors) {
    ValidationRule[] globalRules = configuration.getGlobalRules();
    for (int i = 0; i < globalRules.length; i++) {
        ValidationRule rule = globalRules[i];
        if (rule.isApplicable(obj) && !rule.getCondition().check(obj)) {
            String errorCode = errorCodeConverter.convertGlobalErrorCode(rule.getErrorCode(), obj.getClass());

            // if there is a nested path in errors, the global errors should be registered as field errors
            // for the nested path. Otherwise, they should be registered as global errors. Starting from Spring 2.0-rc2
            // this is actually not required - it's just enough to call rejectValue() with null as the field name,
            // but we keep this implementation for now to support earlier versions.

            if (StringUtils.hasLength(errors.getNestedPath())) {
                String nestedPath = errors.getNestedPath();
                String propertyName = nestedPath.substring(0, nestedPath.length() - 1);
                errors.popNestedPath();
                errors.rejectValue(propertyName, errorCode, rule.getErrorArguments(obj),
                        rule.getDefaultErrorMessage());
                errors.pushNestedPath(propertyName);
            } else {
                errors.reject(errorCode, rule.getErrorArguments(obj), rule.getDefaultErrorMessage());
            }
        }
    }
}

From source file:org.codehaus.groovy.grails.validation.AbstractConstraint.java

public void rejectValueWithDefaultMessage(Object target, Errors errors, String defaultMessage, String[] codes,
        Object[] args) {//from   www .j av a  2  s .  c  o m
    BindingResult result = (BindingResult) errors;
    Set<String> newCodes = new LinkedHashSet<String>();

    if (args.length > 1 && messageSource != null) {
        if ((args[0] instanceof String) && (args[1] instanceof Class<?>)) {
            final Locale locale = LocaleContextHolder.getLocale();
            final Class<?> constrainedClass = (Class<?>) args[1];
            final String fullClassName = constrainedClass.getName();

            String classNameCode = fullClassName + ".label";
            String resolvedClassName = messageSource.getMessage(classNameCode, null, fullClassName, locale);
            final String classAsPropertyName = GrailsNameUtils.getPropertyName(constrainedClass);

            if (resolvedClassName.equals(fullClassName)) {
                // try short version
                classNameCode = classAsPropertyName + ".label";
                resolvedClassName = messageSource.getMessage(classNameCode, null, fullClassName, locale);
            }

            // update passed version
            if (!resolvedClassName.equals(fullClassName)) {
                args[1] = resolvedClassName;
            }

            String propertyName = (String) args[0];
            String propertyNameCode = fullClassName + '.' + propertyName + ".label";
            String resolvedPropertyName = messageSource.getMessage(propertyNameCode, null, propertyName,
                    locale);
            if (resolvedPropertyName.equals(propertyName)) {
                propertyNameCode = classAsPropertyName + '.' + propertyName + ".label";
                resolvedPropertyName = messageSource.getMessage(propertyNameCode, null, propertyName, locale);
            }

            // update passed version
            if (!resolvedPropertyName.equals(propertyName)) {
                args[0] = resolvedPropertyName;
            }
        }
    }

    //Qualified class name is added first to match before unqualified class (which is still resolved for backwards compatibility)
    newCodes.addAll(Arrays.asList(result.resolveMessageCodes(
            constraintOwningClass.getName() + '.' + constraintPropertyName + '.' + getName() + ".error",
            constraintPropertyName)));
    newCodes.addAll(Arrays.asList(result.resolveMessageCodes(
            classShortName + '.' + constraintPropertyName + '.' + getName() + ".error",
            constraintPropertyName)));
    for (String code : codes) {
        newCodes.addAll(Arrays.asList(result.resolveMessageCodes(
                constraintOwningClass.getName() + '.' + constraintPropertyName + '.' + code,
                constraintPropertyName)));
        newCodes.addAll(Arrays.asList(result.resolveMessageCodes(
                classShortName + '.' + constraintPropertyName + '.' + code, constraintPropertyName)));
        //We resolve the error code on it's own last so that a global code doesn't override a class/field specific error
        newCodes.addAll(Arrays.asList(result.resolveMessageCodes(code, constraintPropertyName)));
    }

    FieldError error = new FieldError(errors.getObjectName(), errors.getNestedPath() + constraintPropertyName,
            getPropertyValue(errors, target), false, newCodes.toArray(new String[newCodes.size()]), args,
            defaultMessage);
    ((BindingResult) errors).addError(error);
}

From source file:org.springjutsu.validation.ValidationManager.java

/**
 * Responsible for testing all XML-defined per-class model rules.
 * We will check recursively: using a BeanWrapper to get a 
 * @link(PropertyDescriptor) for each field, and then checking to
 * see if any of the fields are supported by validation rules.
 * If so, we will test those nested paths using that class's
 * model rules as well. This ensures that sub beans are properly
 * validated using their standard model rules.
 * @param model the model object to validate. May be a recursed sub bean.
 * @param errors standard Errors object to record validation errors to.
 * @param checkedModels A list of model objects we have already validated,
 *    in order to prevent unneeded or infinite recursion
 *//*  ww w .  j  a  va 2  s.  c  o  m*/
protected void validateModelRules(Object model, Errors errors, List<Object> checkedModels) {
    if (model == null) {
        return;
    }

    BeanWrapperImpl beanWrapper = new BeanWrapperImpl(model);
    Object validateMe = null;
    String beanPath = appendPath(errors.getNestedPath(), "");

    // get sub bean to validate
    if (beanPath.isEmpty()) {
        validateMe = model;
    } else {
        validateMe = beanWrapper.getPropertyValue(beanPath);
    }

    //TODO: Refactor and re-enable recursion check
    // Infinite recursion check
    if (validateMe == null) {
        return;
        //      } else {
        //         checkedModels.add(validateMe.hashCode());
    }

    List<ValidationRule> modelRules = rulesContainer.getModelRules(validateMe.getClass());
    callModelRules(model, errors, modelRules);

    // Get fields for subbeans and iterate
    BeanWrapperImpl subBeanWrapper = new BeanWrapperImpl(validateMe);
    PropertyDescriptor[] propertyDescriptors = subBeanWrapper.getPropertyDescriptors();
    for (PropertyDescriptor property : propertyDescriptors) {
        if (rulesContainer.supportsClass(property.getPropertyType())) {
            errors.pushNestedPath(property.getName());
            validateModelRules(model, errors, checkedModels);
            errors.popNestedPath();
        } else if (List.class.isAssignableFrom(property.getPropertyType())
                || property.getPropertyType().isArray()) {
            Object potentialList = subBeanWrapper.getPropertyValue(property.getName());
            List list = (List) (property.getPropertyType().isArray() && potentialList != null
                    ? Arrays.asList(potentialList)
                    : potentialList);

            if (list == null || list.isEmpty()) {
                continue;
            } else if (list.get(0) == null || !supports(list.get(0).getClass())) {
                continue;
            }

            for (int i = 0; i < list.size(); i++) {
                errors.pushNestedPath(property.getName() + "[" + i + "]");
                validateModelRules(model, errors, checkedModels);
                errors.popNestedPath();
            }
        }
    }
}

From source file:org.springjutsu.validation.ValidationManager.java

/**
 * Responsible for delegating each actual model rule
 *  to the appropriate @link{RuleExecutor}.
 *  Errors are recorded if no previous error has been
 *  recorded for the given path.//from w w w.  j a  v a2 s.com
 * @param model The object being validated
 * @param errors Standard errors object to record validation errors.
 * @param modelRules A list of ValidationRules parsed from
 *  the &lt;model-rules> section of the validation XML.
 */
protected void callModelRules(Object model, Errors errors, List<ValidationRule> modelRules) {
    if (modelRules == null) {
        return;
    }
    for (ValidationRule rule : modelRules) {

        // get full path to current model
        String fullPath = appendPath(errors.getNestedPath(), rule.getPath());

        // if this field is not on the page we're checking,
        // or the field already has errors, skip it.   
        //TODO: refactor this out into another method or provider class that can be made configurable
        boolean containedInRequestParams = false;
        for (Object key : RequestUtils.getRequestParameters().keySet()) {
            if (key instanceof String
                    && (key.equals(fullPath) || ((String) key).replaceAll("\\(.*\\)", "").equals(fullPath))) {
                containedInRequestParams = true;
            }
        }

        if (!rule.isValidateWhenNotInRequest() && !fullPath.isEmpty() && !containedInRequestParams
                || errors.hasFieldErrors(rule.getPath())) {
            continue;
        }

        // update rule for full path
        ValidationRule modelRule = rule.cloneWithPath(fullPath);

        if (passes(modelRule, model)) {
            // If the rule passes and it has children,
            // it is a condition for nested elements.
            // Call children instead.
            if (modelRule.hasChildren()) {
                callModelRules(model, errors, modelRule.getRules());
            }
        } else {
            // If the rule fails and it has children,
            // it is a condition for nested elements.
            // Skip nested elements.
            if (modelRule.hasChildren()) {
                continue;
            } else {
                // If the rule has no children and fails,
                // perform fail action.
                logError(modelRule, model, errors);
            }
        }
    }
}

From source file:org.springjutsu.validation.ValidationManager.java

/**
 * In the event that a validation rule fails, this method is responsible
 * for recording an error message on the affected path of the Errors object.
 * The error message is gathered in three parts:
 * First the base message, if not provided is based on the rule executor class.
 * This is a message like "\{0} should be longer than \{1} chars."
 * Next, the first argument \{0} is the model descriptor. This will resolve to a 
 * label for the path that failed, based on second to last path subBean and the
 * field that failed. So, if "account.accountOwner.username" had an error, 
 * it would look for a message based on the class name of accountOwner, and the
 * field username: like "user.username". If the message files contained a 
 * "user.username=User name", then the message would now read something like
 * "User name should be longer than \{1} chars." 
 * Finally, the argument is resolved. /*  w  w w.  j  a  v  a  2  s  .  c o  m*/
 * If the argument is just a flat string, like "16", then you would get 
 * "User name should be longer than 16 chars."
 * If the argument contained EL that resolved on the model, it would perform
 * the same model lookup detailed above, so you could potentially have something 
 * like "User name should be longer than First name", which is a bit weird, but
 * has its uses.
 * For either the model or argument lookup, if EL is used in the path 
 * which resolves off the model, the literal value of the evaluated 
 * EL expression is used.
 * @param rule the rule which failed
 * @param rootModel the root model (not failed bean)
 * @param errors standard Errors object to record error on.
 */
protected void logError(ValidationRule rule, Object rootModel, Errors errors) {
    String errorMessageKey = rule.getMessage();
    if (errorMessageKey == null || errorMessageKey.isEmpty()) {
        errorMessageKey = errorMessagePrefix + rule.getType();
    }

    String defaultError = rule.getPath() + " " + rule.getType();
    String modelMessageKey = getMessageResolver(rootModel, rule.getPath(), true);
    String ruleArg = getMessageResolver(rootModel, rule.getValue(), false);

    MessageSourceResolvable modelMessageResolvable = new DefaultMessageSourceResolvable(
            new String[] { modelMessageKey }, modelMessageKey);
    MessageSourceResolvable argumentMessageResolvable = new DefaultMessageSourceResolvable(
            new String[] { ruleArg }, ruleArg);

    // get the local path to error, in case errors object is on nested path.
    String errorMessagePath = rule.getErrorPath();
    if (errorMessagePath == null || errorMessagePath.isEmpty()) {
        errorMessagePath = rule.getPath();
    }
    if (!errors.getNestedPath().isEmpty() && errorMessagePath.startsWith(errors.getNestedPath())) {
        errorMessagePath = appendPath(errorMessagePath.substring(errors.getNestedPath().length()), "");
    }

    errors.rejectValue(errorMessagePath, errorMessageKey,
            new Object[] { modelMessageResolvable, argumentMessageResolvable }, defaultError);
}

From source file:org.springmodules.validation.bean.BeanValidator.java

/**
 * The heart of this validator. This is a recursive method that validates the given object (object) under the
 * context of the given object graph root (root). The validation rules to be applied are loaded using the
 * configured {@link org.springmodules.validation.bean.conf.loader.BeanValidationConfigurationLoader}. All errors are registered with the given {@link Errors}
 * object under the context of the object graph root.
 *
 * @param root The root of the object graph.
 * @param obj The object to be validated
 * @param errors The {@link Errors} instance where the validation errors will be registered.
 * @param validatedObjects keeps track of all the validated objects (to prevent revalidating the same objects when
 *        a circular relationship exists).
 *//*from  w  w  w .  ja v a2s .co  m*/
protected void validateObjectGraphConstraints(Object root, Object obj, Errors errors, Set validatedObjects) {

    // cannot load any validation rules for null values
    if (obj == null) {
        return;
    }

    // if this object was already validated, the skipping this valiation.
    if (validatedObjects.contains(obj)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Skipping validation of object in path '" + errors.getObjectName()
                    + "' for it was already validated");
        }
        return;
    }

    if (logger.isDebugEnabled()) {
        logger.debug("Validating object in path '" + errors.getNestedPath() + "'");
    }

    // loading the bean validation configuration based on the validated object class.
    Class clazz = obj.getClass();
    BeanValidationConfiguration configuration = configurationLoader.loadConfiguration(clazz);

    if (configuration == null) {
        return; // no validation configuration for this object, then there's nothing to validate.
    }

    // applying all the validation rules for the object and registering the object as "validated"
    applyBeanValidation(configuration, obj, errors);
    validatedObjects.add(obj);

    // after all the validation rules where applied, checking what properties of the object require their own
    // validation and recursively calling this method on them.
    CascadeValidation[] cascadeValidations = configuration.getCascadeValidations();
    BeanWrapper wrapper = wrapBean(obj);
    for (int i = 0; i < cascadeValidations.length; i++) {
        CascadeValidation cascadeValidation = cascadeValidations[i];
        Condition applicabilityCondition = cascadeValidation.getApplicabilityCondition();

        if (!applicabilityCondition.check(obj)) {
            continue;
        }

        String propertyName = cascadeValidation.getPropertyName();
        Class propertyType = wrapper.getPropertyType(propertyName);
        Object propertyValue = wrapper.getPropertyValue(propertyName);

        // if the property value is not there nothing to validate.
        if (propertyValue == null) {
            continue;
        }

        // if the property is an array of a collection, then iterating on it and validating each element. Note that
        // the error codes that are registered for arrays/collection elements follow the pattern supported by
        // spring's PropertyAccessor. Also note that just before each recursive call, the context of the validation
        // is appropriately adjusted using errors.pushNestedPath(...), and after each call it is being adjusted back
        // using errors.popNestedPath().
        if (propertyType.isArray()) {
            validateArrayProperty(root, propertyValue, propertyName, errors, validatedObjects);
        } else if (List.class.isAssignableFrom(propertyType) || Set.class.isAssignableFrom(propertyType)) {
            validateListOrSetProperty(root, (Collection) propertyValue, propertyName, errors, validatedObjects);
        } else if (Map.class.isAssignableFrom(propertyType)) {
            validateMapProperty(root, ((Map) propertyValue), propertyName, errors, validatedObjects);
        } else {
            // if the object is just a normal object (not an array or a collection), then applying its
            // validation rules.
            validatedSubBean(root, propertyValue, propertyName, errors, validatedObjects);
        }
    }
}