Last active
April 28, 2016 11:23
-
-
Save monossido/f6630598850b87ca9be8670219dc191b to your computer and use it in GitHub Desktop.
Custom Email Validator (with MX support) for saripaar android library //compile 'javax.jmdns:jmdns:3.4.1' in build.gradle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.unipiazza.restlibrary.customsaripaar; | |
//compile 'javax.jmdns:jmdns:3.4.1' in build.gradle | |
import org.xbill.DNS.Lookup; | |
import org.xbill.DNS.Record; | |
import org.xbill.DNS.TextParseException; | |
import org.xbill.DNS.Type; | |
import java.io.Serializable; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
/** | |
* Created by monossido on 30/10/15. | |
*/ | |
public class CustomEmailValidator implements Serializable { | |
private static final long serialVersionUID = 1705927040799295880L; | |
private static final String SPECIAL_CHARS = "\\p{Cntrl}\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]"; | |
private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]"; | |
private static final String QUOTED_USER = "(\"[^\"]*\")"; | |
private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")"; | |
private static final String EMAIL_REGEX = "^\\s*?(.+)@(.+?)\\s*$"; | |
private static final String IP_DOMAIN_REGEX = "^\\[(.*)\\]$"; | |
private static final String USER_REGEX = "^\\s*" + WORD + "(\\." + WORD + ")*$"; | |
private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX); | |
private static final Pattern IP_DOMAIN_PATTERN = Pattern.compile(IP_DOMAIN_REGEX); | |
private static final Pattern USER_PATTERN = Pattern.compile(USER_REGEX); | |
private final boolean allowLocal; | |
/** | |
* Singleton instance of this class, which | |
* doesn't consider local addresses as valid. | |
*/ | |
private static final CustomEmailValidator EMAIL_VALIDATOR = new CustomEmailValidator(false); | |
/** | |
* Singleton instance of this class, which does | |
* consider local addresses valid. | |
*/ | |
private static final CustomEmailValidator EMAIL_VALIDATOR_WITH_LOCAL = new CustomEmailValidator(true); | |
/** | |
* Returns the Singleton instance of this validator. | |
* | |
* @return singleton instance of this validator. | |
*/ | |
public static CustomEmailValidator getInstance() { | |
return EMAIL_VALIDATOR; | |
} | |
/** | |
* Returns the Singleton instance of this validator, | |
* with local validation as required. | |
* | |
* @param allowLocal Should local addresses be considered valid? | |
* @return singleton instance of this validator | |
*/ | |
public static CustomEmailValidator getInstance(boolean allowLocal) { | |
if (allowLocal) { | |
return EMAIL_VALIDATOR_WITH_LOCAL; | |
} | |
return EMAIL_VALIDATOR; | |
} | |
/** | |
* Protected constructor for subclasses to use. | |
* | |
* @param allowLocal Should local addresses be considered valid? | |
*/ | |
protected CustomEmailValidator(boolean allowLocal) { | |
super(); | |
this.allowLocal = allowLocal; | |
} | |
/** | |
* <p>Checks if a field has a valid e-mail address.</p> | |
* | |
* @param email The value validation is being performed on. A <code>null</code> | |
* value is considered invalid. | |
* @return true if the email address is valid. | |
*/ | |
public boolean isValid(String email) { | |
if (email == null) { | |
return false; | |
} | |
if (email.endsWith(".")) { // check this first - it's cheap! | |
return false; | |
} | |
// Check the whole email address structure | |
Matcher emailMatcher = EMAIL_PATTERN.matcher(email); | |
if (!emailMatcher.matches()) { | |
return false; | |
} | |
if (!isValidUser(emailMatcher.group(1))) { | |
return false; | |
} | |
return isValidDomain(emailMatcher.group(2)); | |
} | |
/** | |
* Returns true if the domain component of an email address is valid. | |
* | |
* @param domain being validated, may be in IDN format | |
* @return true if the email address's domain is valid. | |
*/ | |
protected boolean isValidDomain(String domain) { | |
// see if domain is an IP address in brackets | |
Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain); | |
if (ipDomainMatcher.matches()) { | |
InetAddressValidator inetAddressValidator = | |
InetAddressValidator.getInstance(); | |
boolean inetAddressValid = inetAddressValidator.isValid(ipDomainMatcher.group(1)); | |
if (inetAddressValid) return isMxDomainValid(domain); | |
else return false; | |
} | |
// Domain is symbolic name | |
DomainValidator domainValidator = | |
DomainValidator.getInstance(allowLocal); | |
boolean domainValid = domainValidator.isValid(domain) || | |
domainValidator.isValidTld(domain); | |
if (domainValid) return isMxDomainValid(domain); | |
else return false; | |
} | |
private boolean isMxDomainValid(String domain) { | |
Record[] records; | |
try { | |
records = new Lookup(domain, Type.MX).run(); | |
if (records == null) | |
return false; | |
} catch (TextParseException e) { | |
e.printStackTrace(); | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Returns true if the user component of an email address is valid. | |
* | |
* @param user being validated | |
* @return true if the user name is valid. | |
*/ | |
protected boolean isValidUser(String user) { | |
return USER_PATTERN.matcher(user).matches(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment