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() );
if ( parameterValues.length != executableMetaData.getParameterTypes().length ) {
throw log.getInvalidParameterCountForExecutableException(
ExecutableElement.getExecutableAsString(
executableMetaData.getType().toString() + "#" + executableMetaData.getName(),
executableMetaData.getParameterTypes()
), parameterValues.length, executableMetaData.getParameterTypes().length
);
}
// 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() ) {