KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > impl > mail > MailModuleImpl


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.core.impl.mail;
10
11 import EDU.oswego.cs.dl.util.concurrent.BoundedLinkedQueue;
12 import EDU.oswego.cs.dl.util.concurrent.Channel;
13 import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
14 import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
15 import org.apache.log4j.Logger;
16 import org.jboss.logging.util.LoggerStream;
17 import org.jboss.portal.core.modules.AbstractModule;
18 import org.jboss.portal.core.modules.MailModule;
19 import javax.mail.MessagingException JavaDoc;
20 import javax.mail.PasswordAuthentication JavaDoc;
21 import javax.mail.Session JavaDoc;
22 import javax.mail.Transport JavaDoc;
23 import javax.mail.URLName JavaDoc;
24 import javax.mail.internet.AddressException JavaDoc;
25 import javax.mail.internet.InternetAddress JavaDoc;
26 import javax.mail.internet.MimeMessage JavaDoc;
27 import java.security.NoSuchProviderException JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Properties JavaDoc;
32
33 /**
34  * @author <a HREF="mailto:julien@jboss.com">Julien Viet</a>
35  * @author <a HREF="mailto:theute@jboss.com">Thomas Heute</a>
36  * @jmx.mbean
37  * @jboss.xmbean
38  */

39 public class MailModuleImpl
40    extends AbstractModule
41    implements MailModule
42 {
43    private final Logger log = Logger.getLogger(getClass());
44
45    /**
46     * Creates a new {@link MailModuleImpl} object.
47     */

48    public MailModuleImpl()
49    {
50    }
51
52    /**
53     * Javamail properties.
54     */

55    private Properties JavaDoc properties = new Properties JavaDoc();
56
57    /**
58     * Queue max capacity or -1 if unbounded.
59     */

60    private int queueCapacity = -1;
61
62    /**
63     * The thread that will send the mail.
64     */

65    private QueuedExecutor executor;
66
67    /**
68     * The queue that will held all the messages.
69     */

70    private Channel queue;
71
72    /**
73     * The SMTP gateway through which mail will be delivered.
74     */

75    public String JavaDoc gateway;
76
77    /**
78     * The username for authenticating to the smtp gateway.
79     */

80    private String JavaDoc smtpUser;
81
82    /**
83     * The password for authenticating to the smtp gateway.
84     */

85    private String JavaDoc smtpPassword;
86
87    /**
88     * The Authenticator implementation used when stmp auth is needed.
89     */

90    private MailAuthenticator smtpAuth;
91
92    /**
93     * True if javamail debug is enabled.
94     */

95    private boolean javaMailDebugEnabled = false;
96
97    /**
98     * SMTP connection timeout.
99     */

100    private int SMTPConnectionTimeout = 10000;
101
102    /**
103     * SMTP timeout.
104     */

105    private int SMTPTimeout = 10000;
106
107    /**
108     * The PrintStream java mail debug output is sent to.
109     */

110    private LoggerStream logs;
111
112    /**
113     * A serial id used to track messages locally.
114     */

115    private int currentSerialId = 0;
116
117    /**
118     * @jmx.managed-attribute
119     */

120    public int getSMTPConnectionTimeout()
121    {
122       return SMTPConnectionTimeout;
123    }
124
125    /**
126     * @jmx.managed-attribute
127     */

128    public void setSMTPConnectionTimeout(int SMTPConnectionTimeout)
129    {
130       this.SMTPConnectionTimeout = SMTPConnectionTimeout;
131    }
132
133    /**
134     * @jmx.managed-attribute
135     */

136    public int getSMTPTimeout()
137    {
138       return SMTPTimeout;
139    }
140
141    /**
142     * @jmx.managed-attribute
143     */

144    public void setSMTPTimeout(int SMTPTimeout)
145    {
146       this.SMTPTimeout = SMTPTimeout;
147    }
148
149    public int getCurrentSerialId()
150    {
151       return currentSerialId;
152    }
153
154    /**
155     * @jmx.managed-attribute
156     */

157    public String JavaDoc getGateway()
158    {
159       return gateway;
160    }
161
162    /**
163     * @jmx.managed-attribute
164     */

165    public void setGateway(String JavaDoc gateway)
166    {
167       this.gateway = gateway;
168    }
169
170    /**
171     * @jmx.managed-attribute
172     */

173    public String JavaDoc getSmtpUser()
174    {
175       return smtpUser;
176    }
177
178    /**
179     * @jmx.managed-attribute
180     */

181    public void setSmtpUser(String JavaDoc smtpUser)
182    {
183       this.smtpUser = smtpUser;
184    }
185
186    /**
187     * @jmx.managed-attribute
188     */

189    public String JavaDoc getSmtpPassword()
190    {
191       return smtpPassword;
192    }
193
194    /**
195     * @jmx.managed-attribute
196     */

197    public void setSmtpPassword(String JavaDoc smtpPassword)
198    {
199       this.smtpPassword = smtpPassword;
200    }
201
202    public int getQueueSize()
203    {
204       if (queue == null)
205       {
206          return -1;
207       }
208       else if (queue instanceof BoundedLinkedQueue)
209       {
210          return ((BoundedLinkedQueue) queue).capacity();
211       }
212       else
213       {
214          return 0;
215       }
216    }
217
218    public String JavaDoc listProperties()
219    {
220       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("[");
221       for (Iterator JavaDoc i = properties.entrySet().iterator(); i.hasNext(); buffer.append(i.hasNext() ? "," : "]"))
222       {
223          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
224          buffer.append(entry.getKey()).append("=").append(entry.getValue());
225       }
226
227       return buffer.toString();
228    }
229
230    public int flushQueue()
231    {
232       try
233       {
234          int size = 0;
235          for (MyMessage r = (MyMessage) queue.poll(0); r != null; r = (MyMessage) queue.poll(0))
236          {
237             log.debug("Removed serialId=" + r.serialId + " from the queue");
238             size++;
239          }
240
241          return size;
242       }
243       catch (InterruptedException JavaDoc ignore)
244       {
245          return -1;
246       }
247    }
248
249    /**
250     * @jmx.managed-attribute
251     */

252    public int getQueueCapacity()
253    {
254       return queueCapacity;
255    }
256
257    /**
258     * @jmx.managed-attribute
259     */

260    public void setQueueCapacity(int queueCapacity)
261    {
262       this.queueCapacity = queueCapacity;
263    }
264
265    /**
266     * @jmx.managed-attribute
267     */

268    public boolean getJavaMailDebugEnabled()
269    {
270       return javaMailDebugEnabled;
271    }
272
273    /**
274     * @jmx.managed-attribute
275     */

276    public void setJavaMailDebugEnabled(boolean javaMailDebugEnabled)
277    {
278       this.javaMailDebugEnabled = javaMailDebugEnabled;
279    }
280
281    public void send(String JavaDoc from,
282                     String JavaDoc to,
283                     String JavaDoc subject,
284                     String JavaDoc body)
285    {
286       try
287       {
288          MyMessage runnable = new MyMessage(from, to, subject, body);
289          log.debug("Enqueuing serialId=" + runnable.serialId);
290          executor.execute(runnable);
291          log.debug("Enqueued serialId=" + runnable.serialId);
292       }
293       catch (InterruptedException JavaDoc ignore)
294       {
295          log.debug("Interrupted during deliver attempt");
296       }
297    }
298
299    public void start()
300    throws Exception JavaDoc
301    {
302       super.start();
303
304       // Create the thread used to deliver messages
305
if (queueCapacity > 0)
306       {
307          queue = new BoundedLinkedQueue(queueCapacity);
308       }
309       else
310       {
311          queue = new LinkedQueue();
312       }
313
314       executor = new QueuedExecutor(queue);
315
316       if ((gateway != null) && (gateway.length() > 0))
317       {
318          properties.setProperty("mail.smtp.host", gateway);
319       }
320       else
321       {
322          log.warn("You did not set up any SMTP gateway, cannot send any email");
323       }
324
325       if (smtpUser != null)
326       {
327          properties.setProperty("mail.smtp.auth", "true");
328          smtpAuth = new MailAuthenticator(smtpUser, smtpPassword);
329       }
330       else
331       {
332          properties.setProperty("mail.smtp.auth", "false");
333          smtpAuth = null;
334       }
335
336       // Set timeouts, default is infinite, we want to avoid it
337
properties.setProperty("mail.smtp.connectiontimeout", "" + SMTPConnectionTimeout);
338       properties.setProperty("mail.smtp.timeout", "" + SMTPTimeout);
339    }
340
341    public void stop()
342    {
343       super.stop();
344       properties.clear();
345       executor.shutdownAfterProcessingCurrentTask();
346       executor = null;
347       queue = null;
348    }
349
350    public boolean deliver(int serialId,
351                           String JavaDoc from,
352                           String JavaDoc to,
353                           String JavaDoc subject,
354                           String JavaDoc body)
355    {
356       boolean delivered = false;
357       try
358       {
359          if ((gateway != null) && (gateway.length() > 0))
360          {
361             delivered = deliver(serialId, gateway, from, to, subject, body);
362          }
363          else
364          {
365             log.warn("You did not specify any gateway, the email cannot be sent");
366          }
367       }
368       catch (Throwable JavaDoc t)
369       {
370          log.error("Problem while delivering serialId=" + serialId, t);
371       }
372
373       return delivered;
374    }
375
376    private boolean deliver(int serialId,
377                            String JavaDoc host,
378                            String JavaDoc from,
379                            String JavaDoc to,
380                            String JavaDoc subject,
381                            String JavaDoc body)
382    throws AddressException JavaDoc,
383           NoSuchProviderException JavaDoc,
384           MessagingException JavaDoc
385    {
386       Transport JavaDoc transport = null;
387       try
388       {
389          InternetAddress JavaDoc toAddress = new InternetAddress JavaDoc(to);
390          Session JavaDoc session = Session.getDefaultInstance(properties, smtpAuth);
391          session.setDebug(javaMailDebugEnabled);
392          session.setDebugOut(logs);
393
394          // Get transport
395
URLName JavaDoc urlname = new URLName JavaDoc("smtp://" + host);
396          transport = session.getTransport(urlname);
397
398          // Connect
399
log.debug("Connecting to " + host + " with serialId=" + serialId);
400          transport.connect();
401          log.debug("Connected to " + host + " with serialId=" + serialId);
402
403          // Prepare message
404
MimeMessage JavaDoc message = new MimeMessage JavaDoc(session);
405          message.setFrom(new InternetAddress JavaDoc(from));
406          message.setSubject(subject);
407          message.setText(body);
408          message.setSentDate(new Date JavaDoc());
409          message.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);
410
411          // Send message
412
log.debug("Sending message serialId=" + serialId);
413          transport.sendMessage(message,
414                                new InternetAddress JavaDoc[]
415                                {
416                                   toAddress
417                                });
418          log.debug("Sent msg, subject=" + subject + ", serialId=" + serialId);
419          return true;
420       }
421       finally
422       {
423          if (transport != null)
424          {
425             try
426             {
427                transport.close();
428             }
429             catch (MessagingException JavaDoc ignore)
430             {
431             }
432          }
433       }
434    }
435
436    /**
437     * Used for sending through a gateway needing authentication
438     */

