I believe its well established that Struts would benefit from a good
validation framework (duh, right?). While there are a number of
really good ideas floating around, some seem to be introducing
unnecessary complexity (IMHO, of course)

Getting to the point, I think constrained properties from the
JavaBeans spec. provides a built in, flexible foundation for
struts invoked validation.
(http://java.sun.com/products/javabeans/docs/spec.html)

key advantages:
  * support is provided by the standard java.beans package
  * it doesn't require learning anything proprietary (even though
    other solutions are very cool :)
  * its conceptually simple; ie. before accepting a new value,
    the bean/ActionForm's setter method(s) ensures its accepted by
    all registered listeners before commiting the value
    (java.bean.VetoableChangeListenter).
  * and finally, its wide open for extension (key since we can't
    predict all validation scenario's, right?)

I also believe that integration with Struts could be pretty straight
forward. In a nutshell, we could make 2 modifications ActionServlet:

  1. Make it responsible for registering "change-listeners"
  2. Make it handle PropertyVetoException(s) thrown by setter methods
     (primarily by turning them into ActionErrors)

Prior to making a "formal" proposal for this, I thought it might be
useful to consider the attached code fragments:

Then again, maybe I'm way off and should be ignored- If I am,
let me know..

Regards,
Levi Cook





<struts-config>
  <!-- etc.. -->
  <form-bean name="myForm" type="MyForm">
    <change-listener 
        property="email" 
        type="RequiredEmailAddressValidator"
    />
  </form-bean>
  <!-- etc.. -->
</struts-config>
import java.beans.*

public class RequiredEmailAddressValidator implements VetoableChangeListener {
  public void vetoableChange(PropertyChangeEvent evt)
    throws PropertyVetoException
  {
    String email= null;
    boolean emptyOk= false;

    try {
      email= (String) evt.getNewValue();
    }
    finally {
      if(StringValidator.checkEmail(email, emptyOk) == false)
        throw new PropertyVetoException("some.msg.key", evt);
    }
  }
}
import org.apache.struts.action.ActionForm;
import java.beans.*;

public class MyForm extends ActionForm {
  private static final String EMAIL_PROP_NAME= "email";
  private String email;

  public String getEmailAddress() {
    return email;
  }

  public void setEmail(String newEmail)
    throws PropertyVetoException
  {
    vcs.fireVetoableChange(EMAIL_PROP_NAME, email, newEmail);
    email= newEmail;
  }

  private VetoableChangeSupport vcs=
    new VetoableChangeSupport(this);

  public void addEmailVetoableChangeListener(VetoableChangeListener lsnr) {
    vcs.addVetoableChangeListener(EMAIL_PROP_NAME, lsnr);
  }

  public void removeEmailVetoableChangeListener(VetoableChangeListener lsnr) {
    vcs.removeVetoableChangeListener(EMAIL_PROP_NAME, lsnr);
  }

}
import java.beans.*;

public class OptionalEmailAddressValidator implements VetoableChangeListener {
  public void vetoableChange(PropertyChangeEvent evt)
    throws PropertyVetoException
  {
    String email= null;
    boolean emptyOk= true;

    try {
      email= (String) evt.getNewValue();
    }
    finally {
      if(StringValidator.checkEmail(email, emptyOk) == false)
        throw new PropertyVetoException("some.msg.key", evt);
    }
  }
}
import org.apache.regexp.*;

public final class StringValidator {
  /**
   *  Check that String email is a valid email address.
   *  emptyOK=true indicates that an empty String is valid
   *  for this test.
   */
  public static boolean checkEmail(String email, boolean emptyOK) {
    if ((emptyOK == true) && (KRStringValidator.isEmpty(email)))
      return true;
    else if (StringValidator.isValidEmail(email))
      return true;
    else
      return false;
  }

  /**
   * Checks to see if a String is a valid email address.
   */
  public static boolean isValidEmail(String email) {
    if(email == null) return false;
    try {
      RE reEmail = new RE("^.+\\@.+\\..+$");
      if (reEmail.match(email) )
        return true;
      else
        return false;
    }
    catch(RESyntaxException e) {
      System.out.println(e);
      return false;
    }
  }

  /**
   * Checks to see if a String is null or all spaces.
   */
  public static boolean isEmpty(String s) {
    return ((s == null) || (s.trim().length() == 0));
  }

}

Reply via email to