nntpclient.java
来自「apache推出的net包」· Java 代码 · 共 1,285 行 · 第 1/4 页
JAVA
1,285 行
/* * Copyright 2001-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.net.nntp;import java.io.BufferedReader;import java.io.IOException;import java.io.Reader;import java.io.StringWriter;import java.io.Writer;import java.util.StringTokenizer;import java.util.Vector;import org.apache.commons.net.io.DotTerminatedMessageReader;import org.apache.commons.net.io.DotTerminatedMessageWriter;import org.apache.commons.net.io.Util;import org.apache.commons.net.MalformedServerReplyException;/*** * NNTPClient encapsulates all the functionality necessary to post and * retrieve articles from an NNTP server. As with all classes derived * from {@link org.apache.commons.net.SocketClient}, * you must first connect to the server with * {@link org.apache.commons.net.SocketClient#connect connect } * before doing anything, and finally * {@link org.apache.commons.net.nntp.NNTP#disconnect disconnect() } * after you're completely finished interacting with the server. * Remember that the * {@link org.apache.commons.net.nntp.NNTP#isAllowedToPost isAllowedToPost()} * method is defined in * {@link org.apache.commons.net.nntp.NNTP}. * <p> * You should keep in mind that the NNTP server may choose to prematurely * close a connection if the client has been idle for longer than a * given time period or if the server is being shutdown by the operator or * some other reason. The NNTP class will detect a * premature NNTP server connection closing when it receives a * {@link org.apache.commons.net.nntp.NNTPReply#SERVICE_DISCONTINUED NNTPReply.SERVICE_DISCONTINUED } * response to a command. * When that occurs, the NNTP class method encountering that reply will throw * an {@link org.apache.commons.net.nntp.NNTPConnectionClosedException} * . * <code>NNTPConectionClosedException</code> * is a subclass of <code> IOException </code> and therefore need not be * caught separately, but if you are going to catch it separately, its * catch block must appear before the more general <code> IOException </code> * catch block. When you encounter an * {@link org.apache.commons.net.nntp.NNTPConnectionClosedException} * , you must disconnect the connection with * {@link org.apache.commons.net.nntp.NNTP#disconnect disconnect() } * to properly clean up the * system resources used by NNTP. Before disconnecting, you may check the * last reply code and text with * {@link org.apache.commons.net.nntp.NNTP#getReplyCode getReplyCode } and * {@link org.apache.commons.net.nntp.NNTP#getReplyString getReplyString }. * <p> * Rather than list it separately for each method, we mention here that * every method communicating with the server and throwing an IOException * can also throw a * {@link org.apache.commons.net.MalformedServerReplyException} * , which is a subclass * of IOException. A MalformedServerReplyException will be thrown when * the reply received from the server deviates enough from the protocol * specification that it cannot be interpreted in a useful manner despite * attempts to be as lenient as possible. * <p> * <p> * @author Daniel F. Savarese * @author Rory Winston * @author Ted Wise * @see NNTP * @see NNTPConnectionClosedException * @see org.apache.commons.net.MalformedServerReplyException ***/public class NNTPClient extends NNTP{ private void __parseArticlePointer(String reply, ArticlePointer pointer) throws MalformedServerReplyException { StringTokenizer tokenizer; // Do loop is a kluge to simulate goto do { tokenizer = new StringTokenizer(reply); if (tokenizer.countTokens() < 3) break; // Skip numeric response value tokenizer.nextToken(); // Get article number try { pointer.articleNumber = Integer.parseInt(tokenizer.nextToken()); } catch (NumberFormatException e) { break; } // Get article id pointer.articleId = tokenizer.nextToken(); return ; } while (false); throw new MalformedServerReplyException( "Could not parse article pointer.\nServer reply: " + reply); } private void __parseGroupReply(String reply, NewsgroupInfo info) throws MalformedServerReplyException { String count, first, last; StringTokenizer tokenizer; // Do loop is a kluge to simulate goto do { tokenizer = new StringTokenizer(reply); if (tokenizer.countTokens() < 5) break; // Skip numeric response value tokenizer.nextToken(); // Get estimated article count count = tokenizer.nextToken(); // Get first article number first = tokenizer.nextToken(); // Get last article number last = tokenizer.nextToken(); // Get newsgroup name info._setNewsgroup(tokenizer.nextToken()); try { info._setArticleCount(Integer.parseInt(count)); info._setFirstArticle(Integer.parseInt(first)); info._setLastArticle(Integer.parseInt(last)); } catch (NumberFormatException e) { break; } info._setPostingPermission(NewsgroupInfo.UNKNOWN_POSTING_PERMISSION); return ; } while (false); throw new MalformedServerReplyException( "Could not parse newsgroup info.\nServer reply: " + reply); } private NewsgroupInfo __parseNewsgroupListEntry(String entry) { NewsgroupInfo result; StringTokenizer tokenizer; int lastNum, firstNum; String last, first, permission; result = new NewsgroupInfo(); tokenizer = new StringTokenizer(entry); if (tokenizer.countTokens() < 4) return null; result._setNewsgroup(tokenizer.nextToken()); last = tokenizer.nextToken(); first = tokenizer.nextToken(); permission = tokenizer.nextToken(); try { lastNum = Integer.parseInt(last); firstNum = Integer.parseInt(first); result._setFirstArticle(firstNum); result._setLastArticle(lastNum); if((firstNum == 0) && (lastNum == 0)) result._setArticleCount(0); else result._setArticleCount(lastNum - firstNum + 1); } catch (NumberFormatException e) { return null; } switch (permission.charAt(0)) { case 'y': case 'Y': result._setPostingPermission( NewsgroupInfo.PERMITTED_POSTING_PERMISSION); break; case 'n': case 'N': result._setPostingPermission( NewsgroupInfo.PROHIBITED_POSTING_PERMISSION); break; case 'm': case 'M': result._setPostingPermission( NewsgroupInfo.MODERATED_POSTING_PERMISSION); break; default: result._setPostingPermission( NewsgroupInfo.UNKNOWN_POSTING_PERMISSION); break; } return result; } private NewsgroupInfo[] __readNewsgroupListing() throws IOException { int size; String line; Vector list; BufferedReader reader; NewsgroupInfo tmp, info[]; reader = new BufferedReader(new DotTerminatedMessageReader(_reader_)); // Start of with a big vector because we may be reading a very large // amount of groups. list = new Vector(2048); while ((line = reader.readLine()) != null) { tmp = __parseNewsgroupListEntry(line); if (tmp != null) list.addElement(tmp); else throw new MalformedServerReplyException(line); } if ((size = list.size()) < 1) return new NewsgroupInfo[0]; info = new NewsgroupInfo[size]; list.copyInto(info); return info; } private Reader __retrieve(int command, String articleId, ArticlePointer pointer) throws IOException { Reader reader; 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); reader = new DotTerminatedMessageReader(_reader_); return reader; } private Reader __retrieve(int command, int articleNumber, ArticlePointer pointer) throws IOException { Reader reader; if (!NNTPReply.isPositiveCompletion(sendCommand(command, Integer.toString(articleNumber)))) return null; if (pointer != null) __parseArticlePointer(getReplyString(), pointer); reader = new DotTerminatedMessageReader(_reader_); return 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 ArticlePointer. The <code> articleId </code> * field of the ArticlePointer cannot always be trusted because some * NNTP servers do not correctly follow the RFC 977 reply format. * <p> * A DotTerminatedMessageReader is returned from which the article can * be read. If the article does not exist, null is returned. * <p> * 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?