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.nntp;
19
20 import javax.mail.Flags;
21 import javax.mail.Folder;
22 import javax.mail.IllegalWriteException;
23 import javax.mail.Message;
24 import javax.mail.MessagingException;
25 import javax.mail.MethodNotSupportedException;
26 import javax.mail.Session;
27 import javax.mail.event.ConnectionEvent;
28
29 import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
30
31 /**
32 * The base NNTP implementation of the javax.mail.Folder This is a base class
33 * for both the Root NNTP server and each NNTP group folder.
34 *
35 * @see javax.mail.Folder
36 *
37 * @version $Rev: 432884 $
38 */
39 public class NNTPFolder extends Folder {
40
41
42 protected NNTPConnection connection;
43
44
45 protected Session session;
46
47
48
49 protected String name;
50
51
52
53
54 protected String fullName;
55
56
57
58 protected Folder parent;
59
60
61 protected boolean folderOpen = false;
62
63
64 protected int messageCount = 0;
65
66
67 protected Flags permanentFlags;
68
69 /**
70 * Super class constructor the base NNTPFolder class.
71 *
72 * @param store
73 * The javamail store this folder is attached to.
74 */
75 protected NNTPFolder(NNTPStore store) {
76 super(store);
77
78
79 this.connection = store.getConnection();
80 this.session = store.getSession();
81
82
83 permanentFlags = new Flags();
84 permanentFlags.add(Flags.Flag.SEEN);
85 }
86
87 /**
88 * Retrieve the folder name.
89 *
90 * @return The folder's name.
91 */
92 public String getName() {
93 return name;
94 }
95
96 /**
97 * Retrieve the folder's full name (including hierarchy information). NNTP
98 * folders are flat, so the full name is generally the same as the name.
99 *
100 * @return The full name value.
101 */
102 public String getFullName() {
103 return fullName;
104 }
105
106 /**
107 * Returns the parent folder for this folder. Returns null if this is the
108 * root folder.
109 */
110 public Folder getParent() throws MessagingException {
111 return parent;
112 }
113
114 /**
115 * Indicated whether the folder "exists" or not. Existance in this context
116 * indicates that the group still exists on the server.
117 *
118 * @return
119 * @exception MessagingException
120 */
121 public boolean exists() throws MessagingException {
122
123
124
125 return true;
126 }
127
128 /**
129 * List the subfolders. For group folders, this is a meaningless so we throw
130 * a MethodNotSupportedException.
131 *
132 * @param pattern
133 * The folder pattern string.
134 *
135 * @return Never returns.
136 * @exception MessagingException
137 */
138 public Folder[] list(String pattern) throws MessagingException {
139 throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
140 }
141
142 /**
143 * Retrieve the list of subscribed folders that match the given pattern
144 * string.
145 *
146 * @param pattern
147 * The pattern string used for the matching
148 *
149 * @return An array of matching folders from the subscribed list.
150 */
151 public Folder[] listSubscribed(String pattern) throws MessagingException {
152 throw new MethodNotSupportedException("NNTP group folders cannot contain sub folders");
153 }
154
155 /**
156 * No sub folders, hence there is no notion of a seperator. We return a null
157 * character (consistent with what Sun returns for POP3 folders).
158 */
159 public char getSeparator() throws MessagingException {
160 return '\0';
161 }
162
163 /**
164 * Return whether this folder can hold just messages or also subfolders.
165 * Only the root folder can hold other folders, so it will need to override.
166 *
167 * @return Either Folder.HOLDS_MESSAGES or Folder.HOLDS_FOLDERS.
168 * @exception MessagingException
169 */
170 public int getType() throws MessagingException {
171 return HOLDS_MESSAGES;
172 }
173
174 /**
175 * Create a new folder. NNTP folders are read only, so this is a nop.
176 *
177 * @param type
178 * The type of folder.
179 *
180 * @return Not support, throws an exception.
181 * @exception MessagingException
182 */
183 public boolean create(int type) throws MessagingException {
184 throw new MethodNotSupportedException("Sub folders cannot be created in NNTP");
185 }
186
187 /**
188 * Check for new messages. We always return false for the root folder. The
189 * group folders will need to override.
190 *
191 * @return Always returns false.
192 * @exception MessagingException
193 */
194 public boolean hasNewMessages() throws MessagingException {
195 return false;
196 }
197
198 /**
199 * Get a named subfolder from this folder. This only has meaning from the
200 * root NNTP folder.
201 *
202 * @param name
203 * The requested name.
204 *
205 * @return If the folder exists, returns a Folder object representing the
206 * named folder.
207 * @exception MessagingException
208 */
209 public Folder getFolder(String name) throws MessagingException {
210 throw new MethodNotSupportedException("NNTP Group folders do not support sub folders");
211 }
212
213 /**
214 * Delete a folder. This is not supported for NNTP.
215 *
216 * @param recurse
217 * The recusion flag.
218 *
219 * @return Never returns.
220 * @exception MessagingException
221 */
222 public boolean delete(boolean recurse) throws MessagingException {
223 throw new MethodNotSupportedException("Deleting of NNTP folders is not supported");
224 }
225
226 /**
227 * Rename a folder. Not supported for NNTP folders.
228 *
229 * @param f
230 * The new folder specifying the rename location.
231 *
232 * @return
233 * @exception MessagingException
234 */
235 public boolean renameTo(Folder f) throws MessagingException {
236 throw new MethodNotSupportedException("Renaming of NNTP folders is not supported.");
237 }
238
239 /**
240 * @see javax.mail.Folder#open(int)
241 */
242 public void open(int mode) throws MessagingException {
243
244
245
246 if (mode == READ_WRITE) {
247 throw new IllegalWriteException("Newsgroup folders cannot be opened read/write");
248 }
249
250
251 checkClosed();
252
253 this.mode = mode;
254
255
256 openFolder();
257
258 folderOpen = true;
259
260 notifyConnectionListeners(ConnectionEvent.OPENED);
261 }
262
263 /**
264 * Perform folder type-specific open actions. The default action is to do
265 * nothing.
266 *
267 * @exception MessagingException
268 */
269 protected void openFolder() throws MessagingException {
270 }
271
272 /**
273 * Peform folder type-specific close actions. The default action is to do
274 * nothing.
275 *
276 * @exception MessagingException
277 */
278 protected void closeFolder() throws MessagingException {
279 }
280
281 /**
282 * Close the folder. Cleans up resources, potentially expunges messages
283 * marked for deletion, and sends an event notification.
284 *
285 * @param expunge
286 * The expunge flag, which is ignored for NNTP folders.
287 *
288 * @exception MessagingException
289 */
290 public void close(boolean expunge) throws MessagingException {
291
292 checkOpen();
293
294
295 closeFolder();
296
297 folderOpen = false;
298 notifyConnectionListeners(ConnectionEvent.CLOSED);
299 }
300
301 /**
302 * Tests the open status of the folder.
303 *
304 * @return true if the folder is open, false otherwise.
305 */
306 public boolean isOpen() {
307 return folderOpen;
308 }
309
310 /**
311 * Get the permanentFlags
312 *
313 * @return The set of permanent flags we support (only SEEN).
314 */
315 public Flags getPermanentFlags() {
316
317 return new Flags(permanentFlags);
318 }
319
320 /**
321 * Get the count of messages in this folder.
322 *
323 * @return The message count.
324 * @exception MessagingException
325 */
326 public int getMessageCount() throws MessagingException {
327 return messageCount;
328 }
329
330 /**
331 * Checks wether the message is in cache, if not will create a new message
332 * object and return it.
333 *
334 * @see javax.mail.Folder#getMessage(int)
335 */
336 public Message getMessage(int msgNum) throws MessagingException {
337
338 throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
339 }
340
341 /**
342 * Append messages to a folder. NNTP folders are read only, so this is not
343 * supported.
344 *
345 * @param msgs
346 * The list of messages to append.
347 *
348 * @exception MessagingException
349 */
350 public void appendMessages(Message[] msgs) throws MessagingException {
351 throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
352
353 }
354
355 /**
356 * Expunge messages marked for deletion and return a list of the Messages.
357 * Not supported for NNTP.
358 *
359 * @return Never returns.
360 * @exception MessagingException
361 */
362 public Message[] expunge() throws MessagingException {
363 throw new MethodNotSupportedException("Root NNTP folder does not contain messages");
364 }
365
366 /**
367 * Below is a list of convenience methods that avoid repeated checking for a
368 * value and throwing an exception
369 */
370
371 /** Ensure the folder is open */
372 protected void checkOpen() throws IllegalStateException {
373 if (!folderOpen) {
374 throw new IllegalStateException("Folder is not Open");
375 }
376 }
377
378 /** Ensure the folder is not open */
379 protected void checkClosed() throws IllegalStateException {
380 if (folderOpen) {
381 throw new IllegalStateException("Folder is Open");
382 }
383 }
384
385 /**
386 * @see javax.mail.Folder#notifyMessageChangedListeners(int,
387 * javax.mail.Message)
388 *
389 * this method is protected and cannot be used outside of Folder, therefore
390 * had to explicitly expose it via a method in NNTPFolder, so that
391 * NNTPMessage has access to it
392 *
393 * Bad design on the part of the Java Mail API.
394 */
395 public void notifyMessageChangedListeners(int type, Message m) {
396 super.notifyMessageChangedListeners(type, m);
397 }
398
399 /**
400 * Retrieve the subscribed status for a folder. This default implementation
401 * just returns false (which is true for the root folder).
402 *
403 * @return Always returns true.
404 */
405 public boolean isSubscribed() {
406 return false;
407 }
408
409 /**
410 * Set the subscribed status for a folder.
411 *
412 * @param flag
413 * The new subscribed status.
414 *
415 * @exception MessagingException
416 */
417 public void setSubscribed(boolean flag) throws MessagingException {
418 throw new MessagingException("Root NNTP folder cannot be subscribed to");
419 }
420
421 /**
422 * Test if a given article number is marked as SEEN.
423 *
424 * @param article
425 * The target article number.
426 *
427 * @return The articles current seen status.
428 */
429 public boolean isSeen(int article) {
430 return false;
431 }
432
433 /**
434 * Set the SEEN status for an article.
435 *
436 * @param article
437 * The target article.
438 * @param flag
439 * The new seen setting.
440 *
441 * @exception MessagingException
442 */
443 public void setSeen(int article, boolean flag) throws MessagingException {
444 throw new MessagingException("Root NNTP folder does not contain articles");
445 }
446
447 }