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