trunk/com/so/news/command/OverCommand.java
changeset 0 f907866f0e4b
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/trunk/com/so/news/command/OverCommand.java	Tue Jan 20 10:21:03 2009 +0100
     1.3 @@ -0,0 +1,183 @@
     1.4 +/*
     1.5 + *   StarOffice News Server
     1.6 + *   see AUTHORS for the list of contributors
     1.7 + *
     1.8 + *   This program is free software: you can redistribute it and/or modify
     1.9 + *   it under the terms of the GNU General Public License as published by
    1.10 + *   the Free Software Foundation, either version 3 of the License, or
    1.11 + *   (at your option) any later version.
    1.12 + *
    1.13 + *   This program is distributed in the hope that it will be useful,
    1.14 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.16 + *   GNU General Public License for more details.
    1.17 + *
    1.18 + *   You should have received a copy of the GNU General Public License
    1.19 + *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    1.20 + */
    1.21 +
    1.22 +package com.so.news.command;
    1.23 +
    1.24 +import java.text.SimpleDateFormat;
    1.25 +import java.util.Locale;
    1.26 +
    1.27 +import com.so.news.Debug;
    1.28 +import com.so.news.NNTPConnection;
    1.29 +import com.so.news.storage.Article;
    1.30 +
    1.31 +/**
    1.32 + * Class handling the OVER/XOVER command.
    1.33 + * 
    1.34 + * Description of the XOVER command:
    1.35 + * 
    1.36 + * XOVER [range]
    1.37 + *
    1.38 + * The XOVER command returns information from the overview
    1.39 + * database for the article(s) specified.
    1.40 + *
    1.41 + * The optional range argument may be any of the following:
    1.42 + *              an article number
    1.43 + *              an article number followed by a dash to indicate
    1.44 + *                 all following
    1.45 + *              an article number followed by a dash followed by
    1.46 + *                 another article number
    1.47 + *
    1.48 + * If no argument is specified, then information from the
    1.49 + * current article is displayed. Successful responses start
    1.50 + * with a 224 response followed by the overview information
    1.51 + * for all matched messages. Once the output is complete, a
    1.52 + * period is sent on a line by itself. If no argument is
    1.53 + * specified, the information for the current article is
    1.54 + * returned.  A news group must have been selected earlier,
    1.55 + * else a 412 error response is returned. If no articles are
    1.56 + * in the range specified, a 420 error response is returned
    1.57 + * by the server. A 502 response will be returned if the
    1.58 + * client only has permission to transfer articles.
    1.59 + *
    1.60 + * Each line of output will be formatted with the article number,
    1.61 + * followed by each of the headers in the overview database or the
    1.62 + * article itself (when the data is not available in the overview
    1.63 + * database) for that article separated by a tab character.  The
    1.64 + * sequence of fields must be in this order: subject, author,
    1.65 + * date, message-id, references, byte count, and line count. Other
    1.66 + * optional fields may follow line count. Other optional fields may
    1.67 + * follow line count. These fields are specified by examining the
    1.68 + * response to the LIST OVERVIEW.FMT command. Where no data exists,
    1.69 + * a null field must be provided (i.e. the output will have two tab
    1.70 + * characters adjacent to each other). Servers should not output
    1.71 + * fields for articles that have been removed since the XOVER database
    1.72 + * was created.
    1.73 + *
    1.74 + * The LIST OVERVIEW.FMT command should be implemented if XOVER
    1.75 + * is implemented. A client can use LIST OVERVIEW.FMT to determine
    1.76 + * what optional fields  and in which order all fields will be
    1.77 + * supplied by the XOVER command. 
    1.78 + *
    1.79 + * Note that any tab and end-of-line characters in any header
    1.80 + * data that is returned will be converted to a space character.
    1.81 + *
    1.82 + * Responses:
    1.83 + *
    1.84 + *   224 Overview information follows
    1.85 + *   412 No news group current selected
    1.86 + *   420 No article(s) selected
    1.87 + *   502 no permission
    1.88 + * 
    1.89 + * @author Christian Lins
    1.90 + */
    1.91 +public class OverCommand extends Command
    1.92 +{
    1.93 +  public OverCommand(NNTPConnection conn)
    1.94 +  {
    1.95 +    super(conn);
    1.96 +  }
    1.97 +  
    1.98 +  public boolean process(String[] command)
    1.99 +    throws Exception
   1.100 +  {
   1.101 +    if(getCurrentGroup() == null)
   1.102 +    {
   1.103 +      printStatus(412, "No news group current selected");
   1.104 +      return false;
   1.105 +    }
   1.106 +    
   1.107 +    // If no parameter was specified, show information about
   1.108 +    // the currently selected article(s)
   1.109 +    if(command.length == 1)
   1.110 +    {
   1.111 +      Article art = getCurrentArticle();
   1.112 +      if(art == null)
   1.113 +      {
   1.114 +        printStatus(420, "No article(s) selected");
   1.115 +        return false;
   1.116 +      }
   1.117 +      
   1.118 +      String o = buildOverview(art, -1);
   1.119 +      printText(o);
   1.120 +    }
   1.121 +    // otherwise print information about the specified range
   1.122 +    else
   1.123 +    {
   1.124 +      int artStart = -1;
   1.125 +      int artEnd   = -1;
   1.126 +      String[] nums = command[1].split("-");
   1.127 +      if(nums.length > 1)
   1.128 +      {
   1.129 +        try
   1.130 +        {
   1.131 +          artStart = Integer.parseInt(nums[0]);
   1.132 +        }
   1.133 +        catch(Exception e) 
   1.134 +        {
   1.135 +          artStart = Integer.parseInt(command[1]);
   1.136 +        }
   1.137 +        try
   1.138 +        {
   1.139 +          artEnd = Integer.parseInt(nums[1]);
   1.140 +        }
   1.141 +        catch(Exception e) {}
   1.142 +      }
   1.143 +
   1.144 +      printStatus(224, "Overview information follows");
   1.145 +      for(int n = artStart; n <= artEnd; n++)
   1.146 +      {
   1.147 +        Article art = Article.getByNumberInGroup(getCurrentGroup(), n);
   1.148 +        if(art == null)
   1.149 +        {
   1.150 +          Debug.getInstance().log("Article (gid=" + getCurrentGroup() + ", art=" + n + " is null!");
   1.151 +        }
   1.152 +        else
   1.153 +        {
   1.154 +          printTextPart(buildOverview(art, n) + NEWLINE);
   1.155 +        }
   1.156 +      }
   1.157 +      println(".");
   1.158 +      flush();
   1.159 +    }
   1.160 +    
   1.161 +    return true;
   1.162 +  }
   1.163 +  
   1.164 +  private String buildOverview(Article art, int nr)
   1.165 +  {
   1.166 +    SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
   1.167 +    StringBuilder overview = new StringBuilder();
   1.168 +    overview.append(nr);
   1.169 +    overview.append('\t');
   1.170 +    overview.append(art.getHeader().get("Subject"));
   1.171 +    overview.append('\t');
   1.172 +    overview.append(art.getHeader().get("From"));
   1.173 +    overview.append('\t');
   1.174 +    overview.append(sdf.format(art.getDate()));
   1.175 +    overview.append('\t');
   1.176 +    overview.append(art.getHeader().get("Message-ID"));
   1.177 +    overview.append('\t');
   1.178 +    overview.append(art.getHeader().get("References"));
   1.179 +    overview.append('\t');
   1.180 +    overview.append(art.getHeader().get("Bytes"));
   1.181 +    overview.append('\t');
   1.182 +    overview.append(art.getHeader().get("Lines"));
   1.183 +    
   1.184 +    return overview.toString();
   1.185 +  }
   1.186 +}