XValidationHandler.java :  » XML-UI » XUI » net » xoetrope » xui » validation » Java Open Source

Java Open Source » XML UI » XUI 
XUI » net » xoetrope » xui » validation » XValidationHandler.java
package net.xoetrope.xui.validation;

import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.FocusEvent;

import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xui.XEventHandler;
import net.xoetrope.xui.build.BuildProperties;

/**
 * <p>Provides a means of managing validations. This class is
 * intended as a mixin class for the panel classes such as XPage. Validations
 * are integrated with the event handler so that when the event with which the
 * validation is associated is triggered the validation is invoked. Failure of
 * a validation results in subsequent event handler methods being blocked.</p>
 * <p>Validations are also invoked at page transition and all validations rules
 * are checked. If all validations are not passed then the page transition
 * can be blocked.</p><p>If a validation failes then an exception is thrown.
 * The exception is by default handled by this class but it can be redirected to
 * a custom exception handler with the setExceptionHandler method. This interface
 * allows exceptions to handled in a variety of different ways.</p>
 * <p>Copyright: Copyright (c) Xoetrope Ltd., 1998-2003<br>
 * License:      see license.txt
 * $Revision: 1.6 $
 */
public class XValidationHandler implements XValidationExceptionHandler
{
  protected XValidationFactory validationFactory;
  protected Hashtable validations;
  protected XValidationExceptionHandler exceptionHandler;
  protected XEventHandler eventHandler;
  protected Container container;

  /**
   * Create a new validation handler for the specified container. The container
   * provides the context in which the validation operate. Therefore validation
   * methods are found by reflection in the specified container. Normally the
   * container is the current XPage or a derived class.
   * @param c the container
   */
  public XValidationHandler( Container c )
  {
    exceptionHandler = this;

    container = c;
    eventHandler = null;
  }

  /**
   * Set the event handler instance. This class needs to interact with the event
   * handler to manage focus and to gain access to the current event
   * @param eh the event handler
   */
  public void setEventHandler( XEventHandler eh )
  {
    eventHandler = eh;

    clearValidations();
    eventHandler.addFocusHandler( container, "validationHandler" );
  }

  /**
   * Set the validation exception handler called when a validation exception is trapped
   * @param eh
   */
  public void setExceptionHandler( XValidationExceptionHandler eh )
  {
    exceptionHandler = eh;
  }

  /**
   * Reset/removes all validations
   */
  public void clearValidations()
  {
    validations = new Hashtable( 5 );
  }

  /**
   * Adds a validation to this page.
   * @param comp the component being validated
   * @param validationName the name of the validation in the validation file
   * @param method the method used to get the component's value if any
   * @param mask the event mask used to filter the events that trigger the validation
   * @return the new and initialized XValidator
   */
  public XValidator addValidation( Component comp, String validationName, String method, int mask )
  {
    XValidator validator = getValidation( validationName, method, mask );
    Vector v = ( Vector )validations.get( new Long( FocusEvent.FOCUS_LOST * comp.hashCode() ) );
    if ( v == null ) {
      v = new Vector();
      v.addElement( comp );
      validations.put( new Long( FocusEvent.FOCUS_LOST * comp.hashCode() ), v );

      switch ( mask ) {
        case FocusEvent.FOCUS_GAINED:
        case FocusEvent.FOCUS_LOST:
        default:
          eventHandler.addFocusHandler( comp, "validationHandler" );
          break;
      }
    }
    v.addElement( validator );
    return validator;
  }

  /**
   * Adds a validation to this page.
   * @param comp the component being validated
   * @param validationName the name of the validation in the validation file
   * @param mask the event mask used to filter the events that trigger the validation
   * @return the new and initialized XValidator
   */
  public XValidator getValidation( String validationName, String method, int mask )
  {
    Method m = null;
    if ( (method != null) && (method.length()>0) ) {
      try {
        m = container.getClass().getMethod( method, null );
      }
      catch ( Exception e ) {
        e.printStackTrace();
      }
    }

    if ( BuildProperties.DEBUG ) {
      if ( validationFactory == null ) {
        DebugLogger.logError( "No validation factory is set for the page. Cannot build the validation rule: " + validationName );
        return null;
      }
    }
    XValidator validator = validationFactory.getValidation( validationName, m, mask, container );
    return validator;
  }

  /**
   * Gets a XValidator object. The parameters of the object are read from the
   * validation file
   * @param validationName the name of the validation in the validation file
   * @param method the method used to get the component's value if any
   * @return the new and initialized XValidator
   */
  public XValidator getValidation( String validationName, String method )
  {
    return getValidation( validationName, method, 0 );
  }

