001: /* -----------------------------------------------------------------------------
002: * Copyright (c) 2001, Low Kin Onn
003: * All rights reserved.
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: *
008: * Redistributions of source code must retain the above copyright notice, this
009: * list of conditions and the following disclaimer.
010: *
011: * Redistributions in binary form must reproduce the above copyright notice,
012: * this list of conditions and the following disclaimer in the documentation
013: * and/or other materials provided with the distribution.
014: *
015: * Neither name of the Scioworks Pte. Ltd. nor the names of its contributors
016: * may beused to endorse or promote products derived from this software without
017: * specific prior written permission.
018: *
019: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
023: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
024: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
025: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
026: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
027: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
028: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: *
030: * -----------------------------------------------------------------------------
031: */
032:
033: package scioworks.imap.business.beans;
034:
035: import java.io.*;
036: import java.util.Date;
037: import java.util.Vector;
038: import java.util.StringTokenizer;
039:
040: import javax.mail.*;
041: import javax.mail.internet.*;
042: import javax.activation.*;
043:
044: import scioworks.imap.spec.*;
045:
046: import scioworks.imap.business.util.MessagingUtilImpl;
047:
048: import scioworks.imap.spec.beans.*;
049: import scioworks.imap.spec.ImapWebException;
050: import scioworks.imap.spec.ImapWebConstant;
051:
052: public class IWMessageImpl extends PublicObject implements IWMessage {
053:
054: int fLineWidth;
055: static final String fLineSeparator = "\n";
056:
057: public IWMessageImpl() {
058: super ();
059: fLineWidth = 72;
060: }
061:
062: public IWMessageImpl(int lineWidth) {
063: super ();
064: this .fLineWidth = lineWidth;
065: }
066:
067: /**
068: * This method will extract the message body from a message
069: */
070: public String getMessageBody(Message mesg) throws ImapWebException {
071:
072: try {
073: String msg_body = new String();
074: Object o = mesg.getContent();
075:
076: //Keep on looping until we find a String part
077: while (!(o instanceof String)) {
078: //we assume this is a multipart
079: Multipart mp = (Multipart) o;
080: o = mp.getBodyPart(0).getContent();
081: }
082:
083: //if here that means we found a String part
084: return (String) o;
085:
086: } catch (MessagingException e) {
087: throw new ImapWebException("Error getting message body.", e);
088:
089: } catch (IOException e) {
090: throw new ImapWebException("Error getting message body.", e);
091: }
092:
093: }
094:
095: /*
096: private void processPart(Multipart forwardMultipart, Part part)
097: throws MessagingException, IOException {
098:
099: //if this is a multipart, recursively call processPart
100: if (part.isMimeType("multipart/*")){
101: Multipart mp = ((Multipart)part.getContent());
102: int count = mp.getCount();
103: for (int i = 0; i < count; i++){
104: processPart(forwardMultipart, mp.getBodyPart(i));
105: }
106:
107: //if this is a rfc822 message, recursively call processPart
108: } else if (part.isMimeType("message/rfc822")) {
109: processPart(forwardMultipart, (Part) part.getContent());
110:
111: //this is a singular part that can be processed
112: } else {
113: Object obj = part.getContent();
114: if (obj instanceof String) {
115: MimeBodyPart mbp = new MimeBodyPart();
116: mbp.setDisposition(MimeBodyPart.ATTACHMENT);
117: mbp.setText((String) obj);
118: forwardMultipart.addBodyPart(mbp);
119: } else {
120: forwardMultipart.addBodyPart((BodyPart) part);
121: }
122: }
123: }
124: */
125:
126: /**
127: * Return the message given by folder and uid. Calling method is responsible
128: * for creating and closing the folder object.
129: */
130: public Message getMessage(Folder folder, long uid)
131: throws ImapWebException {
132: try {
133:
134: UIDFolder ufolder = (UIDFolder) folder;
135:
136: // open the folder for read and write
137: folder.open(Folder.READ_WRITE);
138:
139: // get the message
140: Message msg = ufolder.getMessageByUID(uid);
141:
142: // mark the msg as seen
143: msg.setFlag(Flags.Flag.SEEN, true);
144:
145: return msg;
146:
147: } catch (MessagingException e) {
148: throw new ImapWebException("Error getting message.", e);
149: }
150: }
151:
152: /**
153: * Return a <b>copy</b> of the message given by folder name and uid.
154: * Closing of folder is handled internally by this method.
155: */
156: public Message getMessage(Store imapStore, String folderName,
157: long uid) throws ImapWebException {
158: try {
159:
160: Folder folder = imapStore.getFolder(folderName);
161:
162: UIDFolder ufolder = (UIDFolder) folder;
163:
164: // open the folder for read and write
165: folder.open(Folder.READ_WRITE);
166:
167: // get the message
168: MimeMessage msg = new MimeMessage((MimeMessage) ufolder
169: .getMessageByUID(uid));
170:
171: // mark the msg as seen
172: msg.setFlag(Flags.Flag.SEEN, true);
173:
174: folder.close(false);
175:
176: return msg;
177:
178: } catch (MessagingException e) {
179: throw new ImapWebException("Error getting message.", e);
180: }
181: }
182:
183: public Message forwardMessage(Session imapSession, Store imapStore,
184: String folderName, long uid, boolean isInline)
185: throws ImapWebException {
186: try {
187: Folder folder = imapStore.getFolder(folderName);
188:
189: // open the folder for read
190: folder.open(Folder.READ_ONLY);
191:
192: UIDFolder ufolder = (UIDFolder) folder;
193:
194: // get the message
195: Message origMsg = ufolder.getMessageByUID(uid);
196:
197: // create a reply object
198: MimeMessage forwardMsg = new MimeMessage(imapSession);
199:
200: if (origMsg.getSubject().startsWith("Fwd:")) {
201: forwardMsg.setSubject(origMsg.getSubject());
202: } else {
203: forwardMsg.setSubject("Fwd: " + origMsg.getSubject());
204: }
205:
206: if (isInline) {
207: MessagingUtilImpl messagingUtilImpl = new MessagingUtilImpl();
208:
209: forwardMsg.setText(fLineSeparator
210: + "--- "
211: + origMsg.getFrom()[0].toString()
212: + " wrote:"
213: + fLineSeparator
214: + messagingUtilImpl.formatMsgBody(this
215: .getMessageBody(origMsg), fLineWidth));
216:
217: } else {
218: forwardMsg.setText(fLineSeparator
219: + "--- Forwarded message attached");
220: }
221:
222: // close the folder
223: folder.close(false);
224:
225: return forwardMsg;
226:
227: } catch (MessagingException e) {
228: throw new ImapWebException(
229: "Error setting message forward.", e);
230: }
231:
232: }
233:
234: public Message replyMessage(Session imapSession, Store imapStore,
235: String folderName, long uid, boolean replyAll,
236: boolean quoteOrig) throws ImapWebException {
237: try {
238: Folder folder = imapStore.getFolder(folderName);
239:
240: // open the folder for read
241: folder.open(Folder.READ_ONLY);
242:
243: UIDFolder ufolder = (UIDFolder) folder;
244:
245: // get the message
246: Message origMsg = ufolder.getMessageByUID(uid);
247:
248: // create a reply object
249: Message replyMsg = origMsg.reply(replyAll);
250:
251: if (quoteOrig) {
252: MessagingUtilImpl messagingUtilImpl = new MessagingUtilImpl();
253: replyMsg.setText("--- "
254: + origMsg.getFrom()[0].toString()
255: + " wrote:"
256: + fLineSeparator
257: + messagingUtilImpl.formatMsgBody(this
258: .getMessageBody(origMsg), fLineWidth));
259: }
260:
261: // close the folder
262: folder.close(false);
263:
264: return replyMsg;
265:
266: } catch (MessagingException e) {
267: throw new ImapWebException("Error setting message reply.",
268: e);
269: }
270: }
271:
272: /**
273: * Creates and send a message as per the given parameter.
274: * Does <b>not</b> handle attachements
275: */
276: public void sendMessage(Store imapStore, Session imapSession,
277: URLName imapURL, String imapDomain, String to,
278: String subject, String cc, String bcc, String message,
279: Vector attachments, boolean isInline, boolean saveCopy,
280: boolean isForwardAttach, String origFolderName, long origUid)
281: throws ImapWebException {
282:
283: Message msg = new MimeMessage(imapSession);
284:
285: InternetAddress[] toAddrs = null;
286: InternetAddress[] ccAddrs = null;
287: InternetAddress[] bccAddrs = null;
288:
289: try {
290:
291: if (!to.equals("")) {
292: toAddrs = InternetAddress.parse(to, false);
293: msg.setRecipients(Message.RecipientType.TO, toAddrs);
294: } else {
295: throw new MessagingException(
296: "No \"To\" address specified");
297: }
298:
299: if (!cc.equals("")) {
300: ccAddrs = InternetAddress.parse(cc, false);
301: msg.setRecipients(Message.RecipientType.CC, ccAddrs);
302: }
303:
304: if (!bcc.equals("")) {
305: bccAddrs = InternetAddress.parse(bcc, false);
306: msg.setRecipients(Message.RecipientType.BCC, bccAddrs);
307: }
308:
309: if (!subject.equals("")) {
310: msg.setSubject(subject);
311: }
312:
313: msg.setFrom(new InternetAddress(imapURL.getUsername() + "@"
314: + imapDomain));
315:
316: // sent the sent date
317: msg.setSentDate(new Date());
318:
319: if (message.equals("")) {
320: message = " ";
321: }
322:
323: if ((attachments.size() == 0) && !isForwardAttach) {
324: // no attachments
325: msg.setText(message);
326:
327: } else {
328:
329: // multiparts
330:
331: // create the Multipart for adding parts to it
332: Multipart mp = new MimeMultipart();
333:
334: // create and fill the first message part
335: MimeBodyPart mbp1 = new MimeBodyPart();
336: mbp1.setDisposition(MimeBodyPart.INLINE);
337: mbp1.setText(message);
338: mp.addBodyPart(mbp1);
339:
340: FileRecord fr;
341: for (int i = 0; i < attachments.size(); i++) {
342: fr = (FileRecord) attachments.elementAt(i);
343: try {
344:
345: MimeBodyPart mbp2 = new MimeBodyPart();
346: FileDataSource fds = new FileDataSource(fr
347: .getTmpFilename());
348: mbp2.setDataHandler(new DataHandler(fds));
349: if (isInline) {
350: mbp2.setDisposition(MimeBodyPart.INLINE);
351: } else {
352: mbp2
353: .setDisposition(MimeBodyPart.ATTACHMENT);
354: }
355: mbp2.setFileName(fr.getFilename());
356:
357: mp.addBodyPart(mbp2);
358:
359: } catch (MessagingException e) {
360: System.err.println("Error attaching file: "
361: + fr.getTmpFilename());
362: e.printStackTrace();
363: }
364: }
365:
366: if (isForwardAttach) {
367:
368: try {
369: Folder origFolder = imapStore
370: .getFolder(origFolderName);
371:
372: // open the folder for read
373: origFolder.open(Folder.READ_ONLY);
374:
375: UIDFolder ufolder = (UIDFolder) origFolder;
376:
377: // create a copy of the message
378: MimeMessage origMessage = new MimeMessage(
379: (MimeMessage) ufolder
380: .getMessageByUID(origUid));
381:
382: // close the folder
383: origFolder.close(false);
384:
385: BodyPart bodypart = new MimeBodyPart();
386: bodypart.setContent(origMessage,
387: "message/rfc822");
388: mp.addBodyPart(bodypart);
389:
390: // processPart(mp, origMessage);
391:
392: } catch (MessagingException e) {
393: System.err
394: .println("Error attaching original message.");
395: e.printStackTrace();
396: }
397:
398: }
399:
400: // add the Multipart to the message
401: msg.setContent(mp);
402:
403: }
404:
405: Transport.send(msg);
406:
407: if (saveCopy) {
408: Folder sentFolder = imapStore.getFolder(ImapWebConstant
409: .singleton().folderSent());
410: // check if sent folder exists
411: if (!sentFolder.exists()) {
412: // not exists, create a new one
413: sentFolder.create(Folder.HOLDS_MESSAGES);
414: }
415:
416: MimeMessage[] messages = new MimeMessage[1];
417: messages[0] = (MimeMessage) msg;
418: sentFolder.appendMessages(messages);
419: }
420:
421: } catch (AddressException e) {
422: throw new ImapWebException("Error creating email.", e);
423:
424: } catch (MessagingException e) {
425: throw new ImapWebException("Error creating email.", e);
426: }
427: }
428:
429: public void deleteMessage(Store imapStore, String folderName,
430: long[] uidArr) throws ImapWebException {
431:
432: try {
433: // get the trash folder
434: Folder trashFolder = imapStore.getFolder(ImapWebConstant
435: .singleton().folderTrash());
436:
437: if (!trashFolder.exists()) {
438: // trash folder not exist, create one
439: trashFolder.create(Folder.HOLDS_MESSAGES);
440: }
441:
442: // get the folder that contains the messages to be deleted
443: Folder folder = imapStore.getFolder(folderName);
444:
445: UIDFolder ufolder = (UIDFolder) folder;
446:
447: // open the folder for read and write
448: folder.open(Folder.READ_WRITE);
449:
450: // get the messages to be deleted
451: Message[] messages = ufolder.getMessagesByUID(uidArr);
452:
453: // Check if this is the trash folder
454: if (!folderName.equals(ImapWebConstant.singleton()
455: .folderTrash())) {
456: // this not the trash folder, copy the messages to trash
457: folder.copyMessages(messages, trashFolder);
458: }
459:
460: // mark the messages for expunge
461: for (int i = 0; i < messages.length; i++) {
462: messages[i].setFlag(Flags.Flag.DELETED, true);
463: }
464:
465: // close the folder and expunge the deleted messages
466: folder.close(true);
467:
468: } catch (MessagingException e) {
469: throw new ImapWebException("Error deleting messages.", e);
470: }
471: }
472:
473: public void moveMessage(Store imapStore, String folderName,
474: long[] uidArr, String targetFolderName)
475: throws ImapWebException {
476:
477: try {
478: // get the folder that contains the messages to be deleted
479: Folder folder = imapStore.getFolder(folderName);
480:
481: UIDFolder ufolder = (UIDFolder) folder;
482:
483: // open the folder for read and write
484: folder.open(Folder.READ_WRITE);
485:
486: // get the messages to be deleted
487: Message[] messages = ufolder.getMessagesByUID(uidArr);
488:
489: // get the target folder
490: Folder targetFolder = imapStore.getFolder(targetFolderName);
491:
492: if (!targetFolder.exists()) {
493: // target folder not exist, create one
494: targetFolder.create(Folder.HOLDS_MESSAGES);
495: }
496:
497: // copy to the target folder
498: folder.copyMessages(messages, targetFolder);
499:
500: // mark the messages for expunge
501: for (int i = 0; i < messages.length; i++) {
502: messages[i].setFlag(Flags.Flag.DELETED, true);
503: }
504:
505: // close the folder and expunge the moved messages
506: folder.close(true);
507:
508: } catch (MessagingException e) {
509: throw new ImapWebException("Error deleting messages.", e);
510: }
511: }
512:
513: public Part getMessagePart(Session imapSession, Store imapStore,
514: String folderName, long uid, String partIdList)
515: throws ImapWebException {
516: try {
517:
518: Folder folder = imapStore.getFolder(folderName);
519:
520: UIDFolder ufolder = (UIDFolder) folder;
521:
522: // open the folder for read and write
523: folder.open(Folder.READ_ONLY);
524:
525: // get the message
526: MimeMessage msg = new MimeMessage((MimeMessage) ufolder
527: .getMessageByUID(uid));
528:
529: folder.close(false);
530:
531: StringTokenizer strtok = new StringTokenizer(partIdList,
532: ".");
533: String partId;
534: Part part = msg;
535: while (strtok.hasMoreTokens()) {
536: partId = strtok.nextToken();
537: if (part.isMimeType("multipart/*")) {
538: part = ((Multipart) part.getContent())
539: .getBodyPart(Integer.parseInt(partId));
540: } else if (part.isMimeType("message/rfc822")) {
541: MimeMessage mm = (MimeMessage) part.getContent();
542: part = ((Multipart) mm.getContent())
543: .getBodyPart(Integer.parseInt(partId));
544: }
545:
546: }
547:
548: return part;
549:
550: } catch (IOException e) {
551: throw new ImapWebException("Error getting part.", e);
552:
553: } catch (MessagingException e) {
554: throw new ImapWebException("Error getting part.", e);
555: }
556: }
557:
558: public Vector getFolderNames(Store imapStore, String currentFolder)
559: throws ImapWebException {
560:
561: Vector res = new Vector();
562: try {
563: Folder[] folders = imapStore.getDefaultFolder().list();
564: String fname;
565: for (int i = 0; i < folders.length; i++) {
566: if (folders[i].getName().equals(currentFolder)
567: || folders[i].getName().equals(
568: ImapWebConstant.singleton()
569: .folderTrash())
570: || folders[i].getName().equals(
571: ImapWebConstant.singleton()
572: .folderSent())) {
573: continue;
574: } else {
575: res.addElement(folders[i].getName());
576: }
577: }
578: } catch (MessagingException e) {
579: throw new ImapWebException("Error getting folder names.", e);
580: }
581: return res;
582: }
583:
584: public void createFolder(Store imapStore, String name)
585: throws ImapWebException {
586: try {
587: // get the current folder
588: Folder folder = imapStore.getFolder(name);
589:
590: if (folder.exists()) {
591: // target folder exists
592: throw new ImapWebException(
593: "A folder with this name already exists.");
594:
595: } else {
596: // target folder not exist, create one
597: folder.create(Folder.HOLDS_MESSAGES);
598: }
599: } catch (MessagingException e) {
600: throw new ImapWebException("Error creating new folder.", e);
601: }
602: }
603:
604: public void renameFolder(Store imapStore, String folderName,
605: String name) throws ImapWebException {
606: try {
607: // get the current folder
608: Folder folder = imapStore.getFolder(folderName);
609:
610: // get the target folder
611: Folder targetFolder = imapStore.getFolder(name);
612:
613: if (!targetFolder.exists()) {
614: // target folder not exist, create one
615: targetFolder.create(Folder.HOLDS_MESSAGES);
616: }
617:
618: // rename to the target foldr
619: folder.renameTo(targetFolder);
620:
621: } catch (MessagingException e) {
622: throw new ImapWebException("Error creating new folder.", e);
623: }
624: }
625:
626: public void removeFolder(Store imapStore, String folderName)
627: throws ImapWebException {
628: try {
629: // get the current folder
630: Folder folder = imapStore.getFolder(folderName);
631:
632: if (folder.getMessageCount() == 0) {
633: // empty folder, can remove
634: folder.delete(false);
635:
636: } else {
637: // not empty, throw error
638: throw new ImapWebException(
639: "Folders must be empty before it can be removed.");
640: }
641:
642: } catch (MessagingException e) {
643: throw new ImapWebException("Error creating new folder.", e);
644: }
645: }
646:
647: }
|