001// Copyright 2004, 2005 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.tapestry.valid;
016
017import org.apache.tapestry.IMarkupWriter;
018import org.apache.tapestry.IRequestCycle;
019import org.apache.tapestry.Tapestry;
020import org.apache.tapestry.form.AbstractFormComponent;
021
022/**
023 * A {@link Form}component that creates a text field that allows for validation of user input and
024 * conversion between string and object values. [ <a
025 * href="../../../../../ComponentReference/ValidField.html">Component Reference </a>]
026 * <p>
027 * A ValidatingTextField uses an {@link IValidationDelegate} to track errors and an
028 * {@link IValidator}to convert between strings and objects (as well as perform validations). The
029 * validation delegate is shared by all validating text fields in a form, the validator may be
030 * shared my multiple elements as desired.
031 * 
032 * @author Howard Lewis Ship
033 */
034
035public abstract class ValidField extends AbstractFormComponent
036{
037    public abstract boolean isHidden();
038
039    public abstract boolean isDisabled();
040
041    public abstract Object getValue();
042
043    public abstract void setValue(Object value);
044
045    /** Parameter */
046
047    public abstract String getDisplayName();
048
049    /**
050     * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter,
051     *      org.apache.tapestry.IRequestCycle)
052     */
053    protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
054    {
055        IValidationDelegate delegate = getForm().getDelegate();
056
057        delegate.registerForFocus(this, delegate.isInError() ? ValidationConstants.ERROR_FIELD
058                : ValidationConstants.NORMAL_FIELD);
059
060        delegate.writePrefix(writer, cycle, this, null);
061
062        writer.beginEmpty("input");
063
064        writer.attribute("type", isHidden() ? "password" : "text");
065
066        if (isDisabled())
067            writer.attribute("disabled", "disabled");
068
069        writer.attribute("name", getName());
070
071        String value = readValue();
072        if (value != null)
073            writer.attribute("value", value);
074
075        renderIdAttribute(writer, cycle);
076
077        renderInformalParameters(writer, cycle);
078
079        delegate.writeAttributes(writer, cycle, this, null);
080
081        IValidator validator = getValidator();
082
083        if (validator == null)
084            throw Tapestry.createRequiredParameterException(this, "validator");
085
086        if (validator.isRequired())
087            delegate.registerForFocus(this, ValidationConstants.REQUIRED_FIELD);
088
089        validator.renderValidatorContribution(this, writer, cycle);
090
091        writer.closeTag();
092
093        delegate.writeSuffix(writer, cycle, this, null);
094    }
095
096    /**
097     * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter,
098     *      org.apache.tapestry.IRequestCycle)
099     */
100    protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
101    {
102        String value = cycle.getParameter(getName());
103
104        updateValue(value);
105    }
106
107    protected String readValue()
108    {
109        IValidator validator = getValidator();
110        if (validator == null)
111            throw Tapestry.createRequiredParameterException(this, "validator");
112
113        IValidationDelegate delegate = getForm().getDelegate();
114
115        if (delegate.isInError())
116            return delegate.getFieldInputValue();
117
118        Object value = getValue();
119
120        String result = validator.toString(this, value);
121
122        return result;
123    }
124
125    protected void updateValue(String value)
126    {
127        Object objectValue = null;
128
129        IValidator validator = getValidator();
130        if (validator == null)
131            throw Tapestry.createRequiredParameterException(this, "validator");
132
133        IValidationDelegate delegate = getForm().getDelegate();
134
135        delegate.recordFieldInputValue(value);
136
137        try
138        {
139            objectValue = validator.toObject(this, value);
140        }
141        catch (ValidatorException ex)
142        {
143            delegate.record(ex);
144            return;
145        }
146
147        setValue(objectValue);
148    }
149
150    public abstract IValidator getValidator();
151}