trunk/com/so/news/command/PostCommand.java
author chris <chris@marvin>
Tue Jan 20 10:21:03 2009 +0100 (2009-01-20)
changeset 0 f907866f0e4b
permissions -rw-r--r--
Initial import.
chris@0
     1
/*
chris@0
     2
 *   StarOffice News Server
chris@0
     3
 *   see AUTHORS for the list of contributors
chris@0
     4
 *
chris@0
     5
 *   This program is free software: you can redistribute it and/or modify
chris@0
     6
 *   it under the terms of the GNU General Public License as published by
chris@0
     7
 *   the Free Software Foundation, either version 3 of the License, or
chris@0
     8
 *   (at your option) any later version.
chris@0
     9
 *
chris@0
    10
 *   This program is distributed in the hope that it will be useful,
chris@0
    11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
chris@0
    12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
chris@0
    13
 *   GNU General Public License for more details.
chris@0
    14
 *
chris@0
    15
 *   You should have received a copy of the GNU General Public License
chris@0
    16
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
chris@0
    17
 */
chris@0
    18
chris@0
    19
package com.so.news.command;
chris@0
    20
chris@0
    21
import java.io.IOException;
chris@0
    22
import java.sql.SQLException;
chris@0
    23
import java.util.Date;
chris@0
    24
import java.text.SimpleDateFormat;
chris@0
    25
import java.util.HashMap;
chris@0
    26
import java.util.Locale;
chris@0
    27
chris@0
    28
import com.so.news.Config;
chris@0
    29
import com.so.news.Debug;
chris@0
    30
import com.so.news.NNTPConnection;
chris@0
    31
import com.so.news.storage.Article;
chris@0
    32
import com.so.news.storage.Database;
chris@0
    33
chris@0
    34
/**
chris@0
    35
 * Contains the code for the POST command.
chris@0
    36
 * @author Christian Lins
chris@0
    37
 * @author Dennis Schwerdel
chris@0
    38
 */
chris@0
    39
