KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > net > axis > transport > mailto > client > BaseMailSender


1 /*
2  * JBoss, the OpenSource J2EE webOS
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  *
7  * Created on Jan 9, 2004
8  */

9 package org.jboss.net.axis.transport.mailto.client;
10
11 import java.io.IOException JavaDoc;
12 import java.io.InputStream JavaDoc;
13 import java.util.Hashtable JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Properties JavaDoc;
17
18 import javax.activation.DataHandler JavaDoc;
19 import javax.mail.Address JavaDoc;
20 import javax.mail.Message JavaDoc;
21 import javax.mail.MessagingException JavaDoc;
22 import javax.mail.Session JavaDoc;
23 import javax.mail.Transport JavaDoc;
24 import javax.mail.internet.AddressException JavaDoc;
25 import javax.mail.internet.InternetAddress JavaDoc;
26 import javax.naming.Context JavaDoc;
27 import javax.naming.InitialContext JavaDoc;
28 import javax.naming.NamingException JavaDoc;
29
30 import org.apache.axis.AxisFault;
31 import org.apache.axis.MessageContext;
32 import org.apache.axis.handlers.BasicHandler;
33 import org.apache.axis.message.addressing.AddressingHeaders;
34 import org.apache.axis.message.addressing.Constants;
35 import org.apache.axis.message.addressing.EndpointReference;
36 import org.apache.axis.message.addressing.RelatesTo;
37 import org.apache.log4j.Logger;
38 import org.jboss.net.axis.transport.mailto.MailConstants;
39 import org.jboss.net.axis.transport.mailto.MailMessage;
40 import org.jboss.net.axis.transport.mailto.SOAPDataSource;
41
42 /**
43  * <dl>
44  * <dt><b>Title: </b><dd>Mail Sender</dd>
45  * <p>
46  * <dt><b>Description: </b><dd>This is the Email Transport's Client Side Pivot. This handler manages sending email
47  * and attempting to get a response email from the server.<br>
48  * To properly setup this transport you will need a client-deploy.wsdd that contains something like:
49  * <pre>
50  * &lt;handler name="MailSender" type="java:org.jboss.net.axis.transport.mail.client.MailSender" &gt;
51  * &lt;parameter name="username" value="user"/&gt;
52  * &lt;parameter name="password" value="pass"/&gt;
53  * &lt;parameter name="timeout" value="120"/&gt;
54  * &lt;!-- any relavent javamail properties may be set here, these are just an example of some posibilities --&gt;
55  * &lt;parameter name="mail.store.protocol" value="pop3"/&gt;
56  * &lt;parameter name="mail.transport.protocol" value="smtp"/&gt;
57  * &lt;parameter name="mail.host" value="mail.someserver.com"/&gt;
58  * &lt;parameter name="mail.user" value="user"/&gt;
59  * &lt;parameter name="mail.from" value="user@someserver.com"/&gt;
60  * &lt;parameter name="mail.debug" value="false"/&gt;
61  * &lt;/handler&gt;
62  * &lt;transport name="mail" pivot="MailSender"/&gt;
63  * </pre>
64  * The parameters "username" and "password" are optional. If your mail server doesn't require authentication they can
65  * be omitted. The parameter "timeout" is to specify the number of minutes the transport will attempt to retrieve a
66  * response from the server. The default is 30 minutes. Any valid Javamail properties may be specified as parameters,
67  * and they will be read and used by the transport.
68  *
69  * </dd>
70  * </dl>
71  * @author <a HREF="mailto:jasone@greenrivercomputing.com">Jason Essington</a>
72  * @version $Revision: 1.1 $
73  */

