KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > common > web > util > EmailValidationUtils


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2006
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.common.web.util;
25
26 import java.util.regex.Matcher JavaDoc;
27 import java.util.regex.Pattern JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * Utility class to perform basic email address syntax checks. The
34  * implementation is based on the jakarta-commons EmailValidator. Oro-Matcher
35  * dependencies have been removed (now using java.util.regex) and comments
36  * are no longer processed, i.e. addresses containing comments will be reported
37  * as invalid.
38  */

39 public final class EmailValidationUtils {
40
41     private static Log log = LogFactory.getLog(EmailValidationUtils.class);
42     
43     private static final String JavaDoc SPECIAL_CHARS = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
44     private static final String JavaDoc VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";
45     private static final String JavaDoc QUOTED_USER = "(\"[^\"]*\")";
46     private static final String JavaDoc ATOM = VALID_CHARS + '+';
47     private static final String JavaDoc WORD = "(" + ATOM + "|" + QUOTED_USER + ")";
48
49     private static final String JavaDoc LEGAL_ASCII_PATTERN = "^[\\x00-\\x7F]+$";
50     private static final String JavaDoc EMAIL_PATTERN = "^(.+)@(.+)$";
51     private static final String JavaDoc IP_DOMAIN_PATTERN =
52             "^(\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})$";
53
54     private static final String JavaDoc USER_PATTERN = "^" + WORD + "(\\.|"
55             + WORD + ")*$";
56             
57     private static final String JavaDoc DOMAIN_PATTERN = "^" + ATOM + "(\\."
58             + ATOM + ")*$";
59             
60     private static final String JavaDoc ATOM_PATTERN = "(" + ATOM + ")";
61     
62     private static final String JavaDoc ADDR_PATTERN = "^[^<]*<([^>]*)>\\s*$";
63
64
65     /* Compiled patterns */
66     private static Pattern JavaDoc legalAsciiPattern = Pattern.compile(LEGAL_ASCII_PATTERN);
67     private static Pattern JavaDoc emailPattern = Pattern.compile(EMAIL_PATTERN);
68     private static Pattern JavaDoc ipDomainPattern = Pattern.compile(IP_DOMAIN_PATTERN);
69     private static Pattern JavaDoc userPattern = Pattern.compile(USER_PATTERN);
70     private static Pattern JavaDoc domainPattern = Pattern.compile(DOMAIN_PATTERN);
71     private static Pattern JavaDoc atomPattern = Pattern.compile(ATOM_PATTERN);
72     private static Pattern JavaDoc addrPattern = Pattern.compile(ADDR_PATTERN);
73
74     
75     private EmailValidationUtils() {
76     }
77
78     /**
79      * <p>Checks if a field has a valid e-mail address.</p>
80      *
81      * @param email The value validation is being performed on.
82      * A <code>null</code> value is considered invalid.
83      */

84     public static boolean isValid(String JavaDoc email) {
85         if (email == null) {
86             log.debug("Address is null");
87             return false;
88         }
89         Matcher JavaDoc addrMatcher = addrPattern.matcher(email);
90         if (addrMatcher.matches()) {
91             email = addrMatcher.group(1);
92             log.debug("Extracted machine part from address: " + email);
93         }
94         
95         if (!legalAsciiPattern.matcher(email).matches()) {
96             log.debug("Address must only contain ASCII characters");
97             return false;
98         }
99
100         // Check the whole email address structure
101
Matcher JavaDoc emailMatcher = emailPattern.matcher(email);
102         if (!emailMatcher.matches()) {
103             log.debug("Invalid address structure");
104             return false;
105         }
106
107         if (email.endsWith(".")) {
108             log.debug("Address must not end with a dot");
109             return false;
110         }
111
112         if (!isValidUser(emailMatcher.group(1))) {
113             log.debug("Invalid user");
114             return false;
115         }
116
117         if (!isValidDomain(emailMatcher.group(2))) {
118             log.debug("Invalid domain");
119             return false;
120         }
121         log.debug("Address is valid");
122         return true;
123     }
124
125     /**
126      * Returns true if the domain component of an email address is valid.
127      * @param domain being validatied.
128      */

129     private static boolean isValidDomain(String JavaDoc domain) {
130         boolean symbolic = false;
131         
132         Matcher JavaDoc ipAddressMatcher = ipDomainPattern.matcher(domain);
133         if (ipAddressMatcher.matches()) {
134             if (!isValidIpAddress(ipAddressMatcher)) {
135                 return false;
136             }
137         }
138         else {
139             // Domain is symbolic name
140
symbolic = domainPattern.matcher(domain).matches();
141         }
142
143         if (symbolic) {
144             if (!isValidSymbolicDomain(domain)) {
145                 return false;
146             }
147         }
148         else {
149             return false;
150         }
151
152         return true;
153     }
154
155     /**
156      * Returns true if the user component of an email address is valid.
157      * @param user being validated
158      */

159     private static boolean isValidUser(String JavaDoc user) {
160         return userPattern.matcher(user).matches();
161     }
162
163     /**
164      * Validates an IP address. Returns true if valid.
165      * @param ipAddressMatcher Pattren matcher
166      */

167     private static boolean isValidIpAddress(Matcher JavaDoc ipAddressMatcher) {
168         for (int i = 1; i <= 4; i++) {
169             String JavaDoc ipSegment = ipAddressMatcher.group(i);
170             if (ipSegment == null || ipSegment.length() <= 0) {
171                 return false;
172             }
173
174             int iIpSegment = 0;
175
176             try {
177                 iIpSegment = Integer.parseInt(ipSegment);
178             }
179             catch (NumberFormatException JavaDoc e) {
180                 return false;
181             }
182
183             if (iIpSegment > 255) {
184                 return false;
185             }
186         }
187         return true;
188     }
189
190     /**
191      * Validates a symbolic domain name. Returns true if it's valid.
192      * @param domain symbolic domain name
193      */

194     private static boolean isValidSymbolicDomain(String JavaDoc domain) {
195         String JavaDoc[] domainSegment = new String JavaDoc[10];
196         boolean match = true;
197         int i = 0;
198         Matcher JavaDoc atomMatcher = atomPattern.matcher(domain);
199         while (match) {
200             match = atomMatcher.find();
201             if (match) {
202                 domainSegment[i] = atomMatcher.group(1);
203                 int l = domainSegment[i].length() + 1;
204                 domain =
205                         (l >= domain.length())
206                         ? ""
207                         : domain.substring(l);
208
209                 i++;
210             }
211         }
212
213         int len = i;
214         if (domainSegment[len - 1].length() < 2
215                 || domainSegment[len - 1].length() > 4) {
216
217             return false;
218         }
219
220         // Make sure there's a host name preceding the domain.
221
if (len < 2) {
222             return false;
223         }
224
225         return true;
226     }
227     
228 }
229
Popular Tags