View Javadoc

1   package org.seasar.cubby.validator.validators;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import java.util.regex.Matcher;
6   import java.util.regex.Pattern;
7   
8   import org.seasar.cubby.validator.BaseValidator;
9   import org.seasar.cubby.validator.ValidationContext;
10  import org.seasar.framework.util.StringUtil;
11  
12  public class EmailValidator extends BaseValidator {
13  
14      private static final String SPECIAL_CHARS = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]";
15      private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";
16      private static final String QUOTED_USER = "(\"[^\"]*\")";
17      private static final String ATOM = VALID_CHARS + '+';
18      private static final String WORD = "(" + ATOM + "|" + QUOTED_USER + ")";
19  
20      private static final String LEGAL_ASCII_PATTERN = "^[\\x00-\\x7F]+$";
21      private static final String EMAIL_PATTERN = "^(.+)@(.+)$";
22      private static final String IP_DOMAIN_PATTERN =
23              "^(\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})$";
24  
25      private static final String USER_PATTERN = "^" + WORD + "(\\." + WORD + ")*$";
26      private static final String DOMAIN_PATTERN = "^" + ATOM + "(\\." + ATOM + ")*$";
27      private static final String ATOM_PATTERN = "(" + ATOM + ")";
28  
29  	public EmailValidator() {
30  		this("valid.email");
31  	}
32  
33  	public EmailValidator(final String messageKey) {
34  		this.setMessageKey(messageKey);
35  	}
36  	
37  	public String validate(final ValidationContext ctx) {
38  		final Object value = ctx.getValue();
39  		if (value == null) {
40  			return null;
41  		}
42  		if (value instanceof String) {
43  			final String email = (String) value;
44  			if (StringUtil.isEmpty(email)) {
45  				return null;
46  			}
47  			
48  			boolean match = !email.endsWith(".");
49  			if(match){
50  				Pattern pattern = Pattern.compile(LEGAL_ASCII_PATTERN);
51  				Matcher matchAsciiPat = pattern.matcher(email);
52  				match = matchAsciiPat.matches();
53  			}
54  			
55  			if(match){
56  				Pattern pattern = Pattern.compile(EMAIL_PATTERN);
57  				Matcher matcher = pattern.matcher(email);
58  				match = matcher.find();
59  	        	if(match){
60  			        if (isValidUser(matcher.group(1)) && 
61  			        	isValidDomain(matcher.group(2))) {
62  			            return null;
63  			        }
64  	        	}
65  			}
66  		}
67  		return getMessage(getPropertyMessage(ctx.getName()));
68      }
69  
70      private boolean isValidDomain(String domain) {
71          Pattern pattern = Pattern.compile(IP_DOMAIN_PATTERN);
72  		Matcher ipAddressMatcher = pattern.matcher(domain);
73  
74          if (ipAddressMatcher.find()) {
75              if (isValidIpAddress(ipAddressMatcher)) {
76                  return true;
77              }
78          } else {
79              pattern = Pattern.compile(DOMAIN_PATTERN);
80      		Matcher domainMatcher = pattern.matcher(domain);
81              if (domainMatcher.matches()) {
82                  if (isValidSymbolicDomain(domain)) {
83                      return true;
84                  }
85              }
86          }
87          return false;
88      }
89  
90      private boolean isValidUser(String user) {
91      	Pattern pattern = Pattern.compile(USER_PATTERN);
92  		Matcher userMatcher = pattern.matcher(user);
93          return userMatcher.matches();
94      }
95  
96      private boolean isValidIpAddress(Matcher ipAddressMatcher) {
97          for (int i = 1; i <= 4; i++) {
98              String ipSegment = ipAddressMatcher.group(i);
99              if (ipSegment == null || ipSegment.length() <= 0) {
100                 return false;
101             }
102 
103             int iIpSegment = 0;
104 
105             try {
106                 iIpSegment = Integer.parseInt(ipSegment);
107             } catch(NumberFormatException e) {
108                 return false;
109             }
110 
111             if (iIpSegment > 255) {
112                 return false;
113             }
114 
115         }
116         return true;
117     }
118 
119     private boolean isValidSymbolicDomain(String domain) {
120         List<String> domainSegments = new ArrayList<String>();
121         boolean match = true;
122         int i = 0;
123         
124         Pattern pattern = Pattern.compile(ATOM_PATTERN);
125 		Matcher atomMatcher;
126 		String ds;
127         while (match) {
128         	atomMatcher = pattern.matcher(domain);
129             match = atomMatcher.find();
130             if (match) {
131             	ds = atomMatcher.group(1);
132             	domainSegments.add(ds);
133                 int l = ds.length() + 1;
134                 domain =
135                         (l >= domain.length())
136                         ? ""
137                         : domain.substring(l);
138 
139                 i++;
140             }
141         }
142 
143         int size = domainSegments.size();
144         if( size > 0){
145 	        String end = domainSegments.get(size-1);
146 	        if (end.length() < 2 || end.length() > 4) {
147 	            return false;
148 	        }
149         }
150 
151         if (domainSegments.size() < 2) {
152             return false;
153         }
154 
155         return true;
156     }
157 }