private <T> int validateParametersForGroup(ValidationContext<T> validationContext, Object[] parameterValues, Group group) {
int numberOfViolationsBefore = validationContext.getFailingConstraints().size();
BeanMetaData<T> beanMetaData = beanMetaDataManager.getBeanMetaData( validationContext.getRootBeanClass() );
ExecutableMetaData executableMetaData = beanMetaData.getMetaDataFor( validationContext.getExecutable() );
// TODO GM: define behavior with respect to redefined default sequences. Should only the
// sequence from the validated bean be honored or also default sequence definitions up in
// the inheritance tree?
// For now a redefined default sequence will only be considered if specified at the bean
// hosting the validated itself, but no other default sequence from parent types
List<Class<?>> groupList;
if ( group.isDefaultGroup() ) {
groupList = beanMetaData.getDefaultGroupSequence( validationContext.getRootBean() );
}
else {
groupList = Arrays.<Class<?>>asList( group.getDefiningClass() );
}
//the only case where we can have multiple groups here is a redefined default group sequence
for ( Class<?> currentValidatedGroup : groupList ) {
int numberOfViolationsOfCurrentGroup = 0;
ValueContext<T, Object> valueContext = getExecutableValueContext(
validationContext.getRootBean(), executableMetaData, currentValidatedGroup
);
valueContext.appendCrossParameterNode();
valueContext.setCurrentValidatedValue( parameterValues );
// 1. validate cross-parameter constraints
numberOfViolationsOfCurrentGroup += validateConstraintsForGroup(
validationContext, valueContext, executableMetaData.getCrossParameterConstraints()
);
if ( shouldFailFast( validationContext ) ) {
return validationContext.getFailingConstraints().size() - numberOfViolationsBefore;
}
valueContext = getExecutableValueContext(
validationContext.getRootBean(), executableMetaData, currentValidatedGroup
);
valueContext.setCurrentValidatedValue( parameterValues );
// 2. validate parameter constraints
for ( int i = 0; i < parameterValues.length; i++ ) {
PathImpl originalPath = valueContext.getPropertyPath();
ParameterMetaData parameterMetaData = executableMetaData.getParameterMetaData( i );
Object value = parameterValues[i];
if ( value != null ) {
Class<?> valueType = value.getClass();
if ( parameterMetaData.getType() instanceof Class && ( (Class<?>) parameterMetaData.getType() ).isPrimitive() ) {
valueType = ReflectionHelper.unBoxedType( valueType );
}
if ( !TypeHelper.isAssignable( parameterMetaData.getType(), valueType ) ) {
throw log.getParameterTypesDoNotMatchException(
valueType.getName(),
parameterMetaData.getType().toString(),
i,
validationContext.getExecutable().getMember()
);
}
}
valueContext.appendNode( executableMetaData.getParameterMetaData( i ) );
valueContext.setCurrentValidatedValue( value );
numberOfViolationsOfCurrentGroup += validateConstraintsForGroup(
validationContext, valueContext, parameterMetaData
);