/**
* Copyright (c) 2011-2014, OpenIoT
*
* This file is part of OpenIoT.
*
* OpenIoT is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* OpenIoT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenIoT. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: OpenIoT mailto: info@openiot.eu
* @author Behnaz Bostanipour
*/
package org.openiot.gsn.http.ac;
/*
* Copyright 2008 Les Hazlewood
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.util.regex.Pattern;
/**
* An email address represents the textual string of an
* <a href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822</a> email address and other corresponding
* information of interest.
*
* <p>If you use this code, please keep the author information in tact and reference
* my site at <a href="http://www.leshazlewood.com">leshazlewood.com</a>. Thanks!
*
* @author Les Hazlewood
*/
public class EmailAddress implements Serializable {
/**
* This constant states that domain literals are allowed in the email address, e.g.:
*
* <p><tt>someone@[192.168.1.100]</tt> or <br/>
* <tt>john.doe@[23:33:A2:22:16:1F]</tt> or <br/>
* <tt>me@[my computer]</tt></p>
*
* <p>The RFC says these are valid email addresses, but most people don't like allowing them.
* If you don't want to allow them, and only want to allow valid domain names
* (<a href="http://www.ietf.org/rfc/rfc1035.txt">RFC 1035</a>, x.y.z.com, etc),
* change this constant to <tt>false</tt>.
*
* <p>Its default value is <tt>true</tt> to remain RFC 2822 compliant, but
* you should set it depending on what you need for your application.
*/
private static final boolean ALLOW_DOMAIN_LITERALS = true;
/**
* This contstant states that quoted identifiers are allowed
* (using quotes and angle brackets around the raw address) are allowed, e.g.:
*
* <p><tt>"John Smith" <john.smith@somewhere.com></tt>
*
* <p>The RFC says this is a valid mailbox. If you don't want to
* allow this, because for example, you only want users to enter in
* a raw address (<tt>john.smith@somewhere.com</tt> - no quotes or angle
* brackets), then change this constant to <tt>false</tt>.
*
* <p>Its default value is <tt>true</tt> to remain RFC 2822 compliant, but
* you should set it depending on what you need for your application.
*/
private static final boolean ALLOW_QUOTED_IDENTIFIERS = true;
// RFC 2822 2.2.2 Structured Header Field Bodies
private static final String wsp = "[ \\t]"; //space or tab
private static final String fwsp = wsp + "*";
//RFC 2822 3.2.1 Primitive tokens
private static final String dquote = "\\\"";
//ASCII Control characters excluding white space:
private static final String noWsCtl = "\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F";
//all ASCII characters except CR and LF:
private static final String asciiText = "[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F]";
// RFC 2822 3.2.2 Quoted characters:
//single backslash followed by a text char
private static final String quotedPair = "(\\\\" + asciiText + ")";
//RFC 2822 3.2.4 Atom:
private static final String atext = "[a-zA-Z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]";
private static final String atom = fwsp + atext + "+" + fwsp;
private static final String dotAtomText = atext + "+" + "(" + "\\." + atext + "+)*";
private static final String dotAtom = fwsp + "(" + dotAtomText + ")" + fwsp;
//RFC 2822 3.2.5 Quoted strings:
//noWsCtl and the rest of ASCII except the doublequote and backslash characters:
private static final String qtext = "[" + noWsCtl + "\\x21\\x23-\\x5B\\x5D-\\x7E]";
private static final String qcontent = "(" + qtext + "|" + quotedPair + ")";
private static final String quotedString = dquote + "(" + fwsp + qcontent + ")*" + fwsp + dquote;
//RFC 2822 3.2.6 Miscellaneous tokens
private static final String word = "((" + atom + ")|(" + quotedString + "))";
private static final String phrase = word + "+"; //one or more words.
//RFC 1035 tokens for domain names:
private static final String letter = "[a-zA-Z]";
private static final String letDig = "[a-zA-Z0-9]";
private static final String letDigHyp = "[a-zA-Z0-9-]";
private static final String rfcLabel = letDig + "(" + letDigHyp + "{0,61}" + letDig + ")?";
private static final String rfc1035DomainName = rfcLabel + "(\\." + rfcLabel + ")*\\." + letter + "{2,6}";
//RFC 2822 3.4 Address specification
//domain text - non white space controls and the rest of ASCII chars not including [, ], or \:
private static final String dtext = "[" + noWsCtl + "\\x21-\\x5A\\x5E-\\x7E]";
private static final String dcontent = dtext + "|" + quotedPair;
private static final String domainLiteral = "\\[" + "(" + fwsp + dcontent + "+)*" + fwsp + "\\]";
private static final String rfc2822Domain = "(" + dotAtom + "|" + domainLiteral + ")";
private static final String domain = ALLOW_DOMAIN_LITERALS ? rfc2822Domain : rfc1035DomainName;
private static final String localPart = "((" + dotAtom + ")|(" + quotedString + "))";
private static final String addrSpec = localPart + "@" + domain;
private static final String angleAddr = "<" + addrSpec + ">";
private static final String nameAddr = "(" + phrase + ")?" + fwsp + angleAddr;
private static final String mailbox = nameAddr + "|" + addrSpec;
//now compile a pattern for efficient re-use:
//if we're allowing quoted identifiers or not:
private static final String patternString = ALLOW_QUOTED_IDENTIFIERS ? mailbox : addrSpec;
public static final Pattern VALID_PATTERN = Pattern.compile(patternString);
//class attributes
private String text;
private boolean bouncing = true;
private boolean verified = false;
private String label;
public EmailAddress() {
super();
}
public EmailAddress(String text) {
super();
setText(text);
}
/**
* Returns the actual email address string, e.g. <tt>someone@somewhere.com</tt>
*
* @return the actual email address string.
*/
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
/**
* Returns whether or not any emails sent to this email address come back as bounced
* (undeliverable).
*
* <p>Default is <tt>false</tt> for convenience's sake - if a bounced message is ever received for this
* address, this value should be set to <tt>true</tt> until verification can made.
*
* @return whether or not any emails sent to this email address come back as bounced
* (undeliverable).
*/
public boolean isBouncing() {
return bouncing;
}
public void setBouncing(boolean bouncing) {
this.bouncing = bouncing;
}
/**
* Returns whether or not the party associated with this email has verified that it is
* their email address.
*
* <p>Verification is usually done by sending an email to this
* address and waiting for the party to respond or click a specific link in the email.
*
* <p>Default is <tt>false</tt>.
*
* @return whether or not the party associated with this email has verified that it is
* their email address.
*/
public boolean isVerified() {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
/**
* Party label associated with this address, for example, 'Home', 'Work', etc.
*
* @return a label associated with this address, for example 'Home', 'Work', etc.
*/
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
/**
* Returns whether or not the text represented by this object instance is valid
* according to the <tt>RFC 2822</tt> rules.
*
* @return true if the text represented by this instance is valid according
* to RFC 2822, false otherwise.
*/
public boolean isValid() {
return isValidText(getText());
}
/**
* Utility method that checks to see if the specified string is a valid
* email address according to the * RFC 2822 specification.
*
* @param email the email address string to test for validity.
* @return true if the given text valid according to RFC 2822, false otherwise.
*/
public static boolean isValidText(String email) {
return (email != null) && VALID_PATTERN.matcher(email).matches();
}
public boolean equals(Object o) {
if (o instanceof EmailAddress) {
EmailAddress ea = (EmailAddress) o;
return getText().equals(ea.getText());
}
return false;
}
public int hashCode() {
return getText().hashCode();
}
public String toString() {
return getText();
}
}