| // Copyright 2004 The Apache Software Foundation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package org.apache.tapestry.valid; |
| |
| import java.util.List; |
| |
| import org.apache.tapestry.IMarkupWriter; |
| import org.apache.tapestry.IRender; |
| import org.apache.tapestry.IRequestCycle; |
| 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. |
| * |
| * <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 |
| */ |
| |
| 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 |
| * |
| **/ |
| |
| 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 |
| * |
| **/ |
| |
| public boolean isInError(); |
| |
| /** |
| * 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 |
| **/ |
| |
| 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 |
| * |
| **/ |
| |
| public void reset(); |
| |
| /** |
| * 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. |
| * |
| * <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). |
| * |
| * @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 |
| * |
| **/ |
| |
| 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. |
| * |
| **/ |
| |
| 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 |
| **/ |
| |
| 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 |
| * |
| **/ |
| |
| 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 <input> 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(); |
| } |