1 /**
2 *
3 * Copyright 2003-2005 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.javamail.store.pop3.message;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.Enumeration;
25
26 import javax.mail.Flags;
27 import javax.mail.Folder;
28 import javax.mail.IllegalWriteException;
29 import javax.mail.MessagingException;
30 import javax.mail.Session;
31 import javax.mail.event.MessageChangedEvent;
32 import javax.mail.internet.InternetHeaders;
33 import javax.mail.internet.MimeMessage;
34
35 import org.apache.geronimo.javamail.store.pop3.POP3CommandFactory;
36 import org.apache.geronimo.javamail.store.pop3.POP3Connection;
37 import org.apache.geronimo.javamail.store.pop3.POP3Folder;
38 import org.apache.geronimo.javamail.store.pop3.POP3Response;
39 import org.apache.geronimo.javamail.store.pop3.response.POP3ListResponse;
40 import org.apache.geronimo.javamail.store.pop3.response.POP3ResponseFactory;
41
42 /**
43 * POP3 implementation of javax.mail.internet.MimeMessage
44 *
45 * Only the most basic information is given and Message objects created here is
46 * a light-weight reference to the actual Message As per the JavaMail spec items
47 * from the actual message will get filled up on demand
48 *
49 * If some other items are obtained from the server as a result of one call,
50 * then the other details are also processed and filled in. For ex if RETR is
51 * called then header information will also be processed in addition to the
52 * content
53 *
54 * @version $Rev: 432884 $ $Date: 2006-08-19 14:53:20 -0700 (Sat, 19 Aug 2006) $
55 */
56 public class POP3Message extends MimeMessage {
57
58 private POP3Connection pop3Con;
59
60 private int msgSize = -1;
61
62 private int headerSize = -1;
63
64
65
66 private InputStream rawHeaders;
67
68
69 private boolean loadHeaders = true;
70
71
72 private Session session;
73
74 protected POP3Message(Folder folder, int msgnum, Session session, POP3Connection pop3Con) {
75 super(folder, msgnum);
76 this.pop3Con = pop3Con;
77 this.session = session;
78 }
79
80 /**
81 * @see javax.mail.internet.MimeMessage#getContentStream()
82 */
83 protected InputStream getContentStream() throws MessagingException {
84 POP3Response msgResponse = null;
85 try {
86 msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_RETR(msgnum));
87 } catch (Exception e) {
88 e.printStackTrace();
89 }
90 loadHeaders = true;
91 loadHeaders(msgResponse.getData());
92 loadContent(msgResponse.getData());
93
94 return contentStream;
95 }
96
97 public void setFlags(Flags newFlags, boolean set) throws MessagingException {
98 Flags oldFlags = (Flags) flags.clone();
99 super.setFlags(newFlags, set);
100
101 if (!flags.equals(oldFlags)) {
102 ((POP3Folder) folder).notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, this);
103 }
104 }
105
106 protected void loadHeaders(InputStream in) throws MessagingException {
107 if (loadHeaders || rawHeaders == null) {
108 rawHeaders = in;
109 headers = new InternetHeaders(rawHeaders);
110 loadHeaders = false;
111 }
112 }
113
114 protected void loadContent(InputStream stream) throws MessagingException {
115 ByteArrayOutputStream out = new ByteArrayOutputStream();
116 try {
117 int byteRead = stream.read();
118 int lastByte = -1;
119 for (; byteRead > 0;) {
120 if (byteRead == ' ' && lastByte == '\n') {
121 break;
122 }
123 lastByte = byteRead;
124 byteRead = stream.read();
125 }
126
127 for (; stream.available() > 0;) {
128 out.write(stream.read());
129 }
130
131 contentStream = new ByteArrayInputStream(out.toByteArray());
132 msgSize = contentStream.available();
133
134 } catch (IOException e) {
135
136 throw new MessagingException("Error loading content info", e);
137 }
138 }
139
140 public int getSize() throws MessagingException {
141 if (msgSize >= 0) {
142 return msgSize;
143 }
144 try {
145
146 if (msgSize < 0) {
147 if (rawHeaders == null) {
148 loadHeaders();
149 }
150 POP3ListResponse res = (POP3ListResponse) POP3ResponseFactory.getListResponse(pop3Con
151 .sendCommand(POP3CommandFactory.getCOMMAND_LIST(msgnum)));
152 msgSize = res.getSize() - headerSize;
153 }
154 return msgSize;
155 } catch (MessagingException ex) {
156 throw new MessagingException("error getting size", ex);
157 }
158 }
159
160 /**
161 * notice that we pass zero as the no of lines from the message,as it
162 * doesn't serv any purpose to get only a certain number of lines.
163 *
164 * However this maybe important if a mail client only shows 3 or 4 lines of
165 * the message in the list and then when the user clicks they would load the
166 * message on demand.
167 *
168 */
169 protected void loadHeaders() throws MessagingException {
170 POP3Response msgResponse = null;
171 try {
172
173 msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_TOP(msgnum, 0));
174 } catch (Exception e) {
175 e.printStackTrace();
176 }
177 loadHeaders(msgResponse.getData());
178 }
179
180 /***************************************************************************
181 * Following is a set of methods that deal with headers I have tried to use
182 * the bare minimum
183 *
184 * Used sun's POP3 impl & JavaMail API as a guide in decided which methods
185 * are important.
186 **************************************************************************/
187
188 public String[] getHeader(String name) throws MessagingException {
189 if (rawHeaders == null)
190 loadHeaders();
191 return headers.getHeader(name);
192 }
193
194 public String getHeader(String name, String delimiter) throws MessagingException {
195 if (headers == null)
196 loadHeaders();
197 return headers.getHeader(name, delimiter);
198 }
199
200 public Enumeration getAllHeaders() throws MessagingException {
201 if (headers == null)
202 loadHeaders();
203 return headers.getAllHeaders();
204 }
205
206 public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
207 if (headers == null)
208 loadHeaders();
209 return headers.getMatchingHeaders(names);
210 }
211
212 public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
213 if (headers == null)
214 loadHeaders();
215 return headers.getNonMatchingHeaders(names);
216 }
217
218 public Enumeration getAllHeaderLines() throws MessagingException {
219 if (headers == null)
220 loadHeaders();
221 return headers.getAllHeaderLines();
222 }
223
224 public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
225 if (headers == null)
226 loadHeaders();
227 return headers.getMatchingHeaderLines(names);
228 }
229
230 public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
231 if (headers == null)
232 loadHeaders();
233 return headers.getNonMatchingHeaderLines(names);
234 }
235
236
237
238
239 public void addHeader(String name, String value) throws MessagingException {
240 throw new IllegalWriteException("POP3 messages are read-only");
241 }
242
243 public void setHeader(String name, String value) throws MessagingException {
244 throw new IllegalWriteException("POP3 messages are read-only");
245 }
246
247 public void removeHeader(String name) throws MessagingException {
248 throw new IllegalWriteException("POP3 messages are read-only");
249 }
250
251 public void addHeaderLine(String line) throws MessagingException {
252 throw new IllegalWriteException("POP3 messages are read-only");
253 }
254
255 /**
256 * We cannot modify these messages
257 */
258 public void saveChanges() throws MessagingException {
259 throw new IllegalWriteException("POP3 messages are read-only");
260 }
261 }