74 public class BaseMailSender extends BasicHandler implements MailConstants
75 {
76
77    public static final String JavaDoc MAIL_PROPS = "MailTransportClient.properties";
78    public static final String JavaDoc TRANS_PROPS = "transport.properties";
79
80    public static final String JavaDoc SESSION_NAME = "SessionName";
81
82    protected Logger log = Logger.getLogger(getClass());
83
84    /** If a JavaMail session is not stored in jndi, this field will hold the
85     * JavaMail properties used to create a session. */

86    static protected Properties JavaDoc mailProps = null;
87
88    /** The name of a javamail session from jndi that we should use rather than
89     * creating a new one. */

90    static protected String JavaDoc mailSessionName = null;
91
92    /* (non-Javadoc)
93     * @see org.apache.axis.Handler#invoke(org.apache.axis.MessageContext)
94     */

95    public void invoke(MessageContext ctx) throws AxisFault
96    {
97
98       if (mailSessionName == null && mailProps == null)
99       {
100          if ((mailSessionName = (String JavaDoc) getOption(SESSION_NAME)) == null)
101          {
102             mailProps = getJavaMailProperties();
103          }
104       }
105
106       String JavaDoc msgID = sendMail(ctx);
107       
108       // hook to store our request for reference while we are waiting for a response.
109
archiveMessage(msgID, ctx);
110
111       // hook just incase you want to do email synchronously
112
checkResponse(ctx);
113    }
114
115    protected String JavaDoc sendMail(MessageContext ctx) throws AxisFault
116    {
117       MailMessage mailMsg;
118       org.apache.axis.Message soapMsg = ctx.getRequestMessage();
119       Session JavaDoc session = getMailSession();
120       String JavaDoc msgID = null;
121       
122       AddressingHeaders headers = (AddressingHeaders) ctx.getProperty(Constants.ENV_ADDRESSING_REQUEST_HEADERS);
123
124       try
125       {
126          mailMsg = new MailMessage(session);
127
128          mailMsg.setRecipients(Message.RecipientType.TO, new Address JavaDoc[]{new InternetAddress JavaDoc(headers.getTo().getPath())});
129
130          
131          try
132          {
133             // from must be a reasonable email address
134
EndpointReference from = headers.getFrom();
135             if (from != null && !Constants.NS_URI_ANONYMOUS.equals(from.getAddress().toString()))
136             {
137                mailMsg.setFrom(new InternetAddress JavaDoc(from.getAddress().getPath()));
138             }
139             else
140             {
141                mailMsg.setFrom(InternetAddress.getLocalAddress(session));
142             }
143          }
144          catch (AddressException JavaDoc ae)
145          {
146             // Our from address not a valid email address, so just use the from address defined in the mail session
147
mailMsg.setFrom(InternetAddress.getLocalAddress(session));
148          }
149
150          if (headers.getMessageID() != null)
151          {
152             mailMsg.setMessageID(headers.getMessageID().toString());
153          }
154          if (headers.getRelatesTo() != null)
155          {
156             List JavaDoc relatesTo = headers.getRelatesTo();
157             for (Iterator JavaDoc iter = relatesTo.iterator(); iter.hasNext();)
158             {
159                RelatesTo rt = (RelatesTo) iter.next();
160                if (Constants.QNAME_RESPONSE.equals(rt.getType()))
161                {
162                   mailMsg.setHeader(HEADER_IN_REPLY_TO, rt.getURI().toString());
163                }
164             }
165          }
166          
167          // TODO do we need to set any more headers?
168
mailMsg.setDataHandler(new DataHandler JavaDoc(new SOAPDataSource(soapMsg)));
169
170          Transport.send(mailMsg);
171
172          msgID = mailMsg.getMessageID();
173
174       } catch (MessagingException JavaDoc e)
175       {
176          log.fatal("There was a problem creating the request email message", e);
177          throw new AxisFault("Unable to create request message");
178       }
179
180       if (log.isDebugEnabled())
181          log.debug("message-id: " + msgID);
182
183       return msgID;
184    }
185
186    /**
187     * Override this method if you need to store outgoing messages.<br>
188     * Note: If web service security handlers are in the handler chain,
189     * the message will be signed/encrypted here.
190     * @param msgID
191     * @param msgCtx
192     */

193    protected void archiveMessage(String JavaDoc msgID, MessageContext msgCtx)
194    {
195    }
196
197    /**
198     * Override this method if you want the client to block until it recieves a response.<br>
199     * In reality, this is probably only usefull for testing since email is not really a synchronous operation.
200     * @param ctx
201     * @throws AxisFault
202     */

203    protected void checkResponse(MessageContext ctx) throws AxisFault
204    {
205    }
206
207    /**
208     * This handler expects the JavaMail properties to be specified in the wsdd (if no SessionName is set).
209     * If the properties aren't there it will look for a parameter by the name of transport.properties that holds the
210     * name of a properties file (to be loaded by the classloader) with the required properties (only javamail properties
211     * will be loaded from this file, timeout and authentication information, if included, will be ignored). As a last
212     * resort the handler will search the classpath for MailTransportClient.properties.
213     *
214     * The precidence is transport.properties, properties in the options, then default file.
215     * @return
216     */

217    protected Properties JavaDoc getJavaMailProperties() throws AxisFault
218    {
219       Properties JavaDoc props = null;
220       Hashtable JavaDoc opts = getOptions();
221       if (opts != null)
222       {
223          for (Iterator JavaDoc iter = opts.keySet().iterator(); iter.hasNext();)
224          {
225             String JavaDoc key = (String JavaDoc) iter.next();
226             if (key != null && key.startsWith("mail."))
227             {
228                if (props == null)
229                   props = new Properties JavaDoc();
230                props.setProperty(key, (String JavaDoc) opts.get(key));
231             }
232          }
233       }
234
235       if (props == null)
236       {
237          String JavaDoc propfileName = (String JavaDoc) getOption(TRANS_PROPS);
238
239          // o.k. we made it this far without properties so lets try to load them from a file
240
// either the file specified by the transport.properties option or our default file
241
propfileName = propfileName == null ? MAIL_PROPS : propfileName;
242
243          InputStream JavaDoc is = getClass().getClassLoader().getResourceAsStream(propfileName);
244          if (is == null)
245             throw new AxisFault(propfileName + " not found.");
246
247          props = new Properties JavaDoc();
248          try
249          {
250             props.load(is);
251          } catch (IOException JavaDoc e)
252          {
253             throw new AxisFault("Unable to load mail properties.", e);
254          }
255       }
256
257       return props;
258    }
259
260    /**
261     * Fetch a mail session.
262     * @return Session
263     */

264    protected Session JavaDoc getMailSession() throws AxisFault
265    {
266       if (log.isDebugEnabled())
267          log.debug("Entering: getMailSession()");
268
269       Context JavaDoc ctx = null;
270       Session JavaDoc mail = null;
271
272       if (mailSessionName == null)
273       {
274          mail = Session.getInstance(mailProps);
275       } else
276       {
277          try
278          {
279             ctx = new InitialContext JavaDoc();
280             mail = (Session JavaDoc) ctx.lookup(mailSessionName);
281          } catch (NamingException JavaDoc ne)
282          {
283             log.fatal("NamingException: getMailSession()\n", ne);
284             throw new AxisFault("Unable to find Email Session.");
285          } finally
286          {
287             if (ctx != null)
288                try
289                {
290                   ctx.close();
291                } catch (NamingException JavaDoc ne)
292                {
293                }
294          }
295       }
296
297       if (log.isDebugEnabled())
298          log.debug("Leaving: getMailSession()");
299       return mail;
300    }
301 }
Popular Tags