Coverage Report - org.mule.transport.email.AbstractMailConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMailConnector
71%
52/73
39%
11/28
1.611
 
 1  
 /*
 2  
  * $Id: AbstractMailConnector.java 10489 2008-01-23 17:53:38Z dfeist $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.email;
 12  
 
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.endpoint.EndpointURI;
 15  
 import org.mule.api.endpoint.ImmutableEndpoint;
 16  
 import org.mule.api.lifecycle.InitialisationException;
 17  
 import org.mule.transport.AbstractConnector;
 18  
 import org.mule.util.StringUtils;
 19  
 
 20  
 import java.util.Enumeration;
 21  
 import java.util.HashMap;
 22  
 import java.util.Map;
 23  
 import java.util.Properties;
 24  
 
 25  
 import javax.mail.Authenticator;
 26  
 import javax.mail.Session;
 27  
 import javax.mail.URLName;
 28  
 
 29  
 /**
 30  
  * Abstract superclass for mail connectors. Provides Mule with an Authenticator
 31  
  * object and other shared functionality like e.g. MuleSession creation.
 32  
  */
 33  
 public abstract class AbstractMailConnector extends AbstractConnector
 34  
 {
 35  
 
 36  
     public static final String MAILBOX = "INBOX";
 37  
 
 38  236
     private Map sessions = new HashMap();
 39  
     private String mailboxFolder;
 40  
     private int defaultPort;
 41  
 
 42  
     /**
 43  
      * A custom authenticator to be used on any mail sessions created with this
 44  
      * connector. This will only be used if user name credendials are set on the
 45  
      * endpoint.
 46  
      */
 47  236
     private Authenticator authenticator = null;
 48  
 
 49  
     public AbstractMailConnector(int defaultPort, String mailboxFolder)
 50  
     {
 51  236
         super();
 52  236
         this.defaultPort = defaultPort;
 53  236
         this.mailboxFolder = mailboxFolder;
 54  236
     }
 55  
 
 56  
     public int getDefaultPort()
 57  
     {
 58  0
         return defaultPort;
 59  
     }
 60  
 
 61  
     public Authenticator getAuthenticator()
 62  
     {
 63  94
         return authenticator;
 64  
     }
 65  
 
 66  
     public void setAuthenticator(Authenticator authenticator)
 67  
     {
 68  42
         this.authenticator = authenticator;
 69  42
     }
 70  
     
 71  
     public String getMailboxFolder()
 72  
     {
 73  90
         return mailboxFolder;
 74  
     }
 75  
 
 76  
     public void setMailboxFolder(String mailboxFolder)
 77  
     {
 78  24
         this.mailboxFolder = mailboxFolder;
 79  24
     }
 80  
 
 81  
     public synchronized SessionDetails getSessionDetails(ImmutableEndpoint endpoint)
 82  
     {
 83  62
         SessionDetails sessionDetails = (SessionDetails) sessions.get(endpoint);
 84  62
         if (null == sessionDetails)
 85  
         {
 86  52
             sessionDetails = newSession(endpoint);
 87  52
             sessions.put(endpoint, sessionDetails);
 88  
         }
 89  62
         return sessionDetails;
 90  
     }
 91  
     
 92  
     public URLName urlFromEndpoint(ImmutableEndpoint endpoint)
 93  
     {
 94  52
         String inbox = endpoint.getEndpointURI().getPath();
 95  52
         if (inbox.length() == 0)
 96  
         {
 97  52
             inbox = getMailboxFolder();
 98  
         }
 99  
         else
 100  
         {
 101  0
             inbox = inbox.substring(1);
 102  
         }
 103  
 
 104  52
         EndpointURI uri = endpoint.getEndpointURI();
 105  52
         return new URLName(uri.getScheme(), uri.getHost(), uri.getPort(), inbox,
 106  
                 uri.getUser(), uri.getPassword());
 107  
     }
 108  
     
 109  
     /**
 110  
      * Some protocols (eg secure extensions) extend a "base" protocol.
 111  
      * Subclasses for such protocols should override this method.
 112  
      * 
 113  
      * @return the underlying (eg non-secure) protocol
 114  
      */
 115  
     protected String getBaseProtocol()
 116  
     {
 117  160
         return getProtocol();
 118  
     }
 119  
     
 120  
     /**
 121  
      * Subclasses should extend this to add further properties.  
 122  
      * Synchronization is managed outside this call (so no need to synchronize further on properties)
 123  
      * 
 124  
      * @param global system properties 
 125  
      * @param local local properties (specific to one session)
 126  
      * @param url the endpoint url
 127  
      */
 128  
     protected void extendPropertiesForSession(Properties global, Properties local, URLName url)
 129  
     {
 130  52
         int port = url.getPort();
 131  52
         if (port == -1)
 132  
         {
 133  8
             port = this.getDefaultPort();
 134  
         }
 135  52
         local.setProperty("mail." + getBaseProtocol() + ".socketFactory.port", Integer.toString(port));
 136  
 
 137  52
         if (StringUtils.isNotBlank(url.getPassword()))
 138  
         {
 139  42
             local.setProperty("mail." + getBaseProtocol() + ".auth", "true");
 140  42
             if (getAuthenticator() == null)
 141  
             {
 142  42
                 setAuthenticator(new DefaultAuthenticator(url.getUsername(), url.getPassword()));
 143  42
                 if (logger.isDebugEnabled())
 144  
                 {
 145  0
                     logger.debug("No Authenticator set on connector: " + getName() + "; using default.");
 146  
                 }
 147  
             }
 148  
         }
 149  
         else
 150  
         {
 151  10
             local.setProperty("mail." + getBaseProtocol() + ".auth", "false");
 152  
         }
 153  
         
 154  
         // TODO - i'm not at all certain that these properties (especially the ones
 155  
         // using the base protocol) are needed.  they are inherited from old, gnarly
 156  
         // code.
 157  
 
 158  52
         if (StringUtils.isNotBlank(url.getHost())) {
 159  52
             local.setProperty("mail." + getBaseProtocol() + ".host", url.getHost());
 160  
         }
 161  52
         local.setProperty("mail." + getBaseProtocol() + ".rsetbeforequit", "true");
 162  52
     }
 163  
 
 164  
     protected SessionDetails newSession(ImmutableEndpoint endpoint)
 165  
     {
 166  52
         URLName url = urlFromEndpoint(endpoint);
 167  
 
 168  52
         Properties global = System.getProperties();
 169  52
         Properties local = new Properties();
 170  
         Session session;
 171  
 
 172  
         // make sure we do not mess with authentication set via system properties
 173  52
         synchronized (global)
 174  
         {
 175  52
             extendPropertiesForSession(global, local, url);
 176  52
             session = Session.getInstance(local, getAuthenticator());
 177  52
         }
 178  
 
 179  52
         if (logger.isDebugEnabled())
 180  
         {
 181  0
             local.setProperty("mail.debug", "true");
 182  
             
 183  0
             dumpProperties("MuleSession local properties", local, true);
 184  0
             dumpProperties("System global properties", global, true);
 185  0
             logger.debug("Creating mail session: host = " + url.getHost() + ", port = " + url.getPort()
 186  
                 + ", user = " + url.getUsername() + ", pass = " + url.getPassword());
 187  
         }
 188  
 
 189  52
         return new SessionDetails(session, url);
 190  
     }
 191  
     
 192  
     protected void dumpProperties(String title, Properties properties, boolean filter)
 193  
     {
 194  0
         int skipped = 0;
 195  0
         logger.debug(title + " =============");
 196  0
         Enumeration keys = properties.keys();
 197  0
         while (keys.hasMoreElements())
 198  
         {
 199  0
             String key = (String) keys.nextElement();
 200  0
             if (!filter || key.startsWith("mule.") || key.startsWith("mail.") || key.startsWith("javax."))
 201  
             {
 202  0
                 String value = properties.getProperty(key);
 203  0
                 logger.debug(key + ": " + value);
 204  0
             }
 205  
             else 
 206  
             {
 207  0
                 ++skipped;
 208  
             }
 209  0
         }
 210  0
         if (filter)
 211  
         {
 212  0
             logger.debug("skipped " + skipped);
 213  
         }
 214  0
     }
 215  
     
 216  
     // supply these here because sub-classes are very simple
 217  
 
 218  
     protected void doInitialise() throws InitialisationException
 219  
     {
 220  
         // template method, nothing to do
 221  206
     }
 222  
 
 223  
     protected void doDispose()
 224  
     {
 225  
         // template method, nothing to do
 226  384
     }
 227  
 
 228  
     protected void doConnect() throws Exception
 229  
     {
 230  
         // template method, nothing to do
 231  234
     }
 232  
 
 233  
     protected void doDisconnect() throws Exception
 234  
     {
 235  
         // template method, nothing to do
 236  234
     }
 237  
 
 238  
     protected void doStart() throws MuleException
 239  
     {
 240  
         // template method, nothing to do
 241  234
     }
 242  
 
 243  
     protected void doStop() throws MuleException
 244  
     {
 245  
         // template method, nothing to do
 246  234
     }
 247  
 
 248  
 }