/* * Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org * Use is subject to license terms. See license.txt. */ package org.beanfabrics.validation; import java.beans.PropertyChangeEvent; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.beanfabrics.AbstractBean; /** * The <code>Validator</code> is responsible for creating a * {@link ValidationState} by evaluating a list of {@link ValidationRule} * instances. <pM> It is a composite of validation rules. Rules can be added and * removed via the collection interface. <pM> A call to the {@link #validate()} * method is delegated to each validation rule in the order they have been * added, until the first not-<code>null</code> {@link ValidationState} is * returned. * * @author Michael Karneim * @see ValidationRule */ public class Validator extends AbstractBean implements Collection<ValidationRule>, ValidationRule { private final List<ValidationRule> rules = new LinkedList<ValidationRule>(); /** * Validates the current context. That context is invalid when at least one * validation rule detects an invalid state. Produces a * {@link ValidationState} by delegating this call to the validation rules * in the same order they have been added, until a not-null value is * returned. */ public ValidationState validate() { for (ValidationRule rule : this) { ValidationState state = rule.validate(); if (state != null) { return state; } } return null; } /** {@inheritDoc} */ public boolean add(ValidationRule o) { boolean result = rules.add(o); if (result) { fireChanged(); } return result; } /** * Inserts the specified rule at the specified position in this validator. * * @param index * @param o */ public void add(int index, ValidationRule o) { rules.add(index, o); fireChanged(); } /** {@inheritDoc} */ public boolean addAll(Collection<? extends ValidationRule> c) { boolean result = rules.addAll(c); if (result) { fireChanged(); } return result; } /** {@inheritDoc} */ public void clear() { if (!isEmpty()) { rules.clear(); fireChanged(); } } /** {@inheritDoc} */ public boolean contains(Object o) { return rules.contains(o); } /** {@inheritDoc} */ public boolean containsAll(Collection<?> c) { return rules.containsAll(c); } /** * Returns the rule at the specified position in this <code>Validator</code> * . * * @param index index of the rule to return * @return rule at the given index */ public ValidationRule get(int index) { return rules.get(index); } /** {@inheritDoc} */ public boolean isEmpty() { return rules.isEmpty(); } /** {@inheritDoc} */ public Iterator<ValidationRule> iterator() { return new Iterator<ValidationRule>() { Iterator<ValidationRule> delegate = rules.iterator(); public void remove() { delegate.remove(); fireChanged(); } public ValidationRule next() { return delegate.next(); } public boolean hasNext() { return delegate.hasNext(); } }; } /** {@inheritDoc} */ public boolean remove(Object o) { boolean result = rules.remove(o); if (result) { fireChanged(); } return result; } /** * Removes the rule at the specified position in this <code>Validator</code> * . * * @param index index of the rule to remove * @return removed rule from the given index */ public ValidationRule remove(int index) { int oldSize = this.size(); ValidationRule result = rules.remove(index); if (oldSize != this.size()) { fireChanged(); } return result; } /** {@inheritDoc} */ public boolean removeAll(Collection<?> c) { boolean result = rules.removeAll(c); if (result) { fireChanged(); } return result; } /** {@inheritDoc} */ public boolean retainAll(Collection<?> c) { boolean result = rules.retainAll(c); if (result) { fireChanged(); } return result; } /** {@inheritDoc} */ public int size() { return rules.size(); } /** {@inheritDoc} */ public Object[] toArray() { return rules.toArray(); } /** {@inheritDoc} */ public <T> T[] toArray(T[] a) { return rules.toArray(a); } /** * Fires a {@link PropertyChangeEvent} for the "rules" property. */ private void fireChanged() { this.getPropertyChangeSupport().firePropertyChange("rules", null, null); } }