package org.simplejavamail.mailer.config; import javax.mail.Session; import java.util.Properties; import static java.lang.String.format; /** * Defines the various types of transport protocols and implements respective properties so that a {@link Session} may be configured using a * <code>TransportStrategy</code> implementation. * * @author Benny Bottema */ public enum TransportStrategy { /** * Simplest possible form: only vanilla ".smtp." property names and no extra properties. Additionally the transport protocol is explicitly set to * smtp. */ SMTP_PLAIN { /** * Here protocol "mail.transport.protocol" is set to "smtp". * * @see TransportStrategy#SMTP_PLAIN */ @Override public Properties generateProperties() { final Properties props = super.generateProperties(); props.put("mail.transport.protocol", "smtp"); return props; } /** * @return "mail.smtp.host" */ @Override public String propertyNameHost() { return "mail.smtp.host"; } /** * @return "mail.smtp.port" */ @Override public String propertyNamePort() { return "mail.smtp.port"; } /** * @return "mail.smtp.username" */ @Override public String propertyNameUsername() { return "mail.smtp.username"; } /** * @return "mail.smtp.auth" */ @Override public String propertyNameAuthenticate() { return "mail.smtp.auth"; } }, /** * SMTPS / SSL transport strategy, that returns the ".smtps." variation of the SMTP_PLAIN version. Additionally the transport protocol is * explicitly set to smtps. Finally, he property "mail.smtps.quitwait" is set to false, to get rid of a strange SSL exception:<br> * <p> * <pre> * javax.mail.MessagingException: Exception reading response; * nested exception is: * javax.net.ssl.SSLException: Unsupported record version Unknown-50.49 * (..) * </pre> * <p> * <blockquote>The mail is sent but the exception is unwanted. The property <em>quitwait</em> means If set to false, the QUIT command is sent and * the connection is immediately closed. If set to true (the default), causes the transport to wait for the response to the QUIT * command</blockquote><br> <strong>- <a href="http://www.rgagnon.com/javadetails/java-0570.html">source</a></strong> */ SMTP_SSL { /** * Here protocol "mail.transport.protocol" is set to "smtps" and the quitwait property "mail.smtps.quitwait" is set to "false". * * @see TransportStrategy#SMTP_SSL */ @Override public Properties generateProperties() { final Properties properties = super.generateProperties(); properties.put("mail.transport.protocol", "smtps"); properties.put("mail.smtps.quitwait", "false"); return properties; } /** * @return "mail.smtps.host" */ @Override public String propertyNameHost() { return "mail.smtps.host"; } /** * @return "mail.smtps.port" */ @Override public String propertyNamePort() { return "mail.smtps.port"; } /** * @return "mail.smtps.username" */ @Override public String propertyNameUsername() { return "mail.smtps.username"; } /** * @return "mail.smtps.auth" */ @Override public String propertyNameAuthenticate() { return "mail.smtps.auth"; } }, /** * <strong>NOTE: this code is in untested beta state</strong> * <p> * Uses standard ".smtp." property names (like {@link TransportStrategy#SMTP_PLAIN}). Additionally the transport protocol is explicitly set to * smtp. Finally, the property "mail.smtp.starttls.enable" is being set to true. */ SMTP_TLS { /** * Here protocol "mail.transport.protocol" is set to "smtp" and the tls property "mail.smtp.starttls.enable" is set to "true". * * @see TransportStrategy#SMTP_TLS */ @Override public Properties generateProperties() { final Properties props = super.generateProperties(); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.starttls.enable", "true"); return props; } /** * @return "mail.smtp.host" */ @Override public String propertyNameHost() { return "mail.smtp.host"; } /** * @return "mail.smtp.port" */ @Override public String propertyNamePort() { return "mail.smtp.port"; } /** * @return "mail.smtp.username" */ @Override public String propertyNameUsername() { return "mail.smtp.username"; } /** * @return "mail.smtp.auth" */ @Override public String propertyNameAuthenticate() { return "mail.smtp.auth"; } }; /** * Marker property used to track which {@link TransportStrategy} has been used. This way we can differentiate between preconfigured custom * <code>Session</code> and sessions created by a <code>Mailer</code> instance, without checking each and every property for a specific strategy. * <p> * This is mainly for logging purposes. */ private static final String TRANSPORT_STRATEGY_MARKER = "simplejavamail.transportstrategy"; /** * Base implementation that simply returns an empty list of properties and a marker for the specific current strategy. * <p> * Should be overridden by the various strategies where appropriate. * * @return An empty <code>Properties</code> instance. */ public Properties generateProperties() { final Properties properties = new Properties(); properties.put(TRANSPORT_STRATEGY_MARKER, name()); return properties; } public abstract String propertyNameHost(); public abstract String propertyNamePort(); public abstract String propertyNameUsername(); public abstract String propertyNameAuthenticate(); /** * @param session The session to determine the current transport strategy for * @return Which strategy matches the current Session properties. * @see #generateProperties() */ public static TransportStrategy findStrategyForSession(final Session session) { final String transportStrategyMarker = session.getProperty(TRANSPORT_STRATEGY_MARKER); if (transportStrategyMarker != null) { return TransportStrategy.valueOf(transportStrategyMarker); } return null; } public String toString(final Properties properties) { return format("session (host: %s, port: %s, username: %s, authenticate: %s, transport: %s)", properties.get(propertyNameHost()), properties.get(propertyNamePort()), properties.get(propertyNameUsername()), properties.get(propertyNameAuthenticate()), this); } }