KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quikj > server > framework > AceMailService


1 /*
2  * AceMailService.java
3  *
4  * Created on November 16, 2002, 7:30 PM
5  */

6
7 package com.quikj.server.framework;
8
9 import java.util.*;
10 import java.io.*;
11 import javax.mail.*;
12
13 /**
14  *
15  * @author bhm
16  */

17 public class AceMailService extends AceThread
18 {
19     public AceMailService(String JavaDoc path, AceLoggerInterface logger)
20     throws IOException, AceException
21     {
22         super("AceMailService");
23         
24         if (logger == null)
25         {
26             this.logger = AceLogger.Instance();
27         }
28         else
29         {
30             this.logger = logger;
31         }
32         
33         // read in the config file
34
try
35         {
36             new AceMailConfiguration(path);
37         }
38         catch (Exception JavaDoc ex)
39         {
40             throw new AceException("Error loading mail configuration file "
41             + path + " : "
42             + ex.getClass().getName() + ex.getMessage());
43         }
44         
45         // do mail server setup
46
Properties props = new Properties();
47         props.put("mail.host", AceMailConfiguration.getInstance().getSendMailServer());
48         
49         AceMailService.MailAuthenticator authenticator = null;
50         String JavaDoc username = AceMailConfiguration.getInstance().getUserName();
51         String JavaDoc password = AceMailConfiguration.getInstance().getPassword();
52         
53         if ((username != null) && (password != null))
54         {
55             authenticator = new MailAuthenticator(username, password);
56         }
57         
58         mailSession = Session.getDefaultInstance(props, authenticator);
59         
60         instance = this;
61     }
62     
63     
64     /** Creates a new instance of AceMailService */
65     public AceMailService(String JavaDoc dir, String JavaDoc file, AceLoggerInterface logger)
66     throws IOException, AceException
67     {
68         this(AceConfigTableFileParser.getAcePath(AceConfigTableFileParser.LOCAL_DATA,
69         dir, file), logger);
70     }
71     
72     /////////////////////////////////////////////////////////////////////////
73
/**
74      * AceMailService - Calls other constructor with AceLoggerInterface
75      * = null
76      * @author amit
77      * @version
78      */
/////////////////////////////////////////////////////////////////////////
79
public AceMailService(String JavaDoc dir, String JavaDoc file)
80     throws IOException, AceException
81     {
82         this(dir, file, null);
83     }
84     
85     public static AceMailService getInstance()
86     {
87         return instance;
88     }
89     
90     public void dispose()
91     {
92         // interrupt the wait (kill this thread)
93
interruptWait(AceSignalMessage.SIGNAL_TERM, "disposed");
94         
95         instance = null;
96     }
97     
98     private void cleanup()
99     {
100         if (retryTimerId != -1)
101         {
102             try
103             {
104                 AceTimer.Instance().cancelTimer(retryTimerId);
105                 retryTimerId = -1;
106             }
107             catch (IOException ex)
108             {
109                 ;
110             }
111         }
112         
113         // serialize out the pending message list
114
if (pendingMessageList.size() > 0)
115         {
116             File file = new File(AceMailConfiguration.getInstance().getPendingDir(),
117             AceMailConfiguration.getInstance().getPendingFile());
118             
119             try
120             {
121                 ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
122                 os.writeObject(pendingMessageList);
123                 os.close();
124             }
125             catch (Exception JavaDoc ex)
126             {
127                 logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
128                 getName()
129                 + "- dispose() -- Error while serializing - "
130                 + ex.getClass().getName() + " : " + ex.getMessage());
131             }
132         }
133         
134         AceMailConfiguration.dispose();
135         
136         instance = null;
137         super.dispose();
138         
139     }
140     
141     public boolean addToMailQueue(AceMailMessage msg)
142     {
143         return sendMessage(new AceMailServiceMessage(msg));
144     }
145     
146     public void run()
147     {
148         logger.log(AceLogger.INFORMATIONAL, AceLogger.SYSTEM_LOG,
149         "AceMailService.run() -- Ace mail service started");
150         
151         //serialize in the pending message file, remove the file, process the pending messages
152

153         File file = new File(AceMailConfiguration.getInstance().getPendingDir(),
154         AceMailConfiguration.getInstance().getPendingFile());
155         
156         
157         if (file.exists() == true)
158         {
159             try
160             {
161                 ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
162                 pendingMessageList = (ArrayList) is.readObject();
163                 is.close();
164                 
165                 if (file.delete() == false)
166                 {
167                     logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
168                     getName()
169                     + "- run() -- Failure deleting save pending mail file "
170                     + file.getAbsolutePath() + ". Please remove the file manually.");
171                 }
172                 
173                 sendPendingMessage();
174             }
175             catch (Exception JavaDoc ex)
176             {
177                 logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
178                 getName()
179                 + "- run() -- Error while serializing in saved pending mail file, pending messages discarded. Error = "
180                 + ex.getClass().getName() + " : " + ex.getMessage());
181                 
182                 if (file.delete() == false)
183                 {
184                     logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
185                     getName()
186                     + "- run() -- Failure deleting save pending mail file "
187                     + file.getAbsolutePath() + ". Please remove the file manually.");
188                 }
189             }
190         }
191         
192         while (true)
193         {
194             AceMessageInterface message = waitMessage();
195             if (message == null)
196             {
197                 // print error message
198
logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
199                 getName()
200                 + "- run() -- A null message was received while waiting for a message - "
201                 + getErrorMessage());
202                 
203                 break;
204             }
205             
206             if ((message instanceof AceSignalMessage) == true)
207             {
208                 // A signal message is received
209

210                 // print informational message
211
logger.log(AceLogger.INFORMATIONAL, AceLogger.SYSTEM_LOG,
212                 getName()
213                 + " - AceMailService.run() -- A signal "
214                 + ((AceSignalMessage)message).getSignalId()
215                 + " is received : "
216                 + ((AceSignalMessage)message).getMessage());
217                 
218                 break;
219             }
220             else if ((message instanceof AceMailServiceMessage) == true)
221             {
222                 AceMailMessage mail_message = ((AceMailServiceMessage) message).getMailMessage();
223                 
224                 // if we have a backlog of outgoing msgs, put message in pending queue
225
if (retryTimerId != -1)
226                 {
227                     pendingMessageList.add(mail_message);
228                 }
229                 else
230                 {
231                     // send the message
232

233                     if (handleMail(mail_message) == false)
234                     {
235                         //put the message in the pending queue and start retry timing
236
pendingMessageList.add(mail_message);
237                         
238                         try
239                         {
240                             retryTimerId = AceTimer.Instance().startTimer(RETRY_INTERVAL,
241                             RETRY_SENDING);
242                         }
243                         catch (IOException ex)
244                         {
245                             logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
246                             getName()
247                             + "- run() -- Error starting retry sending timer - "
248                             + ex.getMessage());
249                         }
250                     }
251                 }
252             }
253             else if ((message instanceof AceTimerMessage) == true)
254             {
255                 AceTimerMessage timer_msg = (AceTimerMessage)message;
256                 
257                 if (timer_msg.getUserSpecifiedParm() == RETRY_SENDING)
258                 {
259                     sendPendingMessage();
260                 }
261                 else
262                 {
263                     // print error message
264
logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
265                     getName()
266                     + "- run() -- An unexpected timeout is received : "
267                     + timer_msg.getUserSpecifiedParm());
268                 }
269             }
270             else // unexpected event
271
{
272                 // print error message
273
logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
274                 getName()
275                 + "- run() -- An unexpected message is received : "
276                 + message.messageType());
277             }
278         }
279         
280         cleanup();
281     }
282     
283     private boolean handleMail(AceMailMessage mail_message)
284     {
285         // override from/reply-to if specified in the config file
286
String JavaDoc from = AceMailConfiguration.getInstance().getOverrideFrom();
287          if (from != null)
288          {
289              mail_message.setFrom(from);
290              mail_message.setReplyTo(new Vector());
291              mail_message.addReplyTo(from);
292          }
293         
294         javax.mail.Message JavaDoc message = mail_message.toEmail(mailSession);
295         if (message == null)
296         {
297             //log message
298
logger.log(AceLogger.WARNING, AceLogger.SYSTEM_LOG,
299             "AceMailService.handleMail() -- Outgoing email message discarded : "
300             + mail_message.getErrorMessage());
301             
302             return true;
303         }
304         
305         try
306         {
307             // send the message
308
Transport.send(message);
309             
310             //Transport.send(new MimeMessage(mailSession)); //testing only, TO GET EXCEPTION
311
}
312         catch (SendFailedException ex)
313         {
314             //log a warning
315
return false;
316         }
317         catch (AuthenticationFailedException ex)
318         {
319             //log a warning
320
return false;
321         }
322         catch (Exception JavaDoc ex) // don't retry on remaining/other exceptions
323
//FolderClosedException, FolderNotFoundException,
324
//IllegalWriteException, MessageRemovedException, MethodNotSupportedException,
325
//NoSuchProviderException, ParseException, ReadOnlyFolderException, SearchException,
326
//StoreClosedException
327
{
328             //log a warning
329
return true;
330         }
331         finally
332         {
333             // check the accumated message queue
334
int size = pendingMessageList.size();
335             if (size > 0)
336             {
337                 Date current_time = new Date();
338                 if (current_time.getTime() >= (accLogged.getTime() + 30 * 60 * 1000))
339                 {
340                     // print log message
341
logger.log(AceLogger.WARNING, AceLogger.SYSTEM_LOG,
342                     "AceMailService.handleMail() -- Accumulated mail queue size is "
343                     + size);
344                     accLogged = current_time;
345                 }
346             }
347         }
348         return true;
349     }
350     
351     private void sendPendingMessage()
352     {
353         if (pendingMessageList.size() > 0)
354         {
355             AceMailMessage msg = (AceMailMessage) pendingMessageList.get(0);
356             if (handleMail(msg) == true)
357             {
358                 pendingMessageList.remove(0);
359             }
360             
361             if (pendingMessageList.size() > 0)
362             {
363                 try
364                 {
365                     retryTimerId = AceTimer.Instance().startTimer(RETRY_INTERVAL,
366                     RETRY_SENDING);
367                     
368                     return;
369                 }
370                 catch (IOException ex1)
371                 {
372                     logger.log(AceLogger.ERROR, AceLogger.SYSTEM_LOG,
373                     getName()
374                     + "- sendPendingMessage() -- Error starting retry sending timer - "
375                     + ex1.getMessage());
376                 }
377             }
378         }
379         
380         retryTimerId = -1;
381     }
382     
383     /** Getter for property mailSession.
384      * @return Value of property mailSession.
385      */

