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    
015    package org.apache.tapestry.form.validator;
016    
017    import org.apache.tapestry.IMarkupWriter;
018    import org.apache.tapestry.IRequestCycle;
019    import org.apache.tapestry.form.FormComponentContributorContext;
020    import org.apache.tapestry.form.IFormComponent;
021    import org.apache.tapestry.form.ValidationMessages;
022    import org.apache.tapestry.json.JSONLiteral;
023    import org.apache.tapestry.json.JSONObject;
024    import org.apache.tapestry.util.RegexpMatcher;
025    import org.apache.tapestry.valid.ValidationConstants;
026    import org.apache.tapestry.valid.ValidationConstraint;
027    import org.apache.tapestry.valid.ValidationStrings;
028    import org.apache.tapestry.valid.ValidatorException;
029    
030    /**
031     * Validates that the user input, a string, is an email address (by checking it against a regular
032     * expression).
033     * 
034     * @author Howard Lewis Ship
035     * @since 4.0
036     */
037    public class Email extends BaseValidator
038    {
039        public static final String PATTERN = "^[A-Za-z0-9]+([-_\\.]*[A-Za-z0-9]+)*@[A-Za-z0-9]+([-_\\.]*[A-Za-z0-9]+)*(\\.[_A-Za-z]{2,6})$";
040        
041        // TODO: Possible thread safety issue if the validator
042        // is shared across threads, because the matcher
043        // will be too.
044        
045        private RegexpMatcher _matcher = new RegexpMatcher();
046        
047        public Email()
048        {
049        }
050        
051        public Email(String initializer)
052        {
053            super(initializer);
054        }
055        
056        public void validate(IFormComponent field, ValidationMessages messages, Object object)
057                throws ValidatorException
058        {
059            String input = (String) object;
060    
061            if (!_matcher.matches(PATTERN, input))
062                throw new ValidatorException(buildMessage(messages, field),
063                        ValidationConstraint.EMAIL_FORMAT);
064        }
065    
066        private String buildMessage(ValidationMessages messages, IFormComponent field)
067        {
068            return messages.formatValidationMessage(
069                    getMessage(),
070                    ValidationStrings.INVALID_EMAIL,
071                    new Object[]
072                    { field.getDisplayName() });
073        }
074        
075        public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
076                FormComponentContributorContext context, IFormComponent field)
077        {
078            context.addInitializationScript(field, "dojo.require(\"dojo.validate.web\");");
079            
080            JSONObject profile = context.getProfile();
081            
082            if (!profile.has(ValidationConstants.CONSTRAINTS)) {
083                profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
084            }
085            JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
086            
087            accumulateProperty(cons, field.getClientId(),
088                    new JSONLiteral("[dojo.validate.isEmailAddress,false,true]"));
089            
090            accumulateProfileProperty(field, profile, 
091                    ValidationConstants.CONSTRAINTS, buildMessage(context, field));
092        }
093    }