List of usage examples for org.springframework.validation Errors getNestedPath
String getNestedPath();
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 <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); } } }