Coverage report

| %line | %branch
--- | --- | ---
org.apache.commons.net.nntp.NNTPClient |
0% |
0% |

1 |  |
     /*
2 |  |
      * Copyright 2001-2005 The Apache Software Foundation
3 |  |
      *
4 |  |
      * Licensed under the Apache License, Version 2.0 (the "License");
5 |  |
      * you may not use this file except in compliance with the License.
6 |  |
      * You may obtain a copy of the License at
7 |  |
      *
8 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
9 |  |
      *
10 |  |
      * Unless required by applicable law or agreed to in writing, software
11 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
12 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  |
      * See the License for the specific language governing permissions and
14 |  |
      * limitations under the License.
15 |  |
      */
16 |  |
     package org.apache.commons.net.nntp;
17 |  |
18 |  |
     import java.io.BufferedReader;
19 |  |
     import java.io.IOException;
20 |  |
     import java.io.Reader;
21 |  |
     import java.io.StringWriter;
22 |  |
     import java.io.Writer;
23 |  |
     import java.util.StringTokenizer;
24 |  |
     import java.util.Vector;
25 |  |
     import org.apache.commons.net.io.DotTerminatedMessageReader;
26 |  |
     import org.apache.commons.net.io.DotTerminatedMessageWriter;
27 |  |
     import org.apache.commons.net.io.Util;
28 |  |
     import org.apache.commons.net.MalformedServerReplyException;
29 |  |
30 |  |
     /***
31 |  |
      * NNTPClient encapsulates all the functionality necessary to post and
32 |  |
      * retrieve articles from an NNTP server.  As with all classes derived
33 |  |
      * from {@link org.apache.commons.net.SocketClient},
34 |  |
      * you must first connect to the server with
35 |  |
      * {@link org.apache.commons.net.SocketClient#connect  connect }
36 |  |
      * before doing anything, and finally
37 |  |
      * {@link org.apache.commons.net.nntp.NNTP#disconnect  disconnect() }
38 |  |
      * after you're completely finished interacting with the server.
39 |  |
      * Remember that the
40 |  |
      * {@link org.apache.commons.net.nntp.NNTP#isAllowedToPost isAllowedToPost()}
41 |  |
      *  method is defined in
42 |  |
      * {@link org.apache.commons.net.nntp.NNTP}.
43 |  |
      * <p>
44 |  |
      * You should keep in mind that the NNTP server may choose to prematurely
45 |  |
      * close a connection if the client has been idle for longer than a
46 |  |
      * given time period or if the server is being shutdown by the operator or
47 |  |
      * some other reason.  The NNTP class will detect a
48 |  |
      * premature NNTP server connection closing when it receives a
49 |  |
      * {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED }
50 |  |
      *  response to a command.
51 |  |
      * When that occurs, the NNTP class method encountering that reply will throw
52 |  |
      * an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
53 |  |
      * .
54 |  |
      * <code>NNTPConectionClosedException</code>
55 |  |
      * is a subclass of <code> IOException </code> and therefore need not be
56 |  |
      * caught separately, but if you are going to catch it separately, its
57 |  |
      * catch block must appear before the more general <code> IOException </code>
58 |  |
      * catch block.  When you encounter an
59 |  |
      * {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
60 |  |
      * , you must disconnect the connection with
61 |  |
      * {@link org.apache.commons.net.nntp.NNTP#disconnect  disconnect() }
62 |  |
      *  to properly clean up the
63 |  |
      * system resources used by NNTP.  Before disconnecting, you may check the
64 |  |
      * last reply code and text with
65 |  |
      * {@link org.apache.commons.net.nntp.NNTP#getReplyCode  getReplyCode } and
66 |  |
      * {@link org.apache.commons.net.nntp.NNTP#getReplyString  getReplyString }.
67 |  |
      * <p>
68 |  |
      * Rather than list it separately for each method, we mention here that
69 |  |
      * every method communicating with the server and throwing an IOException
70 |  |
      * can also throw a
71 |  |
      * {@link org.apache.commons.net.MalformedServerReplyException}
72 |  |
      * , which is a subclass
73 |  |
      * of IOException.  A MalformedServerReplyException will be thrown when
74 |  |
      * the reply received from the server deviates enough from the protocol
75 |  |
      * specification that it cannot be interpreted in a useful manner despite
76 |  |
      * attempts to be as lenient as possible.
77 |  |
      * <p>
78 |  |
      * <p>
79 |  |
      * @author Daniel F. Savarese
80 |  |
      * @author Rory Winston
81 |  |
      * @author Ted Wise
82 |  |
      * @see NNTP
83 |  |
      * @see NNTPConnectionClosedException
84 |  |
      * @see org.apache.commons.net.MalformedServerReplyException
85 |  |
      ***/
86 |  |
87 | 0 |
     public class NNTPClient extends NNTP
