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