1
2
3
4
5
6
7 package org.mule.transport.email;
8
9 import org.mule.api.MuleEvent;
10 import org.mule.api.MuleMessage;
11 import org.mule.api.endpoint.EndpointURI;
12 import org.mule.api.endpoint.InboundEndpoint;
13 import org.mule.transport.AbstractMessageRequester;
14
15 import com.sun.mail.imap.IMAPMessage;
16
17 import java.net.URLDecoder;
18
19 import javax.mail.Flags;
20 import javax.mail.Folder;
21 import javax.mail.Message;
22 import javax.mail.MessagingException;
23 import javax.mail.Store;
24 import javax.mail.internet.MimeMessage;
25
26
27
28
29
30
31
32 public class RetrieveMessageRequester extends AbstractMessageRequester
33 {
34 private Folder folder;
35 private Folder moveToFolder;
36
37 public RetrieveMessageRequester(InboundEndpoint endpoint)
38 {
39 super(endpoint);
40 }
41
42 private AbstractRetrieveMailConnector castConnector()
43 {
44 return (AbstractRetrieveMailConnector) getConnector();
45 }
46
47 @Override
48 protected void doConnect() throws Exception
49 {
50 if (folder == null || !folder.isOpen())
51 {
52 Store store = castConnector().getSessionDetails(endpoint).newStore();
53
54 EndpointURI uri = endpoint.getEndpointURI();
55 String encoding = endpoint.getEncoding();
56 String user = (uri.getUser() != null ? URLDecoder.decode(uri.getUser(), encoding) : null);
57 String pass = (uri.getPassword() != null ? URLDecoder.decode(uri.getPassword(), encoding) : null);
58 store.connect(uri.getHost(), uri.getPort(), user, pass);
59
60 folder = store.getFolder(castConnector().getMailboxFolder());
61 ensureFolderIsOpen(folder);
62
63 if (castConnector().getMoveToFolder() != null)
64 {
65 moveToFolder = store.getFolder(castConnector().getMoveToFolder());
66 ensureFolderIsOpen(moveToFolder);
67 }
68 }
69 }
70
71 protected void ensureFolderIsOpen(Folder fldr)
72 {
73 if (!fldr.isOpen())
74 {
75 try
76 {
77
78
79
80 fldr.open(Folder.READ_WRITE);
81 }
82 catch (MessagingException e)
83 {
84 logger.warn("Failed to open folder: " + fldr.getFullName() + " This is not an exception since some server implementations do not require the folder to be open", e);
85 }
86 }
87 }
88
89 @Override
90 protected void doDisconnect() throws Exception
91 {
92
93 try
94 {
95 if (folder != null)
96 {
97 try
98 {
99 folder.expunge();
100 }
101 catch (MessagingException e)
102 {
103 if (logger.isDebugEnabled())
104 {
105 logger.debug("ignoring exception on expunge: " + e.getMessage());
106 }
107 }
108 if (folder.isOpen())
109 {
110 folder.close(true);
111 }
112 }
113 }
114 catch (Exception e)
115 {
116 logger.error("Failed to close inbox: " + e.getMessage(), e);
117 }
118
119 try
120 {
121 if (moveToFolder != null)
122 {
123 if (moveToFolder.isOpen())
124 {
125 moveToFolder.close(false);
126 }
127 }
128 }
129 catch (Exception e)
130 {
131 logger.error("Failed to close moveToFolder: " + e.getMessage(), e);
132 }
133 }
134
135
136
137
138
139 protected void doDispatch(MuleEvent event) throws Exception
140 {
141 throw new UnsupportedOperationException("Cannot dispatch from a POP3/IMAP connection");
142 }
143
144
145
146
147
148 protected MuleMessage doSend(MuleEvent event) throws Exception
149 {
150 throw new UnsupportedOperationException("Cannot send from a POP3/IMAP connection");
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165 @Override
166 protected MuleMessage doRequest(long timeout) throws Exception
167 {
168 long t0 = System.currentTimeMillis();
169 if (timeout < 0)
170 {
171 timeout = Long.MAX_VALUE;
172 }
173
174 do
175 {
176 if (hasMessages())
177 {
178 int count = getMessageCount();
179 if (count > 0)
180 {
181 Message message = getNextMessage();
182 if (message != null)
183 {
184
185 flagMessage(message);
186
187 if (moveToFolder != null)
188 {
189 Message newMessage = message;
190
191
192 if (message instanceof IMAPMessage)
193 {
194
195 newMessage = new MimeMessage((IMAPMessage) message);
196 }
197 folder.copyMessages(new Message[]{message}, moveToFolder);
198 message = newMessage;
199 }
200 return createMuleMessage(message, endpoint.getEncoding());
201 }
202 }
203 else if (count == -1)
204 {
205 throw new MessagingException("Cannot monitor folder: " + folder.getFullName()
206 + " as folder is closed");
207 }
208 }
209
210 long sleep =
211 Math.min(castConnector().getCheckFrequency(),
212 timeout - (System.currentTimeMillis() - t0));
213
214 if (sleep > 0)
215 {
216 if (logger.isDebugEnabled())
217 {
218 logger.debug("No results, sleeping for " + sleep);
219 }
220 try
221 {
222 Thread.sleep(sleep);
223 }
224 catch (InterruptedException e)
225 {
226 logger.warn("Thread interrupted while requesting email on: " + endpoint.getEndpointURI().toString());
227 return null;
228 }
229 }
230 else
231 {
232
233 logger.debug("Timeout");
234 return null;
235 }
236
237 }
238 while (true);
239 }
240
241
242
243
244
245
246 protected void flagMessage(Message message) throws MessagingException
247 {
248 if (castConnector().isDeleteReadMessages())
249 {
250 message.setFlag(Flags.Flag.DELETED, true);
251 }
252 else
253 {
254 message.setFlag(Flags.Flag.SEEN, true);
255 }
256 }
257
258 protected Message getNextMessage() throws MessagingException
259 {
260 if (getMessageCount() > 0)
261 {
262 Message message = folder.getMessage(1);
263 if (!message.isExpunged())
264 {
265 return message;
266 }
267 }
268 return null;
269 }
270
271 protected int getMessageCount() throws MessagingException
272 {
273 return folder.getMessageCount();
274 }
275
276
277
278
279
280
281 protected boolean hasMessages() throws MessagingException
282 {
283 return getMessageCount() > 0;
284 }
285
286 @Override
287 protected void doDispose()
288 {
289 if (null != folder && folder.isOpen())
290 {
291 try
292 {
293
294 folder.close(true);
295 }
296 catch (Exception e)
297 {
298 logger.debug("ignoring exception: " + e.getMessage(), e);
299 }
300 }
301 }
302 }