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