View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  
21  
22  package org.apache.james.pop3server;
23  
24  import org.apache.james.util.stream.ExtraDotOutputStream;
25  import org.apache.james.util.watchdog.BytesWrittenResetOutputStream;
26  import org.apache.mailet.Mail;
27  
28  import javax.mail.MessagingException;
29  import javax.mail.internet.MimeMessage;
30  
31  import java.io.BufferedReader;
32  import java.io.IOException;
33  import java.io.InputStreamReader;
34  import java.io.OutputStream;
35  import java.util.Enumeration;
36  
37  /**
38    * Handles TOP command
39    */
40  public class TopCmdHandler implements CommandHandler {
41  
42      /**
43       * @see org.apache.james.pop3server.CommandHandler#onCommand(POP3Session)
44       */
45      public void onCommand(POP3Session session) {
46          doTOP(session,session.getCommandArgument());
47      }
48  
49      /**
50       * Handler method called upon receipt of a TOP command.
51       * This command retrieves the top N lines of a specified
52       * message in the mailbox.
53       *
54       * The expected command format is
55       *  TOP [mail message number] [number of lines to return]
56       *
57       * @param arguments the first argument parsed by the parseCommand method
58       */
59      private void doTOP(POP3Session session,String arguments) {
60          String responseString = null;
61          
62          if (arguments == null) {
63              responseString = POP3Handler.ERR_RESPONSE + " Usage: TOP [mail number] [Line number]";
64              session.writeResponse(responseString);
65              return;
66          }
67          
68          String argument = "";
69          String argument1 = "";
70          int pos = arguments.indexOf(" ");
71          if (pos > 0) {
72              argument = arguments.substring(0,pos);
73              argument1 = arguments.substring(pos+1);
74          }
75  
76          if (session.getHandlerState() == POP3Handler.TRANSACTION) {
77              int num = 0;
78              int lines = 0;
79              try {
80                  num = Integer.parseInt(argument);
81                  lines = Integer.parseInt(argument1);
82              } catch (NumberFormatException nfe) {
83                  responseString = POP3Handler.ERR_RESPONSE + " Usage: TOP [mail number] [Line number]";
84                  session.writeResponse(responseString);
85                  return;
86              }
87              try {
88                  Mail mc = (Mail) session.getUserMailbox().get(num);
89                  if (mc != POP3Handler.DELETED) {
90                      responseString = POP3Handler.OK_RESPONSE + " Message follows";
91                      session.writeResponse(responseString);
92                      try {
93                          for (Enumeration e = mc.getMessage().getAllHeaderLines(); e.hasMoreElements(); ) {
94                              session.writeResponse(e.nextElement().toString());
95                          }
96                          session.writeResponse("");
97                          ExtraDotOutputStream edouts =
98                                  new ExtraDotOutputStream(session.getOutputStream());
99                          OutputStream nouts = new BytesWrittenResetOutputStream(edouts,
100                                                                   session.getWatchdog(),
101                                                                   session.getConfigurationData().getResetLength());
102                         writeMessageContentTo(mc.getMessage(),nouts,lines);
103                         nouts.flush();
104                         edouts.checkCRLFTerminator();
105                         edouts.flush();
106                     } finally {
107                         session.writeResponse(".");
108                     }
109                 } else {
110                     StringBuffer responseBuffer =
111                         new StringBuffer(64)
112                                 .append(POP3Handler.ERR_RESPONSE)
113                                 .append(" Message (")
114                                 .append(num)
115                                 .append(") already deleted.");
116                     responseString = responseBuffer.toString();
117                     session.writeResponse(responseString);
118                 }
119             } catch (IOException ioe) {
120                 responseString = POP3Handler.ERR_RESPONSE + " Error while retrieving message.";
121                 session.writeResponse(responseString);
122             } catch (MessagingException me) {
123                 responseString = POP3Handler.ERR_RESPONSE + " Error while retrieving message.";
124                 session.writeResponse(responseString);
125             } catch (IndexOutOfBoundsException iob) {
126                 StringBuffer exceptionBuffer =
127                     new StringBuffer(64)
128                             .append(POP3Handler.ERR_RESPONSE)
129                             .append(" Message (")
130                             .append(num)
131                             .append(") does not exist.");
132                 responseString = exceptionBuffer.toString();
133                 session.writeResponse(responseString);
134             }
135         } else {
136             responseString = POP3Handler.ERR_RESPONSE;
137             session.writeResponse(responseString);
138         }
139     }
140 
141 
142     /**
143      * Writes the content of the message, up to a total number of lines, out to 
144      * an OutputStream.
145      *
146      * @param out the OutputStream to which to write the content
147      * @param lines the number of lines to write to the stream
148      *
149      * @throws MessagingException if the MimeMessage is not set for this MailImpl
150      * @throws IOException if an error occurs while reading or writing from the stream
151      */
152     public void writeMessageContentTo(MimeMessage message, OutputStream out, int lines)
153         throws IOException, MessagingException {
154         String line;
155         BufferedReader br;
156         if (message != null) {
157             br = new BufferedReader(new InputStreamReader(message.getRawInputStream()));
158             try {
159                 while (lines-- > 0) {
160                     if ((line = br.readLine()) == null) {
161                         break;
162                     }
163                     line += "\r\n";
164                     out.write(line.getBytes());
165                 }
166             } finally {
167                 br.close();
168             }
169         } else {
170             throw new MessagingException("No message set for this MailImpl.");
171         }
172     }
173 
174 }