(2048);
String line;
try {
while ((line = reader.readLine()) != null) {
NewsgroupInfo tmp = __parseNewsgroupListEntry(line);
if (tmp != null) {
list.addElement(tmp);
}
else {
throw new MalformedServerReplyException(line);
}
}
}
finally {
reader.close();
}
int size;
if ((size = list.size()) < 1) {
return new NewsgroupInfo[0];
}
NewsgroupInfo[] info = new NewsgroupInfo[size];
list.copyInto(info);
return info;
}
private BufferedReader __retrieve(int command, String articleId, ArticleInfo pointer) throws IOException {
if (articleId != null) {
if (!NNTPReply.isPositiveCompletion(sendCommand(command, articleId))) {
return null;
}
}
else {
if (!NNTPReply.isPositiveCompletion(sendCommand(command))) {
return null;
}
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return new DotTerminatedMessageReader(_reader_);
}
private BufferedReader __retrieve(int command, long articleNumber, ArticleInfo pointer) throws IOException {
if (!NNTPReply.isPositiveCompletion(sendCommand(command, Long.toString(articleNumber)))) {
return null;
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return new DotTerminatedMessageReader(_reader_);
}
/***
* Retrieves an article from the NNTP server. The article is referenced by its unique article
* identifier (including the enclosing < and >). The article number and identifier
* contained in the server reply are returned through an ArticleInfo. The
* articleId
field of the ArticleInfo cannot always be trusted because some NNTP
* servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleId The unique article identifier of the article to retrieve. If this parameter
* is null, the currently selected article is retrieved.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article can be read. null if the
* article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticle(String articleId, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.ARTICLE, articleId, pointer);
}
/**
* Same as retrieveArticle(articleId, (ArticleInfo) null)
Note: the return can be
* cast to a {@link BufferedReader}
*
* @param articleId the article id to retrieve
* @return A DotTerminatedMessageReader instance from which the article can be read. null if the
* article does not exist.
* @throws IOException if an IO error occurs
*/
public Reader retrieveArticle(String articleId) throws IOException {
return retrieveArticle(articleId, (ArticleInfo)null);
}
/**
* Same as retrieveArticle((String) null)
Note: the return can be cast to a
* {@link BufferedReader}
*
* @return A DotTerminatedMessageReader instance from which the article can be read. null if the
* article does not exist.
* @throws IOException if an IO error occurs
*/
public Reader retrieveArticle() throws IOException {
return retrieveArticle((String)null);
}
/***
* Retrieves an article from the currently selected newsgroup. The article is referenced by its
* article number. The article number and identifier contained in the server reply are returned
* through an ArticleInfo. The articleId
field of the ArticleInfo cannot always
* be trusted because some NNTP servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleNumber The number of the the article to retrieve.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article can be read. null if the
* article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticle(long articleNumber, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.ARTICLE, articleNumber, pointer);
}
/**
* Same as retrieveArticle(articleNumber, null)
*
* @param articleNumber the article number to fetch
* @return A DotTerminatedMessageReader instance from which the article can be read. null if the
* article does not exist.
* @throws IOException if an IO error occurs
*/
public BufferedReader retrieveArticle(long articleNumber) throws IOException {
return retrieveArticle(articleNumber, null);
}
/***
* Retrieves an article header from the NNTP server. The article is referenced by its unique
* article identifier (including the enclosing < and >). The article number and identifier
* contained in the server reply are returned through an ArticleInfo. The
* articleId
field of the ArticleInfo cannot always be trusted because some NNTP
* servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleId The unique article identifier of the article whose header is being
* retrieved. If this parameter is null, the header of the currently selected article
* is retrieved.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article header can be read. null
* if the article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticleHeader(String articleId, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.HEAD, articleId, pointer);
}
/**
* Same as retrieveArticleHeader(articleId, (ArticleInfo) null)
Note: the return
* can be cast to a {@link BufferedReader}
*
* @param articleId the article id to fetch
* @return the reader
* @throws IOException if an error occurs
*/
public Reader retrieveArticleHeader(String articleId) throws IOException {
return retrieveArticleHeader(articleId, (ArticleInfo)null);
}
/**
* Same as retrieveArticleHeader((String) null)
Note: the return can be cast to a
* {@link BufferedReader}
*
* @return the reader
* @throws IOException if an error occurs
*/
public Reader retrieveArticleHeader() throws IOException {
return retrieveArticleHeader((String)null);
}
/***
* Retrieves an article header from the currently selected newsgroup. The article is referenced
* by its article number. The article number and identifier contained in the server reply are
* returned through an ArticleInfo. The articleId
field of the ArticleInfo cannot
* always be trusted because some NNTP servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleNumber The number of the the article whose header is being retrieved.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article header can be read. null
* if the article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticleHeader(long articleNumber, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.HEAD, articleNumber, pointer);
}
/**
* Same as retrieveArticleHeader(articleNumber, null)
*
* @param articleNumber the article number
* @return the reader
* @throws IOException if an error occurs
*/
public BufferedReader retrieveArticleHeader(long articleNumber) throws IOException {
return retrieveArticleHeader(articleNumber, null);
}
/***
* Retrieves an article body from the NNTP server. The article is referenced by its unique
* article identifier (including the enclosing < and >). The article number and identifier
* contained in the server reply are returned through an ArticleInfo. The
* articleId
field of the ArticleInfo cannot always be trusted because some NNTP
* servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleId The unique article identifier of the article whose body is being retrieved.
* If this parameter is null, the body of the currently selected article is
* retrieved.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article body can be read. null
* if the article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticleBody(String articleId, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.BODY, articleId, pointer);
}
/**
* Same as retrieveArticleBody(articleId, (ArticleInfo) null)
Note: the return
* can be cast to a {@link BufferedReader}
*
* @param articleId the article id
* @return A DotTerminatedMessageReader instance from which the article body can be read. null
* if the article does not exist.
* @throws IOException if an error occurs
*/
public Reader retrieveArticleBody(String articleId) throws IOException {
return retrieveArticleBody(articleId, (ArticleInfo)null);
}
/**
* Same as retrieveArticleBody(null)
Note: the return can be cast to a
* {@link BufferedReader}
*
* @return A DotTerminatedMessageReader instance from which the article body can be read. null
* if the article does not exist.
* @throws IOException if an error occurs
*/
public Reader retrieveArticleBody() throws IOException {
return retrieveArticleBody(null);
}
/***
* Retrieves an article body from the currently selected newsgroup. The article is referenced by
* its article number. The article number and identifier contained in the server reply are
* returned through an ArticleInfo. The articleId
field of the ArticleInfo cannot
* always be trusted because some NNTP servers do not correctly follow the RFC 977 reply format.
*
* A DotTerminatedMessageReader is returned from which the article can be read. If the article
* does not exist, null is returned.
*
* You must not issue any commands to the NNTP server (i.e., call any other methods) until you
* finish reading the message from the returned BufferedReader instance. The NNTP protocol uses
* the same stream for issuing commands as it does for returning results. Therefore the returned
* BufferedReader actually reads directly from the NNTP connection. After the end of message has
* been reached, new commands can be executed and their replies read. If you do not follow these
* requirements, your program will not work properly.
*
*
* @param articleNumber The number of the the article whose body is being retrieved.
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return A DotTerminatedMessageReader instance from which the article body can be read. null
* if the article does not exist.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public BufferedReader retrieveArticleBody(long articleNumber, ArticleInfo pointer) throws IOException {
return __retrieve(NNTPCommand.BODY, articleNumber, pointer);
}
/**
* Same as retrieveArticleBody(articleNumber, null)
*
* @param articleNumber the article number
* @return the reader
* @throws IOException if an error occurs
*/
public BufferedReader retrieveArticleBody(long articleNumber) throws IOException {
return retrieveArticleBody(articleNumber, null);
}
/***
* Select the specified newsgroup to be the target of for future article retrieval and posting
* operations. Also return the newsgroup information contained in the server reply through the
* info parameter.
*
*
* @param newsgroup The newsgroup to select.
* @param info A parameter through which the newsgroup information of the selected newsgroup
* contained in the server reply is returned. Set this to null if you do not desire
* this information.
* @return True if the newsgroup exists and was selected, false otherwise.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean selectNewsgroup(String newsgroup, NewsgroupInfo info) throws IOException {
if (!NNTPReply.isPositiveCompletion(group(newsgroup))) {
return false;
}
if (info != null) {
__parseGroupReply(getReplyString(), info);
}
return true;
}
/**
* Same as selectNewsgroup(newsgroup, null)
*
* @param newsgroup the newsgroup name
* @return true if newsgroup exist and was selected
* @throws IOException if an error occurs
*/
public boolean selectNewsgroup(String newsgroup) throws IOException {
return selectNewsgroup(newsgroup, null);
}
/***
* List the command help from the server.
*
*
* @return The sever help information.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public String listHelp() throws IOException {
if (!NNTPReply.isInformational(help())) {
return null;
}
StringWriter help = new StringWriter();
BufferedReader reader = new DotTerminatedMessageReader(_reader_);
Util.copyReader(reader, help);
reader.close();
help.close();
return help.toString();
}
/**
* Send a "LIST OVERVIEW.FMT" command to the server.
*
* @return the contents of the Overview format, of {@code null} if the command failed
* @throws IOException on error
*/
public String[] listOverviewFmt() throws IOException {
if (!NNTPReply.isPositiveCompletion(sendCommand("LIST", "OVERVIEW.FMT"))) {
return null;
}
BufferedReader reader = new DotTerminatedMessageReader(_reader_);
String line;
ArrayList list = new ArrayList();
while ((line = reader.readLine()) != null) {
list.add(line);
}
reader.close();
return list.toArray(new String[list.size()]);
}
/***
* Select an article by its unique identifier (including enclosing < and >) and return its
* article number and id through the pointer parameter. This is achieved through the STAT
* command. According to RFC 977, this will NOT set the current article pointer on the server.
* To do that, you must reference the article by its number.
*
*
* @param articleId The unique article identifier of the article that is being selectedd. If
* this parameter is null, the body of the current article is selected
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return True if successful, false if not.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean selectArticle(String articleId, ArticleInfo pointer) throws IOException {
if (articleId != null) {
if (!NNTPReply.isPositiveCompletion(stat(articleId))) {
return false;
}
}
else {
if (!NNTPReply.isPositiveCompletion(stat())) {
return false;
}
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return true;
}
/**
* Same as selectArticle(articleId, (ArticleInfo) null)
*
* @param articleId the article Id
* @return true if successful
* @throws IOException on error
*/
public boolean selectArticle(String articleId) throws IOException {
return selectArticle(articleId, (ArticleInfo)null);
}
/****
* Same as selectArticle((String) null, articleId)
. Useful for retrieving the
* current article number.
*
* @param pointer to the article
* @return true if OK
* @throws IOException on error
***/
public boolean selectArticle(ArticleInfo pointer) throws IOException {
return selectArticle(null, pointer);
}
/***
* Select an article in the currently selected newsgroup by its number. and return its article
* number and id through the pointer parameter. This is achieved through the STAT command.
* According to RFC 977, this WILL set the current article pointer on the server. Use this
* command to select an article before retrieving it, or to obtain an article's unique
* identifier given its number.
*
*
* @param articleNumber The number of the article to select from the currently selected
* newsgroup.
* @param pointer A parameter through which to return the article's number and unique id.
* Although the articleId field cannot always be trusted because of server deviations
* from RFC 977 reply formats, we haven't found a server that misformats this
* information in response to this particular command. You may set this parameter to
* null if you do not desire to retrieve the returned article information.
* @return True if successful, false if not.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean selectArticle(long articleNumber, ArticleInfo pointer) throws IOException {
if (!NNTPReply.isPositiveCompletion(stat(articleNumber))) {
return false;
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return true;
}
/***
* Same as selectArticle(articleNumber, null)
*
* @param articleNumber the numger
* @return true if successful
* @throws IOException on error
***/
public boolean selectArticle(long articleNumber) throws IOException {
return selectArticle(articleNumber, null);
}
/***
* Select the article preceeding the currently selected article in the currently selected
* newsgroup and return its number and unique id through the pointer parameter. Because of
* deviating server implementations, the articleId information cannot be trusted. To obtain the
* article identifier, issue a selectArticle(pointer.articleNumber, pointer)
* immediately afterward.
*
*
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return True if successful, false if not (e.g., there is no previous article).
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean selectPreviousArticle(ArticleInfo pointer) throws IOException {
if (!NNTPReply.isPositiveCompletion(last())) {
return false;
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return true;
}
/***
* Same as selectPreviousArticle((ArticleInfo) null)
*
* @return true if successful
* @throws IOException on error
***/
public boolean selectPreviousArticle() throws IOException {
return selectPreviousArticle((ArticleInfo)null);
}
/***
* Select the article following the currently selected article in the currently selected
* newsgroup and return its number and unique id through the pointer parameter. Because of
* deviating server implementations, the articleId information cannot be trusted. To obtain the
* article identifier, issue a selectArticle(pointer.articleNumber, pointer)
* immediately afterward.
*
*
* @param pointer A parameter through which to return the article's number and unique id. The
* articleId field cannot always be trusted because of server deviations from RFC 977
* reply formats. You may set this parameter to null if you do not desire to retrieve
* the returned article information.
* @return True if successful, false if not (e.g., there is no following article).
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean selectNextArticle(ArticleInfo pointer) throws IOException {
if (!NNTPReply.isPositiveCompletion(next())) {
return false;
}
if (pointer != null) {
__parseArticlePointer(getReplyString(), pointer);
}
return true;
}
/***
* Same as selectNextArticle((ArticleInfo) null)
*
* @return true if successful
* @throws IOException on error
***/
public boolean selectNextArticle() throws IOException {
return selectNextArticle((ArticleInfo)null);
}
/***
* List all newsgroups served by the NNTP server. If no newsgroups are served, a zero length
* array will be returned. If the command fails, null will be returned. The method uses the
* "LIST" command.
*
*
* @return An array of NewsgroupInfo instances containing the information for each newsgroup
* served by the NNTP server. If no newsgroups are served, a zero length array will be
* returned. If the command fails, null will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @see #iterateNewsgroupListing()
* @see #iterateNewsgroups()
***/
public NewsgroupInfo[] listNewsgroups() throws IOException {
if (!NNTPReply.isPositiveCompletion(list())) {
return null;
}
return __readNewsgroupListing();
}
/**
* List all newsgroups served by the NNTP server. If no newsgroups are served, no entries will
* be returned. The method uses the "LIST" command.
*
*
* @return An iterable of NewsgroupInfo instances containing the information for each newsgroup
* served by the NNTP server. If no newsgroups are served, no entries will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @since 3.0
*/
public Iterable iterateNewsgroupListing() throws IOException {
if (NNTPReply.isPositiveCompletion(list())) {
return new ReplyIterator(_reader_);
}
throw new IOException("LIST command failed: " + getReplyString());
}
/**
* List all newsgroups served by the NNTP server. If no newsgroups are served, no entries will
* be returned. The method uses the "LIST" command.
*
*
* @return An iterable of Strings containing the raw information for each newsgroup served by
* the NNTP server. If no newsgroups are served, no entries will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @since 3.0
*/
public Iterable iterateNewsgroups() throws IOException {
return new NewsgroupIterator(iterateNewsgroupListing());
}
/**
* List the newsgroups that match a given pattern. Uses the "LIST ACTIVE" command.
*
*
* @param wildmat a pseudo-regex pattern (cf. RFC 2980)
* @return An array of NewsgroupInfo instances containing the information for each newsgroup
* served by the NNTP server corresponding to the supplied pattern. If no such
* newsgroups are served, a zero length array will be returned. If the command fails,
* null will be returned.
* @throws IOException on error
* @see #iterateNewsgroupListing(String)
* @see #iterateNewsgroups(String)
*/
public NewsgroupInfo[] listNewsgroups(String wildmat) throws IOException {
if (!NNTPReply.isPositiveCompletion(listActive(wildmat))) {
return null;
}
return __readNewsgroupListing();
}
/**
* List the newsgroups that match a given pattern. Uses the "LIST ACTIVE" command.
*
*
* @param wildmat a pseudo-regex pattern (cf. RFC 2980)
* @return An iterable of Strings containing the raw information for each newsgroup served by
* the NNTP server corresponding to the supplied pattern. If no such newsgroups are
* served, no entries will be returned.
* @throws IOException on error
* @since 3.0
*/
public Iterable iterateNewsgroupListing(String wildmat) throws IOException {
if (NNTPReply.isPositiveCompletion(listActive(wildmat))) {
return new ReplyIterator(_reader_);
}
throw new IOException("LIST ACTIVE " + wildmat + " command failed: " + getReplyString());
}
/**
* List the newsgroups that match a given pattern. Uses the "LIST ACTIVE" command.
*
*
* @param wildmat a pseudo-regex pattern (cf. RFC 2980)
* @return An iterable NewsgroupInfo instances containing the information for each newsgroup
* served by the NNTP server corresponding to the supplied pattern. If no such
* newsgroups are served, no entries will be returned.
* @throws IOException on error
* @since 3.0
*/
public Iterable iterateNewsgroups(String wildmat) throws IOException {
return new NewsgroupIterator(iterateNewsgroupListing(wildmat));
}
/***
* List all new newsgroups added to the NNTP server since a particular date subject to the
* conditions of the specified query. If no new newsgroups were added, a zero length array will
* be returned. If the command fails, null will be returned. This uses the "NEWGROUPS" command.
*
*
* @param query The query restricting how to search for new newsgroups.
* @return An array of NewsgroupInfo instances containing the information for each new newsgroup
* added to the NNTP server. If no newsgroups were added, a zero length array will be
* returned. If the command fails, null will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @see #iterateNewNewsgroups(NewGroupsOrNewsQuery)
* @see #iterateNewNewsgroupListing(NewGroupsOrNewsQuery)
***/
public NewsgroupInfo[] listNewNewsgroups(NewGroupsOrNewsQuery query) throws IOException {
if (!NNTPReply.isPositiveCompletion(newgroups(query.getDate(), query.getTime(), query.isGMT(),
query.getDistributions()))) {
return null;
}
return __readNewsgroupListing();
}
/**
* List all new newsgroups added to the NNTP server since a particular date subject to the
* conditions of the specified query. If no new newsgroups were added, no entries will be
* returned. This uses the "NEWGROUPS" command.
*
*
* @param query The query restricting how to search for new newsgroups.
* @return An iterable of Strings containing the raw information for each new newsgroup added to
* the NNTP server. If no newsgroups were added, no entries will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @since 3.0
*/
public Iterable iterateNewNewsgroupListing(NewGroupsOrNewsQuery query) throws IOException {
if (NNTPReply.isPositiveCompletion(newgroups(query.getDate(), query.getTime(), query.isGMT(),
query.getDistributions()))) {
return new ReplyIterator(_reader_);
}
throw new IOException("NEWGROUPS command failed: " + getReplyString());
}
/**
* List all new newsgroups added to the NNTP server since a particular date subject to the
* conditions of the specified query. If no new newsgroups were added, no entries will be
* returned. This uses the "NEWGROUPS" command.
*
*
* @param query The query restricting how to search for new newsgroups.
* @return An iterable of NewsgroupInfo instances containing the information for each new
* newsgroup added to the NNTP server. If no newsgroups were added, no entries will be
* returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @since 3.0
*/
public Iterable iterateNewNewsgroups(NewGroupsOrNewsQuery query) throws IOException {
return new NewsgroupIterator(iterateNewNewsgroupListing(query));
}
/***
* List all new articles added to the NNTP server since a particular date subject to the
* conditions of the specified query. If no new new news is found, a zero length array will be
* returned. If the command fails, null will be returned. You must add at least one newsgroup to
* the query, else the command will fail. Each String in the returned array is a unique message
* identifier including the enclosing < and >. This uses the "NEWNEWS" command.
*
*
* @param query The query restricting how to search for new news. You must add at least one
* newsgroup to the query.
* @return An array of String instances containing the unique message identifiers for each new
* article added to the NNTP server. If no new news is found, a zero length array will
* be returned. If the command fails, null will be returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @see #iterateNewNews(NewGroupsOrNewsQuery)
***/
public String[] listNewNews(NewGroupsOrNewsQuery query) throws IOException {
if (!NNTPReply.isPositiveCompletion(newnews(query.getNewsgroups(), query.getDate(), query.getTime(),
query.isGMT(), query.getDistributions()))) {
return null;
}
Vector list = new Vector();
BufferedReader reader = new DotTerminatedMessageReader(_reader_);
String line;
try {
while ((line = reader.readLine()) != null) {
list.addElement(line);
}
}
finally {
reader.close();
}
int size = list.size();
if (size < 1) {
return new String[0];
}
String[] result = new String[size];
list.copyInto(result);
return result;
}
/**
* List all new articles added to the NNTP server since a particular date subject to the
* conditions of the specified query. If no new new news is found, no entries will be returned.
* This uses the "NEWNEWS" command. You must add at least one newsgroup to the query, else the
* command will fail. Each String which is returned is a unique message identifier including the
* enclosing < and >.
*
*
* @param query The query restricting how to search for new news. You must add at least one
* newsgroup to the query.
* @return An iterator of String instances containing the unique message identifiers for each
* new article added to the NNTP server. If no new news is found, no strings will be
* returned.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
* @since 3.0
*/
public Iterable iterateNewNews(NewGroupsOrNewsQuery query) throws IOException {
if (NNTPReply.isPositiveCompletion(newnews(query.getNewsgroups(), query.getDate(), query.getTime(),
query.isGMT(), query.getDistributions()))) {
return new ReplyIterator(_reader_);
}
throw new IOException("NEWNEWS command failed: " + getReplyString());
}
/***
* There are a few NNTPClient methods that do not complete the entire sequence of NNTP commands
* to complete a transaction. These commands require some action by the programmer after the
* reception of a positive preliminary command. After the programmer's code completes its
* actions, it must call this method to receive the completion reply from the server and verify
* the success of the entire transaction.
*
* For example
*
*
* writer = client.postArticle();
* if (writer == null) // failure
* return false;
* header = new SimpleNNTPHeader("[email protected]", "Just testing");
* header.addNewsgroup("alt.test");
* writer.write(header.toString());
* writer.write("This is just a test");
* writer.close();
* if (!client.completePendingCommand()) // failure
* return false;
*
*
*
* @return True if successfully completed, false if not.
* @exception NNTPConnectionClosedException If the NNTP server prematurely closes the connection
* as a result of the client being idle or some other reason causing the server
* to send NNTP reply code 400. This exception may be caught either as an
* IOException or independently as itself.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean completePendingCommand() throws IOException {
return NNTPReply.isPositiveCompletion(getReply());
}
/***
* Post an article to the NNTP server. This method returns a DotTerminatedMessageWriter instance
* to which the article can be written. Null is returned if the posting attempt fails. You
* should check {@link NNTP#isAllowedToPost isAllowedToPost() } before trying to post. However,
* a posting attempt can fail due to malformed headers.
*
* You must not issue any commands to the NNTP server (i.e., call any (other methods) until you
* finish writing to the returned Writer instance and close it. The NNTP protocol uses the same
* stream for issuing commands as it does for returning results. Therefore the returned Writer
* actually writes directly to the NNTP connection. After you close the writer, you can execute
* new commands. If you do not follow these requirements your program will not work properly.
*
* Different NNTP servers will require different header formats, but you can use the provided
* {@link panda.net.nntp.SimpleNNTPHeader} class to construct the bare minimum acceptable header
* for most news readers. To construct more complicated headers you should refer to RFC 822.
* When the Java Mail API is finalized, you will be able to use it to compose fully compliant
* Internet text messages. The DotTerminatedMessageWriter takes care of doubling line-leading
* dots and ending the message with a single dot upon closing, so all you have to worry about is
* writing the header and the message.
*
* Upon closing the returned Writer, you need to call {@link #completePendingCommand
* completePendingCommand() } to finalize the posting and verify its success or failure from the
* server reply.
*
*
* @return A DotTerminatedMessageWriter to which the article (including header) can be written.
* Returns null if the command fails.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public Writer postArticle() throws IOException {
if (!NNTPReply.isPositiveIntermediate(post())) {
return null;
}
return new DotTerminatedMessageWriter(_writer_);
}
public Writer forwardArticle(String articleId) throws IOException {
if (!NNTPReply.isPositiveIntermediate(ihave(articleId))) {
return null;
}
return new DotTerminatedMessageWriter(_writer_);
}
/***
* Logs out of the news server gracefully by sending the QUIT command. However, you must still
* disconnect from the server before you can open a new connection.
*
*
* @return True if successfully completed, false if not.
* @exception IOException If an I/O error occurs while either sending a command to the server or
* receiving a reply from the server.
***/
public boolean logout() throws IOException {
return NNTPReply.isPositiveCompletion(quit());
}
/**
* Log into a news server by sending the AUTHINFO USER/AUTHINFO PASS command sequence. This is
* usually sent in response to a 480 reply code from the NNTP server.
*
*
* @param username a valid username
* @param password the corresponding password
* @return True for successful login, false for a failure
* @throws IOException on error
*/
public boolean authenticate(String username, String password) throws IOException {
int replyCode = authinfoUser(username);
if (replyCode == NNTPReply.MORE_AUTH_INFO_REQUIRED) {
replyCode = authinfoPass(password);
if (replyCode == NNTPReply.AUTHENTICATION_ACCEPTED) {
_isAllowedToPost = true;
return true;
}
}
return false;
}
/***
* Private implementation of XOVER functionality. See {@link NNTP#xover} for legal agument
* formats. Alternatively, read RFC 2980 :-)
*
*
* @param articleRange
* @return Returns a DotTerminatedMessageReader if successful, null otherwise
* @exception IOException
*/
private BufferedReader __retrieveArticleInfo(String articleRange) throws IOException {
if (!NNTPReply.isPositiveCompletion(xover(articleRange))) {
return null;
}
return new DotTerminatedMessageReader(_reader_);
}
/**
* Return article headers for a specified post.
*
*
* @param articleNumber the article to retrieve headers for
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException on error
*/
public BufferedReader retrieveArticleInfo(long articleNumber) throws IOException {
return __retrieveArticleInfo(Long.toString(articleNumber));
}
/**
* Return article headers for all articles between lowArticleNumber and highArticleNumber,
* inclusively. Uses the XOVER command.
*
*
* @param lowArticleNumber low number
* @param highArticleNumber high number
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException on error
*/
public BufferedReader retrieveArticleInfo(long lowArticleNumber, long highArticleNumber) throws IOException {
return __retrieveArticleInfo(lowArticleNumber + "-" + highArticleNumber);
}
/**
* Return article headers for all articles between lowArticleNumber and highArticleNumber,
* inclusively, using the XOVER command.
*
*
* @param lowArticleNumber low
* @param highArticleNumber high
* @return an Iterable of Articles
* @throws IOException if the command failed
* @since 3.0
*/
public Iterable iterateArticleInfo(long lowArticleNumber, long highArticleNumber) throws IOException {
BufferedReader info = retrieveArticleInfo(lowArticleNumber, highArticleNumber);
if (info == null) {
throw new IOException("XOVER command failed: " + getReplyString());
}
// N.B. info is already DotTerminated, so don't rewrap
return new ArticleIterator(new ReplyIterator(info, false));
}
/***
* Private implementation of XHDR functionality. See {@link NNTP#xhdr} for legal agument
* formats. Alternatively, read RFC 1036.
*
*
* @param header
* @param articleRange
* @return Returns a DotTerminatedMessageReader if successful, null otherwise
* @exception IOException
*/
private BufferedReader __retrieveHeader(String header, String articleRange) throws IOException {
if (!NNTPReply.isPositiveCompletion(xhdr(header, articleRange))) {
return null;
}
return new DotTerminatedMessageReader(_reader_);
}
/**
* Return an article header for a specified post.
*
*
* @param header the header to retrieve
* @param articleNumber the article to retrieve the header for
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException on error
*/
public BufferedReader retrieveHeader(String header, long articleNumber) throws IOException {
return __retrieveHeader(header, Long.toString(articleNumber));
}
/**
* Return an article header for all articles between lowArticleNumber and highArticleNumber,
* inclusively.
*
*
* @param header the header
* @param lowArticleNumber to fetch
* @param highArticleNumber to fetch
* @return a DotTerminatedReader if successful, null otherwise
* @throws IOException on error
*/
public BufferedReader retrieveHeader(String header, long lowArticleNumber, long highArticleNumber)
throws IOException {
return __retrieveHeader(header, lowArticleNumber + "-" + highArticleNumber);
}
}