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 }