123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /*
- @VaadinApache2LicenseForJavaFiles@
- */
-
- package com.vaadin.data.validator;
-
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.List;
-
- import com.vaadin.data.Validator;
-
- /**
- * The <code>CompositeValidator</code> allows you to chain (compose) many
- * validators to validate one field. The contained validators may be required to
- * all validate the value to validate or it may be enough that one contained
- * validator validates the value. This behaviour is controlled by the modes
- * <code>AND</code> and <code>OR</code>.
- *
- * @author Vaadin Ltd.
- * @version @VERSION@
- * @since 3.0
- */
- @SuppressWarnings("serial")
- public class CompositeValidator implements Validator {
-
- public enum CombinationMode {
- /**
- * The validators are combined with <code>AND</code> clause: validity of
- * the composite implies validity of the all validators it is composed
- * of must be valid.
- */
- AND,
- /**
- * The validators are combined with <code>OR</code> clause: validity of
- * the composite implies that some of validators it is composed of must
- * be valid.
- */
- OR;
- }
-
- /**
- * @deprecated from 7.0, use {@link CombinationMode#AND} instead
- */
- @Deprecated
- public static final CombinationMode MODE_AND = CombinationMode.AND;
- /**
- * @deprecated from 7.0, use {@link CombinationMode#OR} instead
- */
- @Deprecated
- public static final CombinationMode MODE_OR = CombinationMode.OR;
-
- private String errorMessage;
-
- /**
- * Operation mode.
- */
- private CombinationMode mode = CombinationMode.AND;
-
- /**
- * List of contained validators.
- */
- private final List<Validator> validators = new LinkedList<Validator>();
-
- /**
- * Construct a composite validator in <code>AND</code> mode without error
- * message.
- */
- public CompositeValidator() {
- this(CombinationMode.AND, "");
- }
-
- /**
- * Constructs a composite validator in given mode.
- *
- * @param mode
- * @param errorMessage
- */
- public CompositeValidator(CombinationMode mode, String errorMessage) {
- setErrorMessage(errorMessage);
- setMode(mode);
- }
-
- /**
- * Validates the given value.
- * <p>
- * The value is valid, if:
- * <ul>
- * <li><code>MODE_AND</code>: All of the sub-validators are valid
- * <li><code>MODE_OR</code>: Any of the sub-validators are valid
- * </ul>
- *
- * If the value is invalid, validation error is thrown. If the error message
- * is set (non-null), it is used. If the error message has not been set, the
- * first error occurred is thrown.
- * </p>
- *
- * @param value
- * the value to check.
- * @throws Validator.InvalidValueException
- * if the value is not valid.
- */
- @Override
- public void validate(Object value) throws Validator.InvalidValueException {
- switch (mode) {
- case AND:
- for (Validator validator : validators) {
- validator.validate(value);
- }
- return;
-
- case OR:
- Validator.InvalidValueException first = null;
- for (Validator v : validators) {
- try {
- v.validate(value);
- return;
- } catch (final Validator.InvalidValueException e) {
- if (first == null) {
- first = e;
- }
- }
- }
- if (first == null) {
- return;
- }
- final String em = getErrorMessage();
- if (em != null) {
- throw new Validator.InvalidValueException(em);
- } else {
- throw first;
- }
- }
- }
-
- /**
- * Gets the mode of the validator.
- *
- * @return Operation mode of the validator: {@link CombinationMode#AND} or
- * {@link CombinationMode#OR}.
- */
- public final CombinationMode getMode() {
- return mode;
- }
-
- /**
- * Sets the mode of the validator. The valid modes are:
- * <ul>
- * <li>{@link CombinationMode#AND} (default)
- * <li>{@link CombinationMode#OR}
- * </ul>
- *
- * @param mode
- * the mode to set.
- */
- public void setMode(CombinationMode mode) {
- if (mode == null) {
- throw new IllegalArgumentException(
- "The validator can't be set to null");
- }
- this.mode = mode;
- }
-
- /**
- * Gets the error message for the composite validator. If the error message
- * is null, original error messages of the sub-validators are used instead.
- */
- public String getErrorMessage() {
- if (errorMessage != null) {
- return errorMessage;
- }
-
- // TODO Return composite error message
-
- return null;
- }
-
- /**
- * Adds validator to the interface.
- *
- * @param validator
- * the Validator object which performs validation checks on this
- * set of data field values.
- */
- public void addValidator(Validator validator) {
- if (validator == null) {
- return;
- }
- validators.add(validator);
- }
-
- /**
- * Removes a validator from the composite.
- *
- * @param validator
- * the Validator object which performs validation checks on this
- * set of data field values.
- */
- public void removeValidator(Validator validator) {
- validators.remove(validator);
- }
-
- /**
- * Gets sub-validators by class.
- *
- * <p>
- * If the component contains directly or recursively (it contains another
- * composite containing the validator) validators compatible with given type
- * they are returned. This only applies to <code>AND</code> mode composite
- * validators.
- * </p>
- *
- * <p>
- * If the validator is in <code>OR</code> mode or does not contain any
- * validators of given type null is returned.
- * </p>
- *
- * @param validatorType
- * The type of validators to return
- *
- * @return Collection<Validator> of validators compatible with given type
- * that must apply or null if none found.
- */
- public Collection<Validator> getSubValidators(Class validatorType) {
- if (mode != CombinationMode.AND) {
- return null;
- }
-
- final HashSet<Validator> found = new HashSet<Validator>();
- for (Validator v : validators) {
- if (validatorType.isAssignableFrom(v.getClass())) {
- found.add(v);
- }
- if (v instanceof CompositeValidator
- && ((CompositeValidator) v).getMode() == MODE_AND) {
- final Collection<Validator> c = ((CompositeValidator) v)
- .getSubValidators(validatorType);
- if (c != null) {
- found.addAll(c);
- }
- }
- }
-
- return found.isEmpty() ? null : found;
- }
-
- /**
- * Sets the message to be included in the exception in case the value does
- * not validate. The exception message is typically shown to the end user.
- *
- * @param errorMessage
- * the error message.
- */
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- }
|