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