Tuesday, November 1, 2011

Validation with pure Java - 2


First, let's create a class called BusinessObject with a simple numeric property. Next, I'll show how you can modify the property into a constrained one to see how it differs from the simple one.
public class BusinessObject {
  private int numericValue;
  public void setNumericValue(int newNumericValue) {
    numericValue = newNumericValue;
  }
  public int getNumericValue() {
    return numericValue;
  }
}
 Please note that the only property of this class will silently accept any value of the proper type. To make it constrained, a vetoable event needs to be produced and distributed to the consumers. A utility class called java.beans.VetoableChangeSupport was designed specifically to fulfill this set of responsibilities. A new class called ConstrainedObject will manage all the arrangements with this utility class, thereby being a good loving parent for the BusinessObject. Speaking of consumers, we need to build another custom class called Validator that hosts generic data-validation algorithms. It is going to be the only consumer of the vetoable events in our framework. This simplified approach deviates from the rules of the JavaBeans game (check JavaBeans API Specification for details), which requires presenting every constrained property as a bound one and providing support for handling multiple listeners. This deviation is perfectly acceptable, since you are not building a JavaBean here, but it's still worth mentioning.
import java.beans.*;
/**
 * The responsibility of the ConstrainedObject is to delegate generic data entry
 * validation responsibilities to the {@link Validator} and provide
 * subclasses with transparent interface to it.
 */
public class ConstrainedObject {
  private VetoableChangeSupport vetoableSupport = new VetoableChangeSupport(this);
  /**
   * Creates a new object with generic property validator
   */
  public ConstrainedObject() {
    vetoableSupport.addVetoableChangeListener(new Validator());
  }
  /**
   * This method will be used by subclasses to validate a new value in
   * the constrained properties of the int type. It can be easily overloaded
   * to deal with other primitive types as well.
   * @param propertyName The programmatic name of the property that is about to change.
   * @param oldValue The old value of the property.
   * @param newValue The new value of the property.
   */
  protected void validate(String propertyName, int oldValue, int newValue) throws PropertyVetoException {
    vetoableSupport.fireVetoableChange(propertyName, new Integer(oldValue), new Integer(newValue));
  }
}

No comments: