[prev in list] [next in list] [prev in thread] [next in thread] 

List:       tapestry-dev
Subject:    cvs commit: jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/valid TestValidationDelega
From:       hlship () apache ! org
Date:       2005-04-30 15:06:47
Message-ID: 20050430150647.64539.qmail () minotaur ! apache ! org
[Download RAW message or body]

hlship      2005/04/30 08:06:47

  Modified:    framework/src/java/org/apache/tapestry/valid
                        IFieldTracking.java IValidationDelegate.java
                        FieldTracking.java ValidationDelegate.java
               framework/src/test/org/apache/tapestry/junit/valid
                        TestValidationDelegate.java
  Log:
  Limit validation delegate to tracking just the contents of a single form, as part \
of the fix for getting field decoration working again.  
  Revision  Changes    Path
  1.4       +35 -46    \
jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IFieldTracking.java  
  Index: IFieldTracking.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IFieldTracking.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- IFieldTracking.java	5 Jan 2005 23:17:15 -0000	1.3
  +++ IFieldTracking.java	30 Apr 2005 15:06:47 -0000	1.4
  @@ -18,74 +18,63 @@
   import org.apache.tapestry.form.IFormComponent;
   
   /**
  - *  Defines the interface for an object that tracks input fields.  This 
  - *  interface is now poorly named, in that it tracks errors that may <em>not</em>
  - *  be associated with a specific field.
  + * Defines the interface for an object that tracks input fields. This interface is \
now poorly named,  + * in that it tracks errors that may <em>not</em> be associated \
with a specific field.  + * <p>
  + * For each field, a flag is stored indicating if the field is, in fact, in error. \
The input  + * supplied by the client is stored so that if the form is re-rendered \
(as is typically done when  + * there are input errors), the value entered by the \
user can be displayed back to the user. An  + * error message renderer is stored; \
this is an object that can render the error message (it is  + * usually a {@link \
                org.apache.tapestry.valid.RenderString}&nbsp;wrapper around a simple \
                string).
    * 
  - *  <p>For each field, a flag is stored indicating if the field is, in fact, in \
                error.
  - *  The input supplied by the client is stored so that if the form is re-rendered
  - *  (as is typically done when there are input errors), the value entered by the \
                user
  - *  is displayed back to the user.  An error message renderer is stored; this is
  - *  an object that can render the error message (it is usually
  - *  a {@link org.apache.tapestry.valid.RenderString} wrapper around a simple \
                string).
  - *
  - *  @author Howard Lewis Ship
  - *  @since 1.0.8
  - *
  - **/
  + * @author Howard Lewis Ship
  + * @since 1.0.8
  + */
   
   public interface IFieldTracking
   {
  -	/**
  -	 *  Returns true if the field is in error (that is,
  -	 *  if it has an error message {@link #getErrorRenderer() renderer}.
  -	 * 
  -	 **/
  -	
  -	public boolean isInError();
  -	
  -	
       /**
  -     *  Returns the field component.  This may return null if the error
  -     *  is not associated with any particular field.
  -     * 
  -     **/
  +     * Returns true if the field is in error (that is, if it has an error message
  +     * {@link #getErrorRenderer() renderer}.
  +     */
  +
  +    public boolean isInError();
  +
  +    /**
  +     * Returns the field component. This may return null if the error is not \
associated with any  +     * particular field. Note: may return null after the field \
tracking object is serialized and  +     * deserialized (the underlying component \
reference is transient); this metehod is primarily  +     * used for testing.
  +     */
   
       public IFormComponent getComponent();
   
       /**
  -     *  Returns an object that will render the error message.
  -     * 
  -     *  @since 1.0.9
  +     * Returns an object that will render the error message.
        * 
  -     **/
  +     * @since 1.0.9
  +     */
   
       public IRender getErrorRenderer();
   
  -
       /**
  -     *  Returns the invalid input recorded for the field.  This is stored
  -     *  so that, on a subsequent render, the smae invalid input can be presented
  -     *  to the client to be corrected.
  -     * 
  -     **/
  +     * Returns the invalid input recorded for the field. This is stored so that, \
on a subsequent  +     * render, the smae invalid input can be presented to the \
client to be corrected.  +     */
   
       public String getInput();
   
       /**
  -     *  Returns the name of the field, that is, the name assigned by the form
  -     *  (this will differ from the component's id when any kind of looping \
                operation
  -     *  is in effect).
  -     * 
  -     **/
  +     * Returns the name of the field, that is, the name assigned by the form (this \
will differ from  +     * the component's id when any kind of looping operation is in \
effect).  +     */
   
       public String getFieldName();
   
       /**
  -     *  Returns the validation constraint that was violated by the input.  This
  -     *  may be null if the constraint isn't known.
  -     * 
  -     **/
  +     * Returns the validation constraint that was violated by the input. This may \
be null if the  +     * constraint isn't known.
  +     */
   
       public ValidationConstraint getConstraint();
   }
  \ No newline at end of file
  
  
  
  1.4       +157 -202  \
jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IValidationDelegate.java
  
  Index: IValidationDelegate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/IValidationDelegate.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- IValidationDelegate.java	6 Jan 2005 02:17:23 -0000	1.3
  +++ IValidationDelegate.java	30 Apr 2005 15:06:47 -0000	1.4
  @@ -14,6 +14,7 @@
   
   package org.apache.tapestry.valid;
   
  +import java.io.Serializable;
   import java.util.List;
   
   import org.apache.tapestry.IMarkupWriter;
  @@ -22,252 +23,206 @@
   import org.apache.tapestry.form.IFormComponent;
   
   /**
  - *  Interface used to track validation errors in forms and
  - *  {@link IFormComponent}s (including {@link \
                org.apache.tapestry.form.AbstractTextField}
  - *  and its subclasses).
  - *
  - *  <p>In addition,
  - *  controls how fields that are in error are presented (they can be
  - *  marked in various ways by the delegate; the default implementation
  - *  adds two red asterisks to the right of the field).
  - *
  - *  <p>The interface is designed so that a single instance can be shared
  - *  with many instances of {@link IFormComponent}.
  - *
  - *  <p>Starting with release 1.0.8, this interface was extensively revised
  - *  (in a non-backwards compatible way) to move the tracking of errors and
  - *  invalid values (during a request cycle) to the delegate.  It has evolved from
  - *  a largely stateless conduit for error messages into a very stateful tracker
  - *  of field state.
  - *
  - *  <p>Starting with release 1.0.9, this interface was <em>again</em>
  - *  reworked, to allow tracking of errors in {@link IFormComponent form \
                components},
  - *  and to allow unassociated (with any field) errors
  - *  to be tracked.
  - *
  - *  <p><b>Fields vs. Form Components</b><br>
  - *  For most simple forms, these terms are pretty much synonymous.
  - *  Your form will render normally, and each form component will render
  - *  only once.  Some of your form components will be {@link ValidField}
  - *  components and handle most of
  - *  their validation internally (with the help of {@link IValidator} objects).
  - *  In addition, your form listener may do additional validation and notify
  - *  the validation delegate of additional errors, some of which
  - *  are associated with a particular field, some of which are unassociated
  - *  with any particular field.
  + * Interface used to track validation errors in forms and
  + * {@link IFormComponent form element component}s (including
  + * {@link org.apache.tapestry.form.AbstractTextField}&nbsp;and its subclasses).
  + * <p>
  + * In addition, controls how fields that are in error are presented (they can be \
<em>decorated</em>  + * in various ways by the delegate; the default implementation \
adds two red asterisks to the right  + * of the field).
  + * <p>
  + * Each {@link org.apache.tapestry.form.Form}&nbsp;must have its own validation \
delegate instance.  + * <p>
  + * Starting with release 1.0.8, this interface was extensively revised (in a \
non-backwards  + * compatible way) to move the tracking of errors and invalid values \
(during a request cycle) to the  + * delegate. It has evolved from a largely \
stateless conduit for error messages into a very stateful  + * tracker of field \
state.  + * <p>
  + * Starting with release 1.0.9, this interface was <em>again</em> reworked, to \
allow tracking of  + * errors in {@link IFormComponent form components}, and to allow \
unassociated errors to be  + * tracked. Unassociated errors are "global", they don't \
apply to any particular field.  + * <p>
  + * <b>Fields vs. Form Element Components </b> <br>
  + * For most simple forms, these terms are pretty much synonymous. Your form will \
render normally,  + * and each form element component will render only once. Some of \
your form components will be  + * {@link ValidField}&nbsp;components and handle most \
of their validation internally (with the help  + * of {@link \
IValidator}&nbsp;objects). In addition, your form listener may do additional  + * \
validation and notify the validation delegate of additional errors, some of which are \
associated  + * with a particular field, some of which are unassociated with any \
particular field.  + * <p>
  + * But what happens if you use a {@link \
org.apache.tapestry.components.Foreach}&nbsp;or  + * {@link \
org.apache.tapestry.form.ListEdit}&nbsp;inside your form? Some of your components \
will  + * render multiple times. In this case you will have multiple <em>fields</em>. \
Each field will  + * have a unique field name (the
  + * {@link org.apache.tapestry.FormSupport#getElementId(IFormComponent) element \
id}, which you can  + * see this in the generated HTML). It is this field name that \
the delegate keys off of, which means  + * that some fields generated by a component \
may have errors and some may not, it all works fine  + * (with one exception).
  + * <p>
  + * <b>The Exception </b> <br>
  + * The problem is that a component doesn't know its field name until its \
<code>render()</code>  + * method is invoked (at which point, it allocates a unique \
field name from the  + * {@link \
org.apache.tapestry.IForm#getElementId(org.apache.tapestry.form.IFormComponent)}. \
This is  + * not a problem for the field or its {@link IValidator}, but screws things \
up for the  + * {@link FieldLabel}.
  + * <p>
  + * Typically, the label is rendered <em>before</em> the corresponding form \
component. Form  + * components leave their last assigned field name in their
  + * {@link IFormComponent#getName() name property}. So if the form component is in \
any kind of loop,  + * the {@link FieldLabel}will key its name, {@link \
IFormComponent#getDisplayName() display name}  + * and error status off of its last \
renderred value. So the moral of the story is don't use  + * {@link FieldLabel}in \
                this situation.
    * 
  - *  <p>
  - *  But what happens if you use a {@link org.apache.tapestry.components.Foreach} \
                or
  - *  {@link org.apache.tapestry.form.ListEdit} inside your form?
  - *  Some of your components will render multiple times.  In this case you will \
                have
  - *  multiple <em>fields</em>.  Each field will have a unique field name (you can \
                see this
  - *  in the generated HTML).  It is this field name that the delegate keys off of, \
                which
  - *  means that some fields generated by a component may have errors and some may \
                not, it
  - *  all works fine (with one exception).
  - *
  - *  <p><b>The Exception</b><br>
  - *  The problem is that a component doesn't know its field name until its
  - *  <code>render()</code> method is invoked (at which point, it allocates a unique \
                field
  - *  name from the {@link \
                org.apache.tapestry.IForm#getElementId(org.apache.tapestry.form.IFormComponent)}.
                
  - *  This is not a problem for the field or its
  - *  {@link IValidator}, but screws things up for the {@link FieldLabel}.
  - *
  - *  <p>Typically, the label is rendered <em>before</em> the corresponding form \
                component.
  - *  Form components leave their last assigned field name in their
  - *  {@link IFormComponent#getName() name property}.  So if the form component is \
                in any kind of
  - *  loop, the {@link FieldLabel} will key its name,
  - *  {@link IFormComponent#getDisplayName() display name} and error status off of
  - *  its last renderred value.  So the moral of the story is don't use
  - *  {@link FieldLabel} in this situation.
  - *
  - *
  - *  @author Howard Lewis Ship
  - *
  - **/
  + * @author Howard Lewis Ship
  + */
   
  -public interface IValidationDelegate
  +public interface IValidationDelegate extends Serializable
   {
       /**
  -     *  Invoked before other methods to configure the delegate for the given
  -     *  form component.  Sets the current field based on
  -     *  the {@link IFormComponent#getName() name} of the form component
  -     *  (which is almost always a {@link ValidField}).
  -     *
  -     *  <p>The caller should invoke this with a parameter of null to record
  -     *  unassociated global errors (errors not associated with any particular \
                field).
  -     *
  -     *  @since 1.0.8
  -     *
  -     **/
  +     * Invoked before other methods to configure the delegate for the given form \
component. Sets the  +     * current field based on the {@link \
IFormComponent#getName() name}of the form component (which  +     * is almost always \
a {@link ValidField}).  +     * <p>
  +     * The caller should invoke this with a parameter of null to record \
unassociated global errors  +     * (errors not associated with any particular \
field).  +     * 
  +     * @since 1.0.8
  +     */
   
       public void setFormComponent(IFormComponent component);
   
       /**
  -     *  Returns true if the current component is in error (that is, had bad input
  -     *  submitted by the end user).
  -     *
  -     *  @since 1.0.8
  -     *
  -     **/
  +     * Returns true if the current component is in error (that is, had bad input \
submitted by the  +     * end user).
  +     * 
  +     * @since 1.0.8
  +     */
   
       public boolean isInError();
   
       /**
  -     *  Returns the string submitted by the client as the value for
  -     *  the current field.
  -     *
  -     *  @since 1.0.8
  -     *
  -     **/
  +     * Returns the string submitted by the client as the value for the current \
field.  +     * 
  +     * @since 1.0.8
  +     */
   
       public String getFieldInputValue();
   
       /**
  -     *  Returns a {@link List} of {@link IFieldTracking}, in default order
  -     *  (the order in which fields are renderred). A caller should
  -     *  not change the values (the List is immutable).
  -     *  May return null if no fields are in error.
  -     *
  -     *  @since 1.0.8
  -     **/
  +     * Returns a {@link List}of {@link IFieldTracking}, in default order (the \
order in which  +     * fields are renderred). A caller should not change the values \
(the List is immutable). May  +     * return null if no fields are in error.
  +     * 
  +     * @since 1.0.8
  +     */
   
       public List getFieldTracking();
   
       /**
  -     *  Resets any tracking information for the current field.  This will
  -     *  clear the field's inError flag, and set its error message and invalid \
                input value
  -     *  to null.
  -     *
  -     *  @since 1.0.8
  -     *
  -     **/
  +     * Resets any tracking information for the current field. This will clear the \
field's inError  +     * flag, and set its error message and invalid input value to \
null.  +     * 
  +     * @since 1.0.8
  +     */
   
       public void reset();
   
       /**
  -     *  Clears all tracking information.
  -     *
  -     *  @since 1.0.10
  -     *
  -     **/
  +     * Clears all tracking information.
  +     * 
  +     * @since 1.0.10
  +     */
   
       public void clear();
   
       /**
  -     *  Records the user's input for the current form component.  Input should
  -     *  be recorded even if there isn't an explicit error, since later form-wide
  -     *  validations may discover an error in the field.
  -     *
  -     *  @since 3.0
  -     *
  -     **/
  +     * Records the user's input for the current form component. Input should be \
recorded even if  +     * there isn't an explicit error, since later form-wide \
validations may discover an error in the  +     * field.
  +     * 
  +     * @since 3.0
  +     */
   
       public void recordFieldInputValue(String input);
   
       /**
  -     *  The error notification method, invoked during the rewind phase
  -     *  (that is, while HTTP parameters are being extracted from the request
  -     *  and assigned to various object properties).
  -     *
  -     *  <p>Typically, the delegate simply invokes
  -     *  {@link #record(String, ValidationConstraint)} or
  -     *  {@link #record(IRender, ValidationConstraint)}, but special
  -     *  delegates may override this behavior to provide (in some cases)
  -     *  different error messages or more complicated error renderers.
  -     *
  -     **/
  +     * The error notification method, invoked during the rewind phase (that is, \
while HTTP  +     * parameters are being extracted from the request and assigned to \
various object properties).  +     * <p>
  +     * Typically, the delegate simply invokes {@link #record(String, \
ValidationConstraint)}or  +     * {@link #record(IRender, ValidationConstraint)}, but \
special delegates may override this  +     * behavior to provide (in some cases) \
different error messages or more complicated error  +     * renderers.
  +     */
   
       public void record(ValidatorException ex);
   
       /**
  -     *  Records an error in the current field, or an unassociated error
  -     *  if there is no current field.
  -     *
  -     *  @param message message to display (@see RenderString}
  -     *  @param constraint the constraint that was violated, or null if not known
  -     *
  -     *  @since 1.0.9
  -     **/
  +     * Records an error in the current field, or an unassociated error if there is \
no current field.  +     * 
  +     * @param message
  +     *            message to display (@see RenderString}
  +     * @param constraint
  +     *            the constraint that was violated, or null if not known
  +     * @since 1.0.9
  +     */
   
       public void record(String message, ValidationConstraint constraint);
   
       /**
  -     *  Records an error in the current component, or an unassociated error.
  -     *  The maximum flexibility recorder.
  -     *
  -     *  @param errorRenderer object that will render the error message (@see \
                RenderString}
  -     *  @param constraint the constraint that was violated, or null if not known
  -     *
  -     **/
  +     * Records an error in the current component, or an unassociated error. The \
maximum flexibility  +     * recorder.
  +     * 
  +     * @param errorRenderer
  +     *            object that will render the error message (@see RenderString}
  +     * @param constraint
  +     *            the constraint that was violated, or null if not known
  +     */
   
       public void record(IRender errorRenderer, ValidationConstraint constraint);
   
       /**
  -     *  Invoked before the field is rendered.  If the field is in error,
  -     *  the delegate may decorate the field in some way (to highlight its
  -     *  error state).
  -     *
  -     **/
  -
  -    public void writePrefix(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator);
  -
  -    /**
  -     *  Invoked just before the &lt;input&gt; element is closed.
  -     *  The delegate can write additional attributes.  This is often used
  -     *  to set the CSS class of the field so that it can be displayed
  -     *  differently, if in error (or required).
  -     *
  -     *  @since 1.0.5
  -     **/
  -
  -    public void writeAttributes(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator);
  -
  -    /**
  -     *  Invoked after the form component is rendered, so that the
  -     *  delegate may decorate the form component (if it is in error).
  -     *
  -     **/
  -
  -    public void writeSuffix(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator);
  -
  -    /**
  -     *  Invoked by a {@link FieldLabel} just before writing the name
  -     *  of the form component.
  -     *
  -     **/
  -
  -    public void writeLabelPrefix(
  -        IFormComponent component,
  -        IMarkupWriter writer,
  -        IRequestCycle cycle);
  -
  -    /**
  -     *  Invoked by a {@link FieldLabel} just after writing the name
  -     *  of the form component.
  -     *
  -     **/
  -
  -    public void writeLabelSuffix(
  -        IFormComponent component,
  -        IMarkupWriter writer,
  -        IRequestCycle cycle);
  -
  -    /**
  -     *   Returns true if any form component has errors.
  -     *
  -     **/
  +     * Invoked before the field is rendered. If the field is in error, the \
delegate may decorate the  +     * field in some way (to highlight its error state).
  +     */
  +
  +    public void writePrefix(IMarkupWriter writer, IRequestCycle cycle, \
IFormComponent component,  +            IValidator validator);
  +
  +    /**
  +     * Invoked just before the &lt;input&gt; element is closed. The delegate can \
write additional  +     * attributes. This is often used to set the CSS class of the \
field so that it can be displayed  +     * differently, if in error (or required).
  +     * 
  +     * @since 1.0.5
  +     */
  +
  +    public void writeAttributes(IMarkupWriter writer, IRequestCycle cycle,
  +            IFormComponent component, IValidator validator);
  +
  +    /**
  +     * Invoked after the form component is rendered, so that the delegate may \
decorate the form  +     * component (if it is in error).
  +     */
  +
  +    public void writeSuffix(IMarkupWriter writer, IRequestCycle cycle, \
IFormComponent component,  +            IValidator validator);
  +
  +    /**
  +     * Invoked by a {@link FieldLabel}just before writing the name of the form \
component.  +     */
  +
  +    public void writeLabelPrefix(IFormComponent component, IMarkupWriter writer, \
IRequestCycle cycle);  +
  +    /**
  +     * Invoked by a {@link FieldLabel}just after writing the name of the form \
component.  +     */
  +
  +    public void writeLabelSuffix(IFormComponent component, IMarkupWriter writer, \
IRequestCycle cycle);  +
  +    /**
  +     * Returns true if any form component has errors.
  +     */
   
       public boolean getHasErrors();
   }
  \ No newline at end of file
  
  
  
  1.4       +24 -20    \
jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/FieldTracking.java  
  Index: FieldTracking.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/FieldTracking.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- FieldTracking.java	5 Jan 2005 23:17:15 -0000	1.3
  +++ FieldTracking.java	30 Apr 2005 15:06:47 -0000	1.4
  @@ -14,43 +14,47 @@
   
   package org.apache.tapestry.valid;
   
  +import org.apache.hivemind.util.Defense;
   import org.apache.tapestry.IRender;
   import org.apache.tapestry.form.IFormComponent;
   
   /**
  - *  Default implementation of {@link IFieldTracking}.
  - *
  - *  @author Howard Lewis Ship
  - *  @since 1.0.8
  - *
  - **/
  + * Default implementation of {@link IFieldTracking}.
  + * 
  + * @author Howard Lewis Ship
  + * @since 1.0.8
  + */
   
   public class FieldTracking implements IFieldTracking
   {
  -    private IFormComponent _component;
  +    private transient IFormComponent _component;
  +
       private String _input;
  +
       private IRender _renderer;
  +
       private String _fieldName;
  +
       private ValidationConstraint _constraint;
   
  -	/**
  -	 *  Constructor used for unassociated errors; errors that are not about any \
                particular
  -	 *  field within the form.
  -	 * 
  -	 **/
  -	
  +    /**
  +     * Constructor used for unassociated errors; errors that are not about any \
particular field  +     * within the form.
  +     */
  +
       FieldTracking()
       {
       }
   
  -	/**
  -	 *  Standard constructor for a field (with the given name), rendered
  -	 *  by the specified component.
  -	 * 
  -	 **/
  -	
  +    /**
  +     * Standard constructor for a field (with the given name), rendered by the \
specified component.  +     */
  +
       FieldTracking(String fieldName, IFormComponent component)
       {
  +        Defense.notNull(fieldName, "fieldName");
  +        Defense.notNull(component, "component");
  +
           _fieldName = fieldName;
           _component = component;
       }
  @@ -95,7 +99,7 @@
           _constraint = constraint;
       }
   
  -    /** @since 3.0 **/
  +    /** @since 3.0 * */
   
       public boolean isInError()
       {
  
  
  
  1.4       +105 -191  \
jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/ValidationDelegate.java \
  Index: ValidationDelegate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/ValidationDelegate.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ValidationDelegate.java	6 Jan 2005 02:17:23 -0000	1.3
  +++ ValidationDelegate.java	30 Apr 2005 15:06:47 -0000	1.4
  @@ -21,7 +21,6 @@
   import java.util.List;
   import java.util.Map;
   
  -import org.apache.tapestry.IForm;
   import org.apache.tapestry.IMarkupWriter;
   import org.apache.tapestry.IRender;
   import org.apache.tapestry.IRequestCycle;
  @@ -29,46 +28,43 @@
   import org.apache.tapestry.form.IFormComponent;
   
   /**
  - *  A base implementation of {@link IValidationDelegate} that can be used
  - *  as a helper bean.  This class is often subclassed, typically to override \
                presentation
  - *  details.
  - *
  - *  @author Howard Lewis Ship
  - *  @since 1.0.5
  + * A base implementation of {@link IValidationDelegate}that can be used as a \
managed bean. This  + * class is often subclassed, typically to override presentation \
                details.
    * 
  - **/
  + * @author Howard Lewis Ship
  + * @since 1.0.5
  + */
   
   public class ValidationDelegate implements IValidationDelegate
   {
  -    private IFormComponent _currentComponent;
  -    private List _trackings;
  +    private transient IFormComponent _currentComponent;
   
       /**
  -     *  A Map of Maps, keyed on the name of the Form.  Each inner map contains
  -     *  the trackings for one form, keyed on component name.  Care must
  -     *  be taken, because the inner Map is not always present.
  -     * 
  -     **/
  +     * A list of {@link IFieldTracking}.
  +     */
  +
  +    private final List _trackings = new ArrayList();
   
  -    private Map _trackingMap;
  +    /**
  +     * A map of {@link IFieldTracking}, keyed on form element name.
  +     */
  +
  +    private final Map _trackingMap = new HashMap();
   
       public void clear()
       {
           _currentComponent = null;
  -        _trackings = null;
  -        _trackingMap = null;
  +        _trackings.clear();
  +        _trackingMap.clear();
       }
   
       /**
  -     *  If the form component is in error, places a &lt;font color="red"&lt; \
                around it.
  -     *  Note: this will only work on the render phase after a rewind, and will be
  -     *  confused if components are inside any kind of loop.
  -     **/
  +     * If the form component is in error, places a &lt;font color="red"&lt; around \
it. Note: this  +     * will only work on the render phase after a rewind, and will \
be confused if components are  +     * inside any kind of loop.
  +     */
   
  -    public void writeLabelPrefix(
  -        IFormComponent component,
  -        IMarkupWriter writer,
  -        IRequestCycle cycle)
  +    public void writeLabelPrefix(IFormComponent component, IMarkupWriter writer, \
IRequestCycle cycle)  {
           if (isInError(component))
           {
  @@ -78,16 +74,12 @@
       }
   
       /**
  -     *  Closes the &lt;font&gt; element,started by
  -     *  {@link #writeLabelPrefix(IFormComponent,IMarkupWriter,IRequestCycle)},
  -     *  if the form component is in error.
  -     *
  -     **/
  -
  -    public void writeLabelSuffix(
  -        IFormComponent component,
  -        IMarkupWriter writer,
  -        IRequestCycle cycle)
  +     * Closes the &lt;font&gt; element,started by
  +     * {@link #writeLabelPrefix(IFormComponent,IMarkupWriter,IRequestCycle)}, if \
the form component  +     * is in error.
  +     */
  +
  +    public void writeLabelSuffix(IFormComponent component, IMarkupWriter writer, \
IRequestCycle cycle)  {
           if (isInError(component))
           {
  @@ -96,35 +88,22 @@
       }
   
       /**
  -     *  Returns the {@link IFieldTracking} for the current component, if any.
  -     *  The {@link IFieldTracking} is usually created in 
  -     *  {@link #record(String, ValidationConstraint)} or
  -     *  in {@link #record(IRender, ValidationConstraint)}.
  -     * 
  -     *  <p>Components may be rendered multiple times, with multiple names \
                (provided
  -     *  by the {@link org.apache.tapestry.form.Form}, care must be taken that this \
                method is invoked
  -     *  <em>after</em> the Form has provided a unique 
  -     *  {@link IFormComponent#getName()} for the component.
  -     * 
  -     *  @see #setFormComponent(IFormComponent)
  -     * 
  -     *  @return the {@link FieldTracking}, or null if the field has no tracking.
  -     * 
  -     **/
  +     * Returns the {@link IFieldTracking}for the current component, if any. The
  +     * {@link IFieldTracking}is usually created in {@link #record(String, \
ValidationConstraint)}or  +     * in {@link #record(IRender, ValidationConstraint)}.
  +     * <p>
  +     * Components may be rendered multiple times, with multiple names (provided by \
the  +     * {@link org.apache.tapestry.form.Form}, care must be taken that this \
method is invoked  +     * <em>after</em> the Form has provided a unique {@link \
IFormComponent#getName()}for the  +     * component.
  +     * 
  +     * @see #setFormComponent(IFormComponent)
  +     * @return the {@link FieldTracking}, or null if the field has no tracking.
  +     */
   
       protected FieldTracking getComponentTracking()
       {
  -        if (_trackingMap == null)
  -            return null;
  -
  -        String formName = _currentComponent.getForm().getName();
  -
  -        Map formMap = (Map) _trackingMap.get(formName);
  -
  -        if (formMap == null)
  -            return null;
  -
  -        return (FieldTracking) formMap.get(_currentComponent.getName());
  +        return (FieldTracking) _trackingMap.get(_currentComponent.getName());
       }
   
       public void setFormComponent(IFormComponent component)
  @@ -147,9 +126,8 @@
       }
   
       /**
  -     *  Returns all the field trackings as an unmodifiable List.
  -     * 
  -     **/
  +     * Returns all the field trackings as an unmodifiable List.
  +     */
   
       public List getFieldTracking()
       {
  @@ -166,23 +144,15 @@
           if (tracking != null)
           {
               _trackings.remove(tracking);
  -
  -            String formName = tracking.getComponent().getForm().getName();
  -
  -            Map formMap = (Map) _trackingMap.get(formName);
  -
  -            if (formMap != null)
  -                formMap.remove(tracking.getFieldName());
  +            _trackingMap.remove(tracking.getFieldName());
           }
       }
   
       /**
  -     *  Invokes {@link #record(String, ValidationConstraint)}, or
  -     *  {@link #record(IRender, ValidationConstraint)} if the 
  -     *  {@link ValidatorException#getErrorRenderer() error renderer property}
  -     *  is not null.
  -     * 
  -     **/
  +     * Invokes {@link #record(String, ValidationConstraint)}, or
  +     * {@link #record(IRender, ValidationConstraint)}if the
  +     * {@link ValidatorException#getErrorRenderer() error renderer property}is not \
null.  +     */
   
       public void record(ValidatorException ex)
       {
  @@ -195,11 +165,9 @@
       }
   
       /**
  -     *  Invokes {@link #record(IRender, ValidationConstraint)}, after
  -     *  wrapping the message parameter in a
  -     *  {@link RenderString}.
  -     * 
  -     **/
  +     * Invokes {@link #record(IRender, ValidationConstraint)}, after wrapping the \
message parameter  +     * in a {@link RenderString}.
  +     */
   
       public void record(String message, ValidationConstraint constraint)
       {
  @@ -207,21 +175,17 @@
       }
   
       /**
  -     *  Records error information about the currently selected component,
  -     *  or records unassociated (with any field) errors.
  -     * 
  -     *  <p>
  -     *  Currently, you may have at most one error per <em>field</em>
  -     *  (note the difference between field and component), but any number of
  -     *  unassociated errors.
  -     * 
  -     *  <p>
  -     *  Subclasses may override the default error message (based on other
  -     *  factors, such as the field and constraint) before invoking this
  -     *  implementation.
  +     * Records error information about the currently selected component, or \
records unassociated  +     * (with any field) errors.
  +     * <p>
  +     * Currently, you may have at most one error per <em>field</em> (note the \
difference between  +     * field and component), but any number of unassociated \
errors.  +     * <p>
  +     * Subclasses may override the default error message (based on other factors, \
such as the field  +     * and constraint) before invoking this implementation.
        * 
  -     *  @since 1.0.9
  -     **/
  +     * @since 1.0.9
  +     */
   
       public void record(IRender errorRenderer, ValidationConstraint constraint)
       {
  @@ -242,25 +206,16 @@
       }
   
       /**
  -     *  Finds or creates the field tracking for the
  -     *  {@link #setFormComponent(IFormComponent)} current component.
  -     *  If no current component, an unassociated error is created
  -     *  and returned.
  +     * Finds or creates the field tracking for the {@link \
#setFormComponent(IFormComponent)}current  +     * component. If no current \
                component, an unassociated error is created and returned.
        * 
  -     *  @since 3.0
  -     * 
  -     **/
  +     * @since 3.0
  +     */
   
       protected FieldTracking findCurrentTracking()
       {
           FieldTracking result = null;
   
  -        if (_trackings == null)
  -            _trackings = new ArrayList();
  -
  -        if (_trackingMap == null)
  -            _trackingMap = new HashMap();
  -
           if (_currentComponent == null)
           {
               result = new FieldTracking();
  @@ -276,22 +231,12 @@
   
               if (result == null)
               {
  -                String formName = _currentComponent.getForm().getName();
  -
  -                Map formMap = (Map) _trackingMap.get(formName);
  -
  -                if (formMap == null)
  -                {
  -                    formMap = new HashMap();
  -                    _trackingMap.put(formName, formMap);
  -                }
  -
                   String fieldName = _currentComponent.getName();
   
                   result = new FieldTracking(fieldName, _currentComponent);
   
                   _trackings.add(result);
  -                formMap.put(fieldName, result);
  +                _trackingMap.put(fieldName, result);
               }
           }
   
  @@ -299,44 +244,30 @@
       }
   
       /**
  -     *  Does nothing.  Override in a subclass to decoreate
  -     *  fields.
  -     * 
  -     **/
  +     * Does nothing. Override in a subclass to decoreate fields.
  +     */
   
  -    public void writePrefix(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator)
  +    public void writePrefix(IMarkupWriter writer, IRequestCycle cycle, \
IFormComponent component,  +            IValidator validator)
       {
       }
   
       /**
  -     *  Does nothing.  Override in a subclass to decorate fields.
  -     * 
  -     **/
  +     * Does nothing. Override in a subclass to decorate fields.
  +     */
   
  -    public void writeAttributes(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator)
  +    public void writeAttributes(IMarkupWriter writer, IRequestCycle cycle,
  +            IFormComponent component, IValidator validator)
       {
       }
   
       /**
  -     *  Default implementation; if the current field is in error,
  -     *  then a suffix is written.  The suffix is:
  -     *  <code>&amp;nbsp;&lt;font color="red"&gt;**&lt;/font&gt;</code>.
  -     * 
  -     **/
  +     * Default implementation; if the current field is in error, then a suffix is \
written. The  +     * suffix is: <code>&amp;nbsp;&lt;font \
color="red"&gt;**&lt;/font&gt;</code>.  +     */
   
  -    public void writeSuffix(
  -        IMarkupWriter writer,
  -        IRequestCycle cycle,
  -        IFormComponent component,
  -        IValidator validator)
  +    public void writeSuffix(IMarkupWriter writer, IRequestCycle cycle, \
IFormComponent component,  +            IValidator validator)
       {
           if (isInError())
           {
  @@ -354,11 +285,10 @@
       }
   
       /**
  -     *  A convienience, as most pages just show the first error on the page.
  -     * 
  -     *  <p>As of release 1.0.9, this returns an instance of {@link IRender}, not a \
                {@link String}.
  -     * 
  -     **/
  +     * A convienience, as most pages just show the first error on the page.
  +     * <p>
  +     * As of release 1.0.9, this returns an instance of {@link IRender}, not a \
{@link String}.  +     */
   
       public IRender getFirstError()
       {
  @@ -379,44 +309,30 @@
       }
   
       /**
  -     *  Checks to see if the field is in error.  This will <em>not</em> work \
                properly
  -     *  in a loop, but is only used by {@link FieldLabel}.  Therefore, using \
                {@link FieldLabel}
  -     *  in a loop (where the {@link IFormComponent} is renderred more than once) \
                will not provide
  -     *  correct results.
  -     * 
  -     **/
  +     * Checks to see if the field is in error. This will <em>not</em> work \
properly in a loop, but  +     * is only used by {@link FieldLabel}. Therefore, using \
{@link FieldLabel}in a loop (where the  +     * {@link IFormComponent}is renderred \
more than once) will not provide correct results.  +     */
   
       protected boolean isInError(IFormComponent component)
       {
  -        if (_trackingMap == null)
  -            return false;
  +        // Get the name as most recently rendered.
   
  -        IForm form = component.getForm();
  -        // if there is no form, the component cannot have been rewound or rendered \
                into a form yet
  -        // so assume it cannot have errors.
  -        if (form == null)
  -            return false;
  -        
  -        String formName = form.getName();
  -        Map formMap = (Map) _trackingMap.get(formName);
  +        String fieldName = component.getName();
   
  -        if (formMap == null)
  -            return false;
  -
  -        IFieldTracking tracking = (IFieldTracking) \
formMap.get(component.getName());  +        IFieldTracking tracking = \
(IFieldTracking) _trackingMap.get(fieldName);  
           return tracking != null && tracking.isInError();
       }
   
       /**
  -     *  Returns a {@link List} of {@link IFieldTracking}s.  This is the master \
                list
  -     *  of trackings, except that it omits and trackings that are not associated
  -     *  with a particular field.  May return an empty list, or null.
  -     * 
  -     *  <p>Order is not determined, though it is likely the order in which \
                components
  -     *  are laid out on in the template (this is subject to change).
  -     * 
  -     **/
  +     * Returns a {@link List}of {@link IFieldTracking}s. This is the master list \
of trackings,  +     * except that it omits and trackings that are not associated \
with a particular field. May  +     * return an empty list, or null.
  +     * <p>
  +     * Order is not determined, though it is likely the order in which components \
are laid out on in  +     * the template (this is subject to change).
  +     */
   
       public List getAssociatedTrackings()
       {
  @@ -441,15 +357,13 @@
       }
   
       /**
  -     *  Like {@link #getAssociatedTrackings()}, but returns only the unassociated \
                trackings.
  -     *  Unassociated trackings are new (in release 1.0.9), and are why
  -     *  interface {@link IFieldTracking} is not very well named.
  -     * 
  -     *  <p>The trackings are returned in an unspecified order, which (for the \
                moment, anyway)
  -     *  is the order in which they were added (this could change in the future, or \
                become
  -     *  more concrete).
  -     * 
  -     **/
  +     * Like {@link #getAssociatedTrackings()}, but returns only the unassociated \
trackings.  +     * Unassociated trackings are new (in release 1.0.9), and are why \
interface  +     * {@link IFieldTracking}is not very well named.
  +     * <p>
  +     * The trackings are returned in an unspecified order, which (for the moment, \
anyway) is the  +     * order in which they were added (this could change in the \
future, or become more concrete).  +     */
   
       public List getUnassociatedTrackings()
       {
  @@ -472,4 +386,4 @@
   
           return result;
       }
  -};
  \ No newline at end of file
  +}
  \ No newline at end of file
  
  
  
  1.5       +15 -204   \
jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/valid/TestValidationDelegate.java
  
  Index: TestValidationDelegate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/junit/valid/TestValidationDelegate.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestValidationDelegate.java	6 Feb 2005 15:08:50 -0000	1.4
  +++ TestValidationDelegate.java	30 Apr 2005 15:06:47 -0000	1.5
  @@ -35,36 +35,15 @@
   
   public class TestValidationDelegate extends BaseValidatorTestCase
   {
  -    private IForm newForm(int count)
  -    {
  -        MockControl control = newControl(IForm.class);
  -
  -        IForm form = (IForm) control.getMock();
  -
  -        form.getName();
  -        control.setReturnValue("TheForm", count);
  -
  -        return form;
  -    }
  -
  -    private IFormComponent newField(String displayName, String name, IForm form)
  +    private IFormComponent newField(String name, int count)
       {
           MockControl control = newControl(IFormComponent.class);
  -        IFormComponent field = (IFormComponent) control.getMock();
  -
  -        field.getForm();
  -        control.setReturnValue(form);
  -
  -        field.getName();
  -        control.setReturnValue(name);
  -
  -        field.getDisplayName();
  -        control.setReturnValue(displayName, 2);
  +        IFormComponent fc = (IFormComponent) control.getMock();
   
  -        field.getForm();
  -        control.setReturnValue(form);
  +        fc.getName();
  +        control.setReturnValue(name, count);
   
  -        return field;
  +        return fc;
       }
   
       private ValidationDelegate d = new ValidationDelegate();
  @@ -81,22 +60,7 @@
   
       public void testInvalidInput()
       {
  -        IForm form = newForm(3);
  -
  -        MockControl control = newControl(IFormComponent.class);
  -        IFormComponent field = (IFormComponent) control.getMock();
  -
  -        field.getForm();
  -        control.setReturnValue(form, 2);
  -
  -        field.getName();
  -        control.setReturnValue("testAdd");
  -
  -        field.getForm();
  -        control.setReturnValue(form);
  -
  -        field.getName();
  -        control.setReturnValue("testAdd");
  +        IFormComponent field = newField("testAdd", 3);
   
           replayControls();
   
  @@ -126,22 +90,7 @@
   
       public void testValidatorErrorRenderer()
       {
  -        IForm form = newForm(3);
  -
  -        MockControl control = newControl(IFormComponent.class);
  -        IFormComponent field = (IFormComponent) control.getMock();
  -
  -        field.getForm();
  -        control.setReturnValue(form, 2);
  -
  -        field.getName();
  -        control.setReturnValue("testValidatorErrorRenderer");
  -
  -        field.getForm();
  -        control.setReturnValue(form);
  -
  -        field.getName();
  -        control.setReturnValue("testValidatorErrorRenderer");
  +        IFormComponent field = newField("testValidatorErrorRenderer", 3);
   
           replayControls();
   
  @@ -172,16 +121,7 @@
   
       public void testNoError()
       {
  -        IForm form = newForm(2);
  -
  -        MockControl control = newControl(IFormComponent.class);
  -        IFormComponent field = (IFormComponent) control.getMock();
  -
  -        field.getForm();
  -        control.setReturnValue(form, 2);
  -
  -        field.getName();
  -        control.setReturnValue("input");
  +        IFormComponent field = newField("input", 2);
   
           replayControls();
   
  @@ -207,16 +147,7 @@
   
       public void testUnassociatedErrors()
       {
  -        IForm form = newForm(2);
  -
  -        MockControl control = newControl(IFormComponent.class);
  -        IFormComponent field = (IFormComponent) control.getMock();
  -
  -        field.getForm();
  -        control.setReturnValue(form, 2);
  -
  -        field.getName();
  -        control.setReturnValue("input");
  +        IFormComponent field = newField("input", 2);
   
           replayControls();
   
  @@ -267,43 +198,8 @@
   
       public void testMultipleInvalidInput()
       {
  -        IForm form = newForm(6);
  -
  -        MockControl c1 = newControl(IFormComponent.class);
  -        IFormComponent f1 = (IFormComponent) c1.getMock();
  -
  -        MockControl c2 = newControl(IFormComponent.class);
  -        IFormComponent f2 = (IFormComponent) c2.getMock();
  -
  -        f1.getForm();
  -        c1.setReturnValue(form, 2);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  +        IFormComponent f1 = newField("monty", 3);
  +        IFormComponent f2 = newField("python", 3);
   
           replayControls();
   
  @@ -336,52 +232,8 @@
   
       public void testReset()
       {
  -        IForm form = newForm(8);
  -
  -        MockControl c1 = newControl(IFormComponent.class);
  -        IFormComponent f1 = (IFormComponent) c1.getMock();
  -
  -        MockControl c2 = newControl(IFormComponent.class);
  -        IFormComponent f2 = (IFormComponent) c2.getMock();
  -
  -        f1.getForm();
  -        c1.setReturnValue(form, 2);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  +        IFormComponent f1 = newField("monty", 4);
  +        IFormComponent f2 = newField("python", 3);
   
           replayControls();
   
  @@ -414,49 +266,8 @@
   
       public void testResetAll()
       {
  -        IForm form = newForm(8);
  -
  -        MockControl c1 = newControl(IFormComponent.class);
  -        IFormComponent f1 = (IFormComponent) c1.getMock();
  -
  -        MockControl c2 = newControl(IFormComponent.class);
  -        IFormComponent f2 = (IFormComponent) c2.getMock();
  -
  -        f1.getForm();
  -        c1.setReturnValue(form, 2);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  -
  -        f1.getName();
  -        c1.setReturnValue("monty");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  -
  -        f2.getName();
  -        c2.setReturnValue("python");
  -
  -        f1.getForm();
  -        c1.setReturnValue(form);
  -
  -        f2.getForm();
  -        c2.setReturnValue(form);
  +        IFormComponent f1 = newField("monty", 3);
  +        IFormComponent f2 = newField("python", 3);
   
           replayControls();
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic