package ilarkesto.email;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
public final class EmailAddress {
public static void main(String[] args) {
System.out.println(EmailAddress.formatAddress("<duke@hell.org> Crap", false));
}
private String address;
private String label;
public EmailAddress(String emailAddress) {
if (emailAddress == null) throw new IllegalArgumentException("emailAddress == null");
this.address = formatAddress(emailAddress, true);
validatePlainAddress(this.address);
int idx = emailAddress.indexOf("<");
if (idx >= 0) {
label = emailAddress.substring(0, idx).trim();
if (label.length() >= 2) {
if (label.startsWith("\"")) label = label.substring(1);
if (label.endsWith("\"")) label = label.substring(0, label.length() - 1);
}
if (label.length() == 0) label = null;
}
}
public EmailAddress(String email, String label) {
if (email == null) throw new IllegalArgumentException("email == null");
validatePlainAddress(email);
this.address = email;
this.label = label;
}
public String getAddress() {
return address;
}
public String getLabel() {
return label;
}
public boolean isLabelSet() {
return label != null;
}
private int hashCode;
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = 23;
hashCode = hashCode * 37 + address.hashCode();
// if (label != null) hashCode = hashCode * 37 + label.hashCode();
}
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof EmailAddress)) return false;
EmailAddress other = (EmailAddress) obj;
return address.equals(other.address); // && Utl.equals(label, other.label);
}
@Override
public String toString() {
if (!isLabelSet()) {
return address;
} else {
return label + " <" + address + ">";
}
}
public static String formatAddress(String email, boolean removeText) {
if (email == null) return null;
email = email.trim();
if (email.endsWith(">")) {
int idx = email.indexOf("<");
if (idx < 0) throw new RuntimeException("Illegal EmailAddress: " + email);
if (removeText) {
email = email.substring(idx);
email = formatPlainAddress(email);
} else {
if (idx == 0) {
email = formatPlainAddress(email);
} else {
String label = email.substring(0, idx).trim();
if (label.length() >= 2) {
if (label.startsWith("\"")) label = label.substring(1);
if (label.endsWith("\"")) label = label.substring(0, label.length() - 1);
}
String address = formatPlainAddress(email.substring(idx));
email = label + " <" + address + ">";
}
}
} else {
email = formatPlainAddress(email);
}
return email;
}
public static final String formatPlainAddress(String email) {
if (email == null) return null;
email = email.trim();
email = email.toLowerCase();
if (email.startsWith("<")) email = email.substring(1);
int closerIdx = email.indexOf('>');
if (closerIdx > 0) email = email.substring(0, closerIdx);
email = email.trim();
int idx = email.indexOf(' ');
if (idx > 0) email = email.substring(0, idx);
return email;
}
public static final void validatePlainAddress(String email) {
String msg = "Illegal email address: " + email;
if (email.length() < 5) throw new RuntimeException(msg);
if (email.contains(" ") || email.contains("\n") || email.contains("\t")) throw new RuntimeException(msg);
int idx = email.indexOf('@');
if (idx < 1) throw new RuntimeException(msg);
if (idx >= email.length() - 3) throw new RuntimeException(msg);
int idx2 = email.lastIndexOf('.');
if (idx2 < 3) throw new RuntimeException(msg);
if (idx2 <= idx) throw new RuntimeException(msg);
if (idx2 >= email.length() - 1) throw new RuntimeException(msg);
}
public static final Set<EmailAddress> parseList(String s) {
if (s == null) return null;
Set<EmailAddress> result = new HashSet<EmailAddress>();
StringTokenizer st = new StringTokenizer(s, ",;");
while (st.hasMoreTokens()) {
result.add(new EmailAddress(st.nextToken()));
}
return result;
}
public static String getAddress(EmailAddress emailAddress) {
return emailAddress == null ? null : emailAddress.getAddress();
}
public static final String toString(Collection<EmailAddress> addresses) {
if (addresses == null) return null;
StringBuilder sb = new StringBuilder();
boolean first = true;
for (EmailAddress ea : addresses) {
if (ea == null) continue;
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(ea);
}
return sb.toString();
}
}