View Javadoc

1   /*
2    * Copyright (c) 2004-2007 Creative Sphere Limited.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *
10   *   Creative Sphere - initial API and implementation
11   *
12   */
13  package org.abstracthorizon.mercury.imap.cmd;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.io.InputStream;
18  import java.io.OutputStream;
19  import java.util.Date;
20  import java.util.GregorianCalendar;
21  
22  import javax.mail.Flags;
23  import javax.mail.Folder;
24  import javax.mail.Message;
25  import javax.mail.MessagingException;
26  import javax.mail.Session;
27  import javax.mail.internet.MimeMessage;
28  
29  import org.abstracthorizon.mercury.common.command.CommandException;
30  import org.abstracthorizon.mercury.common.io.TempStorage;
31  import org.abstracthorizon.mercury.imap.IMAPSession;
32  import org.abstracthorizon.mercury.imap.util.IMAPScanner;
33  import org.abstracthorizon.mercury.imap.util.ParserException;
34  
35  /**
36   * Append IMAP command
37   *
38   * @author Daniel Sendula
39   */
40  public class Append extends IMAPCommand {
41  
42      /** Default buffer len */
43      public static final int BUFFER_LEN = 10240;
44  
45      /**
46       * Constructor
47       * @param mnemonic mnemonic
48       */
49      public Append(String mnemonic) {
50          super(mnemonic);
51      }
52  
53      /**
54       * Executes method
55       * @param session
56       * @throws ParserException
57       * @throws MessagingException
58       * @throws CommandException
59       * @throws IOException
60       */
61      public void execute(IMAPSession session) throws ParserException, MessagingException, CommandException, IOException {
62          //APPEND" SP mailbox [SP flag-list] [SP date-time] SP literal
63          StringBuffer mailboxName = new StringBuffer();
64          if (!session.getScanner().mailbox(mailboxName)) {
65              throw new ParserException("<mailbox_name>");
66          }
67          Folder folder = session.getStore().getFolder(mailboxName.toString());
68          if (folder == null) {
69              throw new MissingMailbox(mailboxName.toString());
70          }
71  
72          IMAPScanner scanner = session.getScanner();
73          if (!scanner.is_char(' ')) {
74              throw new ParserException("<SP>");
75          }
76          Flags flags = new Flags();
77          if (scanner.flag_list(flags)) {
78              if (!scanner.is_char(' ')) {
79                  throw new ParserException("<SP>");
80              }
81          }
82  
83          boolean haveDate = false;
84          GregorianCalendar calendar = new GregorianCalendar();
85          if (scanner.date_time(calendar)) {
86              haveDate = true;
87              if (!scanner.is_char(' ')) {
88                  throw new ParserException("<SP>");
89              }
90          }
91          long size = scanner.raw_literal();
92          if (size == -1) {
93              throw new ParserException("<literal>");
94          }
95  
96          InputStream in = (InputStream)session.adapt(InputStream.class);
97  
98          TempStorage tempStorage = new TempStorage();
99  
100         int buflen = BUFFER_LEN;
101         if (buflen > size) {
102             buflen = (int)size;
103         }
104 
105         byte[] buf = new byte[buflen];
106 
107         OutputStream out = tempStorage.getOutputStream();
108 
109         while (size > 0) {
110             int rdsz = buf.length;
111             if (rdsz > size) {
112                 rdsz = (int)size;
113             }
114             int rd = in.read(buf, 0, rdsz);
115             if (rd < 0) {
116                 size = -1;
117                 throw new IOException("Premature end of literal");
118             } else {
119                 out.write(buf, 0, rd);
120                 size = size - rd;
121             }
122         }
123         checkEOL(session);
124 
125         out.close();
126 
127         MimeMessage message = null;
128         if (haveDate) {
129             message = new MimeMessage(session.getJavaMailSession(), tempStorage.getInputStream());
130         } else {
131             message = new MMessage(session.getJavaMailSession(), tempStorage.getInputStream(), calendar.getTime());
132         }
133 
134         File file = tempStorage.getFile();
135         if (file != null) {
136             message.setFileName(file.getAbsolutePath());
137         }
138         folder.appendMessages(new Message[]{message});
139 
140         //session.close();
141         sendOK(session);
142     }
143 
144     /**
145      * Message wrapper that adds received date
146      *
147      * @author Daniel Sendula
148      */
149     public static class MMessage extends MimeMessage {
150 
151         /** Received date */
152         protected Date receivedDate;
153 
154         /**
155          * Constructor
156          * @param session JavaMail session
157          * @param stream input stream
158          * @param date received message date
159          * @throws MessagingException
160          */
161         protected MMessage(Session session, InputStream stream, Date date) throws MessagingException {
162             super(session, stream);
163             receivedDate = date;
164         }
165 
166         /**
167          * Returns received date
168          *
169          * @return received date
170          */
171         public Date getReceivedDate() {
172             return receivedDate;
173         }
174     }
175 
176 }