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    
015    package org.apache.tapestry.valid;
016    
017    import org.apache.tapestry.IMarkupWriter;
018    import org.apache.tapestry.IRequestCycle;
019    import org.apache.tapestry.Tapestry;
020    import 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    
035    public 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    }