src/org/sonews/util/io/ArticleWriter.java
author Christian Lins <christian@lins.me>
Wed Sep 14 23:25:00 2011 +0200 (2011-09-14)
changeset 62 be4e87479855
parent 35 ed84c8bdd87b
permissions -rwxr-xr-x
Reformatting XDaemonCommand
     1 /*
     2  *   SONEWS News Server
     3  *   see AUTHORS for the list of contributors
     4  *
     5  *   This program is free software: you can redistribute it and/or modify
     6  *   it under the terms of the GNU General Public License as published by
     7  *   the Free Software Foundation, either version 3 of the License, or
     8  *   (at your option) any later version.
     9  *
    10  *   This program is distributed in the hope that it will be useful,
    11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  *   GNU General Public License for more details.
    14  *
    15  *   You should have received a copy of the GNU General Public License
    16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 
    19 package org.sonews.util.io;
    20 
    21 import java.io.BufferedOutputStream;
    22 import java.io.BufferedReader;
    23 import java.io.IOException;
    24 import java.io.InputStreamReader;
    25 import java.io.UnsupportedEncodingException;
    26 import java.net.Socket;
    27 import java.net.UnknownHostException;
    28 import org.sonews.storage.Article;
    29 
    30 /**
    31  * Posts an Article to a NNTP server using the POST command.
    32  * @author Christian Lins
    33  * @since sonews/0.5.0
    34  */
    35 public class ArticleWriter
    36 {
    37 
    38 	private BufferedOutputStream out;
    39 	private BufferedReader inr;
    40 
    41 	public ArticleWriter(String host, int port)
    42 		throws IOException, UnknownHostException
    43 	{
    44 		// Connect to NNTP server
    45 		Socket socket = new Socket(host, port);
    46 		this.out = new BufferedOutputStream(socket.getOutputStream());
    47 		this.inr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    48 		String line = inr.readLine();
    49 		if (line == null || !line.startsWith("200 ")) {
    50 			throw new IOException("Invalid hello from server: " + line);
    51 		}
    52 	}
    53 
    54 	public void close()
    55 		throws IOException, UnsupportedEncodingException
    56 	{
    57 		this.out.write("QUIT\r\n".getBytes("UTF-8"));
    58 		this.out.flush();
    59 	}
    60 
    61 	protected void finishPOST()
    62 		throws IOException
    63 	{
    64 		this.out.write("\r\n.\r\n".getBytes());
    65 		this.out.flush();
    66 		String line = inr.readLine();
    67 		if (line == null || !line.startsWith("240 ") || !line.startsWith("441 ")) {
    68 			throw new IOException(line);
    69 		}
    70 	}
    71 
    72 	protected void preparePOST()
    73 		throws IOException
    74 	{
    75 		this.out.write("POST\r\n".getBytes("UTF-8"));
    76 		this.out.flush();
    77 
    78 		String line = this.inr.readLine();
    79 		if (line == null || !line.startsWith("340 ")) {
    80 			throw new IOException(line);
    81 		}
    82 	}
    83 
    84 	public void writeArticle(Article article)
    85 		throws IOException, UnsupportedEncodingException
    86 	{
    87 		byte[] buf = new byte[512];
    88 		ArticleInputStream in = new ArticleInputStream(article);
    89 
    90 		preparePOST();
    91 
    92 		int len = in.read(buf);
    93 		while (len != -1) {
    94 			writeLine(buf, len);
    95 			len = in.read(buf);
    96 		}
    97 
    98 		finishPOST();
    99 	}
   100 
   101 	/**
   102 	 * Writes the raw content of an article to the remote server. This method
   103 	 * does no charset conversion/handling of any kind so its the preferred
   104 	 * method for sending an article to remote peers.
   105 	 * @param rawArticle
   106 	 * @throws IOException
   107 	 */
   108 	public void writeArticle(byte[] rawArticle)
   109 		throws IOException
   110 	{
   111 		preparePOST();
   112 		writeLine(rawArticle, rawArticle.length);
   113 		finishPOST();
   114 	}
   115 
   116 	/**
   117 	 * Writes the given buffer to the connect remote server.
   118 	 * @param buffer
   119 	 * @param len
   120 	 * @throws IOException
   121 	 */
   122 	protected void writeLine(byte[] buffer, int len)
   123 		throws IOException
   124 	{
   125 		this.out.write(buffer, 0, len);
   126 		this.out.flush();
   127 	}
   128 }