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.