1 21 22 package org.apache.commons.validator; 23 24 import org.apache.oro.text.perl.Perl5Util; 25 26 42 public class EmailValidator { 43 44 private static final String SPECIAL_CHARS = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"; 45 private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]"; 46 private static final String QUOTED_USER = "(\"[^\"]*\")"; 47 private static final String ATOM = VALID_CHARS + '+'; 48 private static final String WORD = "(" + ATOM + "|" + QUOTED_USER + ")"; 49 50 private static final String LEGAL_ASCII_PATTERN = "/^[\\000-\\177]+$/"; 52 private static final String EMAIL_PATTERN = "/^(.+)@(.+)$/"; 53 private static final String IP_DOMAIN_PATTERN = 54 "/^\\[(\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})\\]$/"; 55 56 private static final String USER_PATTERN = "/^\\s*" + WORD + "(\\." + WORD + ")*\\s*$/"; 57 private static final String DOMAIN_PATTERN = "/^\\s*" + ATOM + "(\\." + ATOM + ")*\\s*$/"; 58 private static final String ATOM_PATTERN = "/(" + ATOM + ")/"; 59 60 63 private static final EmailValidator instance = new EmailValidator(); 64 65 68 public static EmailValidator getInstance() { 69 return instance; 70 } 71 72 75 protected EmailValidator() { 76 super(); 77 } 78 79 85 public boolean isValid(String email) { 86 if (email == null) { 87 return false; 88 } 89 90 Perl5Util matchAsciiPat = new Perl5Util(); 91 if (!matchAsciiPat.match(LEGAL_ASCII_PATTERN, email)) { 92 return false; 93 } 94 95 email = stripComments(email); 96 97 Perl5Util emailMatcher = new Perl5Util(); 99 if (!emailMatcher.match(EMAIL_PATTERN, email)) { 100 return false; 101 } 102 103 if (email.endsWith(".")) { 104 return false; 105 } 106 107 if (!isValidUser(emailMatcher.group(1))) { 108 return false; 109 } 110 111 if (!isValidDomain(emailMatcher.group(2))) { 112 return false; 113 } 114 115 return true; 116 } 117 118 122 protected boolean isValidDomain(String domain) { 123 boolean symbolic = false; 124 Perl5Util ipAddressMatcher = new Perl5Util(); 125 126 if (ipAddressMatcher.match(IP_DOMAIN_PATTERN, domain)) { 127 if (!isValidIpAddress(ipAddressMatcher)) { 128 return false; 129 } else { 130 return true; 131 } 132 } else { 133 Perl5Util domainMatcher = new Perl5Util(); 135 symbolic = domainMatcher.match(DOMAIN_PATTERN, domain); 136 } 137 138 if (symbolic) { 139 if (!isValidSymbolicDomain(domain)) { 140 return false; 141 } 142 } else { 143 return false; 144 } 145 146 return true; 147 } 148 149 153 protected boolean isValidUser(String user) { 154 Perl5Util userMatcher = new Perl5Util(); 155 return userMatcher.match(USER_PATTERN, user); 156 } 157 158 162 protected boolean isValidIpAddress(Perl5Util ipAddressMatcher) { 163 for (int i = 1; i <= 4; i++) { 164 String ipSegment = ipAddressMatcher.group(i); 165 if (ipSegment == null || ipSegment.length() <= 0) { 166 return false; 167 } 168 169 int iIpSegment = 0; 170 171 try { 172 iIpSegment = Integer.parseInt(ipSegment); 173 } catch(NumberFormatException e) { 174 return false; 175 } 176 177 if (iIpSegment > 255) { 178 return false; 179 } 180 181 } 182 return true; 183 } 184 185 189 protected boolean isValidSymbolicDomain(String domain) { 190 String [] domainSegment = new String [10]; 191 boolean match = true; 192 int i = 0; 193 Perl5Util atomMatcher = new Perl5Util(); 194 while (match) { 195 match = atomMatcher.match(ATOM_PATTERN, domain); 196 if (match) { 197 domainSegment[i] = atomMatcher.group(1); 198 int l = domainSegment[i].length() + 1; 199 domain = 200 (l >= domain.length()) 201 ? "" 202 : domain.substring(l); 203 204 i++; 205 } 206 } 207 208 int len = i; 209 if (domainSegment[len - 1].length() < 2 210 || domainSegment[len - 1].length() > 4) { 211 212 return false; 213 } 214 215 if (len < 2) { 217 return false; 218 } 219 220 return true; 221 } 222 228 protected String stripComments(String emailStr) { 229 String input = emailStr; 230 String result = emailStr; 231 String commentPat = "s/^((?:[^\"\\\\]|\\\\.)*(?:\"(?:[^\"\\\\]|\\\\.)*\"(?:[^\"\\\\]|\111111\\\\.)*)*)\\((?:[^()\\\\]|\\\\.)*\\)/$1 /osx"; 232 Perl5Util commentMatcher = new Perl5Util(); 233 result = commentMatcher.substitute(commentPat,input); 234 while (!result.equals(input)) { 236 input = result; 237 result = commentMatcher.substitute(commentPat,input); 238 } 239 return result; 240 241 } 242 } 243 | Popular Tags |