KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > providers > email > Pop3MessageReceiver


1 /*
2  * $Id: Pop3MessageReceiver.java 4219 2006-12-09 10:15:14Z lajos $
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 MuleSource MPL
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 java.io.File JavaDoc;
14 import java.io.FileOutputStream JavaDoc;
15 import java.io.IOException JavaDoc;
16
17 import javax.mail.Address JavaDoc;
18 import javax.mail.Flags JavaDoc;
19 import javax.mail.Folder JavaDoc;
20 import javax.mail.Message JavaDoc;
21 import javax.mail.MessagingException JavaDoc;
22 import javax.mail.Session JavaDoc;
23 import javax.mail.Store JavaDoc;
24 import javax.mail.URLName JavaDoc;
25 import javax.mail.event.MessageCountEvent JavaDoc;
26 import javax.mail.event.MessageCountListener JavaDoc;
27 import javax.mail.internet.MimeMessage JavaDoc;
28 import javax.mail.internet.InternetAddress JavaDoc;
29
30 import org.apache.commons.lang.StringUtils;
31 import org.mule.MuleManager;
32 import org.mule.config.i18n.Messages;
33 import org.mule.impl.MuleMessage;
34 import org.mule.providers.PollingMessageReceiver;
35 import org.mule.umo.UMOComponent;
36 import org.mule.umo.UMOException;
37 import org.mule.umo.UMOMessage;
38 import org.mule.umo.endpoint.UMOEndpoint;
39 import org.mule.umo.lifecycle.InitialisationException;
40 import org.mule.umo.lifecycle.Startable;
41 import org.mule.umo.lifecycle.Stoppable;
42 import org.mule.umo.provider.ReceiveException;
43 import org.mule.umo.provider.UMOConnector;
44 import org.mule.umo.routing.RoutingException;
45 import org.mule.util.FileUtils;
46 import org.mule.util.UUID;
47
48 /**
49  * <code>Pop3MessageReceiver</code> polls a POP3 mailbox for messages, removes the
50  * messages and routes them as events into Mule.
51  */

