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.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.StringTokenizer;
27
28 import javax.mail.FetchProfile;
29 import javax.mail.FolderNotFoundException;
30 import javax.mail.Message;
31 import javax.mail.MessagingException;
32
33 import org.apache.geronimo.javamail.store.nntp.newsrc.NNTPNewsrcGroup;
34 import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
35
36
37
38
39
40
41
42
43
44
45
46
47 public class NNTPGroupFolder extends NNTPFolder {
48
49
50 protected int firstArticle = -1;
51
52 protected int lastArticle = -1;
53
54
55 Map articles;
56
57
58 NNTPNewsrcGroup groupInfo;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 protected NNTPGroupFolder(NNTPRootFolder parent, NNTPStore store, String name, NNTPNewsrcGroup groupInfo) {
74 super(store);
75
76 this.name = name;
77 this.fullName = name;
78
79 this.parent = parent = parent;
80 this.groupInfo = groupInfo;
81 }
82
83
84
85
86
87
88 private void updateGroupStats() throws MessagingException {
89
90
91
92 NNTPReply reply = connection.sendCommand("GROUP " + name);
93
94
95 if (reply.getCode() == NNTPReply.NO_SUCH_NEWSGROUP) {
96 throw new FolderNotFoundException(this, "Folder does not exist on server: " + reply);
97 } else if (reply.getCode() != NNTPReply.GROUP_SELECTED) {
98 throw new MessagingException("Error requesting group information: " + reply);
99 }
100
101
102
103
104
105 StringTokenizer tokenizer = new StringTokenizer(reply.getMessage());
106
107
108
109
110
111 if (tokenizer.hasMoreTokens()) {
112 String count = tokenizer.nextToken();
113 try {
114 messageCount = Integer.parseInt(count);
115 } catch (NumberFormatException e) {
116
117 }
118 }
119
120
121 if (tokenizer.hasMoreTokens()) {
122 String first = tokenizer.nextToken();
123 try {
124 firstArticle = Integer.parseInt(first);
125 } catch (NumberFormatException e) {
126
127 }
128 }
129
130
131 if (tokenizer.hasMoreTokens()) {
132 String last = tokenizer.nextToken();
133 try {
134 lastArticle = Integer.parseInt(last);
135 } catch (NumberFormatException e) {
136
137 }
138 }
139 }
140
141
142
143
144
145
146
147
148
149 public boolean exists() throws MessagingException {
150
151 try {
152
153
154
155 updateGroupStats();
156
157 return true;
158 } catch (FolderNotFoundException e) {
159 return false;
160 }
161 }
162
163
164
165
166
167
168
169
170
171 public boolean hasNewMessages() throws MessagingException {
172 int oldLast = lastArticle;
173 updateGroupStats();
174
175 return lastArticle > oldLast;
176 }
177
178
179
180
181
182
183
184 protected void openFolder() throws MessagingException {
185
186 updateGroupStats();
187
188
189 articles = new HashMap();
190 }
191
192
193
194
195
196
197 public void closeFolder() throws MessagingException {
198
199
200 articles = null;
201 }
202
203
204
205
206
207
208
209 public Message getMessage(int msgNum) throws MessagingException {
210
211 checkOpen();
212
213
214
215
216 Integer key = new Integer(msgNum);
217 NNTPMessage message = (NNTPMessage) articles.get(key);
218 if (message != null) {
219
220 return message;
221 }
222
223
224
225 updateGroupStats();
226
227
228
229
230 NNTPReply reply = connection.sendCommand("STAT " + Integer.toString(msgNum));
231 if (reply.getCode() != NNTPReply.REQUEST_TEXT_SEPARATELY) {
232 throw new MessagingException("Error retrieving article from NNTP server: " + reply);
233 }
234
235
236 String response = reply.getMessage();
237
238 int idStart = response.indexOf('<');
239 int idEnd = response.indexOf('>');
240
241
242
243 message = new NNTPMessage(this, (NNTPStore) store, msgNum, response.substring(idStart, idEnd + 1));
244
245
246 articles.put(key, message);
247
248 return message;
249 }
250
251
252
253
254
255
256 public Message[] getMessages() throws MessagingException {
257
258 checkOpen();
259
260
261
262
263
264 NNTPReply reply = connection.sendCommand("XHDR Message-ID " + Integer.toString(firstArticle) + "-"
265 + Integer.toString(lastArticle), NNTPReply.HEAD_FOLLOWS);
266
267 List messages = new ArrayList();
268
269 if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
270 List lines = reply.getData();
271
272 for (int i = 0; i < lines.size(); i++) {
273 String line = (String) lines.get(i);
274
275 try {
276 int pos = line.indexOf(' ');
277 int articleID = Integer.parseInt(line.substring(0, pos));
278 String messageID = line.substring(pos + 1);
279 Integer key = new Integer(articleID);
280
281 Message message = (Message)articles.get(key);
282 if (message == null) {
283 message = new NNTPMessage(this, (NNTPStore) store, key.intValue(), messageID);
284 articles.put(key, message);
285 }
286
287 messages.add(message);
288
289 } catch (NumberFormatException e) {
290
291 }
292 }
293 } else {
294
295
296 for (int i = firstArticle; i <= lastArticle; i++) {
297 try {
298 messages.add(getMessage(i));
299 } catch (MessagingException e) {
300
301
302 }
303 }
304 }
305
306 return (Message[]) messages.toArray(new Message[0]);
307 }
308
309
310
311
312
313
314
315
316 public void fetch(Message[] msgs, FetchProfile fp) throws MessagingException {
317
318 checkOpen();
319
320 for (int i = 0; i < msgs.length; i++) {
321 Message msg = msgs[i];
322
323 if (msg == null || !(msg instanceof NNTPMessage)) {
324
325 continue;
326 }
327
328
329 if (fp.contains(FetchProfile.Item.ENVELOPE) && fp.contains(FetchProfile.Item.CONTENT_INFO)) {
330
331
332 ((NNTPMessage) msg).loadArticle();
333 }
334
335 else if (fp.contains(FetchProfile.Item.ENVELOPE)) {
336 ((NNTPMessage) msg).loadHeaders();
337 } else if (fp.contains(FetchProfile.Item.CONTENT_INFO)) {
338 ((NNTPMessage) msg).loadContent();
339 }
340 }
341 }
342
343
344
345
346
347
348
349 public boolean isSubscribed() {
350 return groupInfo.isSubscribed();
351 }
352
353
354
355
356
357
358
359 public void setSubscribed(boolean flag) {
360 groupInfo.setSubscribed(flag);
361 }
362
363
364
365
366
367
368
369
370
371
372 public boolean isSeen(int article) {
373 return groupInfo.isArticleSeen(article);
374 }
375
376
377
378
379
380
381
382
383
384 public void setSeen(int article, boolean flag) {
385 if (flag) {
386 groupInfo.markArticleSeen(article);
387 } else {
388 groupInfo.markArticleUnseen(article);
389 }
390 }
391 }