001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016:
017: package org.columba.mail.gui.composer.command;
018:
019: import java.io.InputStream;
020: import java.nio.charset.Charset;
021: import java.nio.charset.UnsupportedCharsetException;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import org.columba.api.command.ICommandReference;
026: import org.columba.api.command.IWorkerStatusController;
027: import org.columba.core.command.Command;
028: import org.columba.core.gui.frame.DefaultContainer;
029: import org.columba.core.io.StreamUtils;
030: import org.columba.core.xml.XmlElement;
031: import org.columba.mail.command.MailFolderCommandReference;
032: import org.columba.mail.composer.MessageBuilderHelper;
033: import org.columba.mail.config.AccountItem;
034: import org.columba.mail.config.MailConfig;
035: import org.columba.mail.folder.IMailbox;
036: import org.columba.mail.gui.composer.ComposerController;
037: import org.columba.mail.gui.composer.ComposerModel;
038: import org.columba.ristretto.coder.Base64DecoderInputStream;
039: import org.columba.ristretto.coder.CharsetDecoderInputStream;
040: import org.columba.ristretto.coder.QuotedPrintableDecoderInputStream;
041: import org.columba.ristretto.io.Source;
042: import org.columba.ristretto.io.TempSourceFactory;
043: import org.columba.ristretto.message.BasicHeader;
044: import org.columba.ristretto.message.Flags;
045: import org.columba.ristretto.message.Header;
046: import org.columba.ristretto.message.LocalMimePart;
047: import org.columba.ristretto.message.Message;
048: import org.columba.ristretto.message.MimeHeader;
049: import org.columba.ristretto.message.MimePart;
050: import org.columba.ristretto.message.MimeTree;
051: import org.columba.ristretto.message.StreamableMimePart;
052: import org.columba.ristretto.parser.MessageParser;
053:
054: /**
055: * Open message in composer.
056: *
057: * @author fdietz
058: */
059: public class OpenMessageWithComposerCommand extends Command {
060: protected ComposerController controller;
061: protected ComposerModel model;
062: protected IMailbox folder;
063: protected Object uid;
064:
065: /**
066: * Constructor for OpenMessageInComposerCommand.
067: *
068: * @param frameMediator
069: * @param references
070: */
071: public OpenMessageWithComposerCommand(ICommandReference reference) {
072: super (reference);
073: }
074:
075: public void updateGUI() throws Exception {
076: // open composer frame
077: controller = new ComposerController();
078: new DefaultContainer(controller);
079:
080: // apply model
081: controller.setComposerModel(model);
082:
083: // model->view update
084: controller.updateComponents(true);
085: }
086:
087: public void execute(IWorkerStatusController worker)
088: throws Exception {
089: model = new ComposerModel();
090:
091: // get selected folder
092: folder = (IMailbox) ((MailFolderCommandReference) getReference())
093: .getSourceFolder();
094:
095: // get selected messages
096: Object[] uids = ((MailFolderCommandReference) getReference())
097: .getUids();
098:
099: // we only need the first message
100: uid = uids[0];
101:
102: //TODO (@author fdietz): keep track of progress here
103:
104: InputStream messageSourceStream = folder
105: .getMessageSourceStream(uid);
106: Source tempSource = TempSourceFactory.createTempSource(
107: messageSourceStream, -1);
108: messageSourceStream.close();
109:
110: Message message = MessageParser.parse(tempSource);
111:
112: initHeader(message);
113:
114: // get message flags
115: Flags flags = folder.getFlags(uid);
116: model.getMessage().getHeader().setFlags(flags);
117:
118: // select the account this mail was received from
119: Integer accountUid = (Integer) folder.getAttribute(uids[0],
120: "columba.accountuid");
121: AccountItem accountItem = MessageBuilderHelper
122: .getAccountItem(accountUid);
123: model.setAccountItem(accountItem);
124:
125: XmlElement html = MailConfig.getInstance()
126: .getMainFrameOptionsConfig().getRoot().getElement(
127: "/options/html");
128:
129: boolean preferHtml = Boolean.valueOf(
130: html.getAttribute("prefer")).booleanValue();
131:
132: initBody(message, preferHtml);
133:
134: // store reference to source message
135: model.setSourceReference(new MailFolderCommandReference(folder,
136: new Object[] { uid }));
137: }
138:
139: private void initBody(Message message, boolean preferHtml)
140: throws Exception {
141: MimeTree mimeTree = message.getMimePartTree();
142:
143: // Which Bodypart shall be shown? (html/plain)
144: LocalMimePart bodyPart = null;
145:
146: if (preferHtml) {
147: bodyPart = (LocalMimePart) mimeTree
148: .getFirstTextPart("html");
149: } else {
150: bodyPart = (LocalMimePart) mimeTree
151: .getFirstTextPart("plain");
152: }
153:
154: if (bodyPart != null) {
155: MimeHeader header = bodyPart.getHeader();
156: if (header.getMimeType().getSubtype().equals("html")) {
157: // html
158: model.setHtml(true);
159: } else {
160: model.setHtml(false);
161: }
162: InputStream bodyStream = folder.getMimePartBodyStream(uid,
163: bodyPart.getAddress());
164:
165: // Do decoding stuff
166: switch (header.getContentTransferEncoding()) {
167: case MimeHeader.QUOTED_PRINTABLE: {
168: bodyStream = new QuotedPrintableDecoderInputStream(
169: bodyStream);
170: break;
171: }
172:
173: case MimeHeader.BASE64: {
174: bodyStream = new Base64DecoderInputStream(bodyStream);
175: }
176: }
177: String charset = header.getContentParameter("charset");
178: if (charset != null) {
179: try {
180: bodyStream = new CharsetDecoderInputStream(
181: bodyStream, Charset.forName(charset));
182: model.setCharset(Charset.forName(charset));
183: } catch (UnsupportedCharsetException e) {
184: // Stick with the default charset
185: }
186: }
187:
188: model.setBodyText(StreamUtils.readCharacterStream(
189: bodyStream).toString());
190:
191: }
192:
193: initAttachments(mimeTree, bodyPart);
194: }
195:
196: private void initHeader(Message message) {
197: Header header = message.getHeader();
198:
199: BasicHeader rfcHeader = new BasicHeader(header);
200:
201: // set subject
202: model.setSubject(rfcHeader.getSubject());
203:
204: model.setTo(rfcHeader.getTo());
205:
206: model.setCc(rfcHeader.getCc());
207: model.setBcc(rfcHeader.getBcc());
208:
209: // copy every headerfield the original message contains
210: model.setHeader(header);
211: }
212:
213: private void initAttachments(MimeTree collection, MimePart bodyPart) {
214: // Get all MimeParts
215: List displayedMimeParts = collection.getAllLeafs();
216:
217: if (bodyPart != null) {
218: MimePart bodyParent = bodyPart.getParent();
219:
220: // remove the bodypart from the mimeparts
221: // that are added to the attachment viewer
222: if (bodyParent != null
223: && bodyParent.getHeader().getMimeType()
224: .getSubtype().equals("alternative")) {
225: List bodyParts = bodyParent.getChilds();
226: displayedMimeParts.removeAll(bodyParts);
227: } else {
228: displayedMimeParts.remove(bodyPart);
229: }
230:
231: Iterator it = displayedMimeParts.iterator();
232:
233: while (it.hasNext()) {
234: model.addMimePart((StreamableMimePart) it.next());
235: }
236: }
237: }
238: }
|