123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
-
- package com.itmill.toolkit.data.validator;
-
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.LinkedList;
-
- import com.itmill.toolkit.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 IT Mill Ltd.
- * @version
- * @VERSION@
- * @since 3.0
- */
- public class CompositeValidator implements Validator {
-
- /**
- * 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.
- */
- public static final int MODE_AND = 0;
-
- /**
- * 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.
- */
- public static final int MODE_OR = 1;
-
- /**
- * The validators are combined with and clause: validity of the composite
- * implies validity of the all validators it is composed of
- */
- public static final int MODE_DEFAULT = MODE_AND;
-
- /**
- * Operation mode.
- */
- private int mode = MODE_DEFAULT;
-
- /**
- * List of contained validators.
- */
- private final LinkedList validators = new LinkedList();
-
- /**
- * Error message.
- */
- private String errorMessage;
-
- /**
- * Construct a composite validator in <code>AND</code> mode without error
- * message.
- */
- public CompositeValidator() {
- }
-
- /**
- * Constructs a composite validator in given mode.
- */
- public CompositeValidator(int mode, String errorMessage) {
- setMode(mode);
- setErrorMessage(errorMessage);
- }
-
- /**
- * 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.
- */
- public void validate(Object value) throws Validator.InvalidValueException {
- switch (mode) {
- case MODE_AND:
- for (final Iterator i = validators.iterator(); i.hasNext();) {
- ((Validator) i.next()).validate(value);
- }
- return;
-
- case MODE_OR:
- Validator.InvalidValueException first = null;
- for (final Iterator i = validators.iterator(); i.hasNext();) {
- try {
- ((Validator) i.next()).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;
- }
- }
- throw new IllegalStateException(
- "The validator is in unsupported operation mode");
- }
-
- /**
- * Checks the validity of the the given value. 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>
- *
- * @param value
- * the value to check.
- */
- public boolean isValid(Object value) {
- switch (mode) {
- case MODE_AND:
- for (final Iterator i = validators.iterator(); i.hasNext();) {
- final Validator v = (Validator) i.next();
- if (!v.isValid(value)) {
- return false;
- }
- }
- return true;
-
- case MODE_OR:
- for (final Iterator i = validators.iterator(); i.hasNext();) {
- final Validator v = (Validator) i.next();
- if (v.isValid(value)) {
- return true;
- }
- }
- return false;
- }
- throw new IllegalStateException(
- "The valitor is in unsupported operation mode");
- }
-
- /**
- * Gets the mode of the validator.
- *
- * @return Operation mode of the validator: <code>MODE_AND</code> or
- * <code>MODE_OR</code>.
- */
- public final int getMode() {
- return mode;
- }
-
- /**
- * Sets the mode of the validator. The valid modes are:
- * <ul>
- * <li><code>MODE_AND</code> (default)
- * <li><code>MODE_OR</code>
- * </ul>
- *
- * @param mode
- * the mode to set.
- */
- public void setMode(int mode) {
- if (mode != MODE_AND && mode != MODE_OR) {
- throw new IllegalArgumentException("Mode " + mode + " unsupported");
- }
- 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;
- }
-
- /**
- * Sets the error message for the composite validator. If the error message
- * is null, original error messages of the sub-validators are used instead.
- *
- * @param errorMessage
- * the Error Message to set.
- */
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- /**
- * 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>
- *
- * @return Collection of validators compatible with given type that must
- * apply or null if none fould.
- */
- public Collection getSubValidators(Class validatorType) {
- if (mode != MODE_AND) {
- return null;
- }
-
- final HashSet found = new HashSet();
- for (final Iterator i = validators.iterator(); i.hasNext();) {
- final Validator v = (Validator) i.next();
- if (validatorType.isAssignableFrom(v.getClass())) {
- found.add(v);
- }
- if (v instanceof CompositeValidator
- && ((CompositeValidator) v).getMode() == MODE_AND) {
- final Collection c = ((CompositeValidator) v)
- .getSubValidators(validatorType);
- if (c != null) {
- found.addAll(c);
- }
- }
- }
-
- return found.isEmpty() ? null : found;
- }
-
- }
|