001: package org.claros.commons.mail.protocols;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.IOException;
005: import java.net.ConnectException;
006: import java.security.Security;
007: import java.util.ArrayList;
008: import java.util.Collections;
009: import java.util.HashMap;
010: import java.util.Iterator;
011: import java.util.Locale;
012: import java.util.Map;
013: import java.util.Properties;
014:
015: import javax.mail.FetchProfile;
016: import javax.mail.Flags;
017: import javax.mail.Folder;
018: import javax.mail.FolderNotFoundException;
019: import javax.mail.Message;
020: import javax.mail.MessagingException;
021: import javax.mail.NoSuchProviderException;
022: import javax.mail.Session;
023: import javax.mail.Store;
024: import javax.mail.internet.MimeMessage;
025:
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028: import org.claros.commons.auth.models.AuthProfile;
029: import org.claros.commons.exception.SystemException;
030: import org.claros.commons.mail.exception.ConnectionException;
031: import org.claros.commons.mail.exception.MailboxActionException;
032: import org.claros.commons.mail.exception.ProtocolNotAvailableException;
033: import org.claros.commons.mail.exception.ServerDownException;
034: import org.claros.commons.mail.models.ConnectionMetaHandler;
035: import org.claros.commons.mail.models.ConnectionProfile;
036: import org.claros.commons.mail.models.EmailHeader;
037: import org.claros.commons.mail.utility.Constants;
038: import org.claros.commons.mail.utility.Utility;
039: import org.claros.commons.utility.Formatter;
040:
041: import com.sun.mail.iap.ProtocolException;
042: import com.sun.mail.imap.IMAPFolder;
043:
044: /**
045: * @author Umut Gokbayrak
046: */
047: public class ImapProtocolImpl implements Protocol {
048: private static Log log = LogFactory.getLog(ImapProtocolImpl.class);
049: private String folder;
050: private ConnectionProfile profile;
051: private AuthProfile auth;
052: private ConnectionMetaHandler handler;
053: private static final Locale loc = new Locale("en", "US");
054: private static Map imapFolders = Collections
055: .synchronizedMap(new HashMap());
056:
057: /**
058: *
059: * @param profile
060: * @param auth
061: * @param handler
062: */
063: ImapProtocolImpl(ConnectionProfile profile, AuthProfile auth,
064: ConnectionMetaHandler handler, String folder) {
065: this .profile = profile;
066: this .auth = auth;
067: this .handler = handler;
068: this .folder = folder;
069:
070: if (imapFolders.get(auth.getUsername()) == null) {
071: HashMap imapUserFolders = new HashMap();
072: imapFolders.put(auth.getUsername(), imapUserFolders);
073: }
074:
075: if (this .folder == null
076: || this .folder.trim().equals("")
077: || this .folder.toLowerCase(loc).equals(
078: Constants.FOLDER_INBOX(profile)
079: .toLowerCase(loc))) {
080: this .folder = Constants.FOLDER_INBOX(profile);
081: } else {
082: if (!this .folder.startsWith(profile.getFolderNameSpace())) {
083: this .folder = profile.getFolderNameSpace()
084: + this .folder;
085: }
086: }
087: }
088:
089: /**
090: *
091: * @return
092: * @throws Exception
093: */
094: public Folder getFolder() throws Exception {
095: return getImapFolder(true);
096: }
097:
098: /**
099: *
100: * @return
101: * @throws Exception
102: */
103: public Folder getImapFolder(boolean useCache) throws Exception {
104: Folder myFold = null;
105: if (folder == null) {
106: folder = Constants.FOLDER_INBOX(profile);
107: }
108:
109: if (folder != null && handler != null) {
110: Store store = handler.getStore();
111: if (store == null || !store.isConnected()) {
112: log.debug("Connection is closed. Restoring it...");
113: handler = connect(Constants.CONNECTION_READ_WRITE);
114: log.debug("Connection re-established");
115: }
116:
117: HashMap imapUserFolders = null;
118: if (useCache) {
119: imapUserFolders = (HashMap) imapFolders.get(auth
120: .getUsername());
121: myFold = (Folder) imapUserFolders.get(folder);
122: }
123: if (myFold == null) {
124: myFold = handler.getStore().getFolder(folder);
125: }
126: if (!myFold.isOpen()) {
127: try {
128: log.debug("Folder :" + folder
129: + " is closed. Opening.");
130: myFold.open(Constants.CONNECTION_READ_WRITE);
131: log.debug("Folder is open.");
132: } catch (Throwable e) {
133: log.debug("nevermind go on");
134: // nevermind go on...
135: }
136: }
137: if (useCache) {
138: try {
139: imapUserFolders.put(folder, myFold);
140: imapFolders
141: .put(auth.getUsername(), imapUserFolders);
142: } catch (Exception e) {
143: e.printStackTrace();
144: }
145: }
146: }
147: return myFold;
148: }
149:
150: /* (non-Javadoc)
151: * @see org.claros.commons.mail.protocols.Protocol#connect(int)
152: */
153: public ConnectionMetaHandler connect(int connectType)
154: throws SystemException, ConnectionException,
155: ServerDownException {
156: Folder fold = null;
157: try {
158: if (handler == null || handler.getStore() == null
159: || !handler.getStore().isConnected()) {
160: Properties props = new Properties();
161:
162: if (log.isDebugEnabled()) {
163: props.setProperty("mail.debug", "true");
164: System.setProperty("javax.net.debug", "all");
165: }
166:
167: if (profile.getFetchSSL() != null
168: && profile.getFetchSSL().toLowerCase().equals(
169: "true")) {
170: Security
171: .addProvider(new com.sun.net.ssl.internal.ssl.Provider());
172:
173: Security
174: .setProperty("ssl.SocketFactory.provider",
175: "org.claros.commons.mail.protocols.DummySSLSocketFactory");
176: props.setProperty("mail.store.protocol", "imap");
177: props.setProperty("mail.imap.host", profile
178: .getFetchServer());
179: props.setProperty("mail.imap.port", profile
180: .getFetchPort());
181:
182: props
183: .setProperty(
184: "mail.imap.socketFactory.class",
185: "org.claros.commons.mail.protocols.DummySSLSocketFactory");
186: props
187: .setProperty(
188: "mail.imap.socketFactory.fallback",
189: "false");
190: props.setProperty("mail.imap.port", profile
191: .getFetchPort());
192: props.setProperty("mail.imap.socketFactory.port",
193: profile.getFetchPort());
194: }
195:
196: Session session = Session.getInstance(props);
197: log.debug("session instance initiated");
198: handler = new ConnectionMetaHandler();
199: handler.setStore(session
200: .getStore(profile.getProtocol()));
201: log.debug("session store set. protocol is: "
202: + profile.getProtocol());
203: handler.getStore().connect(profile.getFetchServer(),
204: profile.getIFetchPort(), auth.getUsername(),
205: auth.getPassword());
206:
207: // check if the store is connected or not.
208: if (handler.getStore().isConnected()) {
209: log.debug("Store has been connected... Successful");
210: } else {
211: log.warn("Connection unsuccessfull...!!");
212: }
213: }
214: fold = handler.getStore().getFolder(
215: Constants.FOLDER_INBOX(profile));
216:
217: HashMap imapUserFolders = (HashMap) imapFolders.get(auth
218: .getUsername());
219: imapUserFolders.put("INBOX", fold);
220: imapFolders.put(auth.getUsername(), imapUserFolders);
221:
222: handler.setMbox(fold);
223: log.debug("Got mailbox folder. Folder is: "
224: + fold.getFullName());
225: handler.setTotalMessagesCount(fold.getMessageCount());
226: log.debug("Message Count:"
227: + handler.getTotalMessagesCount());
228: } catch (FolderNotFoundException e) {
229: log
230: .fatal(profile.getProtocol()
231: + " cannot identify the INBOX folder. Please check your folder-namespace variable at config.xml.");
232: throw new SystemException(e);
233: } catch (NoSuchProviderException e) {
234: log.fatal(profile.getProtocol()
235: + " provider could not be found.");
236: throw new SystemException(e);
237: } catch (MessagingException e) {
238: Exception ne = e.getNextException();
239: if (ne != null) {
240: if (ne instanceof ConnectException
241: || ne instanceof IOException) {
242: throw new ServerDownException(
243: "Server is unreachable.");
244: }
245: }
246: log.error("Connection could not be established."
247: + e.getMessage());
248: // throw new ConnectionException(e);
249: } catch (Exception e) {
250: log.error("An unknown exception while connect.", e);
251: }
252: return handler;
253: }
254:
255: /* (non-Javadoc)
256: * @see org.claros.commons.mail.protocols.Protocol#deleteMessages(int[])
257: */
258: public ConnectionMetaHandler deleteMessages(int[] messageIds)
259: throws MailboxActionException, SystemException,
260: ConnectionException {
261: Folder fold = null;
262: try {
263: fold = getFolder();
264: if (messageIds != null && messageIds.length > 0) {
265: for (int i = 0; i < messageIds.length; i++) {
266: try {
267: if (messageIds[i] > 0) {
268: Message msg = fold
269: .getMessage(messageIds[i]);
270: msg.setFlag(Flags.Flag.DELETED, true);
271: }
272: } catch (Exception e) {
273: log.debug("error while deleting messsage", e);
274: }
275: }
276: fold.expunge();
277: }
278: } catch (MessagingException e) {
279: log.error("Could not delete message ids: " + messageIds, e);
280: throw new MailboxActionException(e);
281: } catch (IndexOutOfBoundsException e) {
282: log.error(
283: "Maybe you are double clicking the delete button",
284: e);
285: } catch (Exception e) {
286: log.error("Could not delete message ids: " + messageIds, e);
287: throw new MailboxActionException(e);
288: } finally {
289: closeFolder(fold);
290: // disconnect();
291: }
292: return handler;
293: }
294:
295: /**
296: *
297: * @return
298: * @throws ProtocolNotAvailableException
299: */
300: public ArrayList getHeadersSortedList(String sortCriteriaRaw,
301: String sortDirectionRaw)
302: throws ProtocolNotAvailableException {
303: Folder fold = null;
304: try {
305: fold = getFolder();
306: IMAPFolder f = (IMAPFolder) fold;
307:
308: String sortCriteria = ImapSortProtocolCommand.SORT_DATE;
309: if (sortCriteriaRaw == null
310: || sortCriteriaRaw.equals("date")) {
311: sortCriteria = ImapSortProtocolCommand.SORT_DATE;
312: } else if (sortCriteriaRaw.equals("subject")) {
313: sortCriteria = ImapSortProtocolCommand.SORT_SUBJECT;
314: } else if (sortCriteriaRaw.equals("to")) {
315: sortCriteria = ImapSortProtocolCommand.SORT_TO;
316: } else if (sortCriteriaRaw.equals("from")) {
317: sortCriteria = ImapSortProtocolCommand.SORT_FROM;
318: } else if (sortCriteriaRaw.equals("size")) {
319: sortCriteria = ImapSortProtocolCommand.SORT_SIZE;
320: }
321:
322: boolean ascending = false;
323: if (sortDirectionRaw != null
324: && sortDirectionRaw.equals("asc")) {
325: ascending = true;
326: }
327:
328: ImapSortProtocolCommand sortCommand = new ImapSortProtocolCommand(
329: sortCriteria, ascending, profile);
330: f.doCommand(sortCommand);
331:
332: // this profile must be set to the session at the caller method.
333: profile = sortCommand.getProfile();
334:
335: ArrayList res = sortCommand.getSortedList();
336: if (res == null) {
337: profile.setSupportSort(false);
338: throw new ProtocolNotAvailableException();
339: }
340: return res;
341: } catch (ProtocolException p) {
342: throw new ProtocolNotAvailableException();
343: } catch (MessagingException e) {
344: if (e.getCause() instanceof ProtocolException) {
345: throw new ProtocolNotAvailableException();
346: }
347: log
348: .error(
349: "Could not fetch message headers. Is mbox connection still alive???",
350: e);
351: } catch (Exception e) {
352: log
353: .error(
354: "Could not fetch message headers. Is mbox connection still alive???",
355: e);
356: }
357: return null;
358: }
359:
360: /**
361: * Fetches all e-mail headers from the server, with appropriate
362: * fields already set.
363: * @param handler
364: * @return ArrayList of MessageHeaders
365: * @throws ConnectionException
366: */
367: public ArrayList fetchAllHeaders() throws SystemException,
368: ConnectionException {
369: return fetchHeaders(null);
370: }
371:
372: /**
373: * Fetches and returns message headers as message objects.
374: * @return
375: * @throws SystemException
376: * @throws ConnectionException
377: */
378: public ArrayList fetchAllHeadersAsMessages()
379: throws SystemException, ConnectionException {
380: ArrayList headers = null;
381: Folder fold = null;
382: try {
383: headers = new ArrayList();
384: fold = getFolder();
385: Message[] msgs = fold.getMessages();
386: FetchProfile fp = new FetchProfile();
387: fp.add(FetchProfile.Item.ENVELOPE);
388: fp.add(FetchProfile.Item.FLAGS);
389: fp.add(FetchProfile.Item.CONTENT_INFO);
390: fp.add("Size");
391: fp.add("Date");
392: fold.fetch(msgs, fp);
393:
394: Message msg = null;
395: for (int i = 0; i < msgs.length; i++) {
396: try {
397: msg = msgs[i];
398:
399: boolean deleted = false;
400: Flags.Flag flags[] = msg.getFlags()
401: .getSystemFlags();
402: if (flags != null) {
403: Flags.Flag flag = null;
404: for (int m = 0; m < flags.length; m++) {
405: flag = flags[m];
406: if (flag.equals(Flags.Flag.DELETED)) {
407: deleted = true;
408: }
409: }
410: }
411: if (!deleted) {
412: headers.add(msg);
413: }
414: } catch (Exception e) {
415: log.debug("probably an error fetching list", e);
416: }
417: }
418: } catch (MessagingException e) {
419: log
420: .error(
421: "Could not fetch message headers. Is mbox connection still alive???",
422: e);
423: throw new ConnectionException(e);
424: } catch (Exception e) {
425: log
426: .error(
427: "Could not fetch message headers. Is mbox connection still alive???",
428: e);
429: throw new ConnectionException(e);
430: }
431: return headers;
432: }
433:
434: /**
435: *
436: */
437: public Message getMessage(int messageId)
438: throws MailboxActionException, SystemException,
439: ConnectionException, Exception {
440: Message msg = null;
441: Folder fold = null;
442: try {
443: try {
444: fold = getFolder();
445: msg = fold.getMessage(messageId);
446: } catch (MessagingException e) {
447: log
448: .error(
449: "Could not fetch message body from remote server.",
450: e);
451: throw new MailboxActionException(e);
452: }
453: } catch (Exception e) {
454: throw e;
455: }
456: return msg;
457: }
458:
459: /**
460: * Disconnects the previously opened data connection if
461: * the connection is still alive.
462: * @param handler
463: */
464: public void disconnect() {
465: try {
466: HashMap imapUserFolders = (HashMap) imapFolders.get(auth
467: .getUsername());
468: Iterator iter = imapUserFolders.keySet().iterator();
469: Folder tmp = null;
470: while (iter.hasNext()) {
471: try {
472: tmp = (Folder) imapUserFolders.get((String) iter
473: .next());
474: closeFolder(tmp);
475: tmp = null;
476: } catch (Throwable e) {
477: log.debug("Unable to close folder:" + tmp);
478: }
479: }
480: imapFolders.put(auth.getUsername(), new HashMap());
481: } catch (Throwable e1) {
482: }
483:
484: try {
485: handler.getStore().close();
486: } catch (Exception e) {
487: e.printStackTrace();
488: }
489: }
490:
491: /**
492: *
493: * @param msgId
494: * @throws Exception
495: */
496: public void markAsRead(Long msgId) throws Exception {
497: Folder f = getFolder();
498: try {
499: Message msg = f.getMessage(msgId.intValue());
500: msg.setFlag(Flags.Flag.SEEN, true);
501: } catch (MessagingException e) {
502: log.warn("Marking as Read not worked.", e);
503: }
504: }
505:
506: /**
507: *
508: * @param buff
509: * @throws Exception
510: */
511: public void appendEmail(byte[] buff) throws Exception {
512: Properties props = new Properties();
513: Session session = Session.getDefaultInstance(props);
514: ByteArrayInputStream bis = new ByteArrayInputStream(buff);
515: MimeMessage msg = new MimeMessage(session, bis);
516: msg.setFlag(Flags.Flag.SEEN, true);
517:
518: ProtocolFactory factory = new ProtocolFactory(profile, auth,
519: handler);
520: ImapProtocolImpl imap = (ImapProtocolImpl) factory
521: .getImap(folder);
522: Folder f = imap.getFolder();
523:
524: try {
525: f.appendMessages(new Message[] { msg });
526: } catch (MessagingException e) {
527: log.warn(
528: "appenging msg to folder : " + folder + " failed.",
529: e);
530: } finally {
531: bis.close();
532: }
533: }
534:
535: /**
536: *
537: * @param msgId
538: * @param destFolder
539: * @throws Exception
540: */
541: public void moveEmail(Long msgId, String destFolder)
542: throws Exception {
543: ProtocolFactory factory = new ProtocolFactory(profile, auth,
544: handler);
545: ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory
546: .getImap(folder);
547: ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory
548: .getImap(destFolder);
549: Folder from = fromProtocol.getFolder();
550: Folder dest = null;
551:
552: try {
553: Message msg = fromProtocol.getMessage(msgId.intValue());
554: if (msg != null) {
555: // because of the buggy imap servers lost the connection after getMessage
556: // we need to check if the folder is open or not.
557: // (Do not use uw-imapd, it sucks!!!)
558: from = fromProtocol.getFolder();
559: dest = destProtocol.getFolder();
560: from.copyMessages(new Message[] { msg }, dest);
561: // deleteMessages(new int[] {msg.getMessageNumber()});
562: flagAsDeleted(new int[] { msg.getMessageNumber() });
563: }
564: } catch (IndexOutOfBoundsException e) {
565: log.debug("Index kaçtı. Moving message to folder : "
566: + destFolder + " failed.", e);
567: } catch (Exception e) {
568: log.warn("Moving message to folder : " + destFolder
569: + " failed.", e);
570: }
571: }
572:
573: /**
574: *
575: * @param messageIds
576: * @param destFolder
577: * @throws Exception
578: */
579: public void moveEmails(int messageIds[], String destFolder)
580: throws Exception {
581: ProtocolFactory factory = new ProtocolFactory(profile, auth,
582: handler);
583: ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory
584: .getImap(folder);
585: ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory
586: .getImap(destFolder);
587: Folder from = fromProtocol.getFolder();
588: Folder dest = null;
589:
590: try {
591: Message msg = null;
592:
593: int counter = 0;
594: dest = destProtocol.getFolder();
595: Message msgs[] = new MimeMessage[messageIds.length];
596:
597: // copy messages to destination folder first
598: for (int i = 0; i < messageIds.length; i++) {
599: try {
600: msg = fromProtocol.getMessage(messageIds[i]);
601:
602: if (msg != null) {
603: msgs[counter] = msg;
604: counter++;
605: }
606: } catch (Exception e) {
607: log.debug("error while copying messages", e);
608: }
609: }
610:
611: from.copyMessages(msgs, dest);
612: // now delete the processed messages all at a time.
613: // deleteMessages(messageIds);
614: flagAsDeleted(messageIds);
615: } catch (IndexOutOfBoundsException e) {
616: log.debug("Index kaçtı. Moving message to folder : "
617: + destFolder + " failed.", e);
618: } catch (Exception e) {
619: log.warn("Moving message to folder : " + destFolder
620: + " failed.", e);
621: }
622: }
623:
624: /**
625: *
626: * @param messageIds
627: * @param destFolders
628: * @throws Exception
629: */
630: public void moveEmails(int messageIds[], String destFolders[])
631: throws Exception {
632: ProtocolFactory factory = new ProtocolFactory(profile, auth,
633: handler);
634: ImapProtocolImpl fromProtocol = (ImapProtocolImpl) factory
635: .getImap(folder);
636: Folder from = fromProtocol.getFolder();
637: Folder dest = null;
638:
639: try {
640: Message msg = null;
641: // copy messages to destination folder first
642: for (int i = 0; i < messageIds.length; i++) {
643: try {
644: msg = fromProtocol.getMessage(messageIds[i]);
645: ImapProtocolImpl destProtocol = (ImapProtocolImpl) factory
646: .getImap(destFolders[i]);
647: dest = destProtocol.getFolder();
648: from.copyMessages(new Message[] { msg }, dest);
649: } catch (Exception e) {
650: log.debug("error while copying messages", e);
651: }
652: }
653:
654: // now delete the processed messages all at a time.
655: // deleteMessages(messageIds);
656: flagAsDeleted(messageIds);
657:
658: } catch (Exception e) {
659: log.warn("Moving message failed.", e);
660: }
661: }
662:
663: /**
664: * @return
665: */
666: public Folder[] listFolders() throws Exception {
667: ProtocolFactory factory = new ProtocolFactory(profile, auth,
668: handler);
669: ImapProtocolImpl protocol = (ImapProtocolImpl) factory
670: .getImap(folder);
671: Folder f = protocol.getFolder();
672:
673: Folder parent = null;
674: Folder[] folders = null;
675:
676: try {
677: parent = f.getParent();
678: folders = parent.listSubscribed("*");
679: } catch (MessagingException e) {
680: log.warn("Cannot get folder list.");
681: } finally {
682: // closeFolder(parent);
683: }
684: return folders;
685: }
686:
687: /**
688: *
689: * @param f
690: */
691: public void closeFolder(Folder f) {
692: if (f != null) {
693: try {
694: if (f.isOpen()) {
695: f.close(true);
696: log.info("Folder: " + f.getName()
697: + " was open and now closed.");
698:
699: HashMap imapUserFolders = (HashMap) imapFolders
700: .get(auth.getUsername());
701: imapUserFolders.put(folder, null);
702: imapFolders
703: .put(auth.getUsername(), imapUserFolders);
704: } else {
705: log.info("Folder: " + f.getName()
706: + " was already closed.");
707: }
708: } catch (MessagingException e) {
709: log.info("Error while closing folder: " + f.getName(),
710: e);
711: }
712: }
713: }
714:
715: /**
716: *
717: */
718: public void createFolder() throws Exception {
719: Folder f = getFolder();
720: try {
721: if (!f.exists()) {
722: f.create(Folder.HOLDS_MESSAGES);
723: f.setSubscribed(true);
724: } else {
725: if (!f.isSubscribed()) {
726: f.setSubscribed(true);
727: }
728: }
729: } catch (MessagingException e) {
730: log.warn("Could not create folder: " + f.getName());
731: }
732: }
733:
734: /**
735: * @return
736: */
737: public int getUnreadMessageCount() throws Exception {
738: Folder f = getFolder();
739:
740: if (f.exists()) {
741: return f.getUnreadMessageCount();
742: }
743: return 0;
744: }
745:
746: /**
747: * @return
748: */
749: public int getTotalMessageCount() throws Exception {
750: Folder f = getFolder();
751:
752: if (f.exists()) {
753: return f.getMessageCount();
754: }
755: return 0;
756: }
757:
758: /**
759: *
760: */
761: public void emptyFolder() throws Exception {
762: Folder f = getFolder();
763:
764: try {
765: Message msgs[] = f.getMessages();
766: FetchProfile fp = new FetchProfile();
767: fp.add(FetchProfile.Item.ENVELOPE);
768: f.fetch(msgs, fp);
769:
770: int ids[] = new int[msgs.length];
771: for (int i = 0; i < msgs.length; i++) {
772: ids[i] = msgs[i].getMessageNumber();
773: }
774: if (ids.length > 0) {
775: flagAsDeleted(ids);
776: // deleteMessages(ids);
777: }
778: } catch (Exception e) {
779: log.warn("Could not delete all messages in folder: "
780: + folder);
781: }
782: }
783:
784: /**
785: *
786: */
787: public void flagAsDeleted(int[] messageIds) throws Exception {
788: Folder fold = null;
789: try {
790: fold = getFolder();
791: if (messageIds != null && messageIds.length > 0) {
792: for (int i = 0; i < messageIds.length; i++) {
793: try {
794: if (messageIds[i] > 0) {
795: Message msg = fold
796: .getMessage(messageIds[i]);
797: msg.setFlag(Flags.Flag.SEEN, true);
798: msg.setFlag(Flags.Flag.DELETED, true);
799: }
800: } catch (Exception e) {
801: log.debug("error while deleting messsage", e);
802: }
803: }
804: }
805: } catch (MessagingException e) {
806: log.error("Could not delete message ids: " + messageIds, e);
807: throw new MailboxActionException(e);
808: } catch (IndexOutOfBoundsException e) {
809: log
810: .warn(
811: "Maybe you are double clicking the delete button. do it a little bit slowly :) ",
812: e);
813: } catch (Exception e) {
814: log.error("Could not delete message ids: " + messageIds, e);
815: throw new MailboxActionException(e);
816: }
817: }
818:
819: /**
820: *
821: */
822: public void deleteFolder() throws Exception {
823: Folder f = getFolder();
824: f.setSubscribed(false);
825: closeFolder(f);
826: f.delete(true);
827: }
828:
829: /**
830: * @param newName
831: */
832: public void renameFolder(String newName) throws Exception {
833: Folder fOld = getFolder();
834: Folder fNew = handler.getStore().getFolder(
835: profile.getFolderNameSpace() + newName);
836: closeFolder(fOld);
837: fOld.renameTo(fNew);
838: fNew.setSubscribed(true);
839: }
840:
841: public ConnectionProfile getProfile() {
842: return profile;
843: }
844:
845: /**
846: *
847: */
848: public ArrayList fetchHeaders(int[] msgNumbers)
849: throws SystemException, ConnectionException {
850: ArrayList headers = new ArrayList();
851: Folder fold = null;
852: try {
853: fold = getFolder();
854: EmailHeader header = null;
855:
856: Message[] msgs = null;
857: if (msgNumbers == null) {
858: msgs = fold.getMessages();
859: } else {
860: msgs = fold.getMessages(msgNumbers);
861: }
862: FetchProfile fp = new FetchProfile();
863: fp.add(FetchProfile.Item.ENVELOPE);
864: fp.add(FetchProfile.Item.FLAGS);
865: fp.add(FetchProfile.Item.CONTENT_INFO);
866: fp.add("Size");
867: fp.add("Date");
868: fp.add("Disposition-Notification-To");
869: fp.add("X-Priority");
870: fp.add("X-MSMail-Priority");
871: fp.add("Sensitivity");
872: fold.fetch(msgs, fp);
873:
874: Message msg = null;
875: for (int i = 0; i < msgs.length; i++) {
876: try {
877: header = new EmailHeader();
878: msg = msgs[i];
879:
880: header
881: .setMultipart((msg
882: .isMimeType("multipart/*")) ? true
883: : false);
884: header.setMessageId(msgs[i].getMessageNumber());
885: header.setFrom(msg.getFrom());
886: header.setTo(msg
887: .getRecipients(Message.RecipientType.TO));
888: header.setCc(msg
889: .getRecipients(Message.RecipientType.CC));
890: header.setBcc(msg
891: .getRecipients(Message.RecipientType.BCC));
892: header.setDate(msg.getSentDate());
893: header.setReplyTo(msg.getReplyTo());
894: header.setSize(msg.getSize());
895: header
896: .setSubject(org.claros.commons.utility.Utility
897: .updateTRChars(msg.getSubject()));
898:
899: // now set the human readables.
900: header.setDateShown(Formatter.formatDate(header
901: .getDate(), "dd.MM.yyyy HH:mm"));
902: header
903: .setFromShown(org.claros.commons.utility.Utility
904: .updateTRChars(Utility
905: .addressArrToStringShort(header
906: .getFrom())));
907: header.setToShown(Utility
908: .addressArrToStringShort(header.getTo()));
909: header.setCcShown(Utility
910: .addressArrToStringShort(header.getCc()));
911: header.setSizeShown(Utility
912: .sizeToHumanReadable(header.getSize()));
913:
914: org.claros.commons.mail.parser.MessageParser
915: .setHeaders(msg, header);
916:
917: boolean deleted = false;
918: if (profile.getProtocol().equals(Constants.IMAP)) {
919: Flags.Flag flags[] = msg.getFlags()
920: .getSystemFlags();
921: if (flags != null) {
922: Flags.Flag flag = null;
923: for (int m = 0; m < flags.length; m++) {
924: flag = flags[m];
925: if (flag.equals(Flags.Flag.SEEN)) {
926: header
927: .setUnread(new Boolean(
928: false));
929: }
930:
931: if (flag.equals(Flags.Flag.DELETED)) {
932: deleted = true;
933: }
934: }
935: }
936: }
937: if (header.getUnread() == null) {
938: header.setUnread(new Boolean(true));
939: }
940:
941: // it is time to add it to the arraylist
942: if (!deleted) {
943: headers.add(header);
944: }
945: } catch (MessagingException e1) {
946: log
947: .error(
948: "Could not parse headers of e-mail. Message might be defuncted or illegal formatted.",
949: e1);
950: }
951: }
952: } catch (MessagingException e) {
953: log
954: .error(
955: "Could not fetch message headers. Is mbox connection still alive???",
956: e);
957: } catch (Exception e) {
958: log
959: .error(
960: "Could not fetch message headers. Is mbox connection still alive???",
961: e);
962: }
963: return headers;
964: }
965: }
|