Add getCurrentFieldTracking() method to IValidationDelegate.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/tapestry/branches/branch-3-0@244053 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/org/apache/tapestry/valid/IValidationDelegate.java b/framework/src/org/apache/tapestry/valid/IValidationDelegate.java
index e4a6baf..e6ad166 100644
--- a/framework/src/org/apache/tapestry/valid/IValidationDelegate.java
+++ b/framework/src/org/apache/tapestry/valid/IValidationDelegate.java
@@ -22,266 +22,226 @@
 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}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.
+ * <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.
  * 
- *  <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
 {
     /**
-     *  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();
-    
+
     /**
-     * Clears all errors, but maintains user input. This is useful when a form
-     * has been submitted for a semantic other than "process this data". A common example
-     * of this is a dependent drop down list; selecting an option in one drop down list
-     * forces a submit to repopulate the options in a second, dependent drop down list.
-     * 
+     * Clears all errors, but maintains user input. This is useful when a form has been submitted
+     * for a semantic other than "process this data". A common example of this is a dependent drop
+     * down list; selecting an option in one drop down list forces a submit to repopulate the
+     * options in a second, dependent drop down list.
      * <p>
-     * In these cases, the user input provided in the request is maintained, but any
-     * errors should be cleared out (to prevent unwanted error messages and decorations).
+     * In these cases, the user input provided in the request is maintained, but any errors should
+     * be cleared out (to prevent unwanted error messages and decorations).
      * 
      * @since 3.0.1
      */
-    
+
     public void clearErrors();
 
     /**
-     *  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).
-     *
-     **/
+     * 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);
+    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
-     **/
+     * 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);
+    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).
-     *
-     **/
+     * 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);
+    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.
-     *
-     **/
+     * Invoked by a {@link FieldLabel}just before writing the name of the form component.
+     */
 
-    public void writeLabelPrefix(
-        IFormComponent component,
-        IMarkupWriter writer,
-        IRequestCycle cycle);
+    public void writeLabelPrefix(IFormComponent component, IMarkupWriter writer, IRequestCycle cycle);
 
     /**
-     *  Invoked by a {@link FieldLabel} just after writing the name
-     *  of the form component.
-     *
-     **/
+     * Invoked by a {@link FieldLabel}just after writing the name of the form component.
+     */
 
-    public void writeLabelSuffix(
-        IFormComponent component,
-        IMarkupWriter writer,
-        IRequestCycle cycle);
+    public void writeLabelSuffix(IFormComponent component, IMarkupWriter writer, IRequestCycle cycle);
 
     /**
-     *   Returns true if any form component has errors.
-     *
-     **/
+     * Returns true if any form component has errors.
+     */
 
     public boolean getHasErrors();
+
+    /**
+     * Returns the {@link IFieldTracking}for the current component, if any. Useful when displaying
+     * error messages for individual fields.
+     * 
+     * @since 3.0.2
+     */
+    public IFieldTracking getCurrentFieldTracking();
 }
\ No newline at end of file
diff --git a/framework/src/org/apache/tapestry/valid/ValidationDelegate.java b/framework/src/org/apache/tapestry/valid/ValidationDelegate.java
index 01c6dcc..6b3c03e 100644
--- a/framework/src/org/apache/tapestry/valid/ValidationDelegate.java
+++ b/framework/src/org/apache/tapestry/valid/ValidationDelegate.java
@@ -29,12 +29,11 @@
 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 helper bean. This
+ * class is often subclassed, typically to override presentation details.
+ * 
+ * @author Howard Lewis Ship
+ * @since 1.0.5
  */
 
 public class ValidationDelegate implements IValidationDelegate
@@ -47,14 +46,11 @@
     private List _trackings;
 
     /**
-     *  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 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.
      * <p>
-     * Each ultimate {@link FieldTracking} object is also in the _trackings
-     * list.
-     * 
+     * Each ultimate {@link FieldTracking}object is also in the _trackings list.
      */
 
     private Map _trackingMap;
@@ -75,20 +71,17 @@
         while (i.hasNext())
         {
             FieldTracking ft = (FieldTracking) i.next();
-			ft.setErrorRenderer(null);
+            ft.setErrorRenderer(null);
         }
     }
 
     /**
-     *  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))
         {
@@ -98,16 +91,12 @@
     }
 
     /**
-     *  Closes the &lt;font&gt; element,started by
-     *  {@link #writeLabelPrefix(IFormComponent,IMarkupWriter,IRequestCycle)},
-     *  if the form component is in error.
-     *
-     **/
+     * 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)
+    public void writeLabelSuffix(IFormComponent component, IMarkupWriter writer, IRequestCycle cycle)
     {
         if (isInError(component))
         {
@@ -116,21 +105,18 @@
     }
 
     /**
-     *  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)}.
+     * 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.
      * 
-     *  <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.
-     * 
-     **/
+     * @see #setFormComponent(IFormComponent)
+     * @return the {@link FieldTracking}, or null if the field has no tracking.
+     */
 
     protected FieldTracking getComponentTracking()
     {
@@ -167,9 +153,8 @@
     }
 
     /**
-     *  Returns all the field trackings as an unmodifiable List.
-     * 
-     **/
+     * Returns all the field trackings as an unmodifiable List.
+     */
 
     public List getFieldTracking()
     {
@@ -197,12 +182,10 @@
     }
 
     /**
-     *  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)
     {
@@ -215,11 +198,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)
     {
@@ -227,21 +208,17 @@
     }
 
     /**
-     *  Records error information about the currently selected component,
-     *  or records unassociated (with any field) errors.
+     * 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.
      * 
-     *  <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)
     {
@@ -262,14 +239,11 @@
     }
 
     /**
-     *  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()
     {
@@ -319,44 +293,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())
         {
@@ -374,11 +334,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()
     {
@@ -399,12 +358,10 @@
     }
 
     /**
-     *  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)
     {
@@ -429,14 +386,13 @@
     }
 
     /**
-     *  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()
     {
@@ -461,15 +417,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()
     {
@@ -492,4 +446,15 @@
 
         return result;
     }
-};
\ No newline at end of file
+
+    /**
+     * Returns the {@link IFieldTracking}for the current component, if any. Useful
+     * when displaying error messages for individual fields.
+     * 
+     * @since 3.0.2
+     */
+    public IFieldTracking getCurrentFieldTracking()
+    {
+        return getComponentTracking();
+    }
+}
\ No newline at end of file