1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.javamail.store.nntp;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.Enumeration;
26
27 import javax.mail.Flags;
28 import javax.mail.IllegalWriteException;
29 import javax.mail.MessagingException;
30 import javax.mail.Session;
31 import javax.mail.internet.InternetHeaders;
32 import javax.mail.internet.MimeMessage;
33
34 import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
35 import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
36 import org.apache.geronimo.javamail.transport.nntp.StringListInputStream;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class NNTPMessage extends MimeMessage {
53
54 String messageID = null;
55
56
57 protected Session session;
58
59
60 protected NNTPStore store;
61
62
63 protected NNTPConnection connection;
64
65
66 protected boolean headersLoaded = false;
67
68
69 protected boolean contentLoaded = false;
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 NNTPMessage(NNTPFolder folder, NNTPStore store, int msgnum, String messageID) throws MessagingException {
86 super(folder, msgnum);
87 this.messageID = messageID;
88 this.store = store;
89 this.session = ((NNTPStore) store).getSession();
90
91
92 this.connection = ((NNTPStore) store).getConnection();
93
94
95 flags = folder.getPermanentFlags();
96
97 if (folder.isSeen(msgnum)) {
98 flags.add(Flags.Flag.SEEN);
99 } else {
100 flags.remove(Flags.Flag.SEEN);
101 }
102 }
103
104
105
106
107
108
109
110
111 public int getSize() throws MessagingException {
112
113
114 loadContent();
115 return super.getSize();
116 }
117
118
119
120
121
122
123
124
125 public int getLineCount() throws MessagingException {
126 String[] headers = getHeader("Lines");
127
128
129
130
131 if (headers.length == 1) {
132 try {
133 return Integer.parseInt(headers[0].trim());
134
135 } catch (NumberFormatException e) {
136
137 }
138 }
139
140 return -1;
141 }
142
143
144
145
146 protected InputStream getContentStream() throws MessagingException {
147
148 loadArticle();
149 return super.getContentStream();
150 }
151
152
153
154
155
156
157
158 public String[] getHeader(String name) throws MessagingException {
159 loadHeaders();
160 return headers.getHeader(name);
161 }
162
163 public String getHeader(String name, String delimiter) throws MessagingException {
164 loadHeaders();
165 return headers.getHeader(name, delimiter);
166 }
167
168 public Enumeration getAllHeaders() throws MessagingException {
169 loadHeaders();
170 return headers.getAllHeaders();
171 }
172
173 public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
174 loadHeaders();
175 return headers.getMatchingHeaders(names);
176 }
177
178 public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
179 loadHeaders();
180 return headers.getNonMatchingHeaders(names);
181 }
182
183 public Enumeration getAllHeaderLines() throws MessagingException {
184 loadHeaders();
185 return headers.getAllHeaderLines();
186 }
187
188 public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
189 loadHeaders();
190 return headers.getMatchingHeaderLines(names);
191 }
192
193 public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
194 loadHeaders();
195 return headers.getNonMatchingHeaderLines(names);
196 }
197
198
199
200
201 public void addHeader(String name, String value) throws MessagingException {
202 throw new IllegalWriteException("NNTP messages are read-only");
203 }
204
205 public void setHeader(String name, String value) throws MessagingException {
206 throw new IllegalWriteException("NNTP messages are read-only");
207 }
208
209 public void removeHeader(String name) throws MessagingException {
210 throw new IllegalWriteException("NNTP messages are read-only");
211 }
212
213 public void addHeaderLine(String line) throws MessagingException {
214 throw new IllegalWriteException("IMAP messages are read-only");
215 }
216
217
218
219
220 public void saveChanges() throws MessagingException {
221 throw new IllegalWriteException("NNTP messages are read-only");
222 }
223
224
225
226
227
228
229 public void loadHeaders() throws MessagingException {
230
231 if (headersLoaded) {
232 return;
233 }
234
235 NNTPReply reply = connection.sendCommand("HEAD " + messageID, NNTPReply.HEAD_FOLLOWS);
236
237 if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
238 try {
239
240 updateHeaders(new StringListInputStream(reply.getData()));
241 } catch (IOException e) {
242 throw new MessagingException("Error retrieving article headers from server", e);
243 }
244 } else {
245 throw new MessagingException("Error retrieving article headers from server: " + reply);
246 }
247 }
248
249
250
251
252
253
254
255
256
257 public void updateHeaders(InputStream in) throws MessagingException {
258
259 headers = new InternetHeaders(in);
260 headersLoaded = true;
261 }
262
263
264
265
266
267
268 public void loadContent() throws MessagingException {
269 if (contentLoaded) {
270 return;
271 }
272
273 NNTPReply reply = connection.sendCommand("BODY " + messageID, NNTPReply.BODY_FOLLOWS);
274
275 if (reply.getCode() == NNTPReply.BODY_FOLLOWS) {
276 try {
277 InputStream in = new StringListInputStream(reply.getData());
278 updateContent(in);
279 } catch (IOException e) {
280 throw new MessagingException("Error retrieving article body from server", e);
281 }
282 } else {
283 throw new MessagingException("Error retrieving article body from server: " + reply);
284 }
285 }
286
287
288
289
290
291
292
293 public void loadArticle() throws MessagingException {
294
295 if (headersLoaded) {
296 loadContent();
297 return;
298 }
299
300
301 NNTPReply reply = connection.sendCommand("ARTICLE " + messageID, NNTPReply.ARTICLE_FOLLOWS);
302
303 if (reply.getCode() == NNTPReply.ARTICLE_FOLLOWS) {
304 try {
305 InputStream in = new StringListInputStream(reply.getData());
306
307 updateHeaders(in);
308 updateContent(in);
309 } catch (IOException e) {
310 throw new MessagingException("Error retrieving article from server", e);
311 }
312 } else {
313 throw new MessagingException("Error retrieving article from server: " + reply);
314 }
315 }
316
317
318
319
320
321
322
323
324
325 public void updateContent(InputStream in) throws MessagingException {
326 try {
327 ByteArrayOutputStream out = new ByteArrayOutputStream();
328
329 byte[] buffer = new byte[4096];
330
331
332
333 while (true) {
334 int read = in.read(buffer);
335 if (read == -1) {
336 break;
337 }
338 out.write(buffer, 0, read);
339 }
340
341 content = out.toByteArray();
342 contentLoaded = true;
343 } catch (IOException e) {
344 throw new MessagingException("Error retrieving message body from server", e);
345 }
346 }
347
348
349
350
351
352
353 public String getMessageId() {
354 return messageID;
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368 public void setFlags(Flags flag, boolean newvalue) throws MessagingException {
369
370
371 if (flag.contains(Flags.Flag.SEEN)) {
372 ((NNTPFolder) folder).setSeen(msgnum, newvalue);
373 }
374
375 super.setFlags(flag, newvalue);
376 }
377 }