001: package org.araneaframework.uilib.form.constraint;
002:
003: import java.util.Collection;
004: import java.util.HashSet;
005: import java.util.Set;
006: import org.araneaframework.Environment;
007: import org.araneaframework.uilib.form.Constraint;
008:
009: /**
010: * Constraint that reverses the contained {@link Constraint}—
011: * validating only when contained {@link Constraint} is invalid.
012: * When contained {@link Constraint} is valid, error message
013: * set with {@link Constraint#setCustomErrorMessage(String)} is produced.
014: *
015: * @author Taimo Peelo (taimo@araneaframework.org)
016: *
017: * @since 1.1
018: */
019: public class ReverseConstraint extends BaseConstraint {
020: protected Set localErrors = new HashSet();
021: protected Constraint toReverse;
022: protected ReverseConstraintErrorMessageFactory errorMessageFactory;
023:
024: /**
025: * @param toReverse {@link Constraint} to reverse
026: */
027: public ReverseConstraint(Constraint toReverse) {
028: this .toReverse = toReverse;
029: }
030:
031: /**
032: * @param toReverse {@link Constraint} to reverse
033: * @param customErrorMessage error message to produce when contained constraint <i>validates</i>.
034: */
035: public ReverseConstraint(Constraint toReverse,
036: String customErrorMessage) {
037: this (toReverse);
038: setCustomErrorMessage(customErrorMessage);
039: }
040:
041: public ReverseConstraint(Constraint toReverse,
042: ReverseConstraintErrorMessageFactory errorMessageFactory) {
043: this (toReverse);
044: this .errorMessageFactory = errorMessageFactory;
045: }
046:
047: /**
048: * @return {@link Constraint} reversed by this {@link ReverseConstraint}
049: */
050: public Constraint getConstraint() {
051: return toReverse;
052: }
053:
054: /**
055: * Can be used to produce reverse constraint validation error message, where
056: * {@link ReverseConstraint#setCustomErrorMessage(String)} or {@link ReverseConstraint#ReverseConstraint(Constraint, String)}
057: * do not suffice.
058: *
059: * @author Taimo Peelo (taimo@araneaframework.org)
060: */
061: public static interface ReverseConstraintErrorMessageFactory {
062: /**
063: * Should return validation errors for {@link ReverseConstraint} which did not validate.
064: * @param c ReverseConstraint which validation failed
065: * @return Collection<String> with constraint validation errors.
066: */
067: public Collection getErrorMessage(ReverseConstraint c);
068: }
069:
070: protected void validateConstraint() throws Exception {
071: toReverse.validate();
072: Set errors = toReverse.getErrors();
073: // Reverse constraint is invalid when wrapped constraint validates
074: if (errors.isEmpty()) {
075: if (customErrorMessage != null)
076: addError(customErrorMessage);
077: else if (errorMessageFactory != null)
078: addErrors(errorMessageFactory.getErrorMessage(this ));
079: else
080: addError("Reverse constraint validation failed for constraint "
081: + getConstraint()
082: + ". No details available because custom validation error message was not set.");
083: }
084: toReverse.clearErrors();
085: }
086:
087: public void clearErrors() {
088: toReverse.clearErrors();
089: localErrors.clear();
090: }
091:
092: protected void addError(String s) {
093: localErrors.add(s);
094: }
095:
096: public Set getErrors() {
097: return localErrors;
098: }
099:
100: public void setEnvironment(Environment environment) {
101: super.setEnvironment(environment);
102: toReverse.setEnvironment(environment);
103: }
104: }
|