386     public javax.mail.Session JavaDoc getMailSession()
387     {
388         return mailSession;
389     }
390     
391     private class MailAuthenticator extends Authenticator
392     {
393         public MailAuthenticator(String JavaDoc name, String JavaDoc password)
394         {
395             authName = name;
396             authPass = password;
397         }
398         
399         protected PasswordAuthentication getPasswordAuthentication()
400         {
401             return new PasswordAuthentication(authName, authPass);
402         }
403         
404         private String JavaDoc authName;
405         private String JavaDoc authPass;
406     }
407     
408     /////////////////////////////////////////////////////////////////////////
409
// Class AceMailService attributes
410
/////////////////////////////////////////////////////////////////////////
411
private static AceMailService instance = null;
412     private AceLoggerInterface logger = null;
413     private Session mailSession;
414     
415     private ArrayList pendingMessageList = new ArrayList();
416     
417     private int retryTimerId = -1;
418     private static final long RETRY_SENDING = 0;
419     private static final int RETRY_INTERVAL = 30 * 1000;
420     
421     private Date accLogged = new Date();
422     
423     public static void main(String JavaDoc[] args)
424     {
425         class MyAceThread extends AceThread
426         {
427             public MyAceThread()
428             throws IOException
429             {
430                 super("MyAceThread", true);
431             }
432             
433             public void dispose()
434             {
435                 AceMailService.getInstance().dispose();
436                 AceLogger.Instance().dispose();
437                 
438                 super.dispose();
439             }
440             
441             public void run()
442             {
443                 try
444                 {
445                     AceTimer.Instance().start(); // create a timer thread
446

447                     new AceLogger("localhost",
448                     8088,
449                     "Test Process",
450                     0,
451                     1);
452                     
453                     AceLogger.Instance().start();
454                     
455                     AceMailService svc = new AceMailService("config/applications/webtalk",
456                     "mail_cfg.xml");
457                     
458                     svc.start();
459                     
460                     int i = 1;
461                     
462                     while(true)
463                     {
464                         
465                         for (int j = 1; j < 4; i++, j++)
466                         {
467                             AceMailMessage msg = new AceMailMessage();
468                             
469                             try
470                             {
471                                 msg.setBody("This is test email " + i + " from test program.");
472                                 msg.setSubject("Testing sendmail program - " + i);
473                                 
474                                 msg.setFrom("robinmc@mindspring.com");
475                                 //msg.setFrom("yp");
476
//msg.addReplyTo("@robin");
477
//msg.addReplyTo("mindspring.com");
478
//msg.addReplyTo("");
479
msg.addReplyTo("mac@mindspring.com");
480                                 msg.addReplyTo("martha@mindspring.com");
481                                 //msg.addCc("@dummy@abc.net");
482

483                                 //msg.addTo("ff");
484
//msg.addTo("dd");msg.addTo("r.r");
485
msg.addTo("beckymc@mindspring.com");
486                                 
487                                 //msg.addCc("dd@");
488
//msg.addCc("@dd");msg.addCc("d@d");msg.addCc("dd.");
489

490                                 //msg.addBcc("@cc.");msg.addBcc("");msg.addBcc("c");msg.addBcc("@");
491

492                                 //msg.addBcc("beckymc@mindspring.com");
493
//msg.addCc("beckymc@mindspring.com");
494

495                                 if (svc.addToMailQueue(msg) == false)
496                                 {
497                                     System.out.println("Error adding message " + i + " to mail service queue");
498                                 }
499                             }
500                             catch (Exception JavaDoc ex)
501                             {
502                                 System.out.println("Exception creating mail message, " + ex.getClass().getName() + " : " + ex.getMessage());
503                             }
504                         }
505                         
506                         Thread.sleep(10000);
507                         
508                         System.out.println("MAIN: Disposing of Ace Mail Service");
509                         svc.dispose();
510                         
511                         Thread.sleep(5000);
512                         
513                         if (i >= 16)
514                         {
515                             break;
516                         }
517                         
518                         System.out.println("MAIN: Creating new Ace Mail Service");
519                         svc = new AceMailService("config/applications/webtalk",
520                         "mail_cfg.xml");
521                         
522                         svc.start();
523                         
524                     }
525                     
526                     System.out.println("All done");
527                 }
528                 catch (Exception JavaDoc ex)
529                 {
530                     System.err.println(ex.getClass().getName() + " occured : "
531                     + ex.getMessage());
532                 }
533             }
534         } // class MyAceThread
535

536         
537         try
538         {
539             MyAceThread thread = new MyAceThread();
540             thread.start();
541             
542             thread.join();
543             System.exit(0);
544         }
545         catch (Exception JavaDoc ex)
546         {
547             System.err.println(ex.getClass().getName() + " occured : "
548             + ex.getMessage());
549             System.exit(1);
550         }
551     }
552 }
553
Popular Tags