  /**
   * Gets all the validations installed for a component
   * @param comp the target component
   * @return a Vector of XValidators
   */
  public Vector getValidations( Component comp )
  {
    XValidator validator = null;
    int ret = 0;
    try {
      // Get the event source
      if ( eventHandler == null )
        return null;

      // Get the list of validators for the component
      Vector v = ( Vector )validations.get( new Long( FocusEvent.FOCUS_LOST * comp.hashCode() ) );
      if ( v != null )
        return v;
    }
    catch ( Exception ex )
    {
    }

    return null;
  }

  /**
   * Adds a validation to this page. It is assumed that the validation will be
   * invoked in response to FocusEvent.FOCUS_LOST events
   * @param comp the component being validated
   * @param validationName the name of the validation in the validation file
   * @param method the method used to get the component's value if any
   * @return the new and initialized XValidator
   */
  public XValidator addValidation( Component comp, String validationName, String method )
  {
    return addValidation( comp, validationName, method, FocusEvent.FOCUS_LOST );
  }

  /**
   * Adds a validation to this page. It is assumed that the validation will be
   * invoked in response to FocusEvent.FOCUS_LOST events
   * @param comp the component being validated
   * @param validationName the name of the validation in the validation file
   * @return the new and initialized XValidator
   */
  public XValidator addValidation( Component comp, String validationName )
  {
    return addValidation( comp, validationName, null, FocusEvent.FOCUS_LOST );
  }

  /**
   * Sets the factory used to create XValidator objects
   * @param vf
   */
  public void setValidationFactory( XValidationFactory vf )
  {
    validationFactory = vf;
  }

  /**
   * Invoke the validators for the last event. Multiple validations are checked
   * in the order in which they were added.
   * @return the maximum level returned by the validators
   */
  public int validationHandler()
  {
    Component comp = null;
    XValidator validator = null;
    int ret = 0;
    try {
      // Get the event source
      comp = ( Component )eventHandler.getCurrentEvent().getSource();

      // Get the list of validators for the component
      Vector v = ( Vector )validations.get( new Long( FocusEvent.FOCUS_LOST * comp.hashCode() ) );
      if ( v != null ) {

        // Iterate over the list of validations
        for ( int i = 1; i < v.size(); i++ ) {
          validator = ( XValidator )v.elementAt( i );
          if ( validator != null ) {
            // Check that the validator is to be used for this event
            if ( eventHandler.getCurrentEvent().getID() == validator.getMask() ) {
              // Validate and get the maximum error level
              ret = Math.max( ret, validator.getLevel() );
              validator.validate( comp, false );
            }
          }
        }
      }
    }
    catch ( Exception ex ) {
      exceptionHandler.handleException( comp, ex, validator );
      return ret;
    }
    return XValidator.LEVEL_IGNORE;
  }

  /**
   * Check all validations for this page. Typically this method should be
   * invoked prior to a page transition or a critical transaction.
   * @return the maximum error level raised by the validators
   */
  public int checkValidations()
  {
    // Initialize the error level
    int ret = XValidator.LEVEL_IGNORE;

    // Iterate over all the validators
    Enumeration e = validations.elements();
    XValidator validator = null;
    Component comp = null;
    while ( e.hasMoreElements() ) {
      Vector v = ( Vector )e.nextElement();
      if ( v != null ) {
        // Check the validators for each component
        comp = ( Component )v.elementAt( 0 );
        int numValidations = v.size();
        for ( int i = 1; i < numValidations; i++ ) {
          try {
            validator = ( XValidator )v.elementAt( i );
            if ( validator != null )
              validator.validate( comp, true );
          }
          catch ( Exception ex ) {
            // Record the maximum error level
            ret = Math.max( ret, validator.getLevel() );

            // Redirect error handling to the error handler.
            exceptionHandler.handleException( comp, ex, validator );
          }
        }
      }
    }

    return ret;
  }

  /**
   * informs the handler when a page validation is starting or stopping. Typically
   * when it starts the page will begin to accumulate messages which are to be displayed.
   * When the parameter is false the page will usually display the accumulated
   * messages
   * @param start boolean to indicate whether the accumulation is started or stopped.
   */
  public int accumulateMessages( boolean accumulate, int level )
  {
    if ( !exceptionHandler.equals(this) )
      return exceptionHandler.accumulateMessages( accumulate, level );

    return 0;
  }

  /**
   * A method called when a validation exeption has been trapped.
   *
   * @param c Component being validated
   * @param ex The exception caused
   * @param validator The validator being used to validate.
   * @return true to continue with error validation or false to suppress further
   * validation.
   */
  public boolean handleException( Component comp, Exception ex, XValidator validator )
  {
    ex.printStackTrace();

    return true;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.