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.valid.ValidationConstants;
025    import org.apache.tapestry.valid.ValidationConstraint;
026    import org.apache.tapestry.valid.ValidationStrings;
027    import org.apache.tapestry.valid.ValidatorException;
028    
029    /**
030     * Validates that the user input, a string, is an email address (by checking it against a regular
031     * expression).
032     * 
033     * @author Howard Lewis Ship
034     * @since 4.0
035     */
036    public class Email extends BaseValidator
037    {
038        public static final String TLD_PATTERN = "arpa|aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|"
039                + "org|pro|travel|xxx|jobs|mobi|post|"
040                + "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|"
041                + "bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|"
042                + "ec|ee|eg|er|eu|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|"
043                + "gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|"
044                + "la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|"
045                + "my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|"
046                + "re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sk|sl|sm|sn|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|"
047                + "tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw";
048        public static final String DOMAIN_PATTERN = "([0-9a-z]([-0-9a-z]{0,61}[0-9a-z])?\\.)+" + "(" + TLD_PATTERN + ")";
049        public static final String USERNAME_PATTERN = "([-/!\\#$*?=_+&'\\da-z]+[.])*[-/!\\#$*?=_+&'\\da-z]+";
050        public static final String PATTERN = "^(?i)"+ USERNAME_PATTERN + "@" + "(" + DOMAIN_PATTERN + ")$";
051    
052        private static final java.util.regex.Pattern PATTERN_COMPILED = java.util.regex.Pattern.compile(PATTERN);
053    
054        public Email()
055        {
056        }
057        
058        public Email(String initializer)
059        {
060            super(initializer);
061        }
062        
063        public void validate(IFormComponent field, ValidationMessages messages, Object object)
064                throws ValidatorException
065        {
066            String input = (String) object;
067    
068            if ( !PATTERN_COMPILED.matcher(input).matches() )
069                throw new ValidatorException(buildMessage(messages, field),
070                        ValidationConstraint.EMAIL_FORMAT);
071        }
072    
073        private String buildMessage(ValidationMessages messages, IFormComponent field)
074        {
075            return messages.formatValidationMessage(
076                    getMessage(),
077                    ValidationStrings.INVALID_EMAIL,
078                    new Object[]
079                    { field.getDisplayName() });
080        }
081        
082        public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
083                FormComponentContributorContext context, IFormComponent field)
084        {        
085            JSONObject profile = context.getProfile();
086            
087            if (!profile.has(ValidationConstants.CONSTRAINTS)) {
088                profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
089            }
090            JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
091            
092            accumulateProperty(cons, field.getClientId(),
093                    new JSONLiteral("[tapestry.form.validation.isEmailAddress,false,true]"));
094            
095            accumulateProfileProperty(field, profile, 
096                    ValidationConstants.CONSTRAINTS, buildMessage(context, field));
097        }
098    }