source: trunk/src/org/expeditee/agents/mail/MailSession.java@ 251

Last change on this file since 251 was 251, checked in by ra33, 16 years ago
File size: 14.7 KB
Line 
1package org.expeditee.agents.mail;
2
3import java.awt.Color;
4import java.awt.Point;
5import java.io.BufferedReader;
6import java.io.InputStream;
7import java.io.InputStreamReader;
8import java.util.Collection;
9import java.util.Date;
10import java.util.LinkedList;
11import java.util.Properties;
12
13import javax.mail.Authenticator;
14import javax.mail.Folder;
15import javax.mail.Message;
16import javax.mail.MessagingException;
17import javax.mail.Multipart;
18import javax.mail.Part;
19import javax.mail.PasswordAuthentication;
20import javax.mail.Session;
21import javax.mail.Store;
22import javax.mail.Transport;
23import javax.mail.Flags.Flag;
24import javax.mail.event.MessageCountAdapter;
25import javax.mail.event.MessageCountEvent;
26import javax.mail.internet.InternetAddress;
27import javax.mail.internet.MimeMessage;
28
29import org.expeditee.dnd.FrameDNDTransferHandler;
30import org.expeditee.gui.AttributeValuePair;
31import org.expeditee.gui.Frame;
32import org.expeditee.gui.FrameCreator;
33import org.expeditee.gui.MessageBay;
34import org.expeditee.items.Item;
35import org.expeditee.items.Text;
36
37public class MailSession {
38 public static boolean _autoConnect = false;
39
40 private static MailSession _theMailSession = null;
41
42 private Session _session;
43
44 private Transport _transport;
45
46 private Store _store;
47
48 private Folder _folder;
49
50 private String _address;
51
52 private String _username;
53
54 private String _password;
55
56 private String _mailServer;
57
58 private String _serverType;
59
60 private Boolean _bConnecting;
61
62 private MailSession(Frame settingsFrame) {
63 _bConnecting = false;
64
65 Properties props = System.getProperties();
66
67 _username = null;
68 _password = "";
69 _mailServer = null;
70 _serverType = null;
71
72 // Set the settings
73 for (Text item : settingsFrame.getBodyTextItems(false)) {
74 if (item.getText().toLowerCase().trim().equals("autoconnect")) {
75 _autoConnect = true;
76 }
77 AttributeValuePair avp = new AttributeValuePair(item.getText());
78 if (!avp.hasPair())
79 continue;
80 String attributeFullCase = avp.getAttribute();
81 String attribute = attributeFullCase.toLowerCase();
82
83 if (attribute.equals("user")) {
84 _username = avp.getValue();
85 props.setProperty("mail.user", _username);
86 } else if (attribute.equals("password")) {
87 _password = avp.getValue();
88 props.setProperty("mail.password", _password);
89 } else if (attribute.equals("address")) {
90 _address = avp.getValue();
91 } else if (attribute.equals("smtpserver")) {
92 props.setProperty("mail.transport.protocol", "smtp");
93 props.setProperty("mail.host", avp.getValue());
94 props.setProperty("mail.smtp.starttls.enable", "true");
95 props.setProperty("mail.smtp.host", avp.getValue());
96 props.setProperty("mail.smtp.auth", "true");
97 } else if (attribute.equals("popserver")) {
98 _mailServer = avp.getValue();
99 _serverType = "pop3s";
100 props.setProperty("mail.pop3.host", _mailServer);
101 } else if (attribute.equals("imapserver")) {
102 _mailServer = avp.getValue();
103 _serverType = "imaps";
104 props.setProperty("mail.imap.host", _mailServer);
105 }
106 }
107
108 // Create the authenticator
109 Authenticator auth = null;
110 if (_username != null) {
111 auth = new SMTPAuthenticator(_username, _password);
112 }
113 java.security.Security
114 .addProvider(new com.sun.net.ssl.internal.ssl.Provider());
115
116 // -- Attaching to default Session, or we could start a new one --
117 _session = Session.getDefaultInstance(props, auth);
118 try {
119 // Set up the mail receiver
120 _store = _session.getStore(_serverType);
121
122 // Connect the mail sender
123 _transport = _session.getTransport();
124 if (_autoConnect) {
125 connectThreaded();
126 }
127 } catch (Exception e) {
128 MessageBay.errorMessage("Error in ExpMail setup");
129 }
130 }
131
132 /**
133 * Attempts to connect the mail transporter to the mail server.
134 *
135 */
136 public static void connect() {
137 if (_theMailSession._bConnecting) {
138 MessageBay.errorMessage("Already connecting to mail server");
139 return;
140 } else if (_theMailSession != null) {
141 _theMailSession.connectThreaded();
142 }
143 }
144
145 private void connectThreaded() {
146 Thread t = new ConnectThread(this);
147 t.start();
148 }
149
150 public synchronized void connectServers() {
151 try {
152 if (!_transport.isConnected()) {
153 MessageBay.displayMessage("Connecting to SMTP server...");
154 _bConnecting = true;
155 _transport.connect();
156 MessageBay.overwriteMessage("SMTP server connected",
157 Color.green);
158 } else {
159 MessageBay.warningMessage("SMTP server already connected");
160 }
161 } catch (MessagingException e) {
162 MessageBay.errorMessage("Error connecting to SMTP server");
163 }
164
165 if (_mailServer != null && !_store.isConnected()) {
166 try {
167 MessageBay.displayMessage("Connecting to " + _mailServer
168 + "...");
169 _store.connect(_mailServer, _username, _password);
170
171 // -- Try to get hold of the default folder --
172 _folder = _store.getDefaultFolder();
173 if (_folder == null)
174 throw new Exception("No default folder");
175 // -- ...and its INBOX --
176 _folder = _folder.getFolder("INBOX");
177 if (_folder == null)
178 throw new Exception("No INBOX");
179 // -- Open the folder for read only --
180 _folder.open(Folder.READ_WRITE);
181 _folder.addMessageCountListener(new MessageCountAdapter() {
182 @Override
183 public void messagesAdded(MessageCountEvent e) {
184 MessageBay.displayMessage("New mail message!",
185 Color.green);
186 displayUnreadMailCount();
187 }
188 });
189
190 new Thread() {
191 public void run() {
192 for (;;) {
193 try {
194 Thread.sleep(1000); // sleep for freq
195 // milliseconds
196 // This is to force the IMAP server to send us
197 // EXISTS notifications
198 // TODO: Is synchronisation needed?
199 _folder.getMessageCount();
200 } catch (Exception e) {
201 }
202 }
203 }
204 }.start();
205
206 MessageBay.overwriteMessage("Connection complete", Color.GREEN);
207
208 displayUnreadMailCount();
209
210 } catch (Exception e) {
211 // e.printStackTrace();
212 MessageBay.errorMessage("Error connecting to " + _mailServer);
213 }
214 }
215 _bConnecting = false;
216 }
217
218 private void displayUnreadMailCount() {
219 Text text = new Text(-1, getUnreadCount() + " unread message"
220 + (getUnreadCount() == 1 ? "" : "s"), Color.BLUE, null);
221 text.addAction("getUnreadMail");
222 MessageBay.displayMessage(text);
223 }
224
225 public static boolean sendTextMessage(String to, String cc, String bcc,
226 String subject, String body) {
227
228 if (_theMailSession == null) {
229 MessageBay.errorMessage("Add mail settings to profile frame");
230 return false;
231 }
232
233 if (_theMailSession._bConnecting) {
234 MessageBay.errorMessage("Busy connecting to mail server...");
235 return false;
236 }
237
238 return _theMailSession.sendText(to, cc, bcc, subject, body);
239 }
240
241 private synchronized boolean sendText(String to, String cc, String bcc,
242 String subject, String body) {
243 if (!_transport.isConnected()) {
244 MessageBay
245 .warningMessage("Not connected to server, attempting to reconnect...");
246 try {
247 _bConnecting = true;
248 _transport.connect();
249 _bConnecting = false;
250 } catch (Exception e) {
251 MessageBay.errorMessage("Could not connect to mail server");
252 _bConnecting = false;
253 return false;
254 }
255 }
256
257 if (to == null) {
258 MessageBay.errorMessage("Add tag @to:<sendToEmailAddress>");
259 return false;
260 }
261
262 try {
263 // -- Create a new message --
264 Message msg = new MimeMessage(_session);
265
266 // -- Set the FROM and TO fields --
267 msg.setFrom(new InternetAddress(_address));
268 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
269 to, false));
270
271 // -- We could include CC recipients too --
272 if (cc != null) {
273 msg.setRecipients(Message.RecipientType.CC, InternetAddress
274 .parse(cc, false));
275 }
276
277 if (bcc != null) {
278 msg.setRecipients(Message.RecipientType.BCC, InternetAddress
279 .parse(bcc, false));
280 }
281
282 // -- Set the subject and body text --
283 msg.setSubject(subject);
284 msg.setContent(body.toString(), "text/plain");
285
286 // -- Set some other header information --
287 msg.setHeader("ExpMail", "Expeditee");
288 msg.setSentDate(new Date());
289
290 Transport.send(msg, msg.getRecipients(Message.RecipientType.TO));
291 } catch (Exception e) {
292 MessageBay.errorMessage("Error sending mail: " + e.getMessage());
293 return false;
294 }
295 MessageBay.displayMessage("Message sent OK.");
296 return true;
297 }
298
299 public static void init(Frame settingsFrame) {
300
301 if (settingsFrame == null)
302 return;
303
304 if (_theMailSession == null)
305 _theMailSession = new MailSession(settingsFrame);
306 }
307
308 private class SMTPAuthenticator extends javax.mail.Authenticator {
309 private String _username;
310
311 private String _password;
312
313 public SMTPAuthenticator(String username, String password) {
314 _username = username;
315 _password = password;
316 }
317
318 @Override
319 public PasswordAuthentication getPasswordAuthentication() {
320 return new PasswordAuthentication(_username, _password);
321 }
322 }
323
324 public static MailSession getInstance() {
325 return _theMailSession;
326 }
327
328 public synchronized void finalise() {
329 try {
330 if (_transport != null && _transport.isConnected()) {
331 _transport.close();
332 }
333
334 if (_folder != null) {
335 _folder.close(false);
336 }
337
338 if (_store != null) {
339 _store.close();
340 }
341 } catch (Exception e) {
342
343 }
344 }
345
346 public int getUnreadCount() {
347 try {
348 return _folder.getUnreadMessageCount();
349 } catch (MessagingException e) {
350 // TODO Auto-generated catch block
351 e.printStackTrace();
352 }
353 return 0;
354 }
355
356 /**
357 * Gets mail and puts a list of mail items with links to the messages
358 * content. TODO: Put reply and forward button on the frame...
359 *
360 * @param flag
361 * @param isPresent
362 * @param frame
363 * @param point
364 * @return
365 */
366 public String getMailString(Flag flag, Boolean isPresent) {
367 StringBuffer sb = new StringBuffer();
368 // -- Get the message wrappers and process them --
369 Message[] msgs;
370 try {
371 msgs = _folder.getMessages();
372 for (int msgNum = 0; msgNum < msgs.length; msgNum++) {
373
374 if (flag == null
375 || msgs[msgNum].getFlags().contains(flag) == isPresent) {
376 if (sb.length() > 0) {
377 sb.append('\n').append('\n').append(
378 "-----------------------------").append('\n')
379 .append('\n');
380 }
381 // Only get messages that have not been read
382 sb.append(getTextMessage(msgs[msgNum]));
383 }
384 }
385 } catch (MessagingException e) {
386 e.printStackTrace();
387 }
388 return sb.toString();
389 }
390
391 /**
392 * Gets mail and puts a list of mail items with links to the messages
393 * content. TODO: Put reply and forward button on the frame...
394 *
395 * @param flag
396 * @param isPresent
397 * @param frame
398 * @param point
399 * @return
400 */
401 public Collection<Item> getMail(Flag flag, Boolean isPresent, Frame frame,
402 Point point) {
403 Collection<Item> mailItems = new LinkedList<Item>();
404 // -- Get the message wrappers and process them --
405 Message[] msgs;
406 try {
407 msgs = _folder.getMessages();
408 for (int msgNum = 0; msgNum < msgs.length; msgNum++) {
409 if (flag == null
410 || msgs[msgNum].getFlags().contains(flag) == isPresent) {
411 Item newItem = readMessage(msgs[msgNum], msgNum, frame, point);
412 if (newItem != null) {
413 mailItems.add(newItem);
414 point.y += newItem.getBoundsHeight();
415 }
416 }
417
418 }
419 } catch (MessagingException e) {
420 e.printStackTrace();
421 }
422 return mailItems;
423 }
424
425 private Item readMessage(final Message message, int messageNo, Frame frame, Point point) {
426 String subject;
427 try {
428 subject = message.getSubject();
429 } catch (MessagingException e) {
430 MessageBay.errorMessage("GetMail error: " + e.getMessage());
431 return null;
432 }
433
434 final Text source = FrameDNDTransferHandler
435 .importString(subject, point);
436 // Create a frameCreator
437 final FrameCreator frames = new FrameCreator(frame.getFramesetName(),
438 frame.path, messageNo + ". " + subject, false);
439
440 new Thread() {
441 public void run() {
442 try {
443 // Get the header information
444 String from = ((InternetAddress) message.getFrom()[0])
445 .getPersonal();
446 if( from != null){
447 frames.addText("@fromName: " + from, null, null, null, false);
448 }
449 from = ((InternetAddress) message.getFrom()[0])
450 .getAddress();
451 frames.addText("@fromAddress: " + from, null, null, null, false);
452
453 // -- Get the message part (i.e. the message itself) --
454 Part messagePart = message;
455 Object content = messagePart.getContent();
456 // -- or its first body part if it is a multipart
457 // message --
458 if (content instanceof Multipart) {
459 messagePart = ((Multipart) content).getBodyPart(0);
460 // System.out.println("[ Multipart Message ]");
461 }
462 // -- Get the content type --
463 String contentType = messagePart.getContentType().toLowerCase();
464 // -- If the content is plain text, we can print it --
465 // System.out.println("CONTENT:" + contentType);
466 if (contentType.startsWith("text/plain")
467 || contentType.startsWith("text/html")) {
468 InputStream is = messagePart.getInputStream();
469 BufferedReader reader = new BufferedReader(
470 new InputStreamReader(is));
471 String thisLine = reader.readLine();
472 while (thisLine != null) {
473 frames.addText(thisLine, null, null, null, false);
474 thisLine = reader.readLine();
475 }
476 }
477 message.setFlag(Flag.SEEN, true);
478
479 frames.save();
480 source.setLink(frames.getName());
481 } catch (Exception e) {
482 MessageBay.errorMessage("GetMail error: " + e.getMessage());
483 }
484 }
485 }.start();
486 return source;
487 }
488
489 /**
490 * "getTextMessage()" method to print a message.
491 */
492 public String getTextMessage(Message message) {
493 StringBuffer sb = new StringBuffer();
494
495 try {
496 // Get the header information
497 String from = ((InternetAddress) message.getFrom()[0])
498 .getPersonal();
499 if (from == null)
500 from = ((InternetAddress) message.getFrom()[0]).getAddress();
501 sb.append("FROM: " + from).append('\n');
502 String subject = message.getSubject();
503 sb.append("SUBJECT: " + subject).append('\n').append('\n');
504 // -- Get the message part (i.e. the message itself) --
505 Part messagePart = message;
506 Object content = messagePart.getContent();
507 // -- or its first body part if it is a multipart message --
508 if (content instanceof Multipart) {
509 messagePart = ((Multipart) content).getBodyPart(0);
510 System.out.println("[ Multipart Message ]");
511 }
512 // -- Get the content type --
513 String contentType = messagePart.getContentType();
514 // -- If the content is plain text, we can print it --
515 // System.out.println("CONTENT:" + contentType);
516 if (contentType.startsWith("text/plain")
517 || contentType.startsWith("text/html")) {
518 InputStream is = messagePart.getInputStream();
519 BufferedReader reader = new BufferedReader(
520 new InputStreamReader(is));
521 String thisLine = reader.readLine();
522 while (thisLine != null) {
523 sb.append(thisLine).append('\n');
524 thisLine = reader.readLine();
525 }
526 }
527 message.setFlag(Flag.SEEN, true);
528 } catch (Exception ex) {
529 ex.printStackTrace();
530 }
531 sb.deleteCharAt(sb.length() - 1);
532 return sb.toString();
533 }
534
535 public Folder getFolder() {
536 return _folder;
537 }
538}
Note: See TracBrowser for help on using the repository browser.