package fr.openwide.core.spring.notification.model; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.IDN; import java.nio.charset.Charset; import java.util.List; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import org.apache.commons.lang3.builder.HashCodeBuilder; import com.google.common.base.Splitter; import fr.openwide.core.spring.notification.exception.InvalidNotificationTargetException; import fr.openwide.core.spring.util.StringUtils; public class NotificationTarget implements Serializable { private static final long serialVersionUID = -1021739893358432630L; private final InternetAddress address; private NotificationTarget(InternetAddress address) { this.address = address; } public InternetAddress getAddress() { return address; } public static NotificationTarget of(String email) throws InvalidNotificationTargetException { return new NotificationTarget(getInternetAddress(email, null, null)); } public static NotificationTarget of(INotificationRecipient recipient, Charset charset) throws InvalidNotificationTargetException { return new NotificationTarget(getInternetAddress(recipient.getEmail(), recipient.getFullName(), charset)); } private static InternetAddress getInternetAddress(String email, String fullName, Charset charset) throws InvalidNotificationTargetException { try { if (!StringUtils.hasText(email)) { throw new AddressException("Email address is empty"); } List<String> emailParts = Splitter.on('@').omitEmptyStrings().trimResults().splitToList(StringUtils.lowerCase(email)); if (emailParts.size() != 2) { throw new AddressException("Invalid email address", email); } String idnEmail = emailParts.get(0) + '@' + IDN.toASCII(emailParts.get(1)); try { InternetAddress internetAddress = new InternetAddress(idnEmail, fullName, charset != null ? charset.name() : null); internetAddress.validate(); return internetAddress; } catch (UnsupportedEncodingException e) { throw new AddressException(String.format("Unable to parse the address %1$s <$2$s>: invalid encoding", fullName, idnEmail)); } } catch (AddressException e) { throw new InvalidNotificationTargetException( String.format("Invalid notification target: %s / %s / %s", email, fullName, charset), e ); } } @Override public String toString() { if (address == null) { return "<null>"; } StringBuilder sb = new StringBuilder(); if (StringUtils.hasText(address.getPersonal())) { sb.append(address.getPersonal()).append(" "); } sb.append("<").append(address.getAddress()).append(">"); return sb.toString(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof NotificationTarget)) { return false; } return address.equals(((NotificationTarget) obj).getAddress()); } @Override public int hashCode() { return new HashCodeBuilder().append(address).toHashCode(); } }