/*
 * Hibernate Validator, declare and validate application constraints
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package org.hibernate.validator.internal.engine;

import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.validator.internal.metadata.aggregated.rule.MethodConfigurationRule;
import org.hibernate.validator.internal.metadata.aggregated.rule.OverridingMethodMustNotAlterParameterConstraints;
import org.hibernate.validator.internal.metadata.aggregated.rule.ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue;
import org.hibernate.validator.internal.metadata.aggregated.rule.ParallelMethodsMustNotDefineParameterConstraints;
import org.hibernate.validator.internal.metadata.aggregated.rule.ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine;
import org.hibernate.validator.internal.metadata.aggregated.rule.VoidMethodsMustNotBeReturnValueConstrained;
import org.hibernate.validator.internal.util.CollectionHelper;
import org.hibernate.validator.internal.util.stereotypes.Immutable;

These properties modify the behavior of the Validator with respect to the Bean Validation specification section 5.6.5. In particular:
"Out of the box, a conforming Bean Validation provider must throw a
ConstraintDeclarationException when discovering that any of these rules are violated.
In addition providers may implement alternative, potentially more liberal, approaches
for handling constrained methods in inheritance hierarchies. Possible means for activating
such alternative behavior include provider-specific configuration properties or annotations.
Note that client code relying on such alternative behavior is not portable between Bean
Validation providers."
Author:Chris Beckey <cbeckey@paypal.com>, Guillaume Smet
/** * These properties modify the behavior of the {@code Validator} with respect to the Bean Validation * specification section 5.6.5. In particular: * <pre> * "Out of the box, a conforming Bean Validation provider must throw a * ConstraintDeclarationException when discovering that any of these rules are violated. * In addition providers may implement alternative, potentially more liberal, approaches * for handling constrained methods in inheritance hierarchies. Possible means for activating * such alternative behavior include provider-specific configuration properties or annotations. * Note that client code relying on such alternative behavior is not portable between Bean * Validation providers." * </pre> * * @author Chris Beckey &lt;cbeckey@paypal.com&gt; * @author Guillaume Smet */
public class MethodValidationConfiguration { private boolean allowOverridingMethodAlterParameterConstraint = false; private boolean allowMultipleCascadedValidationOnReturnValues = false; private boolean allowParallelMethodsDefineParameterConstraints = false; @Immutable private Set<MethodConfigurationRule> configuredRuleSet; private MethodValidationConfiguration(boolean allowOverridingMethodAlterParameterConstraint, boolean allowMultipleCascadedValidationOnReturnValues, boolean allowParallelMethodsDefineParameterConstraints) { this.allowOverridingMethodAlterParameterConstraint = allowOverridingMethodAlterParameterConstraint; this.allowMultipleCascadedValidationOnReturnValues = allowMultipleCascadedValidationOnReturnValues; this.allowParallelMethodsDefineParameterConstraints = allowParallelMethodsDefineParameterConstraints; this.configuredRuleSet = buildConfiguredRuleSet( allowOverridingMethodAlterParameterConstraint, allowMultipleCascadedValidationOnReturnValues, allowParallelMethodsDefineParameterConstraints ); }
Returns:true if more than one return value within a class hierarchy can be marked for cascaded validation, false otherwise.
/** * @return {@code true} if more than one return value within a class hierarchy can be marked for cascaded * validation, {@code false} otherwise. */
public boolean isAllowOverridingMethodAlterParameterConstraint() { return this.allowOverridingMethodAlterParameterConstraint; }
Returns:true if more than one return value within a class hierarchy can be marked for cascaded validation, false otherwise.
/** * @return {@code true} if more than one return value within a class hierarchy can be marked for cascaded * validation, {@code false} otherwise. */
public boolean isAllowMultipleCascadedValidationOnReturnValues() { return this.allowMultipleCascadedValidationOnReturnValues; }
Returns:true if constraints on methods in parallel class hierarchy are allowed, false otherwise.
/** * @return {@code true} if constraints on methods in parallel class hierarchy are allowed, {@code false} otherwise. */
public boolean isAllowParallelMethodsDefineParameterConstraints() { return this.allowParallelMethodsDefineParameterConstraints; }
Return an unmodifiable Set of MethodConfigurationRule that are to be enforced based on the configuration.
Returns:a set of method configuration rules based on this configuration state
/** * Return an unmodifiable Set of MethodConfigurationRule that are to be * enforced based on the configuration. * * @return a set of method configuration rules based on this configuration state */
public Set<MethodConfigurationRule> getConfiguredRuleSet() { return configuredRuleSet; } private static Set<MethodConfigurationRule> buildConfiguredRuleSet(boolean allowOverridingMethodAlterParameterConstraint, boolean allowMultipleCascadedValidationOnReturnValues, boolean allowParallelMethodsDefineParameterConstraints) { HashSet<MethodConfigurationRule> result = newHashSet( 5 ); if ( !allowOverridingMethodAlterParameterConstraint ) { result.add( new OverridingMethodMustNotAlterParameterConstraints() ); } if ( !allowParallelMethodsDefineParameterConstraints ) { result.add( new ParallelMethodsMustNotDefineParameterConstraints() ); } result.add( new VoidMethodsMustNotBeReturnValueConstrained() ); if ( !allowMultipleCascadedValidationOnReturnValues ) { result.add( new ReturnValueMayOnlyBeMarkedOnceAsCascadedPerHierarchyLine() ); } result.add( new ParallelMethodsMustNotDefineGroupConversionForCascadedReturnValue() ); return CollectionHelper.toImmutableSet( result ); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ( allowMultipleCascadedValidationOnReturnValues ? 1231 : 1237 ); result = prime * result + ( allowOverridingMethodAlterParameterConstraint ? 1231 : 1237 ); result = prime * result + ( allowParallelMethodsDefineParameterConstraints ? 1231 : 1237 ); return result; } @Override public boolean equals(Object obj) { if ( this == obj ) { return true; } if ( obj == null ) { return false; } if ( getClass() != obj.getClass() ) { return false; } MethodValidationConfiguration other = (MethodValidationConfiguration) obj; if ( allowMultipleCascadedValidationOnReturnValues != other.allowMultipleCascadedValidationOnReturnValues ) { return false; } if ( allowOverridingMethodAlterParameterConstraint != other.allowOverridingMethodAlterParameterConstraint ) { return false; } if ( allowParallelMethodsDefineParameterConstraints != other.allowParallelMethodsDefineParameterConstraints ) { return false; } return true; } public static class Builder { private boolean allowOverridingMethodAlterParameterConstraint = false; private boolean allowMultipleCascadedValidationOnReturnValues = false; private boolean allowParallelMethodsDefineParameterConstraints = false; public Builder() { } public Builder(MethodValidationConfiguration template) { allowOverridingMethodAlterParameterConstraint = template.allowOverridingMethodAlterParameterConstraint; allowMultipleCascadedValidationOnReturnValues = template.allowMultipleCascadedValidationOnReturnValues; allowParallelMethodsDefineParameterConstraints = template.allowParallelMethodsDefineParameterConstraints; }
Define whether overriding methods that override constraints should throw a ConstraintDefinitionException. The default value is false, i.e. do not allow. See Section 5.6.5 of the JSR-380 Specification, specifically
"In sub types (be it sub classes/interfaces or interface implementations), no parameter constraints may
be declared on overridden or implemented methods, nor may parameters be marked for cascaded validation.
This would pose a strengthening of preconditions to be fulfilled by the caller."
Params:
  • allow – flag determining whether validation will allow overriding to alter parameter constraints.
Returns:this following the chaining method pattern
/** * Define whether overriding methods that override constraints should throw a {@code ConstraintDefinitionException}. * The default value is {@code false}, i.e. do not allow. * * See Section 5.6.5 of the JSR-380 Specification, specifically * <pre> * "In sub types (be it sub classes/interfaces or interface implementations), no parameter constraints may * be declared on overridden or implemented methods, nor may parameters be marked for cascaded validation. * This would pose a strengthening of preconditions to be fulfilled by the caller." * </pre> * * @param allow flag determining whether validation will allow overriding to alter parameter constraints. * * @return {@code this} following the chaining method pattern */
public Builder allowOverridingMethodAlterParameterConstraint(boolean allow) { this.allowOverridingMethodAlterParameterConstraint = allow; return this; }
Define whether more than one constraint on a return value may be marked for cascading validation are allowed. The default value is false, i.e. do not allow. "One must not mark a method return value for cascaded validation more than once in a line of a class hierarchy. In other words, overriding methods on sub types (be it sub classes/interfaces or interface implementations) cannot mark the return value for cascaded validation if the return value has already been marked on the overridden method of the super type or interface."
Params:
  • allow – flag determining whether validation will allow multiple cascaded validation on return values.
Returns:this following the chaining method pattern
/** * Define whether more than one constraint on a return value may be marked for cascading validation are allowed. * The default value is {@code false}, i.e. do not allow. * * "One must not mark a method return value for cascaded validation more than once in a line of a class hierarchy. * In other words, overriding methods on sub types (be it sub classes/interfaces or interface implementations) * cannot mark the return value for cascaded validation if the return value has already been marked on the * overridden method of the super type or interface." * * @param allow flag determining whether validation will allow multiple cascaded validation on return values. * * @return {@code this} following the chaining method pattern */
public Builder allowMultipleCascadedValidationOnReturnValues(boolean allow) { this.allowMultipleCascadedValidationOnReturnValues = allow; return this; }
Define whether parallel methods that define constraints should throw a ConstraintDefinitionException. The default value is false, i.e. do not allow. See Section 5.6.5 of the JSR-380 Specification, specifically "If a sub type overrides/implements a method originally defined in several parallel types of the hierarchy (e.g. two interfaces not extending each other, or a class and an interface not implemented by said class), no parameter constraints may be declared for that method at all nor parameters be marked for cascaded validation. This again is to avoid an unexpected strengthening of preconditions to be fulfilled by the caller."
Params:
  • allow – flag determining whether validation will allow parameter constraints in parallel hierarchies
Returns:this following the chaining method pattern
/** * Define whether parallel methods that define constraints should throw a {@code ConstraintDefinitionException}. The * default value is {@code false}, i.e. do not allow. * * See Section 5.6.5 of the JSR-380 Specification, specifically * "If a sub type overrides/implements a method originally defined in several parallel types of the hierarchy * (e.g. two interfaces not extending each other, or a class and an interface not implemented by said class), * no parameter constraints may be declared for that method at all nor parameters be marked for cascaded validation. * This again is to avoid an unexpected strengthening of preconditions to be fulfilled by the caller." * * @param allow flag determining whether validation will allow parameter constraints in parallel hierarchies * * @return {@code this} following the chaining method pattern */
public Builder allowParallelMethodsDefineParameterConstraints(boolean allow) { this.allowParallelMethodsDefineParameterConstraints = allow; return this; } public boolean isAllowOverridingMethodAlterParameterConstraint() { return allowOverridingMethodAlterParameterConstraint; } public boolean isAllowMultipleCascadedValidationOnReturnValues() { return allowMultipleCascadedValidationOnReturnValues; } public boolean isAllowParallelMethodsDefineParameterConstraints() { return allowParallelMethodsDefineParameterConstraints; } public MethodValidationConfiguration build() { return new MethodValidationConfiguration( allowOverridingMethodAlterParameterConstraint, allowMultipleCascadedValidationOnReturnValues, allowParallelMethodsDefineParameterConstraints ); } } }