52
53 public class Pop3MessageReceiver extends PollingMessageReceiver
54     implements MessageCountListener JavaDoc, Startable, Stoppable
55 {
56     private Folder JavaDoc folder = null;
57
58     private String JavaDoc backupFolder = null;
59
60     protected Session JavaDoc session;
61
62     private Pop3Connector connector;
63
64     public Pop3MessageReceiver(UMOConnector connector,
65                                UMOComponent component,
66                                UMOEndpoint endpoint,
67                                Long JavaDoc checkFrequency,
68                                String JavaDoc backupFolder) throws InitialisationException
69     {
70         super(connector, component, endpoint, checkFrequency);
71         this.backupFolder = backupFolder;
72         this.connector = (Pop3Connector)connector;
73     }
74
75     public void doConnect() throws Exception JavaDoc
76     {
77         // TODO refactor inbox discovery logic into a getter method for subclasses to
78
// override
79
String JavaDoc inbox;
80         if (connector.getProtocol().toLowerCase().startsWith("imap"))
81         {
82             inbox = endpoint.getEndpointURI().getPath();
83             if (inbox.length() == 0)
84             {
85                 // TODO danger here, custom connector may not necessarily inherit
86
// ImapConnector
87
if (connector.getProtocol().toLowerCase().compareTo("imaps") == 0)
88                 {
89                     inbox = ((ImapsConnector)connector).getMailboxFolder();
90                 }
91                 else
92                 {
93                     inbox = ((ImapConnector)connector).getMailboxFolder();
94                 }
95             }
96             else
97             {
98                 inbox = inbox.substring(1);
99             }
100         }
101         else
102         {
103             inbox = Pop3Connector.MAILBOX;
104         }
105
106         URLName JavaDoc url = new URLName JavaDoc(endpoint.getEndpointURI().getScheme(), endpoint.getEndpointURI().getHost(),
107             endpoint.getEndpointURI().getPort(), inbox, endpoint.getEndpointURI().getUsername(),
108             endpoint.getEndpointURI().getPassword());
109
110         session = MailUtils.createMailSession(url, connector);
111         session.setDebug(logger.isDebugEnabled());
112
113         Store JavaDoc store = session.getStore(url);
114         store.connect();
115         folder = store.getFolder(inbox);
116
117         // If user explicitly sets backup folder to "" it will disable email back up
118
if (backupFolder == null)
119         {
120             this.backupFolder = MuleManager.getConfiguration().getWorkingDirectory() + "/mail/"
121                                 + folder.getName();
122         }
123         else if (StringUtils.EMPTY.equals(backupFolder))
124         {
125             backupFolder = null;
126         }
127
128         if (backupFolder != null && !this.backupFolder.endsWith(File.separator))
129         {
130             this.backupFolder += File.separator;
131         }
132     }
133
134     public void doDisconnect() throws Exception JavaDoc
135     {
136         // nothing to do here
137
}
138
139     public void doStop()
140     {
141         if (folder != null)
142         {
143             folder.removeMessageCountListener(this);
144         }
145     }
146
147     public void doStart() throws UMOException
148     {
149         super.doStart();
150         folder.addMessageCountListener(this);
151     }
152
153     /*
154      * (non-Javadoc)
155      *
156      * @see javax.mail.event.MessageCountListener#messagesAdded(javax.mail.event.MessageCountEvent)
157      */

158     public void messagesAdded(MessageCountEvent JavaDoc event)
159     {
160         Message JavaDoc messages[] = event.getMessages();
161         if (messages != null)
162         {
163             UMOMessage message = null;
164             for (int i = 0; i < messages.length; i++)
165             {
166                 try
167                 {
168                     if (!messages[i].getFlags().contains(Flags.Flag.DELETED))
169                     {
170                         MimeMessage JavaDoc mimeMessage = new MimeMessage JavaDoc((MimeMessage JavaDoc)messages[i]);
171                         storeMessage(mimeMessage);
172                         message = new MuleMessage(connector.getMessageAdapter(mimeMessage));
173
174                         if (connector.isDeleteReadMessages())
175                         {
176                             // Mark as deleted
177
messages[i].setFlag(Flags.Flag.DELETED, true);
178                         }
179                         else
180                         {
181                             messages[i].setFlag(Flags.Flag.SEEN, true);
182                         }
183                         routeMessage(message, endpoint.isSynchronous());
184                     }
185                 }
186                 catch (UMOException e)
187                 {
188                     handleException(e);
189                 }
190                 catch (Exception JavaDoc e)
191                 {
192                     Exception JavaDoc forwarded;
193
194                     if (message != null)
195                     {
196                         forwarded = new RoutingException(new org.mule.config.i18n.Message(
197                             Messages.ROUTING_ERROR), message, endpoint, e);
198                     }
199                     else
200                     {
201                         forwarded = new ReceiveException(endpoint, -1, e);
202                     }
203
204                     handleException(forwarded);
205                 }
206             }
207         }
208     }
209
210     protected UMOMessage handleUnacceptedFilter(UMOMessage message)
211     {
212         super.handleUnacceptedFilter(message);
213         if (message.getPayload() instanceof Message JavaDoc)
214         {
215             Message JavaDoc msg = (Message JavaDoc)message.getPayload();
216             try
217             {
218                 msg.setFlag(Flags.Flag.DELETED, endpoint.isDeleteUnacceptedMessages());
219             }
220             catch (MessagingException JavaDoc e)
221             {
222                 logger.error("failled to set message deleted: " + e.getMessage(), e);
223             }
224         }
225         return null;
226     }
227
228     /*
229      * (non-Javadoc)
230      *
231      * @see javax.mail.event.MessageCountListener#messagesRemoved(javax.mail.event.MessageCountEvent)
232      */

233     public void messagesRemoved(MessageCountEvent JavaDoc event)
234     {
235         if (logger.isDebugEnabled())
236         {
237             Message JavaDoc messages[] = event.getMessages();
238             for (int i = 0; i < messages.length; i++)
239             {
240                 try
241                 {
242                     logger.debug("Message removed: " + messages[i].getSubject());
243                 }
244                 catch (MessagingException JavaDoc ignore)
245                 {
246                     // ignore
247
}
248             }
249         }
250     }
251
252     /**
253      * @return the current Mail folder
254      */

255     public Folder JavaDoc getFolder()
256     {
257         return folder;
258     }
259
260     /**
261      * @param folder
262      */

263     public synchronized void setFolder(Folder JavaDoc folder)
264     {
265         if (folder == null)
266         {
267             throw new IllegalArgumentException JavaDoc("Mail folder cannot be null");
268         }
269         this.folder = folder;
270         synchronized (this.folder)
271         {
272             if (!this.folder.isOpen())
273             {
274                 try
275                 {
276                     this.folder.open(Folder.READ_WRITE);
277                 }
278                 catch (MessagingException JavaDoc e)
279                 {
280                     logger.warn("Failed to open folder: " + folder.getFullName(), e);
281                 }
282             }
283         }
284     }
285
286     /**
287      * Helper method for testing which stores a copy of the message locally as the
288      * POP3 <p/> message will be deleted from the server
289      *
290      * @param msg the message to store
291      * @throws IOException If a failure happens writing the message
292      * @throws MessagingException If a failure happens reading the message
293      */

294     private void storeMessage(Message JavaDoc msg) throws IOException JavaDoc, MessagingException JavaDoc
295     {
296         if (backupFolder != null)
297         {
298             String JavaDoc filename = msg.getFileName();
299             if (filename == null)
300             {
301                 Address JavaDoc[] from = msg.getFrom();
302                 if (from != null && from.length > 0)
303                 {
304                     filename = from[0] instanceof InternetAddress JavaDoc
305                             ? ((InternetAddress JavaDoc) from[0]).getAddress()
306                             : from[0].toString();
307                 }
308                 else
309                 {
310                     filename = "(no from address)";
311                 }
312                 filename += "[" + UUID.getUUID() + "]";
313             }
314             filename = FileUtils.prepareWinFilename(filename);
315             filename = backupFolder + filename + ".msg";
316             logger.debug("Writing message to: " + filename);
317             File JavaDoc f = FileUtils.createFile(filename);
318             FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(f);
319             msg.writeTo(fos);
320         }
321     }
322
323     public synchronized void poll()
324     {
325         try
326         {
327             try
328             {
329                 if (!folder.isOpen())
330                 {
331                     folder.open(Folder.READ_WRITE);
332                 }
333             }
334             catch (Exception JavaDoc e)
335             {
336                 // ignore
337
}
338
339             int count = folder.getMessageCount();
340             if (count > 0)
341             {
342                 Message JavaDoc[] messages = folder.getMessages();
343                 MessageCountEvent JavaDoc event = new MessageCountEvent JavaDoc(folder, MessageCountEvent.ADDED, true,
344                     messages);
345                 messagesAdded(event);
346             }
347             else if (count == -1)
348             {
349                 throw new MessagingException JavaDoc("Cannot monitor folder: " + folder.getFullName()
350                                              + " as folder is closed");
351             }
352         }
353         catch (MessagingException JavaDoc e)
354         {
355             handleException(e);
356         }
357         finally
358         {
359             try
360             {
361                 folder.close(true); // close and expunge deleted messages
362
}
363             catch (Exception JavaDoc e)
364             {
365                 logger.error("Failed to close pop3 inbox: " + e.getMessage());
366             }
367         }
368     }
369
370     protected void doDispose()
371     {
372         super.doDispose();
373         if (folder != null)
374         {
375             folder.removeMessageCountListener(this);
376         }
377     }
378
379 }
380
Popular Tags