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 java.util.HashMap;
018import java.util.Locale;
019import java.util.Map;
020
021import org.apache.tapestry.IMarkupWriter;
022import org.apache.tapestry.IRequestCycle;
023import org.apache.tapestry.form.IFormComponent;
024
025/**
026 * Simple validation of email strings, to enforce required, and minimum length (maximum length is
027 * enforced in the client browser, by setting a maximum input length on the text field).
028 * 
029 * @author Malcolm Edgar
030 * @since 2.3
031 */
032
033public class EmailValidator extends BaseValidator
034{
035    private int _minimumLength;
036
037    private String _minimumLengthMessage;
038
039    private String _invalidEmailFormatMessage;
040
041    private String _scriptPath = "/org/apache/tapestry/valid/EmailValidator.script";
042
043    public EmailValidator()
044    {
045    }
046
047    /**
048     * Initializes the EmailValidator with properties defined by the initializer.
049     * 
050     * @since 4.0
051     */
052
053    public EmailValidator(String initializer)
054    {
055        super(initializer);
056    }
057
058    public String toString(IFormComponent field, Object value)
059    {
060        if (value == null)
061            return null;
062
063        return value.toString();
064    }
065
066    public Object toObject(IFormComponent field, String input) throws ValidatorException
067    {
068        if (checkRequired(field, input))
069            return null;
070
071        if (_minimumLength > 0 && input.length() < _minimumLength)
072            throw new ValidatorException(buildMinimumLengthMessage(field),
073                    ValidationConstraint.MINIMUM_WIDTH);
074
075        if (!isValidEmail(input))
076            throw new ValidatorException(buildInvalidEmailFormatMessage(field),
077                    ValidationConstraint.EMAIL_FORMAT);
078
079        return input;
080    }
081
082    public int getMinimumLength()
083    {
084        return _minimumLength;
085    }
086
087    public void setMinimumLength(int minimumLength)
088    {
089        _minimumLength = minimumLength;
090    }
091
092    public void renderValidatorContribution(IFormComponent field, IMarkupWriter writer,
093            IRequestCycle cycle)
094    {
095        if (!isClientScriptingEnabled())
096            return;
097
098        Map symbols = new HashMap();
099
100        Locale locale = field.getPage().getLocale();
101        String displayName = field.getDisplayName();
102
103        if (isRequired())
104            symbols.put("requiredMessage", buildRequiredMessage(field));
105
106        if (_minimumLength > 0)
107            symbols.put("minimumLengthMessage", buildMinimumLengthMessage(field));
108
109        String pattern = getPattern(getInvalidEmailFormatMessage(), "invalid-email-format", locale);
110
111        symbols.put("emailFormatMessage", formatString(pattern, displayName));
112
113        processValidatorScript(_scriptPath, cycle, field, symbols);
114    }
115
116    public String getScriptPath()
117    {
118        return _scriptPath;
119    }
120
121    /**
122     * Allows a developer to use the existing validation logic with a different client-side script.
123     * This is often sufficient to allow application-specific error presentation (perhaps by using
124     * DHTML to update the content of a &lt;span&gt; tag, or to use a more sophisticated pop-up
125     * window than <code>window.alert()</code>).
126     */
127
128    public void setScriptPath(String scriptPath)
129    {
130        _scriptPath = scriptPath;
131    }
132
133    /**
134     * Return true if the email format is valid.
135     * 
136     * @param email
137     *            the email string to validate
138     * @return true if the email format is valid
139     */
140
141    protected boolean isValidEmail(String email)
142    {
143        int atIndex = email.indexOf('@');
144
145        return !((atIndex <= 0) || (atIndex == email.length() - 1));
146    }
147
148    /** @since 3.0 */
149
150    public String getInvalidEmailFormatMessage()
151    {
152        return _invalidEmailFormatMessage;
153    }
154
155    /** @since 3.0 */
156
157    public String getMinimumLengthMessage()
158    {
159        return _minimumLengthMessage;
160    }
161
162    /**
163     * Overrides the <code>invalid-email-format</code> bundle key. Parameter {0} is the display
164     * name of the field.
165     * 
166     * @since 3.0
167     */
168
169    public void setInvalidEmailFormatMessage(String string)
170    {
171        _invalidEmailFormatMessage = string;
172    }
173
174    /**
175     * Overrides the <code>field-too-short</code> bundle key. Parameter {0} is the minimum length.
176     * Parameter {1} is the display name of the field.
177     * 
178     * @since 3.0
179     */
180    public void setMinimumLengthMessage(String string)
181    {
182        _minimumLengthMessage = string;
183    }
184
185    /** @since 3.0 */
186
187    protected String buildMinimumLengthMessage(IFormComponent field)
188    {
189        String pattern = getPattern(_minimumLengthMessage, "field-too-short", field.getPage()
190                .getLocale());
191
192        return formatString(pattern, Integer.toString(_minimumLength), field.getDisplayName());
193    }
194
195    /** @since 3.0 */
196
197    protected String buildInvalidEmailFormatMessage(IFormComponent field)
198    {
199        String pattern = getPattern(_invalidEmailFormatMessage, "invalid-email-format", field
200                .getPage().getLocale());
201
202        return formatString(pattern, field.getDisplayName());
203    }
204}