org/sonews/util/io/ArticleReader.java
author chris <chris@marvin>
Fri, 26 Jun 2009 16:48:50 +0200
changeset 1 6fceb66e1ad7
child 3 2fdc9cc89502
permissions -rw-r--r--
Hooray... sonews/0.5.0 final

HG: Enter commit message. Lines beginning with 'HG:' are removed.
HG: Remove all lines to abort the collapse operation.
     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.BufferedInputStream;
    22 import java.io.BufferedOutputStream;
    23 import java.io.ByteArrayOutputStream;
    24 import java.io.IOException;
    25 import java.io.InputStream;
    26 import java.io.UnsupportedEncodingException;
    27 import java.net.Socket;
    28 import java.net.UnknownHostException;
    29 import org.sonews.util.Log;
    30 
    31 /**
    32  * Reads an news article from a NNTP server.
    33  * @author Christian Lins
    34  * @since sonews/0.5.0
    35  */
    36 public class ArticleReader 
    37 {
    38 
    39   private BufferedOutputStream out;
    40   private BufferedInputStream  in;
    41   private String               messageID;
    42   
    43   public ArticleReader(String host, int port, String messageID)
    44     throws IOException, UnknownHostException
    45   {
    46     this.messageID = messageID;
    47 
    48     // Connect to NNTP server
    49     Socket socket = new Socket(host, port);
    50     this.out = new BufferedOutputStream(socket.getOutputStream());
    51     this.in  = new BufferedInputStream(socket.getInputStream());
    52     String line = readln(this.in);
    53     if(!line.startsWith("200 "))
    54     {
    55       throw new IOException("Invalid hello from server: " + line);
    56     }
    57   }
    58   
    59   private boolean eofArticle(byte[] buf)
    60   {
    61     if(buf.length < 4)
    62     {
    63       return false;
    64     }
    65     
    66     int l = buf.length - 1;
    67     return buf[l-3] == 10 // '*\n'
    68         && buf[l-2] == '.'                   // '.'
    69         && buf[l-1] == 13 && buf[l] == 10;  // '\r\n'
    70   }
    71   
    72   public byte[] getArticleData()
    73     throws IOException, UnsupportedEncodingException
    74   {
    75     try
    76     {
    77       this.out.write(("ARTICLE " + this.messageID + "\r\n").getBytes("UTF-8"));
    78       this.out.flush();
    79 
    80       String line = readln(this.in);
    81       if(line.startsWith("220 "))
    82       {
    83         ByteArrayOutputStream buf = new ByteArrayOutputStream();
    84         
    85         while(!eofArticle(buf.toByteArray()))
    86         {
    87           for(int b = in.read(); b != 10; b = in.read())
    88           {
    89             buf.write(b);
    90           }
    91 
    92           buf.write(10);
    93         }
    94         
    95         return buf.toByteArray();
    96       }
    97       else
    98       {
    99         Log.msg("ArticleReader: " + line, false);
   100         return null;
   101       }
   102     }
   103     catch(IOException ex)
   104     {
   105       throw ex;
   106     }
   107     finally
   108     {
   109       this.out.write("QUIT\r\n".getBytes("UTF-8"));
   110       this.out.flush();
   111       this.out.close();
   112     }
   113   }
   114   
   115   private String readln(InputStream in)
   116     throws IOException
   117   {
   118     ByteArrayOutputStream buf = new ByteArrayOutputStream();
   119     for(int b = in.read(); b != 10 /* \n */; b = in.read())
   120     {
   121       buf.write(b);
   122     }
   123     
   124     return new String(buf.toByteArray());
   125   }
   126 
   127 }