001// Copyright 2006, 2007, 2008, 2011 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry5;
016
017import org.apache.tapestry5.ioc.MessageFormatter;
018import org.apache.tapestry5.services.FormSupport;
019
020/**
021 * Used by a {@link Field} to enforce a <strong>constraint</strong> related to a form submission. Validators themselves
022 * are stateless singletons.
023 * <p/>
024 * Validators are usually encapsulated inside a {@link FieldValidator}.
025 *
026 * @see FieldValidationSupport
027 * @see org.apache.tapestry5.services.FieldValidatorDefaultSource
028 */
029public interface Validator<C, T>
030{
031    /**
032     * Returns the type of constraint value used with this validator. Constraint values are used to parameterize a
033     * validator, for example a "maxLength" validator will have a constraint value of type int (the maximum length
034     * allowed). For constraints that do not have a constraint value, this method returns null.
035     */
036    Class<C> getConstraintType();
037
038    /**
039     * Returns the value type associated with this validator. {@link #validate(Field, Object, MessageFormatter, Object)}
040     * will only be invoked when the value is assignable to the validator's value type.
041     */
042    Class<T> getValueType();
043
044    /**
045     * Returns the message key, within the validation messages, normally used by this validator. This is used to provide
046     * the {@link MessageFormatter} passed to {@link #validate(Field, Object, MessageFormatter, Object)} (unless
047     * overridden).
048     *
049     * @return a message key
050     */
051    String getMessageKey();
052
053    /**
054     * Invoked after the client-submitted value has been {@link org.apache.tapestry5.Translator translated} to check
055     * that the value conforms to expectations (often, in terms of minimum or maximum value). If and only if the value
056     * is approved by all Validators is the value applied by the field.
057     *
058     * @param field           the field for which a client submitted value is being validated
059     * @param constraintValue the value used to constrain
060     * @param formatter       Validation messages, in the appropriate locale
061     * @param value           the translated value supplied by the user
062     * @throws ValidationException if the value violates the constraint
063     */
064    void validate(Field field, C constraintValue, MessageFormatter formatter, T value) throws ValidationException;
065
066    /**
067     * Returns true if the validator should be invoked for null or blank (empty string) values. This is generally false,
068     * but is true for validators that enforce that a non-blank value is required.  This is the basis of the {@link
069     * org.apache.tapestry5.Field#isRequired()} property.
070     */
071    boolean isRequired();
072
073    /**
074     * Hook used by components to allow the validator to contribute additional attributes or (more often) client-side
075     * JavaScript (via the {@link FormSupport#addValidation(Field, String, String, Object)}).
076     *
077     * @param field           the field which is currently being rendered
078     * @param constraintValue the value used to constrain input
079     * @param formatter       validation message, in the appropriate locale
080     * @param writer          markup writer, allowing additional attributes to be written into the active element
081     * @param formSupport     used to add JavaScript
082     */
083    void render(Field field, C constraintValue, MessageFormatter formatter, MarkupWriter writer,
084                FormSupport formSupport);
085}