001// Copyright 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.form;
016
017import java.util.Iterator;
018
019import org.apache.hivemind.service.ThreadLocale;
020import org.apache.tapestry.IMarkupWriter;
021import org.apache.tapestry.IRequestCycle;
022import org.apache.tapestry.coerce.ValueConverter;
023import org.apache.tapestry.form.validator.Validator;
024import org.apache.tapestry.valid.ValidatorException;
025
026/**
027 * Default {@link VadidatableFieldSupport} implementation. This implementation generates calls to a
028 * static javascript function during render if client-side validation is enabled.
029 * 
030 * @author Paul Ferraro
031 * @since 4.0
032 */
033public class ValidatableFieldSupportImpl implements ValidatableFieldSupport
034{
035    private ValueConverter _converter;
036
037    private ThreadLocale _threadLocale;
038
039    public void setValueConverter(ValueConverter converter)
040    {
041        _converter = converter;
042    }
043
044    public void setThreadLocale(ThreadLocale threadLocale)
045    {
046        _threadLocale = threadLocale;
047    }
048
049    protected Iterator getValidatorsIterator(ValidatableField component)
050    {
051        return (Iterator) _converter.coerceValue(component.getValidators(), Iterator.class);
052    }
053
054    /**
055     * @see org.apache.tapestry.form.ValidatableFieldSupport#renderValidatorContributions(org.apache.tapestry.form.ValidatableField, org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
056     */
057    public void renderContributions(ValidatableField component, IMarkupWriter writer,
058            IRequestCycle cycle)
059    {
060        if (component.getForm().isClientValidationEnabled())
061        {
062            FormComponentContributorContext context = new FormComponentContributorContextImpl(
063                    _threadLocale.getLocale(), cycle, component);
064
065            Iterator validators = getValidatorsIterator(component);
066
067            while (validators.hasNext())
068            {
069                Validator validator = (Validator) validators.next();
070
071                validator.renderContribution(writer, cycle, context, component);
072            }
073        }
074    }
075
076    /**
077     * @see org.apache.tapestry.form.ValidatableFieldSupport#validate(org.apache.tapestry.form.ValidatableField, org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle, java.lang.Object)
078     */
079    public void validate(ValidatableField component, IMarkupWriter writer, IRequestCycle cycle, Object object) throws ValidatorException
080    {
081        boolean isNonNull = (object != null);
082
083        Iterator validators = getValidatorsIterator(component);
084
085        ValidationMessages messages = new ValidationMessagesImpl(component, _threadLocale.getLocale());
086
087        while (validators.hasNext())
088        {
089            Validator validator = (Validator) validators.next();
090
091            if (isNonNull || validator.getAcceptsNull())
092                validator.validate(component, messages, object);
093        }
094    }
095
096    public boolean isRequired(ValidatableField field)
097    {
098        Iterator i = getValidatorsIterator(field);
099
100        while (i.hasNext())
101        {
102            Validator validator = (Validator) i.next();
103
104            if (validator.isRequired())
105                return true;
106        }
107
108        return false;
109    }
110}