trunk/com/so/news/command/OverCommand.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.
     1 /*
     2  *   StarOffice 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 com.so.news.command;
    20 
    21 import java.text.SimpleDateFormat;
    22 import java.util.Locale;
    23 
    24 import com.so.news.Debug;
    25 import com.so.news.NNTPConnection;
    26 import com.so.news.storage.Article;
    27 
    28 /**
    29  * Class handling the OVER/XOVER command.
    30  * 
    31  * Description of the XOVER command:
    32  * 
    33  * XOVER [range]
    34  *
    35  * The XOVER command returns information from the overview
    36  * database for the article(s) specified.
    37  *
    38  * The optional range argument may be any of the following:
    39  *              an article number
    40  *              an article number followed by a dash to indicate
    41  *                 all following
    42  *              an article number followed by a dash followed by
    43  *                 another article number
    44  *
    45  * If no argument is specified, then information from the
    46  * current article is displayed. Successful responses start
    47  * with a 224 response followed by the overview information
    48  * for all matched messages. Once the output is complete, a
    49  * period is sent on a line by itself. If no argument is
    50  * specified, the information for the current article is
    51  * returned.  A news group must have been selected earlier,
    52  * else a 412 error response is returned. If no articles are
    53  * in the range specified, a 420 error response is returned
    54  * by the server. A 502 response will be returned if the
    55  * client only has permission to transfer articles.
    56  *
    57  * Each line of output will be formatted with the article number,
    58  * followed by each of the headers in the overview database or the
    59  * article itself (when the data is not available in the overview
    60  * database) for that article separated by a tab character.  The
    61  * sequence of fields must be in this order: subject, author,
    62  * date, message-id, references, byte count, and line count. Other
    63  * optional fields may follow line count. Other optional fields may
    64  * follow line count. These fields are specified by examining the
    65  * response to the LIST OVERVIEW.FMT command. Where no data exists,
    66  * a null field must be provided (i.e. the output will have two tab
    67  * characters adjacent to each other). Servers should not output
    68  * fields for articles that have been removed since the XOVER database
    69  * was created.
    70  *
    71  * The LIST OVERVIEW.FMT command should be implemented if XOVER
    72  * is implemented. A client can use LIST OVERVIEW.FMT to determine
    73  * what optional fields  and in which order all fields will be
    74  * supplied by the XOVER command. 
    75  *
    76  * Note that any tab and end-of-line characters in any header
    77  * data that is returned will be converted to a space character.
    78  *
    79  * Responses:
    80  *
    81  *   224 Overview information follows
    82  *   412 No news group current selected
    83  *   420 No article(s) selected
    84  *   502 no permission
    85  * 
    86  * @author Christian Lins
    87  */
    88 public class OverCommand extends Command
    89 {
    90   public OverCommand(NNTPConnection conn)
    91   {
    92     super(conn);
    93   }
    94   
    95   public boolean process(String[] command)
    96     throws Exception
    97   {
    98     if(getCurrentGroup() == null)
    99     {
   100       printStatus(412, "No news group current selected");
   101       return false;
   102     }
   103     
   104     // If no parameter was specified, show information about
   105     // the currently selected article(s)
   106     if(command.length == 1)
   107     {
   108       Article art = getCurrentArticle();
   109       if(art == null)
   110       {
   111         printStatus(420, "No article(s) selected");
   112         return false;
   113       }
   114       
   115       String o = buildOverview(art, -1);
   116       printText(o);
   117     }
   118     // otherwise print information about the specified range
   119     else
   120     {
   121       int artStart = -1;
   122       int artEnd   = -1;
   123       String[] nums = command[1].split("-");
   124       if(nums.length > 1)
   125       {
   126         try
   127         {
   128           artStart = Integer.parseInt(nums[0]);
   129         }
   130         catch(Exception e) 
   131         {
   132           artStart = Integer.parseInt(command[1]);
   133         }
   134         try
   135         {
   136           artEnd = Integer.parseInt(nums[1]);
   137         }
   138         catch(Exception e) {}
   139       }
   140 
   141       printStatus(224, "Overview information follows");
   142       for(int n = artStart; n <= artEnd; n++)
   143       {
   144         Article art = Article.getByNumberInGroup(getCurrentGroup(), n);
   145         if(art == null)
   146         {
   147           Debug.getInstance().log("Article (gid=" + getCurrentGroup() + ", art=" + n + " is null!");
   148         }
   149         else
   150         {
   151           printTextPart(buildOverview(art, n) + NEWLINE);
   152         }
   153       }
   154       println(".");
   155       flush();
   156     }
   157     
   158     return true;
   159   }
   160   
   161   private String buildOverview(Article art, int nr)
   162   {
   163     SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
   164     StringBuilder overview = new StringBuilder();
   165     overview.append(nr);
   166     overview.append('\t');
   167     overview.append(art.getHeader().get("Subject"));
   168     overview.append('\t');
   169     overview.append(art.getHeader().get("From"));
   170     overview.append('\t');
   171     overview.append(sdf.format(art.getDate()));
   172     overview.append('\t');
   173     overview.append(art.getHeader().get("Message-ID"));
   174     overview.append('\t');
   175     overview.append(art.getHeader().get("References"));
   176     overview.append('\t');
   177     overview.append(art.getHeader().get("Bytes"));
   178     overview.append('\t');
   179     overview.append(art.getHeader().get("Lines"));
   180     
   181     return overview.toString();
   182   }
   183 }