001: /***
002: * jwma Java WebMail
003: * Copyright (c) 2000-2003 jwma team
004: *
005: * jwma is free software; you can distribute and use this source
006: * under the terms of the BSD-style license received along with
007: * the distribution.
008: ***/package dtw.webmail.model;
009:
010: import java.util.*;
011: import java.io.*;
012: import javax.mail.*;
013: import javax.mail.internet.*;
014: import javax.activation.*;
015:
016: import org.apache.log4j.Logger;
017: import dtw.webmail.util.EntityHandler;
018: import dtw.webmail.util.MimeBodyPartDataSource;
019: import dtw.webmail.JwmaSession;
020:
021: //import dtw.webmail.JwmaKernel;
022:
023: /**
024: * Class implementing the JwmaComposeMessage model.
025: * <p>
026: * This implementation is specialized to wrap a
027: * <tt>javax.mail.Message</tt> for composing.
028: *
029: * @author Dieter Wimberger
030: * @version 0.9.7 07/02/2003
031: */
032: public class JwmaComposeMessage implements JwmaMessage {
033:
034: //logging
035: private static Logger log = Logger
036: .getLogger(JwmaComposeMessage.class);
037:
038: //instance attributes
039: private boolean m_Reply;
040: private boolean m_Forward;
041: private boolean m_Draft;
042: private StringBuffer m_Body;
043: private MimeMessage m_Message;
044: private MimeMultipart m_Attachments;
045: private boolean m_Singlepart = true;
046: private JwmaDisplayMessage m_RepliedMessage;
047: private boolean m_InvisibleToList = false;
048: private JwmaMessagePart[] m_Parts;
049: private int m_Number = -1;
050:
051: /**
052: * Constructs a <tt>JwmaComposeMessage</tt> instance.
053: */
054: private JwmaComposeMessage() {
055: }//constructor
056:
057: /**
058: * Constructs a <tt>JwmaComposeMessage</tt> instance.
059: *
060: * @param msg the aggregated <tt>MimeMessage</tt>.
061: */
062: private JwmaComposeMessage(MimeMessage msg) {
063: m_Message = msg;
064: m_Attachments = new MimeMultipart();
065: m_Parts = new JwmaMessagePart[0];
066: try {
067: m_Message.setHeader("X-Mailer", X_MAILER_STRING);
068: } catch (Exception ex) {
069: }
070: }//constructor
071:
072: public String getFullHeader() {
073: StringBuffer fullhead = new StringBuffer();
074: try {
075: for (Enumeration enum = m_Message.getAllHeaderLines();
076: enum.hasMoreElements();) {
077: fullhead.append((String) enum.nextElement())
078: .append("\n");
079: }
080: } catch (MessagingException mex) {
081: }
082: return fullhead.toString();
083: }//getFullHeader
084:
085: public int getMessageNumber() {
086: return m_Number;
087: }//getMessageNumber
088:
089: private void setMessageNumber(int nr) {
090: m_Number = nr;
091: }//setMessageNumber
092:
093: public Date getReceivedDate() {
094: return null;
095: }//getDate
096:
097: public Date getSentDate() {
098: return null;
099: }//getSentDate
100:
101: public Date getDate() {
102: return null;
103: }//getDate
104:
105: public boolean isSent() {
106: return false;
107: }//isSent
108:
109: public boolean isReceived() {
110: return false;
111: }//isReceived
112:
113: /**
114: * Tests if the message is a reply.
115: *
116: * @return true if the message is a reply,
117: * false otherwise.
118: */
119: public boolean isReply() {
120: return m_Reply;
121: }//isReply
122:
123: public boolean isDraft() {
124: return m_Draft;
125: }//isDraft
126:
127: /**
128: * Flags the message as a forward.
129: *
130: * @param true if the message is a forward,
131: * false otherwise.
132: */
133: private void setForward(boolean b) {
134: m_Forward = b;
135: }//setForward
136:
137: /**
138: * Flags the message as a reply.
139: *
140: * @param true if the message is a reply,
141: * false otherwise.
142: */
143: private void setReply(boolean b) {
144: m_Reply = b;
145: }//setReply
146:
147: /**
148: * Flags the message as a draft.
149: *
150: * @param true if the message is a draft,
151: * false otherwise.
152: */
153: private void setDraft(boolean b) {
154: m_Draft = b;
155: }//setDraft
156:
157: /**
158: * Sets the message that is being replied to.
159: * In case the message gets send, this can be
160: * used to set the answered flag.
161: * Normally this is done by calling reply in the JavaMail API,
162: * but as the folder is not open in READ_WRITE mode,
163: * and even if it was, the message might never get send,
164: * this is the consistent way.
165: */
166: private void setRepliedMessage(JwmaDisplayMessage msg) {
167: m_RepliedMessage = msg;
168: }//setRepliedMessage
169:
170: public String getFrom() {
171: try {
172: return EntityHandler.encode(InternetAddress
173: .toString(m_Message.getFrom()));
174: } catch (Exception ex) {
175: return "";
176: }
177: }//getFrom
178:
179: /**
180: * Set the sender(s) address of the message.
181: *
182: * @param from the sender(s) address of the message
183: * as <tt>String</tt>.
184: */
185: public void setFrom(String from) {
186: try {
187: m_Message.setFrom(new InternetAddress(from));
188: } catch (Exception ex) {
189:
190: }
191: }//setFrom
192:
193: public String getReplyTo() {
194: try {
195: return InternetAddress.toString(m_Message.getReplyTo());
196: } catch (Exception ex) {
197: return "";
198: }
199: }//getReplyTo
200:
201: /**
202: * Set the Reply-To address(es) of the message.
203: *
204: * @param from the Reply-To address(es) of the message
205: * as <tt>String</tt>.
206: */
207: public void setReplyTo(String from) {
208: try {
209: m_Message.setReplyTo(InternetAddress.parse(from));
210: } catch (Exception ex) {
211:
212: }
213: }//setReplyTo
214:
215: public String getTo() {
216: String str = "";
217: try {
218: str = InternetAddress.toString(m_Message
219: .getRecipients(Message.RecipientType.TO));
220: if (str == null) {
221: str = "";
222: }
223: } catch (Exception ex) {
224: return str;
225: }
226: return str;
227: }//getTo
228:
229: /**
230: * Sets the receiver's address(es) of the message as
231: * <tt>String</tt>.
232: *
233: * @param to the receiver(s) address(es) of the message as String.
234: *
235: * @throws MessagingException if the receiver's address(es) is (are) malformed.
236: */
237: public void setTo(String to) throws MessagingException {
238: if (to == null || to.equals("")) {
239: return;
240: } else {
241: m_Message.setRecipients(Message.RecipientType.TO,
242: InternetAddress.parse(to));
243: }
244: }//setTo
245:
246: private void setTo(Address to) throws MessagingException {
247: m_Message.setRecipient(Message.RecipientType.TO, to);
248: }//setTo
249:
250: public boolean isInvisibleToList() {
251: return m_InvisibleToList;
252: }//isInvisibleToList
253:
254: public void setInvisibleToList(boolean invisibleToList) {
255: m_InvisibleToList = invisibleToList;
256: }//setInvisibleToList
257:
258: public String getCCTo() {
259: String str = "";
260: try {
261: str = InternetAddress.toString(m_Message
262: .getRecipients(Message.RecipientType.CC));
263: if (str == null) {
264: str = "";
265: }
266: } catch (Exception ex) {
267: return str;
268: }
269: return str;
270: }//getCCTo
271:
272: /**
273: * Sets the carbon copy receiver's address(es) of the message.
274: *
275: * @param to the carbon copy receiver(s) address(es) of the
276: * message as String.
277: *
278: * @throws MessagingException if the carbon copy receiver's address(es)
279: * is (are) malformed.
280: */
281: public void setCCTo(String ccto) throws MessagingException {
282: m_Message.setRecipients(Message.RecipientType.CC,
283: InternetAddress.parse(ccto));
284: }//setCCTo;
285:
286: public String getBCCTo() {
287: String str = "";
288: try {
289: str = InternetAddress.toString(m_Message
290: .getRecipients(Message.RecipientType.BCC));
291: if (str == null) {
292: str = "";
293: }
294: } catch (Exception ex) {
295: return str;
296: }
297: return str;
298: }//getBCCTo
299:
300: /**
301: * Sets the blind carbon copy receiver's address(es) of the message.
302: *
303: * @param to the blind carbon copy receiver(s) address(es) of the
304: * message as String.
305: *
306: * @throws MessagingException if the blind carbon copy receiver's address(es)
307: * is (are) malformed.
308: */
309: public void setBCCTo(String bccto) throws MessagingException {
310:
311: m_Message.setRecipients(Message.RecipientType.BCC,
312: InternetAddress.parse(bccto));
313: }//setBCCTo;
314:
315: public String getSubject() {
316: String str = "";
317: try {
318: str = MimeUtility.decodeText(m_Message.getSubject());
319: if (str == null) {
320: str = "";
321: }
322: } catch (Exception ex) {
323: return str;
324: }
325: return str;
326: }//getSubject
327:
328: /**
329: * Sets the subject of the message.
330: *
331: * @param subject the subject of the message as <tt>String</tt>.
332: *
333: * @throws JwmaException if the string is malformed (encoding, null).
334: */
335: public void setSubject(String subject) throws JwmaException {
336:
337: try {
338: if (subject != null) {
339: m_Message.setSubject(MimeUtility.encodeText(subject));
340: } else {
341: m_Message.setSubject("");
342: }
343: } catch (Exception ex) {
344:
345: }
346: }//setSubject
347:
348: public String getBody() {
349: if (m_Body == null || m_Body.length() == 0) {
350: return "";
351: } else {
352: return m_Body.toString();
353: }
354: }//getBody
355:
356: /**
357: * Sets the body of the message.
358: * <p>
359: * Note that the body will be the text/plain content of
360: * a singlepart message, and attached as text/plain part to
361: * a multipart message.
362: *
363: * @param body the text/plain content of the message as
364: * <tt>String</tt>.
365: */
366: public void setBody(String body) {
367: if (body != null) {
368: m_Body = new StringBuffer(body);
369: } else {
370: m_Body = new StringBuffer();
371: }
372: }//setBody
373:
374: /**
375: * Appends to the body of the message.
376: *
377: * @param str more text/plain content for the
378: * message as <tt>String</tt>.
379: */
380: public void appendBody(String str) {
381: if (m_Body == null) {
382: m_Body = new StringBuffer(str);
383: } else {
384: m_Body.append(str);
385: }
386: }//appendBody
387:
388: /**
389: * Adds attachments to this <tt>JwmaComposeMessage</tt>.
390: *
391: * @param mmp the <tt>MimeMultipart</tt> that represents the
392: * attachments.
393: */
394: public void addAttachments(MimeMultipart mmp) {
395: try {
396: for (int i = 0; i < mmp.getCount(); i++) {
397: m_Attachments.addBodyPart((MimeBodyPart) mmp
398: .getBodyPart(i));
399: }
400: m_Singlepart = false;
401: } catch (Exception ex) {
402: log.error("addAttachments()", ex);
403: }
404: }//addAttachments
405:
406: public boolean isSinglepart() {
407: return m_Singlepart;
408: }//isSinglepart
409:
410: public boolean isMultipart() {
411: return !m_Singlepart;
412: }//isMultipart
413:
414: public JwmaMessagePart[] getMessageParts() {
415: return m_Parts;
416: }//getMessageParts
417:
418: /**
419: * Returns the <tt>Message</tt> instance associated
420: * with this <tt>JwmaComposeMessage</tt>.
421: *
422: * @return associated <tt>Message</tt> instance.
423: */
424: public Message getMessage() {
425: return m_Message;
426: }//getMessage
427:
428: /**
429: * Sends this instance via the standard convenience <tt>Transport.send()</tt>.
430: * <p>
431: * Asserts that a sender is set, and creates either a multipart
432: * or a singlepart <tt>Message</tt> from the data stored
433: * in this instance.
434: *
435: * @throws JwmaException If there is no sender, or if sending fails.
436: */
437: public void send(JwmaSession ses) throws JwmaException {
438:
439: try {
440: //Assert that a valid sender identity is set.
441: if (getFrom() == null || getFrom().equals("")) {
442: throw new JwmaException(
443: "jwma.composemessage.send.sendermissing", true);
444: }
445:
446: //set content either single or multipart
447: if (isMultipart()) {
448:
449: //body represents the first part
450: if (getBody() != null && getBody().length() > 0) {
451: MimeBodyPart bodypart = new MimeBodyPart();
452: bodypart.setText(getBody());
453: m_Attachments.addBodyPart(bodypart, 0);
454: }
455: //set the content
456: m_Message.setContent(m_Attachments);
457:
458: } else {
459: m_Message.setText(getBody());
460: }
461: //transport the message
462: if (isInvisibleToList()) {
463: log
464: .debug("send()::"
465: + "sending message seperately to receivers on list.");
466: InternetAddress[] tos = (InternetAddress[]) m_Message
467: .getRecipients(Message.RecipientType.TO);
468: for (int i = 0; i < tos.length; i++) {
469: setTo(tos[i]);
470: ses.getJwmaTransport().sendMessage(m_Message);
471: }
472: //reset tos to remember for saving
473: m_Message.setRecipients(Message.RecipientType.TO, tos);
474: } else {
475: ses.getJwmaTransport().sendMessage(m_Message);
476: }
477: //flag the message as answered
478: try {
479: if (isReply() && m_RepliedMessage != null) {
480: Message msg = m_RepliedMessage.getMessage();
481: Folder fld = msg.getFolder();
482: fld.open(Folder.READ_WRITE);
483:
484: msg.setFlag(Flags.Flag.ANSWERED, true);
485: fld.close(false);
486: }
487: } catch (MessagingException mex) {
488: log.error("Failed to send message", mex);
489: //JwmaKernel.getReference().debugLog().writeStackTrace(mex);
490: }
491:
492: } catch (MessagingException mex) {
493: throw new JwmaException("jwma.composemessage.send.failed",
494: true).setException(mex);
495: }
496: }//send
497:
498: public void openDraft(JwmaStoreImpl store) throws JwmaException {
499: log.debug("openDraft()");
500: try {
501:
502: if (isDraft()) {
503: //existing draft will be updated
504: //this should ensure the message is fetched RW?!
505: Folder f = m_Message.getFolder();
506: f.open(Folder.READ_WRITE);
507: //mark old deleted
508: m_Message.setFlag(Flags.Flag.DELETED, true);
509: m_Message = new MimeMessage(m_Message);
510: f.close(false);
511: } //else {
512: //new draft will be appended
513: //get the folder
514: // Folder draft = store.getDraftFolder();
515: //open it read write
516: //draft.open(Folder.READ_WRITE);
517: //}
518: } catch (Exception ex) {
519: log.error("openDraft()", ex);
520: throw new JwmaException(
521: "jwma.composemessage.draft.openfailed");
522: }
523:
524: }//openDraft
525:
526: public void closeDraft(JwmaStoreImpl store) throws JwmaException {
527: //log.debug("closeDraft()");
528: try {
529:
530: //Assert that a valid sender identity is set.
531: if (getFrom() == null || getFrom().equals("")) {
532: throw new JwmaException(
533: "jwma.composemessage.sendermissing", true);
534: }
535: //set content either single or multipart
536: if (isMultipart()) {
537:
538: //body represents the first part
539: if (getBody() != null && getBody().length() > 0) {
540: MimeBodyPart bodypart = new MimeBodyPart();
541: bodypart.setText(getBody());
542: m_Attachments.addBodyPart(bodypart, 0);
543: }
544: //set the content
545: m_Message.setContent(m_Attachments);
546:
547: } else {
548: m_Message.setText(getBody());
549: }
550: //set draft flag
551: m_Message.setFlag(Flags.Flag.DRAFT, true);
552: m_Message.saveChanges();
553: Folder draft = store.getDraftFolder();
554: draft.open(Folder.READ_WRITE);
555: Message[] tosave = { m_Message };
556: draft.appendMessages(tosave);
557: draft.close(true);
558: } catch (Exception ex) {
559: log.error("closeDraft()", ex);
560: throw new JwmaException("jwma.composemessage.draft.failed",
561: true);
562: }
563: }//closeDraft
564:
565: /**
566: * Prepares the message instance, specifically for forwarding and replying,
567: * were the content probably has to be copied into the message to be
568: * composed.
569: * A copy of multi-parts will be attached to a forward if requested.
570: *
571: * @param msg the <tt>JwmaDisplayMessage</tt> instance that is replied
572: * to or forwarded.
573: * @param prefs the <tt>JwmaPreferences</tt> instance associated with the
574: * actual user (for settings).
575: * @param togglequote the flag that can toggle the setting from the user's
576: * preferences.
577: * @param attfwd the flag that toggles whether attachments are forwarded
578: * with this message.
579: *
580: * @throws JwmaException if there is a failure on accessing or quoting the
581: * given message's content.
582: */
583: private void prepare(JwmaDisplayMessage msg, JwmaPreferences prefs,
584: boolean togglequote, boolean attfwd)
585: throws JwmaException {
586:
587: if (!m_Forward) {
588: log.debug("Reply");
589: setSubject("Re: " + msg.getSubject());
590: //transfer quoted text if applicable
591: //there is a little bit of logic in the if ;)
592: if (prefs.isAutoQuote() != togglequote) {
593: //FIXME!!!
594: //replace for textproc processor
595: //and add On blah blah wrote....
596:
597: //retrieve the quotechar
598: String quotechar = prefs.getQuoteChar();
599:
600: //Quote singlepart mail
601: if (msg.isSinglepart()) {
602: //log.debug("Quoting single part message");
603: String messtr = msg.getBody();
604: StringBuffer rbodybuf = new StringBuffer(messtr.length() + 10);
605: rbodybuf.append("\n\n");
606: rbodybuf.append(quotechar);
607: boolean done = false;
608: int pos = 0;
609: int foundpos = 0;
610: while (!done) {
611: foundpos = messtr.indexOf(10, pos);
612: if (foundpos != -1) {
613: rbodybuf.append(messtr.substring(pos, foundpos + 1));
614: rbodybuf.append(quotechar);
615: pos = foundpos + 1;
616: } else {
617: rbodybuf.append(messtr.substring(pos, messtr.length()));
618: done = true;
619: }
620: }
621: this .appendBody(rbodybuf.toString());
622: rbodybuf = null;
623: messtr = null;
624: } else {
625: //log.debug("Quoting multi part message (text parts).");
626: JwmaMessagePart[] mparts = msg.getMessageParts();
627: //quote text parts of multipart messages
628: for (int i = 0; i < mparts.length; i++) {
629: JwmaMessagePartImpl part = (JwmaMessagePartImpl) mparts[i];
630: if (part.isMimeType("text/plain")) {
631: //FIXME: Process to make quoted
632: this .appendBody(part.getTextContent());
633: }
634: }
635: }
636: }
637: } else {
638: //log.debug("Forwarding message.");
639: setSubject("Fwd: " + msg.getSubject());
640: if (msg.isSinglepart()) {
641: //FIXME: process to make quote
642: this .appendBody(msg.getBody());
643: //log.debug("Quoting single part message");
644: } else {
645: if (attfwd) {
646: //log.debug("Forwarding message with attachments.");
647: JwmaMessagePart[] mparts = msg.getMessageParts();
648:
649: try {
650: //1. get MimeMultiPart
651: MimeMultipart mmp = (MimeMultipart) msg.getMessage().getContent();
652: MimeMultipart nmmp = new MimeMultipart();
653: ArrayList nonplaintextparts = new ArrayList(mmp.getCount());
654: //2. copy over contents
655: for (int n = 0; n < mmp.getCount(); n++) {
656: if (mparts[n].isMimeType("text/plain")) {
657: //FIXME: process to make quote?
658: this .appendBody(((JwmaMessagePartImpl) mparts[n]).getTextContent());
659: //log.debug("Forwarding message: quoted plain text attachment.");
660: } else {
661: MimeBodyPart mbp = (MimeBodyPart) mmp.getBodyPart(n);
662: MimeBodyPart nmbp = new MimeBodyPart();
663: //copy all headers
664: for (Enumeration enum = mbp.getAllHeaders(); enum.hasMoreElements();) {
665: Header h = (Header) enum.nextElement();
666: nmbp.setHeader(h.getName(), h.getValue());
667: }
668:
669: //copy content
670: InputStream in = mbp.getInputStream();
671: /*String[] encoding = mbp.getHeader("Content-Transfer-Encoding");
672: if (encoding != null && encoding.length > 0) {
673: in = MimeUtility.decode(in, encoding[0]);
674: }
675: */
676: ByteArrayOutputStream bout = new ByteArrayOutputStream();
677: OutputStream out = (OutputStream) bout;
678: byte[] buffer = new byte[10240];
679: int amount = 0;
680: while ((amount = in.read(buffer)) >= 0) {
681: out.write(buffer, 0, amount);
682: }
683: out.flush();
684: out.close();
685:
686: //create the datasource
687: MimeBodyPartDataSource mbpds =
688: new MimeBodyPartDataSource(
689: mparts[n].getContentType(), mparts[n].getName(), bout.toByteArray()
690: );
691: nmbp.setDataHandler(new DataHandler(mbpds));
692: //ensure transfer encoding is set
693: nmbp.setHeader("Content-Transfer-Encoding", "base64");
694: nmmp.addBodyPart(nmbp);
695: nonplaintextparts.add(mparts[n]);
696: //log.debug("Forwarding message: added attachment and partinfo.");
697: }
698: }
699: //copy over non plain text message part infos
700: m_Parts = new JwmaMessagePart[nonplaintextparts.size()];
701: m_Parts = (JwmaMessagePart[]) nonplaintextparts.toArray(m_Parts);
702:
703: //3. append message's attachments to this message
704: this .addAttachments(nmmp);
705: } catch (Exception ex) {
706: throw new JwmaException("jwma.composemessage.failedattforward").setException(ex);
707: }
708: } else {
709: //log.debug("Forwarding message without attachments.");
710: JwmaMessagePart[] mparts = msg.getMessageParts();
711: //quote text parts of multipart messages
712: for (int i = 0; i < mparts.length; i++) {
713: JwmaMessagePartImpl part = (JwmaMessagePartImpl) mparts[i];
714: if (part.isMimeType("text/plain")) {
715: //FIXME: Process to make quoted
716: this .appendBody(part.getTextContent());
717: //log.debug("Forwarding message woa: quoted plain/text part.");
718: }
719: }
720: }
721: }
722: }
723: //set sender identity from the active mailidentity
724: String from = prefs.getMailIdentity().getFrom();
725: if (from == null || from.length() == 0) {
726: from = prefs.getFirstname() + " " + prefs.getLastname() +
727: " <" + prefs.getUserIdentity() + ">";
728: }
729: setFrom(from);
730: }//prepare
731:
732: /**
733: * Creates a <tt>JwmaComposeMessage</tt> instance.
734: * <p>This factory method should be used to create new instances
735: * of <tt>JwmaComposeMessage</tt>, which are not a reply to
736: * an already existing message.
737: *
738: * @param ses the mail <tt>Session</tt> the message is created within.
739: * @return the newly created instance.
740: */
741: public static JwmaComposeMessage createJwmaComposeMessage(
742: Session ses) {
743:
744: JwmaComposeMessage message = null;
745:
746: message = new JwmaComposeMessage(new MimeMessage(ses));
747: message.setReply(false);
748:
749: return message;
750: }//createJwmaComposeMessage
751:
752: /**
753: * Creates a <tt>JwmaComposeMessage</tt> instance.
754: * <p> This factory method should be used to create new instances
755: * of <tt>JwmaComposeMessage</tt>, which are a reply to
756: * an already existing message.
757: * <p>The reply will address the sender, and if flagged, also all
758: * recipients of the original <tt>Message</tt>.
759: *
760: *
761: * @param msg the <tt>Message</tt> to be replied.
762: * @param toall a flag determining wheter the reply should address also all
763: * recipients of the original <tt>Message</tt>.
764: * @return the newly created instance.
765: * @throws JwmaException if it fails to create the new instance.
766: */
767: public static JwmaComposeMessage createReply(
768: JwmaDisplayMessage msg, boolean toall,
769: JwmaPreferences prefs, boolean togglequote)
770:
771: throws JwmaException {
772:
773: JwmaComposeMessage message = null;
774: try {
775: message = new JwmaComposeMessage((MimeMessage) msg
776: .getMessage().reply(toall));
777: message.setRepliedMessage(msg);
778: message.setReply(true);
779: message.prepare(msg, prefs, togglequote, false);
780: } catch (MessagingException mex) {
781: throw new JwmaException(
782: "jwma.composemessage.failedcreation", true)
783: .setException(mex);
784: }
785: return message;
786: }//createReply
787:
788: /**
789: * Creates a <tt>JwmaComposeMessage</tt> instance.
790: * <p> This factory method should be used to create new instances
791: * of <tt>JwmaComposeMessage</tt>, which are a reply to
792: * an already existing message.
793: * <p>The reply will address the sender, and if flagged, also all
794: * recipients of the original <tt>Message</tt>.
795: *
796: *
797: * @param msg the <tt>Message</tt> to be replied.
798: * @param toall a flag determining wheter the reply should address also all
799: * recipients of the original <tt>Message</tt>.
800: * @return the newly created instance.
801: * @throws JwmaException if it fails to create the new instance.
802: */
803: public static JwmaComposeMessage createForward(Session ses,
804: JwmaDisplayMessage msg, String to, JwmaPreferences prefs,
805: boolean togglequote, boolean attfwd) throws JwmaException {
806: log.debug("createForward()");
807: JwmaComposeMessage message = createJwmaComposeMessage(ses);
808: try {
809: message.setForward(true);
810: message.setTo(to);
811: Folder fld = msg.getMessage().getFolder();
812: fld.open(Folder.READ_ONLY);
813: message.prepare(msg, prefs, togglequote, attfwd);
814: fld.close(false);
815:
816: } catch (MessagingException mex) {
817: throw new JwmaException(
818: "jwma.composemessage.failedcreation", true)
819: .setException(mex);
820: }
821: return message;
822: }//createReply
823:
824: public static JwmaComposeMessage createDraft(Message msg)
825: throws JwmaException {
826:
827: JwmaComposeMessage message = new JwmaComposeMessage(
828: (MimeMessage) msg);
829: try {
830: message.setDraft(true);
831: message.setMessageNumber(msg.getMessageNumber());
832: message.setBody(msg.getContent().toString());
833:
834: } catch (Exception ex) {
835: throw new JwmaException(
836: "jwma.composemessage.failedcreation", true)
837: .setException(ex);
838: }
839: return message;
840: }//createDraft
841:
842: /**
843: * Defines the X-MAILER set by jwma.
844: * This can probably help one day to recognize special mailer features.
845: */
846: public static final String X_MAILER_STRING = "jwma";
847:
848: }//class JwmaComposeMessage
|