public class PostCommand extends Command
chris@0
    40
{
chris@0
    41
  public PostCommand(NNTPConnection conn)
chris@0
    42
  {
chris@0
    43
    super(conn);
chris@0
    44
  }
chris@0
    45
chris@0
    46
  public boolean process(String[] command) throws IOException
chris@0
    47
  {
chris@0
    48
    printStatus(340, "send article to be posted. End with <CR-LF>.<CR-LF>");
chris@0
    49
chris@0
    50
    // some initialization
chris@0
    51
    Article article = new Article();
chris@0
    52
    int lineCount     = 0;
chris@0
    53
    long bodySize     = 0;
chris@0
    54
    long maxBodySize  = Config.getInstance().get("n3tpd.article.maxsize", 1024) * 1024; // Size in bytes
chris@0
    55
chris@0
    56
    // begin with a stringbuilder body
chris@0
    57
    StringBuilder body = new StringBuilder();
chris@0
    58
    HashMap<String, String> header = new HashMap<String, String>();
chris@0
    59
chris@0
    60
    boolean isHeader = true; // are we in the header part
chris@0
    61
chris@0
    62
    String line = readTextLine();
chris@0
    63
    while(line != null)
chris@0
    64
    {
chris@0
    65
      bodySize += line.length();
chris@0
    66
      if(bodySize > maxBodySize)
chris@0
    67
      {
chris@0
    68
        printStatus(500, "article is too long");
chris@0
    69
        return false;
chris@0
    70
      }
chris@0
    71
chris@0
    72
      if(!isHeader)
chris@0
    73
      { // body
chris@0
    74
        if(line.trim().equals("."))
chris@0
    75
          break;
chris@0
    76
        
chris@0
    77
        bodySize += line.length() + 1;
chris@0
    78
        lineCount++;
chris@0
    79
        body.append(line + NEWLINE);
chris@0
    80
      }
chris@0
    81
      
chris@0
    82
      if(line.equals(""))
chris@0
    83
      {
chris@0
    84
        isHeader = false; // we finally met the blank line
chris@0
    85
                          // separating headers from body
chris@0
    86
      }
chris@0
    87
chris@0
    88
      if(isHeader)
chris@0
    89
      { // header
chris@0
    90
        // split name and value and add the header to the map
chris@0
    91
        int colon = line.indexOf(':');
chris@0
    92
        String fieldName = line.substring(0, colon).trim();
chris@0
    93
        String fieldValue = line.substring(colon + 1).trim();
chris@0
    94
        header.put(fieldName, fieldValue);
chris@0
    95
      }
chris@0
    96
      line = readTextLine(); // read a new line
chris@0
    97
    } // end of input reading
chris@0
    98
chris@0
    99
    article.setBody(body.toString()); // set the article body
chris@0
   100
    article.setHeader(header);     // add the header entries for the article
chris@0
   101
    
chris@0
   102
    // Read the date header and fall back to the current date if it is not set
chris@0
   103
    try
chris@0
   104
    {
chris@0
   105
      SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
chris@0
   106
      String date = header.get("DATE");
chris@0
   107
      if(date == null)
chris@0
   108
        article.setDate(new Date());
chris@0
   109
      else
chris@0
   110
        article.setDate(new Date(sdf.parse(date).getTime())) ;
chris@0
   111
    }
chris@0
   112
    catch (Exception e)
chris@0
   113
    {
chris@0
   114
      e.printStackTrace(Debug.getInstance().getStream());
chris@0
   115
      printStatus(541, "posting failed - invalid date format");
chris@0
   116
      return true;
chris@0
   117
    }
chris@0
   118
chris@0
   119
    // check for a cancel command
chris@0
   120
    if ( header.containsKey("Control") ) 
chris@0
   121
    {
chris@0
   122
      String[] control = header.get("Control").split(" ") ;
chris@0
   123
      if ( control.length >= 2 && control[0].equalsIgnoreCase("cancel") ) 
chris@0
   124
      {
chris@0
   125
        // this article is a cancel-article, try to delete the old article
chris@0
   126
        try
chris@0
   127
        {
chris@0
   128
          Article.getByMessageID(control[1]).delete();
chris@0
   129
          printStatus(240, "article posted ok - original article canceled"); // quite
chris@0
   130
          return true; // quit, do not actually post this article since it
chris@0
   131
        }
chris@0
   132
        catch (Exception e)
chris@0
   133
        {
chris@0
   134
          e.printStackTrace();
chris@0
   135
          printStatus(441, "posting failed - original posting not found");
chris@0
   136
          return true;
chris@0
   137
        }
chris@0
   138
      }
chris@0
   139
    }
chris@0
   140
chris@0
   141
    // set some headers
chris@0
   142
    header.put("Message-ID", article.getMessageID());
chris@0
   143
    header.put("Lines", "" + lineCount);
chris@0
   144
    header.put("Bytes", "" + bodySize);
chris@0
   145
chris@0
   146
    // if needed, set an empty references header, that means this is
chris@0
   147
    // a initial posting
chris@0
   148
    if (!header.containsKey("References"))
chris@0
   149
      header.put("References", "");
chris@0
   150
chris@0
   151
    // try to create the article in the database
chris@0
   152
    try
chris@0
   153
    {
chris@0
   154
      Database.getInstance().addArticle(article);
chris@0
   155
      printStatus(240, "article posted ok");
chris@0
   156
    }
chris@0
   157
    catch(SQLException ex)
chris@0
   158
    {
chris@0
   159
      System.err.println(ex.getLocalizedMessage());
chris@0
   160
      ex.printStackTrace(Debug.getInstance().getStream());
chris@0
   161
      printStatus(500, "internal server error");
chris@0
   162
    }
chris@0
   163
chris@0
   164
    return true;
chris@0
   165
  }
chris@0
   166
}