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