88 |  |
     {
89 |  |
90 |  |
         private void __parseArticlePointer(String reply, ArticlePointer pointer)
91 |  |
         throws MalformedServerReplyException
92 |  |
         {
93 |  |
             StringTokenizer tokenizer;
94 |  |
95 |  |
             // Do loop is a kluge to simulate goto
96 |  |
             do
97 |  |
             {
98 | 0 |
                 tokenizer = new StringTokenizer(reply);
99 |  |
100 | 0 |
                 if (tokenizer.countTokens() < 3)
101 | 0 |
                     break;
102 |  |
103 |  |
                 // Skip numeric response value
104 | 0 |
                 tokenizer.nextToken();
105 |  |
                 // Get article number
106 |  |
                 try
107 |  |
                 {
108 | 0 |
                     pointer.articleNumber = Integer.parseInt(tokenizer.nextToken());
109 |  |
                 }
110 | 0 |
                 catch (NumberFormatException e)
111 |  |
                 {
112 | 0 |
                     break;
113 | 0 |
                 }
114 |  |
115 |  |
                 // Get article id
116 | 0 |
                 pointer.articleId = tokenizer.nextToken();
117 | 0 |
                 return ;
118 |  |
             }
119 |  |
             while (false);
120 |  |
121 | 0 |
             throw new MalformedServerReplyException(
122 |  |
                 "Could not parse article pointer.\nServer reply: " + reply);
123 |  |
         }
124 |  |
125 |  |
126 |  |
         private void __parseGroupReply(String reply, NewsgroupInfo info)
127 |  |
         throws MalformedServerReplyException
128 |  |
         {
129 |  |
             String count, first, last;
130 |  |
             StringTokenizer tokenizer;
131 |  |
132 |  |
             // Do loop is a kluge to simulate goto
133 |  |
             do
134 |  |
             {
135 | 0 |
                 tokenizer = new StringTokenizer(reply);
136 |  |
137 | 0 |
                 if (tokenizer.countTokens() < 5)
138 | 0 |
                     break;
139 |  |
140 |  |
                 // Skip numeric response value
141 | 0 |
                 tokenizer.nextToken();
142 |  |
                 // Get estimated article count
143 | 0 |
                 count = tokenizer.nextToken();
144 |  |
                 // Get first article number
145 | 0 |
                 first = tokenizer.nextToken();
146 |  |
                 // Get last article number
147 | 0 |
                 last = tokenizer.nextToken();
148 |  |
                 // Get newsgroup name
149 | 0 |
                 info._setNewsgroup(tokenizer.nextToken());
150 |  |
151 |  |
                 try
152 |  |
                 {
153 | 0 |
                     info._setArticleCount(Integer.parseInt(count));
154 | 0 |
                     info._setFirstArticle(Integer.parseInt(first));
155 | 0 |
                     info._setLastArticle(Integer.parseInt(last));
156 |  |
                 }
157 | 0 |
                 catch (NumberFormatException e)
158 |  |
                 {
159 | 0 |
                     break;
160 | 0 |
                 }
161 |  |
162 | 0 |
                 info._setPostingPermission(NewsgroupInfo.UNKNOWN_POSTING_PERMISSION);
163 | 0 |
                 return ;
164 |  |
             }
165 |  |
             while (false);
166 |  |
167 | 0 |
             throw new MalformedServerReplyException(
168 |  |
                 "Could not parse newsgroup info.\nServer reply: " + reply);
169 |  |
         }
170 |  |
171 |  |
172 |  |
         private NewsgroupInfo __parseNewsgroupListEntry(String entry)
173 |  |
         {
174 |  |
             NewsgroupInfo result;
175 |  |
             StringTokenizer tokenizer;
176 |  |
             int lastNum, firstNum;
177 |  |
             String last, first, permission;
178 |  |
179 | 0 |
             result = new NewsgroupInfo();
180 | 0 |
             tokenizer = new StringTokenizer(entry);
181 |  |
182 | 0 |
             if (tokenizer.countTokens() < 4)
183 | 0 |
                 return null;
184 |  |
185 | 0 |
             result._setNewsgroup(tokenizer.nextToken());
186 | 0 |
             last = tokenizer.nextToken();
187 | 0 |
             first = tokenizer.nextToken();
188 | 0 |
             permission = tokenizer.nextToken();
189 |  |
190 |  |
             try
191 |  |
             {
192 | 0 |
                 lastNum = Integer.parseInt(last);
193 | 0 |
                 firstNum = Integer.parseInt(first);
194 | 0 |
                 result._setFirstArticle(firstNum);
195 | 0 |
                 result._setLastArticle(lastNum);
196 |  |
197 | 0 |
     	    if((firstNum == 0) && (lastNum == 0))
198 | 0 |
     		    result._setArticleCount(0);
199 |  |
     	    else
200 | 0 |
     		    result._setArticleCount(lastNum - firstNum + 1);
201 |  |
             }
202 | 0 |
             catch (NumberFormatException e)
203 |  |
             {
204 | 0 |
                 return null;
205 | 0 |
             }
206 |  |
207 | 0 |
             switch (permission.charAt(0))
208 |  |
             {
209 |  |
             case 'y':
210 |  |
             case 'Y':
211 | 0 |
                 result._setPostingPermission(
212 |  |
                     NewsgroupInfo.PERMITTED_POSTING_PERMISSION);
213 | 0 |
                 break;
214 |  |
             case 'n':
215 |  |
             case 'N':
216 | 0 |
                 result._setPostingPermission(
217 |  |
                     NewsgroupInfo.PROHIBITED_POSTING_PERMISSION);
218 | 0 |
                 break;
219 |  |
             case 'm':
220 |  |
             case 'M':
221 | 0 |
                 result._setPostingPermission(
222 |  |
                     NewsgroupInfo.MODERATED_POSTING_PERMISSION);
223 | 0 |
                 break;
224 |  |
             default:
225 | 0 |
                 result._setPostingPermission(
226 |  |
                     NewsgroupInfo.UNKNOWN_POSTING_PERMISSION);
227 |  |
                 break;
228 |  |
             }
229 |  |
230 | 0 |
             return result;
231 |  |
         }
232 |  |
233 |  |
         private NewsgroupInfo[] __readNewsgroupListing() throws IOException
234 |  |
         {
235 |  |
             int size;
236 |  |
             String line;
237 |  |
             Vector list;
238 |  |
             BufferedReader reader;
239 |  |
             NewsgroupInfo tmp, info[];
240 |  |
241 | 0 |
             reader = new BufferedReader(class="keyword">new DotTerminatedMessageReader(_reader_));
242 |  |
             // Start of with a big vector because we may be reading a very large
243 |  |
             // amount of groups.
244 | 0 |
             list = new Vector(2048);
245 |  |
246 | 0 |
             while ((line = reader.readLine()) != null)
247 |  |
             {
248 | 0 |
                 tmp = __parseNewsgroupListEntry(line);
249 | 0 |
                 if (tmp != null)
250 | 0 |
                     list.addElement(tmp);
251 |  |
                 else
252 | 0 |
                     throw new MalformedServerReplyException(line);
253 |  |
             }
254 |  |
255 | 0 |
             if ((size = list.size()) < 1)
256 | 0 |
                 return new NewsgroupInfo[0];
257 |  |
258 | 0 |
             info = new NewsgroupInfo[size];
259 | 0 |
             list.copyInto(info);
260 |  |
261 | 0 |
             return info;
262 |  |
         }
263 |  |
264 |  |
265 |  |
         private Reader __retrieve(int command,
266 |  |
                                   String articleId, ArticlePointer pointer)
267 |  |
         throws IOException
268 |  |
         {
269 |  |
             Reader reader;
270 |  |
271 | 0 |
             if (articleId != null)
272 |  |
             {
273 | 0 |
                 if (!NNTPReply.isPositiveCompletion(sendCommand(command, articleId)))
274 | 0 |
                     return null;
275 |  |
             }
276 |  |
             else
277 |  |
             {
278 | 0 |
                 if (!NNTPReply.isPositiveCompletion(sendCommand(command)))
279 | 0 |
                     return null;
280 |  |
             }
281 |  |
282 |  |
283 | 0 |
             if (pointer != null)
284 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
285 |  |
286 | 0 |
             reader = new DotTerminatedMessageReader(_reader_);
287 | 0 |
             return reader;
288 |  |
         }
289 |  |
290 |  |
291 |  |
         private Reader __retrieve(int command,
292 |  |
                                   int articleNumber, ArticlePoclass="keyword">inter poclass="keyword">inter)
293 |  |
         throws IOException
294 |  |
         {
295 |  |
             Reader reader;
296 |  |
297 | 0 |
             if (!NNTPReply.isPositiveCompletion(sendCommand(command,
298 |  |
                                                 Integer.toString(articleNumber))))
299 | 0 |
                 return null;
300 |  |
301 | 0 |
             if (pointer != null)
302 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
303 |  |
304 | 0 |
             reader = new DotTerminatedMessageReader(_reader_);
305 | 0 |
             return reader;
306 |  |
         }
307 |  |
308 |  |
309 |  |
310 |  |
         /***
311 |  |
          * Retrieves an article from the NNTP server.  The article is referenced
312 |  |
          * by its unique article identifier (including the enclosing &lt and &gt).
313 |  |
          * The article number and identifier contained in the server reply
314 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
315 |  |
          * field of the ArticlePointer cannot always be trusted because some
316 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
317 |  |
          * <p>
318 |  |
          * A DotTerminatedMessageReader is returned from which the article can
319 |  |
          * be read.  If the article does not exist, null is returned.
320 |  |
          * <p>
321 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
322 |  |
          * other methods) until you finish reading the message from the returned
323 |  |
          * Reader instance.
324 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
325 |  |
          * for returning results.  Therefore the returned Reader actually reads
326 |  |
          * directly from the NNTP connection.  After the end of message has been
327 |  |
          * reached, new commands can be executed and their replies read.  If
328 |  |
          * you do not follow these requirements, your program will not work
329 |  |
          * properly.
330 |  |
          * <p>
331 |  |
          * @param articleId  The unique article identifier of the article to
332 |  |
          *     retrieve.  If this parameter is null, the currently selected
333 |  |
          *     article is retrieved.
334 |  |
          * @param pointer    A parameter through which to return the article's
335 |  |
          *   number and unique id.  The articleId field cannot always be trusted
336 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
337 |  |
          *   set this parameter to null if you do not desire to retrieve the
338 |  |
          *   returned article information.
339 |  |
          * @return A DotTerminatedMessageReader instance from which the article
340 |  |
          *         be read.  null if the article does not exist.
341 |  |
          * @exception NNTPConnectionClosedException
342 |  |
          *      If the NNTP server prematurely closes the connection as a result
343 |  |
          *      of the client being idle or some other reason causing the server
344 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
345 |  |
          *      as an IOException or independently as itself.
346 |  |
          * @exception IOException  If an I/O error occurs while either sending a
347 |  |
          *      command to the server or receiving a reply from the server.
348 |  |
          ***/
349 |  |
         public Reader retrieveArticle(String articleId, ArticlePointer pointer)
350 |  |
         throws IOException
351 |  |
         {
352 | 0 |
             return __retrieve(NNTPCommand.ARTICLE, articleId, pointer);
353 |  |
354 |  |
         }
355 |  |
356 |  |
         /*** Same as <code> retrieveArticle(articleId, null) </code> ***/
357 |  |
         public Reader retrieveArticle(String articleId) throws IOException
358 |  |
         {
359 | 0 |
             return retrieveArticle(articleId, null);
360 |  |
         }
361 |  |
362 |  |
         /*** Same as <code> retrieveArticle(null) </code> ***/
363 |  |
         public Reader retrieveArticle() throws IOException
364 |  |
         {
365 | 0 |
             return retrieveArticle(null);
366 |  |
         }
367 |  |
368 |  |
369 |  |
         /***
370 |  |
          * Retrieves an article from the currently selected newsgroup.  The
371 |  |
          * article is referenced by its article number.
372 |  |
          * The article number and identifier contained in the server reply
373 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
374 |  |
          * field of the ArticlePointer cannot always be trusted because some
375 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
376 |  |
          * <p>
377 |  |
          * A DotTerminatedMessageReader is returned from which the article can
378 |  |
          * be read.  If the article does not exist, null is returned.
379 |  |
          * <p>
380 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
381 |  |
          * other methods) until you finish reading the message from the returned
382 |  |
          * Reader instance.
383 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
384 |  |
          * for returning results.  Therefore the returned Reader actually reads
385 |  |
          * directly from the NNTP connection.  After the end of message has been
386 |  |
          * reached, new commands can be executed and their replies read.  If
387 |  |
          * you do not follow these requirements, your program will not work
388 |  |
          * properly.
389 |  |
          * <p>
390 |  |
          * @param articleNumber  The number of the the article to
391 |  |
          *     retrieve.
392 |  |
          * @param pointer    A parameter through which to return the article's
393 |  |
          *   number and unique id.  The articleId field cannot always be trusted
394 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
395 |  |
          *   set this parameter to null if you do not desire to retrieve the
396 |  |
          *   returned article information.
397 |  |
          * @return A DotTerminatedMessageReader instance from which the article
398 |  |
          *         be read.  null if the article does not exist.
399 |  |
          * @exception NNTPConnectionClosedException
400 |  |
          *      If the NNTP server prematurely closes the connection as a result
401 |  |
          *      of the client being idle or some other reason causing the server
402 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
403 |  |
          *      as an IOException or independently as itself.
404 |  |
          * @exception IOException  If an I/O error occurs while either sending a
405 |  |
          *      command to the server or receiving a reply from the server.
406 |  |
          ***/
407 |  |
         public Reader retrieveArticle(int articleNumber, ArticlePoclass="keyword">inter poclass="keyword">inter)
408 |  |
         throws IOException
409 |  |
         {
410 | 0 |
             return __retrieve(NNTPCommand.ARTICLE, articleNumber, pointer);
411 |  |
         }
412 |  |
413 |  |
         /*** Same as <code> retrieveArticle(articleNumber, null) </code> ***/
414 |  |
         public Reader retrieveArticle(int articleNumber) throws IOException
415 |  |
         {
416 | 0 |
             return retrieveArticle(articleNumber, null);
417 |  |
         }
418 |  |
419 |  |
420 |  |
421 |  |
         /***
422 |  |
          * Retrieves an article header from the NNTP server.  The article is
423 |  |
          * referenced
424 |  |
          * by its unique article identifier (including the enclosing &lt and &gt).
425 |  |
          * The article number and identifier contained in the server reply
426 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
427 |  |
          * field of the ArticlePointer cannot always be trusted because some
428 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
429 |  |
          * <p>
430 |  |
          * A DotTerminatedMessageReader is returned from which the article can
431 |  |
          * be read.  If the article does not exist, null is returned.
432 |  |
          * <p>
433 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
434 |  |
          * other methods) until you finish reading the message from the returned
435 |  |
          * Reader instance.
436 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
437 |  |
          * for returning results.  Therefore the returned Reader actually reads
438 |  |
          * directly from the NNTP connection.  After the end of message has been
439 |  |
          * reached, new commands can be executed and their replies read.  If
440 |  |
          * you do not follow these requirements, your program will not work
441 |  |
          * properly.
442 |  |
          * <p>
443 |  |
          * @param articleId  The unique article identifier of the article whose
444 |  |
          *    header is being retrieved.  If this parameter is null, the
445 |  |
          *    header of the currently selected article is retrieved.
446 |  |
          * @param pointer    A parameter through which to return the article's
447 |  |
          *   number and unique id.  The articleId field cannot always be trusted
448 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
449 |  |
          *   set this parameter to null if you do not desire to retrieve the
450 |  |
          *   returned article information.
451 |  |
          * @return A DotTerminatedMessageReader instance from which the article
452 |  |
          *         header can be read.  null if the article does not exist.
453 |  |
          * @exception NNTPConnectionClosedException
454 |  |
          *      If the NNTP server prematurely closes the connection as a result
455 |  |
          *      of the client being idle or some other reason causing the server
456 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
457 |  |
          *      as an IOException or independently as itself.
458 |  |
          * @exception IOException  If an I/O error occurs while either sending a
459 |  |
          *      command to the server or receiving a reply from the server.
460 |  |
          ***/
461 |  |
         public Reader retrieveArticleHeader(String articleId, ArticlePointer pointer)
462 |  |
         throws IOException
463 |  |
         {
464 | 0 |
             return __retrieve(NNTPCommand.HEAD, articleId, pointer);
465 |  |
466 |  |
         }
467 |  |
468 |  |
         /*** Same as <code> retrieveArticleHeader(articleId, null) </code> ***/
469 |  |
         public Reader retrieveArticleHeader(String articleId) throws IOException
470 |  |
         {
471 | 0 |
             return retrieveArticleHeader(articleId, null);
472 |  |
         }
473 |  |
474 |  |
         /*** Same as <code> retrieveArticleHeader(null) </code> ***/
475 |  |
         public Reader retrieveArticleHeader() throws IOException
476 |  |
         {
477 | 0 |
             return retrieveArticleHeader(null);
478 |  |
         }
479 |  |
480 |  |
481 |  |
         /***
482 |  |
          * Retrieves an article header from the currently selected newsgroup.  The
483 |  |
          * article is referenced by its article number.
484 |  |
          * The article number and identifier contained in the server reply
485 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
486 |  |
          * field of the ArticlePointer cannot always be trusted because some
487 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
488 |  |
          * <p>
489 |  |
          * A DotTerminatedMessageReader is returned from which the article can
490 |  |
          * be read.  If the article does not exist, null is returned.
491 |  |
          * <p>
492 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
493 |  |
          * other methods) until you finish reading the message from the returned
494 |  |
          * Reader instance.
495 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
496 |  |
          * for returning results.  Therefore the returned Reader actually reads
497 |  |
          * directly from the NNTP connection.  After the end of message has been
498 |  |
          * reached, new commands can be executed and their replies read.  If
499 |  |
          * you do not follow these requirements, your program will not work
500 |  |
          * properly.
501 |  |
          * <p>
502 |  |
          * @param articleNumber  The number of the the article whose header is
503 |  |
          *     being retrieved.
504 |  |
          * @param pointer    A parameter through which to return the article's
505 |  |
          *   number and unique id.  The articleId field cannot always be trusted
506 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
507 |  |
          *   set this parameter to null if you do not desire to retrieve the
508 |  |
          *   returned article information.
509 |  |
          * @return A DotTerminatedMessageReader instance from which the article
510 |  |
          *         header can be read.  null if the article does not exist.
511 |  |
          * @exception NNTPConnectionClosedException
512 |  |
          *      If the NNTP server prematurely closes the connection as a result
513 |  |
          *      of the client being idle or some other reason causing the server
514 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
515 |  |
          *      as an IOException or independently as itself.
516 |  |
          * @exception IOException  If an I/O error occurs while either sending a
517 |  |
          *      command to the server or receiving a reply from the server.
518 |  |
          ***/
519 |  |
         public Reader retrieveArticleHeader(int articleNumber,
520 |  |
                                             ArticlePointer pointer)
521 |  |
         throws IOException
522 |  |
         {
523 | 0 |
             return __retrieve(NNTPCommand.HEAD, articleNumber, pointer);
524 |  |
         }
525 |  |
526 |  |
527 |  |
         /*** Same as <code> retrieveArticleHeader(articleNumber, null) </code> ***/
528 |  |
         public Reader retrieveArticleHeader(int articleNumber) throws IOException
529 |  |
         {
530 | 0 |
             return retrieveArticleHeader(articleNumber, null);
531 |  |
         }
532 |  |
533 |  |
534 |  |
535 |  |
         /***
536 |  |
          * Retrieves an article body from the NNTP server.  The article is
537 |  |
          * referenced
538 |  |
          * by its unique article identifier (including the enclosing &lt and &gt).
539 |  |
          * The article number and identifier contained in the server reply
540 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
541 |  |
          * field of the ArticlePointer cannot always be trusted because some
542 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
543 |  |
          * <p>
544 |  |
          * A DotTerminatedMessageReader is returned from which the article can
545 |  |
          * be read.  If the article does not exist, null is returned.
546 |  |
          * <p>
547 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
548 |  |
          * other methods) until you finish reading the message from the returned
549 |  |
          * Reader instance.
550 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
551 |  |
          * for returning results.  Therefore the returned Reader actually reads
552 |  |
          * directly from the NNTP connection.  After the end of message has been
553 |  |
          * reached, new commands can be executed and their replies read.  If
554 |  |
          * you do not follow these requirements, your program will not work
555 |  |
          * properly.
556 |  |
          * <p>
557 |  |
          * @param articleId  The unique article identifier of the article whose
558 |  |
          *    body is being retrieved.  If this parameter is null, the
559 |  |
          *    body of the currently selected article is retrieved.
560 |  |
          * @param pointer    A parameter through which to return the article's
561 |  |
          *   number and unique id.  The articleId field cannot always be trusted
562 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
563 |  |
          *   set this parameter to null if you do not desire to retrieve the
564 |  |
          *   returned article information.
565 |  |
          * @return A DotTerminatedMessageReader instance from which the article
566 |  |
          *         body can be read.  null if the article does not exist.
567 |  |
          * @exception NNTPConnectionClosedException
568 |  |
          *      If the NNTP server prematurely closes the connection as a result
569 |  |
          *      of the client being idle or some other reason causing the server
570 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
571 |  |
          *      as an IOException or independently as itself.
572 |  |
          * @exception IOException  If an I/O error occurs while either sending a
573 |  |
          *      command to the server or receiving a reply from the server.
574 |  |
          ***/
575 |  |
         public Reader retrieveArticleBody(String articleId, ArticlePointer pointer)
576 |  |
         throws IOException
577 |  |
         {
578 | 0 |
             return __retrieve(NNTPCommand.BODY, articleId, pointer);
579 |  |
580 |  |
         }
581 |  |
582 |  |
         /*** Same as <code> retrieveArticleBody(articleId, null) </code> ***/
583 |  |
         public Reader retrieveArticleBody(String articleId) throws IOException
584 |  |
         {
585 | 0 |
             return retrieveArticleBody(articleId, null);
586 |  |
         }
587 |  |
588 |  |
         /*** Same as <code> retrieveArticleBody(null) </code> ***/
589 |  |
         public Reader retrieveArticleBody() throws IOException
590 |  |
         {
591 | 0 |
             return retrieveArticleBody(null);
592 |  |
         }
593 |  |
594 |  |
595 |  |
         /***
596 |  |
          * Retrieves an article body from the currently selected newsgroup.  The
597 |  |
          * article is referenced by its article number.
598 |  |
          * The article number and identifier contained in the server reply
599 |  |
          * are returned through an ArticlePointer.  The <code> articleId </code>
600 |  |
          * field of the ArticlePointer cannot always be trusted because some
601 |  |
          * NNTP servers do not correctly follow the RFC 977 reply format.
602 |  |
          * <p>
603 |  |
          * A DotTerminatedMessageReader is returned from which the article can
604 |  |
          * be read.  If the article does not exist, null is returned.
605 |  |
          * <p>
606 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
607 |  |
          * other methods) until you finish reading the message from the returned
608 |  |
          * Reader instance.
609 |  |
          * The NNTP protocol uses the same stream for issuing commands as it does
610 |  |
          * for returning results.  Therefore the returned Reader actually reads
611 |  |
          * directly from the NNTP connection.  After the end of message has been
612 |  |
          * reached, new commands can be executed and their replies read.  If
613 |  |
          * you do not follow these requirements, your program will not work
614 |  |
          * properly.
615 |  |
          * <p>
616 |  |
          * @param articleNumber  The number of the the article whose body is
617 |  |
          *     being retrieved.
618 |  |
          * @param pointer    A parameter through which to return the article's
619 |  |
          *   number and unique id.  The articleId field cannot always be trusted
620 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
621 |  |
          *   set this parameter to null if you do not desire to retrieve the
622 |  |
          *   returned article information.
623 |  |
          * @return A DotTerminatedMessageReader instance from which the article
624 |  |
          *         body can be read.  null if the article does not exist.
625 |  |
          * @exception NNTPConnectionClosedException
626 |  |
          *      If the NNTP server prematurely closes the connection as a result
627 |  |
          *      of the client being idle or some other reason causing the server
628 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
629 |  |
          *      as an IOException or independently as itself.
630 |  |
          * @exception IOException  If an I/O error occurs while either sending a
631 |  |
          *      command to the server or receiving a reply from the server.
632 |  |
          ***/
633 |  |
         public Reader retrieveArticleBody(int articleNumber,
634 |  |
                                           ArticlePointer pointer)
635 |  |
         throws IOException
636 |  |
         {
637 | 0 |
             return __retrieve(NNTPCommand.BODY, articleNumber, pointer);
638 |  |
         }
639 |  |
640 |  |
641 |  |
         /*** Same as <code> retrieveArticleBody(articleNumber, null) </code> ***/
642 |  |
         public Reader retrieveArticleBody(int articleNumber) throws IOException
643 |  |
         {
644 | 0 |
             return retrieveArticleBody(articleNumber, null);
645 |  |
         }
646 |  |
647 |  |
648 |  |
         /***
649 |  |
          * Select the specified newsgroup to be the target of for future article
650 |  |
          * retrieval and posting operations.  Also return the newsgroup
651 |  |
          * information contained in the server reply through the info parameter.
652 |  |
          * <p>
653 |  |
          * @param newsgroup  The newsgroup to select.
654 |  |
          * @param info  A parameter through which the newsgroup information of
655 |  |
          *      the selected newsgroup contained in the server reply is returned.
656 |  |
          *      Set this to null if you do not desire this information.
657 |  |
          * @return True if the newsgroup exists and was selected, false otherwise.
658 |  |
          * @exception NNTPConnectionClosedException
659 |  |
          *      If the NNTP server prematurely closes the connection as a result
660 |  |
          *      of the client being idle or some other reason causing the server
661 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
662 |  |
          *      as an IOException or independently as itself.
663 |  |
          * @exception IOException  If an I/O error occurs while either sending a
664 |  |
          *      command to the server or receiving a reply from the server.
665 |  |
          ***/
666 |  |
         public boolean selectNewsgroup(String newsgroup, NewsgroupInfo info)
667 |  |
         throws IOException
668 |  |
         {
669 | 0 |
             if (!NNTPReply.isPositiveCompletion(group(newsgroup)))
670 | 0 |
                 return false;
671 |  |
672 | 0 |
             if (info != null)
673 | 0 |
                 __parseGroupReply(getReplyString(), info);
674 |  |
675 | 0 |
             return true;
676 |  |
         }
677 |  |
678 |  |
         /*** Same as <code> selectNewsgroup(newsgroup, null) </code> ***/
679 |  |
         public boolean selectNewsgroup(String newsgroup) throws IOException
680 |  |
         {
681 | 0 |
             return selectNewsgroup(newsgroup, null);
682 |  |
         }
683 |  |
684 |  |
         /***
685 |  |
          * List the command help from the server.
686 |  |
          * <p>
687 |  |
          * @return The sever help information.
688 |  |
          * @exception NNTPConnectionClosedException
689 |  |
          *      If the NNTP server prematurely closes the connection as a result
690 |  |
          *      of the client being idle or some other reason causing the server
691 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
692 |  |
          *      as an IOException or independently as itself.
693 |  |
          * @exception IOException  If an I/O error occurs while either sending a
694 |  |
          *      command to the server or receiving a reply from the server.
695 |  |
          ***/
696 |  |
         public String listHelp() throws IOException
697 |  |
         {
698 |  |
             StringWriter help;
699 |  |
             Reader reader;
700 |  |
701 | 0 |
             if (!NNTPReply.isInformational(help()))
702 | 0 |
                 return null;
703 |  |
704 | 0 |
             help = new StringWriter();
705 | 0 |
             reader = new DotTerminatedMessageReader(_reader_);
706 | 0 |
             Util.copyReader(reader, help);
707 | 0 |
             reader.close();
708 | 0 |
             help.close();
709 | 0 |
             return help.toString();
710 |  |
         }
711 |  |
712 |  |
713 |  |
         /***
714 |  |
          * Select an article by its unique identifier (including enclosing
715 |  |
          * &lt and &gt) and return its article number and id through the
716 |  |
          * pointer parameter.  This is achieved through the STAT command.
717 |  |
          * According to RFC 977, this will NOT set the current article pointer
718 |  |
          * on the server.  To do that, you must reference the article by its
719 |  |
          * number.
720 |  |
          * <p>
721 |  |
          * @param articleId  The unique article identifier of the article that
722 |  |
          *    is being selectedd.  If this parameter is null, the
723 |  |
          *    body of the current article is selected
724 |  |
          * @param pointer    A parameter through which to return the article's
725 |  |
          *   number and unique id.  The articleId field cannot always be trusted
726 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
727 |  |
          *   set this parameter to null if you do not desire to retrieve the
728 |  |
          *   returned article information.
729 |  |
          * @return True if successful, false if not.
730 |  |
          * @exception NNTPConnectionClosedException
731 |  |
          *      If the NNTP server prematurely closes the connection as a result
732 |  |
          *      of the client being idle or some other reason causing the server
733 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
734 |  |
          *      as an IOException or independently as itself.
735 |  |
          * @exception IOException  If an I/O error occurs while either sending a
736 |  |
          *      command to the server or receiving a reply from the server.
737 |  |
          ***/
738 |  |
         public boolean selectArticle(String articleId, ArticlePointer pointer)
739 |  |
         throws IOException
740 |  |
         {
741 | 0 |
             if (articleId != null)
742 |  |
             {
743 | 0 |
                 if (!NNTPReply.isPositiveCompletion(stat(articleId)))
744 | 0 |
                     return false;
745 |  |
             }
746 |  |
             else
747 |  |
             {
748 | 0 |
                 if (!NNTPReply.isPositiveCompletion(stat()))
749 | 0 |
                     return false;
750 |  |
             }
751 |  |
752 | 0 |
             if (pointer != null)
753 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
754 |  |
755 | 0 |
             return true;
756 |  |
         }
757 |  |
758 |  |
         /**** Same as <code> selectArticle(articleId, null) </code> ***/
759 |  |
         public boolean selectArticle(String articleId) throws IOException
760 |  |
         {
761 | 0 |
             return selectArticle(articleId, null);
762 |  |
         }
763 |  |
764 |  |
         /****
765 |  |
          * Same as <code> selectArticle(null, articleId) </code>.  Useful
766 |  |
          * for retrieving the current article number.
767 |  |
          ***/
768 |  |
         public boolean selectArticle(ArticlePointer pointer) throws IOException
769 |  |
         {
770 | 0 |
             return selectArticle(null, pointer);
771 |  |
         }
772 |  |
773 |  |
774 |  |
         /***
775 |  |
          * Select an article in the currently selected newsgroup by its number.
776 |  |
          * and return its article number and id through the
777 |  |
          * pointer parameter.  This is achieved through the STAT command.
778 |  |
          * According to RFC 977, this WILL set the current article pointer
779 |  |
          * on the server.  Use this command to select an article before retrieving
780 |  |
          * it, or to obtain an article's unique identifier given its number.
781 |  |
          * <p>
782 |  |
          * @param articleNumber The number of the article to select from the
783 |  |
          *       currently selected newsgroup.
784 |  |
          * @param pointer    A parameter through which to return the article's
785 |  |
          *   number and unique id.  Although the articleId field cannot always
786 |  |
          *   be trusted because of server deviations from RFC 977 reply formats,
787 |  |
          *   we haven't found a server that misformats this information in response
788 |  |
          *   to this particular command.  You may set this parameter to null if
789 |  |
          *   you do not desire to retrieve the returned article information.
790 |  |
          * @return True if successful, false if not.
791 |  |
          * @exception NNTPConnectionClosedException
792 |  |
          *      If the NNTP server prematurely closes the connection as a result
793 |  |
          *      of the client being idle or some other reason causing the server
794 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
795 |  |
          *      as an IOException or independently as itself.
796 |  |
          * @exception IOException  If an I/O error occurs while either sending a
797 |  |
          *      command to the server or receiving a reply from the server.
798 |  |
          ***/
799 |  |
         public boolean selectArticle(int articleNumber, ArticlePoclass="keyword">inter poclass="keyword">inter)
800 |  |
         throws IOException
801 |  |
         {
802 | 0 |
             if (!NNTPReply.isPositiveCompletion(stat(articleNumber)))
803 | 0 |
                 return false;
804 |  |
805 | 0 |
             if (pointer != null)
806 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
807 |  |
808 | 0 |
             return true;
809 |  |
         }
810 |  |
811 |  |
812 |  |
         /*** Same as <code> selectArticle(articleNumber, null) </code> ***/
813 |  |
         public boolean selectArticle(int articleNumber) throws IOException
814 |  |
         {
815 | 0 |
             return selectArticle(articleNumber, null);
816 |  |
         }
817 |  |
818 |  |
819 |  |
         /***
820 |  |
          * Select the article preceeding the currently selected article in the
821 |  |
          * currently selected newsgroup and return its number and unique id
822 |  |
          * through the pointer parameter.  Because of deviating server
823 |  |
          * implementations, the articleId information cannot be trusted.  To
824 |  |
          * obtain the article identifier, issue a
825 |  |
          * <code> selectArticle(pointer.articleNumber, pointer) </code> immediately
826 |  |
          * afterward.
827 |  |
          * <p>
828 |  |
          * @param pointer    A parameter through which to return the article's
829 |  |
          *   number and unique id.  The articleId field cannot always be trusted
830 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
831 |  |
          *   set this parameter to null if you do not desire to retrieve the
832 |  |
          *   returned article information.
833 |  |
          * @return True if successful, false if not (e.g., there is no previous
834 |  |
          *     article).
835 |  |
          * @exception NNTPConnectionClosedException
836 |  |
          *      If the NNTP server prematurely closes the connection as a result
837 |  |
          *      of the client being idle or some other reason causing the server
838 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
839 |  |
          *      as an IOException or independently as itself.
840 |  |
          * @exception IOException  If an I/O error occurs while either sending a
841 |  |
          *      command to the server or receiving a reply from the server.
842 |  |
          ***/
843 |  |
         public boolean selectPreviousArticle(ArticlePointer pointer)
844 |  |
         throws IOException
845 |  |
         {
846 | 0 |
             if (!NNTPReply.isPositiveCompletion(last()))
847 | 0 |
                 return false;
848 |  |
849 | 0 |
             if (pointer != null)
850 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
851 |  |
852 | 0 |
             return true;
853 |  |
         }
854 |  |
855 |  |
         /*** Same as <code> selectPreviousArticle(null) </code> ***/
856 |  |
         public boolean selectPreviousArticle() throws IOException
857 |  |
         {
858 | 0 |
             return selectPreviousArticle(null);
859 |  |
         }
860 |  |
861 |  |
862 |  |
         /***
863 |  |
          * Select the article following the currently selected article in the
864 |  |
          * currently selected newsgroup and return its number and unique id
865 |  |
          * through the pointer parameter.  Because of deviating server
866 |  |
          * implementations, the articleId information cannot be trusted.  To
867 |  |
          * obtain the article identifier, issue a
868 |  |
          * <code> selectArticle(pointer.articleNumber, pointer) </code> immediately
869 |  |
          * afterward.
870 |  |
          * <p>
871 |  |
          * @param pointer    A parameter through which to return the article's
872 |  |
          *   number and unique id.  The articleId field cannot always be trusted
873 |  |
          *   because of server deviations from RFC 977 reply formats.  You may
874 |  |
          *   set this parameter to null if you do not desire to retrieve the
875 |  |
          *   returned article information.
876 |  |
          * @return True if successful, false if not (e.g., there is no following
877 |  |
          *         article).
878 |  |
          * @exception NNTPConnectionClosedException
879 |  |
          *      If the NNTP server prematurely closes the connection as a result
880 |  |
          *      of the client being idle or some other reason causing the server
881 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
882 |  |
          *      as an IOException or independently as itself.
883 |  |
          * @exception IOException  If an I/O error occurs while either sending a
884 |  |
          *      command to the server or receiving a reply from the server.
885 |  |
          ***/
886 |  |
         public boolean selectNextArticle(ArticlePointer pointer) throws IOException
887 |  |
         {
888 | 0 |
             if (!NNTPReply.isPositiveCompletion(next()))
889 | 0 |
                 return false;
890 |  |
891 | 0 |
             if (pointer != null)
892 | 0 |
                 __parseArticlePointer(getReplyString(), pointer);
893 |  |
894 | 0 |
             return true;
895 |  |
         }
896 |  |
897 |  |
898 |  |
         /*** Same as <code> selectNextArticle(null) </code> ***/
899 |  |
         public boolean selectNextArticle() throws IOException
900 |  |
         {
901 | 0 |
             return selectNextArticle(null);
902 |  |
         }
903 |  |
904 |  |
905 |  |
         /***
906 |  |
          * List all newsgroups served by the NNTP server.  If no newsgroups
907 |  |
          * are served, a zero length array will be returned.  If the command
908 |  |
          * fails, null will be returned.
909 |  |
          * <p>
910 |  |
          * @return An array of NewsgroupInfo instances containing the information
911 |  |
          *    for each newsgroup served by the NNTP server.   If no newsgroups
912 |  |
          *    are served, a zero length array will be returned.  If the command
913 |  |
          *    fails, null will be returned.
914 |  |
          * @exception NNTPConnectionClosedException
915 |  |
          *      If the NNTP server prematurely closes the connection as a result
916 |  |
          *      of the client being idle or some other reason causing the server
917 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
918 |  |
          *      as an IOException or independently as itself.
919 |  |
          * @exception IOException  If an I/O error occurs while either sending a
920 |  |
          *      command to the server or receiving a reply from the server.
921 |  |
          ***/
922 |  |
         public NewsgroupInfo[] listNewsgroups() throws IOException
923 |  |
         {
924 | 0 |
             if (!NNTPReply.isPositiveCompletion(list()))
925 | 0 |
                 return null;
926 |  |
927 | 0 |
             return __readNewsgroupListing();
928 |  |
         }
929 |  |
930 |  |
         /**
931 |  |
          * An overloaded listNewsgroups() command that allows us to
932 |  |
          * specify with a pattern what groups we want to list. Wraps the
933 |  |
          * LIST ACTIVE command.
934 |  |
          * <p>
935 |  |
          * @param wildmat a pseudo-regex pattern (cf. RFC 2980)
936 |  |
          * @return An array of NewsgroupInfo instances containing the information
937 |  |
          *    for each newsgroup served by the NNTP server corresponding to the
938 |  |
          *    supplied pattern.   If no such newsgroups are served, a zero length
939 |  |
          *    array will be returned.  If the command fails, null will be returned.
940 |  |
          * @throws IOException
941 |  |
          */
942 |  |
         public NewsgroupInfo[] listNewsgroups(String wildmat) throws IOException
943 |  |
         {
944 | 0 |
             if(!NNTPReply.isPositiveCompletion(listActive(wildmat)))
945 | 0 |
                 return null;
946 | 0 |
             return __readNewsgroupListing();
947 |  |
         }
948 |  |
949 |  |
950 |  |
         /***
951 |  |
          * List all new newsgroups added to the NNTP server since a particular
952 |  |
          * date subject to the conditions of the specified query.  If no new
953 |  |
          * newsgroups were added, a zero length array will be returned.  If the
954 |  |
          * command fails, null will be returned.
955 |  |
          * <p>
956 |  |
          * @param query  The query restricting how to search for new newsgroups.
957 |  |
          * @return An array of NewsgroupInfo instances containing the information
958 |  |
          *    for each new newsgroup added to the NNTP server.   If no newsgroups
959 |  |
          *    were added, a zero length array will be returned.  If the command
960 |  |
          *    fails, null will be returned.
961 |  |
          * @exception NNTPConnectionClosedException
962 |  |
          *      If the NNTP server prematurely closes the connection as a result
963 |  |
          *      of the client being idle or some other reason causing the server
964 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
965 |  |
          *      as an IOException or independently as itself.
966 |  |
          * @exception IOException  If an I/O error occurs while either sending a
967 |  |
          *      command to the server or receiving a reply from the server.
968 |  |
          ***/
969 |  |
         public NewsgroupInfo[] listNewNewsgroups(NewGroupsOrNewsQuery query)
970 |  |
         throws IOException
971 |  |
         {
972 | 0 |
             if (!NNTPReply.isPositiveCompletion(newgroups(
973 |  |
                                                     query.getDate(), query.getTime(),
974 |  |
                                                     query.isGMT(), query.getDistributions())))
975 | 0 |
                 return null;
976 |  |
977 | 0 |
             return __readNewsgroupListing();
978 |  |
         }
979 |  |
980 |  |
981 |  |
         /***
982 |  |
          * List all new articles added to the NNTP server since a particular
983 |  |
          * date subject to the conditions of the specified query.  If no new
984 |  |
          * new news is found, a zero length array will be returned.  If the
985 |  |
          * command fails, null will be returned.  You must add at least one
986 |  |
          * newsgroup to the query, else the command will fail.  Each String
987 |  |
          * in the returned array is a unique message identifier including the
988 |  |
          * enclosing &lt and &gt.
989 |  |
          * <p>
990 |  |
          * @param query  The query restricting how to search for new news.  You
991 |  |
          *    must add at least one newsgroup to the query.
992 |  |
          * @return An array of String instances containing the unique message
993 |  |
          *    identifiers for each new article added to the NNTP server.  If no
994 |  |
          *    new news is found, a zero length array will be returned.  If the
995 |  |
          *    command fails, null will be returned.
996 |  |
          * @exception NNTPConnectionClosedException
997 |  |
          *      If the NNTP server prematurely closes the connection as a result
998 |  |
          *      of the client being idle or some other reason causing the server
999 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
1000 |  |
          *      as an IOException or independently as itself.
1001 |  |
          * @exception IOException  If an I/O error occurs while either sending a
1002 |  |
          *      command to the server or receiving a reply from the server.
1003 |  |
          ***/
1004 |  |
         public String[] listNewNews(NewGroupsOrNewsQuery query)
1005 |  |
         throws IOException
1006 |  |
         {
1007 |  |
             int size;
1008 |  |
             String line;
1009 |  |
             Vector list;
1010 |  |
             String[] result;
1011 |  |
             BufferedReader reader;
1012 |  |
1013 | 0 |
             if (!NNTPReply.isPositiveCompletion(newnews(
1014 |  |
                                                     query.getNewsgroups(), query.getDate(), query.getTime(),
1015 |  |
                                                     query.isGMT(), query.getDistributions())))
1016 | 0 |
                 return null;
1017 |  |
1018 | 0 |
             list = new Vector();
1019 | 0 |
             reader = new BufferedReader(class="keyword">new DotTerminatedMessageReader(_reader_));
1020 |  |
1021 | 0 |
             while ((line = reader.readLine()) != null)
1022 | 0 |
                 list.addElement(line);
1023 |  |
1024 | 0 |
             size = list.size();
1025 |  |
1026 | 0 |
             if (size < 1)
1027 | 0 |
                 return new String[0];
1028 |  |
1029 | 0 |
             result = new String[size];
1030 | 0 |
             list.copyInto(result);
1031 |  |
1032 | 0 |
             return result;
1033 |  |
         }
1034 |  |
1035 |  |
         /***
1036 |  |
          * There are a few NNTPClient methods that do not complete the
1037 |  |
          * entire sequence of NNTP commands to complete a transaction.  These
1038 |  |
          * commands require some action by the programmer after the reception
1039 |  |
          * of a positive preliminary command.  After the programmer's code
1040 |  |
          * completes its actions, it must call this method to receive
1041 |  |
          * the completion reply from the server and verify the success of the
1042 |  |
          * entire transaction.
1043 |  |
          * <p>
1044 |  |
          * For example
1045 |  |
          * <pre>
1046 |  |
          * writer = client.postArticle();
1047 |  |
          * if(writer == null) // failure
1048 |  |
          *   return false;
1049 |  |
          * header = new SimpleNNTPHeader("foobar@foo.com", "Just testing");
1050 |  |
          * header.addNewsgroup("alt.test");
1051 |  |
          * writer.write(header.toString());
1052 |  |
          * writer.write("This is just a test");
1053 |  |
          * writer.close();
1054 |  |
          * if(!client.completePendingCommand()) // failure
1055 |  |
          *   return false;
1056 |  |
          * </pre>
1057 |  |
          * <p>
1058 |  |
          * @return True if successfully completed, false if not.
1059 |  |
          * @exception NNTPConnectionClosedException
1060 |  |
          *      If the NNTP server prematurely closes the connection as a result
1061 |  |
          *      of the client being idle or some other reason causing the server
1062 |  |
          *      to send NNTP reply code 400.  This exception may be caught either
1063 |  |
          *      as an IOException or independently as itself.
1064 |  |
          * @exception IOException  If an I/O error occurs while either sending a
1065 |  |
          *      command to the server or receiving a reply from the server.
1066 |  |
          ***/
1067 |  |
         public boolean completePendingCommand() throws IOException
1068 |  |
         {
1069 | 0 |
             return NNTPReply.isPositiveCompletion(getReply());
1070 |  |
         }
1071 |  |
1072 |  |
         /***
1073 |  |
          * Post an article to the NNTP server.  This method returns a
1074 |  |
          * DotTerminatedMessageWriter instance to which the article can be
1075 |  |
          * written.  Null is returned if the posting attempt fails.  You
1076 |  |
          * should check {@link NNTP#isAllowedToPost isAllowedToPost() }
1077 |  |
          *  before trying to post.  However, a posting
1078 |  |
          * attempt can fail due to malformed headers.
1079 |  |
          * <p>
1080 |  |
          * You must not issue any commands to the NNTP server (i.e., call any
1081 |  |
          * (other methods) until you finish writing to the returned Writer
1082 |  |
          * instance and close it.  The NNTP protocol uses the same stream for
1083 |  |
          * issuing commands as it does for returning results.  Therefore the
1084 |  |
          * returned Writer actually writes directly to the NNTP connection.
1085 |  |
          * After you close the writer, you can execute new commands.  If you
1086 |  |
          * do not follow these requirements your program will not work properly.
1087 |  |
          * <p>
1088 |  |
          * Different NNTP servers will require different header formats, but
1089 |  |
          * you can use the provided
1090 |  |
          * {@link org.apache.commons.net.nntp.SimpleNNTPHeader}
1091 |  |
          * class to construct the bare minimum acceptable header for most
1092 |  |
          * news readers.  To construct more complicated headers you should
1093 |  |
          * refer to RFC 822.  When the Java Mail API is finalized, you will be
1094 |  |
          * able to use it to compose fully compliant Internet text messages.
1095 |  |
          * The DotTerminatedMessageWriter takes care of doubling line-leading
1096 |  |
          * dots and ending the message with a single dot upon closing, so all
1097 |  |
          * you have to worry about is writing the header and the message.
1098 |  |
          * <p>
1099 |  |
          * Upon closing the returned Writer, you need to call
1100 |  |
          * {@link #completePendingCommand  completePendingCommand() }
1101 |  |
          * to finalize the posting and verify its success or failure from
1102 |  |
          * the server reply.
1103 |  |
          * <p>
1104 |  |
          * @return A DotTerminatedMessageWriter to which the article (including
1105 |  |
          *      header) can be written.  Returns null if the command fails.
1106 |  |
          * @exception IOException  If an I/O error occurs while either sending a
1107 |  |
          *      command to the server or receiving a reply from the server.
1108 |  |
          ***/
1109 |  |
1110 |  |
         public Writer postArticle() throws IOException
1111 |  |
         {
1112 | 0 |
             if (!NNTPReply.isPositiveIntermediate(post()))
1113 | 0 |
                 return null;
1114 |  |
1115 | 0 |
             return new DotTerminatedMessageWriter(_writer_);
1116 |  |
         }
1117 |  |
1118 |  |
1119 |  |
         public Writer forwardArticle(String articleId) throws IOException
1120 |  |
         {
1121 | 0 |
             if (!NNTPReply.isPositiveIntermediate(ihave(articleId)))
1122 | 0 |
                 return null;
1123 |  |
1124 | 0 |
             return new DotTerminatedMessageWriter(_writer_);
1125 |  |
         }
1126 |  |
1127 |  |
1128 |  |
         /***
1129 |  |
          * Logs out of the news server gracefully by sending the QUIT command.
1130 |  |
          * However, you must still disconnect from the server before you can open
1131 |  |
          * a new connection.
1132 |  |
          * <p>
1133 |  |
          * @return True if successfully completed, false if not.
1134 |  |
          * @exception IOException  If an I/O error occurs while either sending a
1135 |  |
          *      command to the server or receiving a reply from the server.
1136 |  |
          ***/
1137 |  |
         public boolean logout() throws IOException
1138 |  |
         {
1139 | 0 |
             return NNTPReply.isPositiveCompletion(quit());
1140 |  |
         }
1141 |  |
1142 |  |
1143 |  |
         /**
1144 |  |
          * Log into a news server by sending the AUTHINFO USER/AUTHINFO
1145 |  |
          * PASS command sequence. This is usually sent in response to a
1146 |  |
          * 480 reply code from the NNTP server.
1147 |  |
          * <p>
1148 |  |
          * @param username a valid username
1149 |  |
          * @param password the corresponding password
1150 |  |
          * @return True for successful login, false for a failure
1151 |  |
          * @throws IOException
1152 |  |
          */
1153 |  |
         public boolean authenticate(String username, String password)
1154 |  |
             throws IOException
1155 |  |
         {
1156 | 0 |
             int replyCode = authinfoUser(username);
1157 |  |
1158 | 0 |
             if (replyCode == NNTPReply.MORE_AUTH_INFO_REQUIRED)
1159 |  |
                 {
1160 | 0 |
                     replyCode = authinfoPass(password);
1161 |  |
1162 | 0 |
                     if (replyCode == NNTPReply.AUTHENTICATION_ACCEPTED)
1163 |  |
                         {
1164 | 0 |
                             _isAllowedToPost = true;
1165 | 0 |
                             return true;
1166 |  |
                         }
1167 |  |
                 }
1168 | 0 |
             return false;
1169 |  |
         }
1170 |  |
1171 |  |
         /***
1172 |  |
          * Private implementation of XOVER functionality.
1173 |  |
          *
1174 |  |
          * See {@link NNTP#xover}
1175 |  |
          * for legal agument formats. Alternatively, read RFC 2980 :-)
1176 |  |
          * <p>
1177 |  |
          * @param articleRange
1178 |  |
          * @return Returns a DotTerminatedMessageReader if successful, null
1179 |  |
          *         otherwise
1180 |  |
          * @exception IOException
1181 |  |
          */
1182 |  |
         private Reader __retrieveArticleInfo(String articleRange)
1183 |  |
             throws IOException
1184 |  |
         {
1185 | 0 |
             if (!NNTPReply.isPositiveCompletion(xover(articleRange)))
1186 | 0 |
                 return null;
1187 |  |
1188 | 0 |
             return new DotTerminatedMessageReader(_reader_);
1189 |  |
         }
1190 |  |
1191 |  |
         /**
1192 |  |
          * Return article headers for a specified post.
1193 |  |
          * <p>
1194 |  |
          * @param articleNumber the article to retrieve headers for
1195 |  |
          * @return a DotTerminatedReader if successful, null otherwise
1196 |  |
          * @throws IOException
1197 |  |
          */
1198 |  |
         public Reader retrieveArticleInfo(int articleNumber) throws IOException
1199 |  |
         {
1200 | 0 |
             return __retrieveArticleInfo(Integer.toString(articleNumber));
1201 |  |
         }
1202 |  |
1203 |  |
         /**
1204 |  |
          * Return article headers for all articles between lowArticleNumber
1205 |  |
          * and highArticleNumber, inclusively.
1206 |  |
          * <p>
1207 |  |
          * @param lowArticleNumber
1208 |  |
          * @param highArticleNumber
1209 |  |
          * @return a DotTerminatedReader if successful, null otherwise
1210 |  |
          * @throws IOException
1211 |  |
          */
1212 |  |
         public Reader retrieveArticleInfo(int lowArticleNumber,
1213 |  |
                                           int highArticleNumber)
1214 |  |
             throws IOException
1215 |  |
         {
1216 | 0 |
             return
1217 |  |
                 __retrieveArticleInfo(new String(lowArticleNumber + "-" +
1218 |  |
                                                  highArticleNumber));
1219 |  |
         }
1220 |  |
1221 |  |
         /***
1222 |  |
          * Private implementation of XHDR functionality.
1223 |  |
          *
1224 |  |
          * See {@link NNTP#xhdr}
1225 |  |
          * for legal agument formats. Alternatively, read RFC 1036.
1226 |  |
          * <p>
1227 |  |
          * @param header
1228 |  |
          * @param articleRange
1229 |  |
          * @return Returns a DotTerminatedMessageReader if successful, null
1230 |  |
          *         otherwise
1231 |  |
          * @exception IOException
1232 |  |
          */
1233 |  |
         private Reader __retrieveHeader(String header, String articleRange)
1234 |  |
             throws IOException
1235 |  |
         {
1236 | 0 |
             if (!NNTPReply.isPositiveCompletion(xhdr(header, articleRange)))
1237 | 0 |
                 return null;
1238 |  |
1239 | 0 |
             return new DotTerminatedMessageReader(_reader_);
1240 |  |
         }
1241 |  |
1242 |  |
         /**
1243 |  |
          * Return an article header for a specified post.
1244 |  |
          * <p>
1245 |  |
          * @param header the header to retrieve
1246 |  |
          * @param articleNumber the article to retrieve the header for
1247 |  |
          * @return a DotTerminatedReader if successful, null otherwise
1248 |  |
          * @throws IOException
1249 |  |
          */
1250 |  |
         public Reader retrieveHeader(String header, int articleNumber)
1251 |  |
             throws IOException
1252 |  |
         {
1253 | 0 |
             return __retrieveHeader(header, Integer.toString(articleNumber));
1254 |  |
         }
1255 |  |
1256 |  |
         /**
1257 |  |
          * Return an article header for all articles between lowArticleNumber
1258 |  |
          * and highArticleNumber, inclusively.
1259 |  |
          * <p>
1260 |  |
          * @param header
1261 |  |
          * @param lowArticleNumber
1262 |  |
          * @param highArticleNumber
1263 |  |
          * @return a DotTerminatedReader if successful, null otherwise
1264 |  |
          * @throws IOException
1265 |  |
          */
1266 |  |
         public Reader retrieveHeader(String header, int lowArticleNumber,
1267 |  |
                                      int highArticleNumber)
1268 |  |
             throws IOException
1269 |  |
         {
1270 | 0 |
             return
1271 |  |
                 __retrieveHeader(header,
1272 |  |
                                  new String(lowArticleNumber + "-" +
1273 |  |
                                             highArticleNumber));
1274 |  |
         }
1275 |  |
     }
1276 |  |
1277 |  |
1278 |  |
     /* Emacs configuration
1279 |  |
      * Local variables:        **
1280 |  |
      * mode:             java  **
1281 |  |
      * c-basic-offset:   4     **
1282 |  |
      * indent-tabs-mode: nil   **
1283 |  |
      * End:                    **
1284 |  |
      */

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.