View Javadoc

1   /*
2    * $Id: SmtpMessageDispatcher.java 10726 2008-02-06 15:38:12Z dirk.olmes $
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.providers.email;
12  
13  import org.mule.config.i18n.CoreMessages;
14  import org.mule.providers.AbstractMessageDispatcher;
15  import org.mule.umo.UMOEvent;
16  import org.mule.umo.UMOMessage;
17  import org.mule.umo.endpoint.EndpointException;
18  import org.mule.umo.endpoint.UMOEndpointURI;
19  import org.mule.umo.endpoint.UMOImmutableEndpoint;
20  import org.mule.umo.provider.DispatchException;
21  
22  import java.util.Calendar;
23  
24  import javax.mail.Message;
25  import javax.mail.MessagingException;
26  import javax.mail.Transport;
27  
28  /**
29   * <code>SmtpMessageDispatcher</code> will dispatch Mule events as Mime email
30   * messages over an SMTP gateway.
31   * 
32   * This contains a reference to a transport (and endpoint and connector, via superclasses)
33   */
34  public class SmtpMessageDispatcher extends AbstractMessageDispatcher
35  {
36      private volatile Transport transport;
37  
38      public SmtpMessageDispatcher(UMOImmutableEndpoint endpoint)
39      {
40          super(endpoint);
41      }
42  
43      private SmtpConnector castConnector()
44      {
45          return (SmtpConnector) getConnector();
46      }
47  
48      protected void doConnect() throws Exception
49      {
50          if (transport == null)
51          {
52              try
53              {
54                  transport = castConnector().getSessionDetails(endpoint).newTransport();
55                  UMOEndpointURI uri = endpoint.getEndpointURI();
56                  transport.connect(uri.getHost(), uri.getPort(), uri.getUsername(), uri.getPassword());
57              }
58              catch (Exception e)
59              {
60                  throw new EndpointException(
61                      org.mule.config.i18n.MessageFactory.createStaticMessage("Unable to connect to mail transport."),
62                      e);
63              }
64          }
65      }
66  
67      protected void doDisconnect() throws Exception
68      {
69          if (null != transport)
70          {
71              try
72              {
73                  transport.close();
74              }
75              finally
76              {
77                  transport = null;
78              }
79          }
80      }
81  
82      protected void doDispatch(UMOEvent event) throws Exception
83      {
84          Object data = event.getTransformedMessage();
85  
86          if (!(data instanceof Message))
87          {
88              throw new DispatchException(
89                  CoreMessages.transformUnexpectedType(data.getClass(), Message.class),
90                  event.getMessage(), event.getEndpoint());
91          }
92          else
93          {
94              // Check the message for any unset data and use defaults
95              sendMailMessage((Message) data);
96          }
97      }
98  
99      /**
100      * Make a specific request to the underlying transport
101      * 
102      * @param timeout the maximum time the operation should block before returning.
103      *            The call should return immediately if there is data available. If
104      *            no data becomes available before the timeout elapses, null will be
105      *            returned
106      * @return the result of the request wrapped in a UMOMessage object. Null will be
107      *         returned if no data was avaialable
108      * @throws Exception if the call to the underlying protocal cuases an exception
109      */
110     protected UMOMessage doReceive(long timeout) throws Exception
111     {
112         throw new UnsupportedOperationException("doReceive");
113     }
114 
115     protected UMOMessage doSend(UMOEvent event) throws Exception
116     {
117         doDispatch(event);
118         return null;
119     }
120 
121     protected void sendMailMessage(Message message) throws MessagingException
122     {
123         // sent date
124         message.setSentDate(Calendar.getInstance().getTime());
125 
126         /*
127          * Double check that the transport is still connected as some SMTP servers may 
128          * disconnect idle connections.
129          */
130         if (!transport.isConnected())
131         {
132             UMOEndpointURI uri = endpoint.getEndpointURI();
133             if (logger.isInfoEnabled())
134             {
135                 logger.info("Connection closed by remote server. Reconnecting.");
136             }
137             transport.connect(uri.getHost(), uri.getPort(), uri.getUsername(), uri.getPassword());
138         }
139 
140         transport.sendMessage(message, message.getAllRecipients());
141 
142         if (logger.isDebugEnabled())
143         {
144             StringBuffer msg = new StringBuffer();
145             msg.append("Email message sent with subject'").append(message.getSubject()).append("' sent- ");
146             msg.append(", From: ").append(MailUtils.mailAddressesToString(message.getFrom())).append(" ");
147             msg.append(", To: ").append(
148                 MailUtils.mailAddressesToString(message.getRecipients(Message.RecipientType.TO))).append(" ");
149             msg.append(", Cc: ").append(
150                 MailUtils.mailAddressesToString(message.getRecipients(Message.RecipientType.CC))).append(" ");
151             msg.append(", Bcc: ")
152             .append(MailUtils.mailAddressesToString(message.getRecipients(Message.RecipientType.BCC)))
153             .append(" ");
154             msg.append(", ReplyTo: ").append(MailUtils.mailAddressesToString(message.getReplyTo()));
155 
156             logger.debug(msg.toString());
157         }
158 
159     }
160 
161     protected void doDispose()
162     {
163         // nothing doing
164     }
165 
166 }