439    private static class MailAuthenticator
440       extends javax.mail.Authenticator JavaDoc
441    {
442       private String JavaDoc username = null;
443       private String JavaDoc password = null;
444
445       public MailAuthenticator(String JavaDoc username,
446                                String JavaDoc password)
447       {
448          this.username = username;
449          this.password = password;
450       }
451
452       public PasswordAuthentication JavaDoc getPasswordAuthentication()
453       {
454          return new PasswordAuthentication JavaDoc(username, password);
455       }
456    }
457
458    /**
459     * Encapsulate a message in this class with a serial id version to keep track.
460     */

461    private class MyMessage
462       implements Runnable JavaDoc
463    {
464       public final int serialId;
465
466       public final String JavaDoc from;
467
468       public final String JavaDoc to;
469
470       public final String JavaDoc subject;
471
472       public final String JavaDoc body;
473
474       public MyMessage(String JavaDoc from,
475                        String JavaDoc to,
476                        String JavaDoc subject,
477                        String JavaDoc body)
478       {
479          this.serialId = currentSerialId++;
480          this.from = from;
481          this.to = to;
482          this.subject = subject;
483          this.body = body;
484       }
485
486       public void run()
487       {
488          try
489          {
490             log.debug("Dequeued serialId=" + serialId + " and delivering it");
491             boolean delivered = deliver(serialId, from, to, subject, body);
492             log.debug(delivered + " on delivery for serialId=" + serialId);
493          }
494          catch (Throwable JavaDoc t)
495          {
496             log.error("Caught throwable while delivering serialId=" + serialId, t);
497          }
498       }
499    }
500 }
Popular Tags