View Javadoc

    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.BufferedWriter;
    20  import java.io.IOException;
    21  import java.io.InputStreamReader;
    22  import java.io.OutputStreamWriter;
    23  import org.apache.commons.net.MalformedServerReplyException;
    24  import org.apache.commons.net.ProtocolCommandSupport;
    25  import org.apache.commons.net.ProtocolCommandListener;
    26  import org.apache.commons.net.SocketClient;
    27
    28  /****
    29   * The NNTP class is not meant to be used by itself and is provided
    30   * only so that you may easily implement your own NNTP client if
    31   * you so desire.  If you have no need to perform your own implementation,
    32   * you should use {@link org.apache.commons.net.nntp.NNTPClient}.
    33   * The NNTP class is made public to provide access to various NNTP constants
    34   * and to make it easier for adventurous programmers (or those with special
    35   * needs) to interact with the NNTP protocol and implement their own clients.
    36   * A set of methods with names corresponding to the NNTP command names are
    37   * provided to facilitate this interaction.
    38   * <p>
    39   * You should keep in mind that the NNTP server may choose to prematurely
    40   * close a connection if the client has been idle for longer than a
    41   * given time period or if the server is being shutdown by the operator or
    42   * some other reason.  The NNTP class will detect a
    43   * premature NNTP server connection closing when it receives a
    44   * {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED }
    45   *  response to a command.
    46   * When that occurs, the NNTP class method encountering that reply will throw
    47   * an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
    48   * .
    49   * <code>NNTPConectionClosedException</code>
    50   * is a subclass of <code> IOException </code> and therefore need not be
    51   * caught separately, but if you are going to catch it separately, its
    52   * catch block must appear before the more general <code> IOException </code>
    53   * catch block.  When you encounter an
    54   * {@link org.apache.commons.net.nntp.NNTPConnectionClosedException}
    55   * , you must disconnect the connection with
    56   * {@link #disconnect  disconnect() } to properly clean up the
    57   * system resources used by NNTP.  Before disconnecting, you may check the
    58   * last reply code and text with
    59   * {@link #getReplyCode  getReplyCode } and
    60   * {@link #getReplyString  getReplyString }.
    61   * <p>
    62   * Rather than list it separately for each method, we mention here that
    63   * every method communicating with the server and throwing an IOException
    64   * can also throw a
    65   * {@link org.apache.commons.net.MalformedServerReplyException}
    66   * , which is a subclass
    67   * of IOException.  A MalformedServerReplyException will be thrown when
    68   * the reply received from the server deviates enough from the protocol
    69   * specification that it cannot be interpreted in a useful manner despite
    70   * attempts to be as lenient as possible.
    71   * <p>
    72   * <p>
    73   * @author Daniel F. Savarese
    74   * @author Rory Winston
    75   * @author Ted Wise
    76   * @see NNTPClient
    77   * @see NNTPConnectionClosedException
    78   * @see org.apache.commons.net.MalformedServerReplyException
    79   ***/
    80
    81  public class NNTP extends SocketClient
    82  {
    83      /**** The default NNTP port.  Its value is 119 according to RFC 977. ***/
    84      public static final int DEFAULT_PORT = 119;
    85
    86      // We have to ensure that the protocol communication is in ASCII
    87      // but we use ISO-8859-1 just in case 8-bit characters cross
    88      // the wire.
    89      private static final String __DEFAULT_ENCODING = "ISO-8859-1";
    90
    91      private StringBuffer __commandBuffer;
    92
    93      boolean _isAllowedToPost;
    94      int _replyCode;
    95      String _replyString;
    96
    97      /***
    98       * Wraps {@link SocketClient#_input_}
    99       * to communicate with server.  Initialized by {@link #_connectAction_}.
    100      * All server reads should be done through this variable.
    101      */
    102     protected BufferedReader _reader_;
    103
    104     /***
    105      * Wraps {@link SocketClient#_output_}
    106      * to communicate with server.  Initialized by {@link #_connectAction_}.
    107      * All server reads should be done through this variable.
    108      */
    109     protected BufferedWriter _writer_;
    110
    111     /****
    112      * A ProtocolCommandSupport object used to manage the registering of
    113      * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
    114      ***/
    115     protected ProtocolCommandSupport _commandSupport_;
    116
    117     /****
    118      * The default NNTP constructor.  Sets the default port to
    119      * <code>DEFAULT_PORT</code> and initializes internal data structures
    120      * for saving NNTP reply information.
    121      ***/
    122     public NNTP()
    123     {
    124         setDefaultPort(DEFAULT_PORT);
    125         __commandBuffer = new StringBuffer();
    126         _replyString = null;
    127         _reader_ = null;
    128         _writer_ = null;
    129         _isAllowedToPost = false;
    130         _commandSupport_ = new ProtocolCommandSupport(this);
    131     }
    132
    133     private void __getReply() throws IOException
    134     {
    135         _replyString = _reader_.readLine();
    136
    137         if (_replyString == null)
    138             throw new NNTPConnectionClosedException(
    139                 "Connection closed without indication.");
    140
    141         // In case we run into an anomaly we don't want fatal index exceptions
    142         // to be thrown.
    143         if (_replyString.length() < 3)
    144             throw new MalformedServerReplyException(
    145                 "Truncated server reply: " + _replyString);
    146         try
    147         {
    148             _replyCode = Integer.parseInt(_replyString.substring(0, 3));
    149         }
    150         catch (NumberFormatException e)
    151         {
    152             throw new MalformedServerReplyException(
    153                 "Could not parse response code.\nServer Reply: " + _replyString);
    154         }
    155
    156         if (_commandSupport_.getListenerCount() > 0)
    157             _commandSupport_.fireReplyReceived(_replyCode, _replyString +
    158                                                SocketClient.NETASCII_EOL);
    159
    160         if (_replyCode == NNTPReply.SERVICE_DISCONTINUED)
    161             throw new NNTPConnectionClosedException(
    162                 "NNTP response 400 received.  Server closed connection.");
    163     }
    164
    165     /****
    166      * Initiates control connections and gets initial reply, determining
    167      * if the client is allowed to post to the server.  Initializes
    168      * {@link #_reader_} and {@link #_writer_} to wrap
    169      * {@link SocketClient#_input_} and {@link SocketClient#_output_}.
    170      ***/
    171     protected void _connectAction_() throws IOException
    172     {
    173         super._connectAction_();
    174         _reader_ =
    175             new BufferedReader(new InputStreamReader(_input_,
    176                                                      __DEFAULT_ENCODING));
    177         _writer_ =
    178             new BufferedWriter(new OutputStreamWriter(_output_,
    179                                                       __DEFAULT_ENCODING));
    180         __getReply();
    181
    182         _isAllowedToPost = (_replyCode == NNTPReply.SERVER_READY_POSTING_ALLOWED);
    183     }
    184
    185     /****
    186      * Adds a ProtocolCommandListener.  Delegates this task to
    187      * {@link #_commandSupport_  _commandSupport_ }.
    188      * <p>
    189      * @param listener  The ProtocolCommandListener to add.
    190      ***/
    191     public void addProtocolCommandListener(ProtocolCommandListener listener)
    192     {
    193         _commandSupport_.addProtocolCommandListener(listener);
    194     }
    195
    196     /****
    197      * Removes a ProtocolCommandListener.  Delegates this task to
    198      * {@link #_commandSupport_  _commandSupport_ }.
    199      * <p>
    200      * @param listener  The ProtocolCommandListener to remove.
    201      ***/
    202     public void removeProtocolCommandListener(ProtocolCommandListener listener)
    203     {
    204         _commandSupport_.removeProtocolCommandListener(listener);
    205     }
    206
    207     /****
    208      * Closes the connection to the NNTP server and sets to null
    209      * some internal data so that the memory may be reclaimed by the
    210      * garbage collector.  The reply text and code information from the
    211      * last command is voided so that the memory it used may be reclaimed.
    212      * <p>
    213      * @exception IOException If an error occurs while disconnecting.
    214      ***/
    215     public void disconnect() throws IOException
    216     {
    217         super.disconnect();
    218         _reader_ = null;
    219         _writer_ = null;
    220         _replyString = null;
    221         _isAllowedToPost = false;
    222     }
    223
    224
    225     /****
    226      * Indicates whether or not the client is allowed to post articles to
    227      * the server it is currently connected to.
    228      * <p>
    229      * @return True if the client can post articles to the server, false
    230      *         otherwise.
    231      ***/
    232     public boolean isAllowedToPost()
    233     {
    234         return _isAllowedToPost;
    235     }
    236
    237
    238     /****
    239      * Sends an NNTP command to the server, waits for a reply and returns the
    240      * numerical response code.  After invocation, for more detailed
    241      * information, the actual reply text can be accessed by calling
    242      * {@link #getReplyString  getReplyString }.
    243      * <p>
    244      * @param command  The text representation of the  NNTP command to send.
    245      * @param args The arguments to the NNTP command.  If this parameter is
    246      *             set to null, then the command is sent with no argument.
    247      * @return The integer value of the NNTP reply code returned by the server
    248      *         in response to the command.
    249      * @exception NNTPConnectionClosedException
    250      *      If the NNTP server prematurely closes the connection as a result
    251      *      of the client being idle or some other reason causing the server
    252      *      to send NNTP reply code 400.  This exception may be caught either
    253      *      as an IOException or independently as itself.
    254      * @exception IOException  If an I/O error occurs while either sending the
    255      *      command or receiving the server reply.
    256      ***/
    257     public int sendCommand(String command, String args) throws IOException
    258     {
    259         String message;
    260
    261         __commandBuffer.setLength(0);
    262         __commandBuffer.append(command);
    263
    264         if (args != null)
    265         {
    266             __commandBuffer.append(' ');
    267             __commandBuffer.append(args);
    268         }
    269         __commandBuffer.append(SocketClient.NETASCII_EOL);
    270
    271         _writer_.write(message = __commandBuffer.toString());
    272         _writer_.flush();
    273
    274         if (_commandSupport_.getListenerCount() > 0)
    275             _commandSupport_.fireCommandSent(command, message);
    276
    277         __getReply();
    278         return _replyCode;
    279     }
    280
    281
    282     /****
    283      * Sends an NNTP command to the server, waits for a reply and returns the
    284      * numerical response code.  After invocation, for more detailed
    285      * information, the actual reply text can be accessed by calling
    286      * {@link #getReplyString  getReplyString }.
    287      * <p>
    288      * @param command  The NNTPCommand constant corresponding to the NNTP command
    289      *                 to send.
    290      * @param args The arguments to the NNTP command.  If this parameter is
    291      *             set to null, then the command is sent with no argument.
    292      * @return The integer value of the NNTP reply code returned by the server
    293      *         in response to the command.
    294      *         in response to the command.
    295      * @exception NNTPConnectionClosedException
    296      *      If the NNTP server prematurely closes the connection as a result
    297      *      of the client being idle or some other reason causing the server
    298      *      to send NNTP reply code 400.  This exception may be caught either
    299      *      as an IOException or independently as itself.
    300      * @exception IOException  If an I/O error occurs while either sending the
    301      *      command or receiving the server reply.
    302      ***/
    303     public int sendCommand(int command, String args) throws IOException
    304     {
    305         return sendCommand(NNTPCommand._commands[command], args);
    306     }
    307
    308
    309     /****
    310      * Sends an NNTP command with no arguments to the server, waits for a
    311      * reply and returns the numerical response code.  After invocation, for
    312      * more detailed information, the actual reply text can be accessed by
    313      * calling {@link #getReplyString  getReplyString }.
    314      * <p>
    315      * @param command  The text representation of the  NNTP command to send.
    316      * @return The integer value of the NNTP reply code returned by the server
    317      *         in response to the command.
    318      *         in response to the command.
    319      * @exception NNTPConnectionClosedException
    320      *      If the NNTP server prematurely closes the connection as a result
    321      *      of the client being idle or some other reason causing the server
    322      *      to send NNTP reply code 400.  This exception may be caught either
    323      *      as an IOException or independently as itself.
    324      * @exception IOException  If an I/O error occurs while either sending the
    325      *      command or receiving the server reply.
    326      ***/
    327     public int sendCommand(String command) throws IOException
    328     {
    329         return sendCommand(command, null);
    330     }
    331
    332
    333     /****
    334      * Sends an NNTP command with no arguments to the server, waits for a
    335      * reply and returns the numerical response code.  After invocation, for
    336      * more detailed information, the actual reply text can be accessed by
    337      * calling {@link #getReplyString  getReplyString }.
    338      * <p>
    339      * @param command  The NNTPCommand constant corresponding to the NNTP command
    340      *                 to send.
    341      * @return The integer value of the NNTP reply code returned by the server
    342      *         in response to the command.
    343      *         in response to the command.
    344      * @exception NNTPConnectionClosedException
    345      *      If the NNTP server prematurely closes the connection as a result
    346      *      of the client being idle or some other reason causing the server
    347      *      to send NNTP reply code 400.  This exception may be caught either
    348      *      as an IOException or independently as itself.
    349      * @exception IOException  If an I/O error occurs while either sending the
    350      *      command or receiving the server reply.
    351      ***/
    352     public int sendCommand(int command) throws IOException
    353     {
    354         return sendCommand(command, null);
    355     }
    356
    357
    358     /****
    359      * Returns the integer value of the reply code of the last NNTP reply.
    360      * You will usually only use this method after you connect to the
    361      * NNTP server to check that the connection was successful since
    362      * <code> connect </code> is of type void.
    363      * <p>
    364      * @return The integer value of the reply code of the last NNTP reply.
    365      ***/
    366     public int getReplyCode()
    367     {
    368         return _replyCode;
    369     }
    370
    371     /****
    372      * Fetches a reply from the NNTP server and returns the integer reply
    373      * code.  After calling this method, the actual reply text can be accessed
    374      * from {@link #getReplyString  getReplyString }.  Only use this
    375      * method if you are implementing your own NNTP client or if you need to
    376      * fetch a secondary response from the NNTP server.
    377      * <p>
    378      * @return The integer value of the reply code of the fetched NNTP reply.
    379      *         in response to the command.
    380      * @exception NNTPConnectionClosedException
    381      *      If the NNTP server prematurely closes the connection as a result
    382      *      of the client being idle or some other reason causing the server
    383      *      to send NNTP reply code 400.  This exception may be caught either
    384      *      as an IOException or independently as itself.
    385      * @exception IOException  If an I/O error occurs while
    386      *      receiving the server reply.
    387      ***/
    388     public int getReply() throws IOException
    389     {
    390         __getReply();
    391         return _replyCode;
    392     }
    393
    394
    395     /****
    396      * Returns the entire text of the last NNTP server response exactly
    397      * as it was received, not including the end of line marker.
    398      * <p>
    399      * @return The entire text from the last NNTP response as a String.
    400      ***/
    401     public String getReplyString()
    402     {
    403         return _replyString;
    404     }
    405
    406
    407     /****
    408      * A convenience method to send the NNTP ARTICLE command to the server,
    409      * receive the initial reply, and return the reply code.
    410      * <p>
    411      * @param messageId  The message identifier of the requested article,
    412      *                   including the encapsulating &lt and &gt characters.
    413      * @return The reply code received from the server.
    414      * @exception NNTPConnectionClosedException
    415      *      If the NNTP server prematurely closes the connection as a result
    416      *      of the client being idle or some other reason causing the server
    417      *      to send NNTP reply code 400.  This exception may be caught either
    418      *      as an IOException or independently as itself.
    419      * @exception IOException  If an I/O error occurs while either sending the
    420      *      command or receiving the server reply.
    421      ***/
    422     public int article(String messageId) throws IOException
    423     {
    424         return sendCommand(NNTPCommand.ARTICLE, messageId);
    425     }
    426
    427     /****
    428      * A convenience method to send the NNTP ARTICLE command to the server,
    429      * receive the initial reply, and return the reply code.
    430      * <p>
    431      * @param articleNumber The number of the article to request from the
    432      *                      currently selected newsgroup.
    433      * @return The reply code received from the server.
    434      * @exception NNTPConnectionClosedException
    435      *      If the NNTP server prematurely closes the connection as a result
    436      *      of the client being idle or some other reason causing the server
    437      *      to send NNTP reply code 400.  This exception may be caught either
    438      *      as an IOException or independently as itself.
    439      * @exception IOException  If an I/O error occurs while either sending the
    440      *      command or receiving the server reply.
    441      ***/
    442     public int article(int articleNumber) throws IOException
    443     {
    444         return sendCommand(NNTPCommand.ARTICLE, Integer.toString(articleNumber));
    445     }
    446
    447     /****
    448      * A convenience method to send the NNTP ARTICLE command to the server,
    449      * receive the initial reply, and return the reply code.
    450      * <p>
    451      * @return The reply code received from the server.
    452      * @exception NNTPConnectionClosedException
    453      *      If the NNTP server prematurely closes the connection as a result
    454      *      of the client being idle or some other reason causing the server
    455      *      to send NNTP reply code 400.  This exception may be caught either
    456      *      as an IOException or independently as itself.
    457      * @exception IOException  If an I/O error occurs while either sending the
    458      *      command or receiving the server reply.
    459      ***/
    460     public int article() throws IOException
    461     {
    462         return sendCommand(NNTPCommand.ARTICLE);
    463     }
    464
    465
    466
    467     /****
    468      * A convenience method to send the NNTP BODY command to the server,
    469      * receive the initial reply, and return the reply code.
    470      * <p>
    471      * @param messageId  The message identifier of the requested article,
    472      *                   including the encapsulating &lt and &gt characters.
    473      * @return The reply code received from the server.
    474      * @exception NNTPConnectionClosedException
    475      *      If the NNTP server prematurely closes the connection as a result
    476      *      of the client being idle or some other reason causing the server
    477      *      to send NNTP reply code 400.  This exception may be caught either
    478      *      as an IOException or independently as itself.
    479      * @exception IOException  If an I/O error occurs while either sending the
    480      *      command or receiving the server reply.
    481      ***/
    482     public int body(String messageId) throws IOException
    483     {
    484         return sendCommand(NNTPCommand.BODY, messageId);
    485     }
    486
    487     /****
    488      * A convenience method to send the NNTP BODY command to the server,
    489      * receive the initial reply, and return the reply code.
    490      * <p>
    491      * @param articleNumber The number of the article to request from the
    492      *                      currently selected newsgroup.
    493      * @return The reply code received from the server.
    494      * @exception NNTPConnectionClosedException
    495      *      If the NNTP server prematurely closes the connection as a result
    496      *      of the client being idle or some other reason causing the server
    497      *      to send NNTP reply code 400.  This exception may be caught either
    498      *      as an IOException or independently as itself.
    499      * @exception IOException  If an I/O error occurs while either sending the
    500      *      command or receiving the server reply.
    501      ***/
    502     public int body(int articleNumber) throws IOException
    503     {
    504         return sendCommand(NNTPCommand.BODY, Integer.toString(articleNumber));
    505     }
    506
    507     /****
    508      * A convenience method to send the NNTP BODY command to the server,
    509      * receive the initial reply, and return the reply code.
    510      * <p>
    511      * @return The reply code received from the server.
    512      * @exception NNTPConnectionClosedException
    513      *      If the NNTP server prematurely closes the connection as a result
    514      *      of the client being idle or some other reason causing the server
    515      *      to send NNTP reply code 400.  This exception may be caught either
    516      *      as an IOException or independently as itself.
    517      * @exception IOException  If an I/O error occurs while either sending the
    518      *      command or receiving the server reply.
    519      ***/
    520     public int body() throws IOException
    521     {
    522         return sendCommand(NNTPCommand.BODY);
    523     }
    524
    525
    526
    527     /****
    528      * A convenience method to send the NNTP HEAD command to the server,
    529      * receive the initial reply, and return the reply code.
    530      * <p>
    531      * @param messageId  The message identifier of the requested article,
    532      *                   including the encapsulating &lt and &gt characters.
    533      * @return The reply code received from the server.
    534      * @exception NNTPConnectionClosedException
    535      *      If the NNTP server prematurely closes the connection as a result
    536      *      of the client being idle or some other reason causing the server
    537      *      to send NNTP reply code 400.  This exception may be caught either
    538      *      as an IOException or independently as itself.
    539      * @exception IOException  If an I/O error occurs while either sending the
    540      *      command or receiving the server reply.
    541      ***/
    542     public int head(String messageId) throws IOException
    543     {
    544         return sendCommand(NNTPCommand.HEAD, messageId);
    545     }
    546
    547     /****
    548      * A convenience method to send the NNTP HEAD command to the server,
    549      * receive the initial reply, and return the reply code.
    550      * <p>
    551      * @param articleNumber The number of the article to request from the
    552      *                      currently selected newsgroup.
    553      * @return The reply code received from the server.
    554      * @exception NNTPConnectionClosedException
    555      *      If the NNTP server prematurely closes the connection as a result
    556      *      of the client being idle or some other reason causing the server
    557      *      to send NNTP reply code 400.  This exception may be caught either
    558      *      as an IOException or independently as itself.
    559      * @exception IOException  If an I/O error occurs while either sending the
    560      *      command or receiving the server reply.
    561      ***/
    562     public int head(int articleNumber) throws IOException
    563     {
    564         return sendCommand(NNTPCommand.HEAD, Integer.toString(articleNumber));
    565     }
    566
    567     /****
    568      * A convenience method to send the NNTP HEAD command to the server,
    569      * receive the initial reply, and return the reply code.
    570      * <p>
    571      * @return The reply code received from the server.
    572      * @exception NNTPConnectionClosedException
    573      *      If the NNTP server prematurely closes the connection as a result
    574      *      of the client being idle or some other reason causing the server
    575      *      to send NNTP reply code 400.  This exception may be caught either
    576      *      as an IOException or independently as itself.
    577      * @exception IOException  If an I/O error occurs while either sending the
    578      *      command or receiving the server reply.
    579      ***/
    580     public int head() throws IOException
    581     {
    582         return sendCommand(NNTPCommand.HEAD);
    583     }
    584
    585
    586
    587     /****
    588      * A convenience method to send the NNTP STAT command to the server,
    589      * receive the initial reply, and return the reply code.
    590      * <p>
    591      * @param messageId  The message identifier of the requested article,
    592      *                   including the encapsulating &lt and &gt characters.
    593      * @return The reply code received from the server.
    594      * @exception NNTPConnectionClosedException
    595      *      If the NNTP server prematurely closes the connection as a result
    596      *      of the client being idle or some other reason causing the server
    597      *      to send NNTP reply code 400.  This exception may be caught either
    598      *      as an IOException or independently as itself.
    599      * @exception IOException  If an I/O error occurs while either sending the
    600      *      command or receiving the server reply.
    601      ***/
    602     public int stat(String messageId) throws IOException
    603     {
    604         return sendCommand(NNTPCommand.STAT, messageId);
    605     }
    606
    607     /****
    608      * A convenience method to send the NNTP STAT command to the server,
    609      * receive the initial reply, and return the reply code.
    610      * <p>
    611      * @param articleNumber The number of the article to request from the
    612      *                      currently selected newsgroup.
    613      * @return The reply code received from the server.
    614      * @exception NNTPConnectionClosedException
    615      *      If the NNTP server prematurely closes the connection as a result
    616      *      of the client being idle or some other reason causing the server
    617      *      to send NNTP reply code 400.  This exception may be caught either
    618      *      as an IOException or independently as itself.
    619      * @exception IOException  If an I/O error occurs while either sending the
    620      *      command or receiving the server reply.
    621      ***/
    622     public int stat(int articleNumber) throws IOException
    623     {
    624         return sendCommand(NNTPCommand.STAT, Integer.toString(articleNumber));
    625     }
    626
    627     /****
    628      * A convenience method to send the NNTP STAT command to the server,
    629      * receive the initial reply, and return the reply code.
    630      * <p>
    631      * @return The reply code received from the server.
    632      * @exception NNTPConnectionClosedException
    633      *      If the NNTP server prematurely closes the connection as a result
    634      *      of the client being idle or some other reason causing the server
    635      *      to send NNTP reply code 400.  This exception may be caught either
    636      *      as an IOException or independently as itself.
    637      * @exception IOException  If an I/O error occurs while either sending the
    638      *      command or receiving the server reply.
    639      ***/
    640     public int stat() throws IOException
    641     {
    642         return sendCommand(NNTPCommand.STAT);
    643     }
    644
    645
    646     /****
    647      * A convenience method to send the NNTP GROUP command to the server,
    648      * receive the reply, and return the reply code.
    649      * <p>
    650      * @param newsgroup  The name of the newsgroup to select.
    651      * @return The reply code received from the server.
    652      * @exception NNTPConnectionClosedException
    653      *      If the NNTP server prematurely closes the connection as a result
    654      *      of the client being idle or some other reason causing the server
    655      *      to send NNTP reply code 400.  This exception may be caught either
    656      *      as an IOException or independently as itself.
    657      * @exception IOException  If an I/O error occurs while either sending the
    658      *      command or receiving the server reply.
    659      ***/
    660     public int group(String newsgroup) throws IOException
    661     {
    662         return sendCommand(NNTPCommand.GROUP, newsgroup);
    663     }
    664
    665
    666     /****
    667      * A convenience method to send the NNTP HELP command to the server,
    668      * receive the reply, and return the reply code.
    669      * <p>
    670      * @return The reply code received from the server.
    671      * @exception NNTPConnectionClosedException
    672      *      If the NNTP server prematurely closes the connection as a result
    673      *      of the client being idle or some other reason causing the server
    674      *      to send NNTP reply code 400.  This exception may be caught either
    675      *      as an IOException or independently as itself.
    676      * @exception IOException  If an I/O error occurs while either sending the
    677      *      command or receiving the server reply.
    678      ***/
    679     public int help() throws IOException
    680     {
    681         return sendCommand(NNTPCommand.HELP);
    682     }
    683
    684
    685     /****
    686      * A convenience method to send the NNTP IHAVE command to the server,
    687      * receive the reply, and return the reply code.
    688      * <p>
    689      * @param messageId  The article identifier,
    690      *                   including the encapsulating &lt and &gt characters.
    691      * @return The reply code received from the server.
    692      * @exception NNTPConnectionClosedException
    693      *      If the NNTP server prematurely closes the connection as a result
    694      *      of the client being idle or some other reason causing the server
    695      *      to send NNTP reply code 400.  This exception may be caught either
    696      *      as an IOException or independently as itself.
    697      * @exception IOException  If an I/O error occurs while either sending the
    698      *      command or receiving the server reply.
    699      ***/
    700     public int ihave(String messageId) throws IOException
    701     {
    702         return sendCommand(NNTPCommand.IHAVE, messageId);
    703     }
    704
    705
    706     /****
    707      * A convenience method to send the NNTP LAST command to the server,
    708      * receive the reply, and return the reply code.
    709      * <p>
    710      * @return The reply code received from the server.
    711      * @exception NNTPConnectionClosedException
    712      *      If the NNTP server prematurely closes the connection as a result
    713      *      of the client being idle or some other reason causing the server
    714      *      to send NNTP reply code 400.  This exception may be caught either
    715      *      as an IOException or independently as itself.
    716      * @exception IOException  If an I/O error occurs while either sending the
    717      *      command or receiving the server reply.
    718      ***/
    719     public int last() throws IOException
    720     {
    721         return sendCommand(NNTPCommand.LAST);
    722     }
    723
    724
    725
    726     /****
    727      * A convenience method to send the NNTP LIST command to the server,
    728      * receive the reply, and return the reply code.
    729      * <p>
    730      * @return The reply code received from the server.
    731      * @exception NNTPConnectionClosedException
    732      *      If the NNTP server prematurely closes the connection as a result
    733      *      of the client being idle or some other reason causing the server
    734      *      to send NNTP reply code 400.  This exception may be caught either
    735      *      as an IOException or independently as itself.
    736      * @exception IOException  If an I/O error occurs while either sending the
    737      *      command or receiving the server reply.
    738      ***/
    739     public int list() throws IOException
    740     {
    741         return sendCommand(NNTPCommand.LIST);
    742     }
    743
    744
    745
    746     /****
    747      * A convenience method to send the NNTP NEXT command to the server,
    748      * receive the reply, and return the reply code.
    749      * <p>
    750      * @return The reply code received from the server.
    751      * @exception NNTPConnectionClosedException
    752      *      If the NNTP server prematurely closes the connection as a result
    753      *      of the client being idle or some other reason causing the server
    754      *      to send NNTP reply code 400.  This exception may be caught either
    755      *      as an IOException or independently as itself.
    756      * @exception IOException  If an I/O error occurs while either sending the
    757      *      command or receiving the server reply.
    758      ***/
    759     public int next() throws IOException
    760     {
    761         return sendCommand(NNTPCommand.NEXT);
    762     }
    763
    764
    765     /****
    766      * A convenience method to send the NNTP NEWGROUPS command to the server,
    767      * receive the reply, and return the reply code.
    768      * <p>
    769      * @param date The date after which to check for new groups.
    770      *             Date format is YYMMDD
    771      * @param time The time after which to check for new groups.
    772      *             Time format is HHMMSS using a 24-hour clock.
    773      * @param GMT  True if the time is in GMT, false if local server time.
    774      * @param distributions  Comma-separated distribution list to check for
    775      *            new groups. Set to null if no distributions.
    776      * @return The reply code received from the server.
    777      * @exception NNTPConnectionClosedException
    778      *      If the NNTP server prematurely closes the connection as a result
    779      *      of the client being idle or some other reason causing the server
    780      *      to send NNTP reply code 400.  This exception may be caught either
    781      *      as an IOException or independently as itself.
    782      * @exception IOException  If an I/O error occurs while either sending the
    783      *      command or receiving the server reply.
    784      ***/
    785     public int newgroups(String date, String time, boolean GMT,
    786                          String distributions) throws IOException
    787     {
    788         StringBuffer buffer = new StringBuffer();
    789
    790         buffer.append(date);
    791         buffer.append(' ');
    792         buffer.append(time);
    793
    794         if (GMT)
    795         {
    796             buffer.append(' ');
    797             buffer.append("GMT");
    798         }
    799
    800         if (distributions != null)
    801         {
    802             buffer.append(" <");
    803             buffer.append(distributions);
    804             buffer.append('>');
    805         }
    806
    807         return sendCommand(NNTPCommand.NEWGROUPS, buffer.toString());
    808     }
    809
    810
    811     /****
    812      * A convenience method to send the NNTP NEWGROUPS command to the server,
    813      * receive the reply, and return the reply code.
    814      * <p>
    815      * @param newsgroups A comma-separated list of newsgroups to check for new
    816      *             news.
    817      * @param date The date after which to check for new news.
    818      *             Date format is YYMMDD
    819      * @param time The time after which to check for new news.
    820      *             Time format is HHMMSS using a 24-hour clock.
    821      * @param GMT  True if the time is in GMT, false if local server time.
    822      * @param distributions  Comma-separated distribution list to check for
    823      *            new news. Set to null if no distributions.
    824      * @return The reply code received from the server.
    825      * @exception NNTPConnectionClosedException
    826      *      If the NNTP server prematurely closes the connection as a result
    827      *      of the client being idle or some other reason causing the server
    828      *      to send NNTP reply code 400.  This exception may be caught either
    829      *      as an IOException or independently as itself.
    830      * @exception IOException  If an I/O error occurs while either sending the
    831      *      command or receiving the server reply.
    832      ***/
    833     public int newnews(String newsgroups, String date, String time, boolean GMT,
    834                        String distributions) throws IOException
    835     {
    836         StringBuffer buffer = new StringBuffer();
    837
    838         buffer.append(newsgroups);
    839         buffer.append(' ');
    840         buffer.append(date);
    841         buffer.append(' ');
    842         buffer.append(time);
    843
    844         if (GMT)
    845         {
    846             buffer.append(' ');
    847             buffer.append("GMT");
    848         }
    849
    850         if (distributions != null)
    851         {
    852             buffer.append(" <");
    853             buffer.append(distributions);
    854             buffer.append('>');
    855         }
    856
    857         return sendCommand(NNTPCommand.NEWNEWS, buffer.toString());
    858     }
    859
    860
    861
    862     /****
    863      * A convenience method to send the NNTP POST command to the server,
    864      * receive the reply, and return the reply code.
    865      * <p>
    866      * @return The reply code received from the server.
    867      * @exception NNTPConnectionClosedException
    868      *      If the NNTP server prematurely closes the connection as a result
    869      *      of the client being idle or some other reason causing the server
    870      *      to send NNTP reply code 400.  This exception may be caught either
    871      *      as an IOException or independently as itself.
    872      * @exception IOException  If an I/O error occurs while either sending the
    873      *      command or receiving the server reply.
    874      ***/
    875     public int post() throws IOException
    876     {
    877         return sendCommand(NNTPCommand.POST);
    878     }
    879
    880
    881
    882     /****
    883      * A convenience method to send the NNTP QUIT command to the server,
    884      * receive the reply, and return the reply code.
    885      * <p>
    886      * @return The reply code received from the server.
    887      * @exception NNTPConnectionClosedException
    888      *      If the NNTP server prematurely closes the connection as a result
    889      *      of the client being idle or some other reason causing the server
    890      *      to send NNTP reply code 400.  This exception may be caught either
    891      *      as an IOException or independently as itself.
    892      * @exception IOException  If an I/O error occurs while either sending the
    893      *      command or receiving the server reply.
    894      ***/
    895     public int quit() throws IOException
    896     {
    897         return sendCommand(NNTPCommand.QUIT);
    898     }
    899
    900     /****
    901      * A convenience method to send the AUTHINFO USER command to the server,
    902      *  receive the reply, and return the reply code. (See RFC 2980)
    903      * <p>
    904      * @param username A valid username.
    905      * @return The reply code received from the server. The server should
    906      *          return a 381 or 281 for this command.
    907      * @exception NNTPConnectionClosedException
    908      *      If the NNTP server prematurely closes the connection as a result
    909      *      of the client being idle or some other reason causing the server
    910      *      to send NNTP reply code 400.  This exception may be caught either
    911      *      as an IOException or independently as itself.
    912      * @exception IOException  If an I/O error occurs while either sending the
    913      *      command or receiving the server reply.
    914      ***/
    915     public int authinfoUser(String username) throws IOException {
    916         String userParameter = "USER " + username;
    917         return sendCommand(NNTPCommand.AUTHINFO, userParameter);
    918     }
    919
    920     /****
    921      * A convenience method to send the AUTHINFO PASS command to the server,
    922      * receive the reply, and return the reply code.  If this step is
    923      * required, it should immediately follow the AUTHINFO USER command
    924      * (See RFC 2980)
    925      * <p>
    926      * @param password a valid password.
    927      * @return The reply code received from the server. The server should
    928      *         return a 281 or 502 for this command.
    929      * @exception NNTPConnectionClosedException
    930      *      If the NNTP server prematurely closes the connection as a result
    931      *      of the client being idle or some other reason causing the server
    932      *      to send NNTP reply code 400.  This exception may be caught either
    933      *      as an IOException or independently as itself.
    934      * @exception IOException  If an I/O error occurs while either sending the
    935      *      command or receiving the server reply.
    936      ***/
    937     public int authinfoPass(String password) throws IOException {
    938         String passParameter = "PASS " + password;
    939         return sendCommand(NNTPCommand.AUTHINFO, passParameter);
    940     }
    941
    942     /****
    943      * A convenience method to send the NNTP XOVER command to the server,
    944      * receive the reply, and return the reply code.
    945      * <p>
    946      * @param selectedArticles a String representation of the range of
    947      * article headers required. This may be an article number, or a
    948      * range of article numbers in the form "XXXX-YYYY", where XXXX
    949      * and YYYY are valid article numbers in the current group.  It
    950      * also may be of the form "XXX-", meaning "return XXX and all
    951      * following articles" In this revision, the last format is not
    952      * possible (yet).
    953      * @return The reply code received from the server.
    954      * @exception NNTPConnectionClosedException
    955      *      If the NNTP server prematurely closes the connection as a result
    956      *      of the client being idle or some other reason causing the server
    957      *      to send NNTP reply code 400.  This exception may be caught either
    958      *      as an IOException or independently as itself.
    959      * @exception IOException  If an I/O error occurs while either sending the
    960      *      command or receiving the server reply.
    961      ***/
    962     public int xover(String selectedArticles) throws IOException {
    963         return sendCommand(NNTPCommand.XOVER, selectedArticles);
    964     }
    965
    966     /****
    967      * A convenience method to send the NNTP XHDR command to the server,
    968      * receive the reply, and return the reply code.
    969      * <p>
    970      * @param header a String naming a header line (e.g., "subject").  See
    971      * RFC-1036 for a list of valid header lines.
    972      * @param selectedArticles a String representation of the range of
    973      * article headers required. This may be an article number, or a
    974      * range of article numbers in the form "XXXX-YYYY", where XXXX
    975      * and YYYY are valid article numbers in the current group.  It
    976      * also may be of the form "XXX-", meaning "return XXX and all
    977      * following articles" In this revision, the last format is not
    978      * possible (yet).
    979      * @return The reply code received from the server.
    980      * @exception NNTPConnectionClosedException
    981      *      If the NNTP server prematurely closes the connection as a result
    982      *      of the client being idle or some other reason causing the server
    983      *      to send NNTP reply code 400.  This exception may be caught either
    984      *      as an IOException or independently as itself.
    985      * @exception IOException  If an I/O error occurs while either sending the
    986      *      command or receiving the server reply.
    987      ***/
    988     public int xhdr(String header, String selectedArticles) throws IOException {
    989         StringBuffer command = new StringBuffer(header);
    990         command.append(" ");
    991         command.append(selectedArticles);
    992         return sendCommand(NNTPCommand.XHDR, command.toString());
    993     }
    994
    995     /***
    996      * A convenience wrapper for the extended LIST command that takes
    997      * an argument, allowing us to selectively list multiple groups.
    998      * <p>
    999      * @param wildmat A wildmat (pseudo-regex) pattern. See RFC 2980 for
    1000      *                details.
    1001      * @return the reply code received from the server.
    1002      * @throws IOException
    1003      */
    1004     public int listActive(String wildmat) throws IOException {
    1005         StringBuffer command = new StringBuffer("ACTIVE ");
    1006         command.append(wildmat);
    1007         return sendCommand(NNTPCommand.LIST, command.toString());
    1008     }
    1009 }
    1010
    1011 /* Emacs configuration
    1012  * Local variables:        **
    1013  * mode:             java  **
    1014  * c-basic-offset:   4     **
    1015  * indent-tabs-mode: nil   **
    1016  * End:                    **
    1017  */