1 package org.apache.commons.net.pop3;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache Commons" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import java.io.BufferedReader;
58 import java.io.BufferedWriter;
59 import java.io.EOFException;
60 import java.io.IOException;
61 import java.io.InputStreamReader;
62 import java.io.OutputStreamWriter;
63 import java.lang.StringBuffer;
64 import java.util.Enumeration;
65 import java.util.Vector;
66 import org.apache.commons.net.MalformedServerReplyException;
67 import org.apache.commons.net.ProtocolCommandListener;
68 import org.apache.commons.net.ProtocolCommandSupport;
69 import org.apache.commons.net.SocketClient;
70
71 /****
72 * The POP3 class is not meant to be used by itself and is provided
73 * only so that you may easily implement your own POP3 client if
74 * you so desire. If you have no need to perform your own implementation,
75 * you should use <a href="org.apache.commons.net.pop3.POP3Client.html">POP3Client</a>.
76 * <p>
77 * Rather than list it separately for each method, we mention here that
78 * every method communicating with the server and throwing an IOException
79 * can also throw a
80 * <a href="org.apache.commons.net.MalformedServerReplyException.html">
81 * MalformedServerReplyException </a>, which is a subclass
82 * of IOException. A MalformedServerReplyException will be thrown when
83 * the reply received from the server deviates enough from the protocol
84 * specification that it cannot be interpreted in a useful manner despite
85 * attempts to be as lenient as possible.
86 * <p>
87 * <p>
88 * @author Daniel F. Savarese
89 * @see POP3Client
90 * @see org.apache.commons.net.MalformedServerReplyException
91 ***/
92
93 public class POP3 extends SocketClient
94 {
95 /**** The default POP3 port. Set to 110 according to RFC 1288. ***/
96 public static final int DEFAULT_PORT = 110;
97 /****
98 * A constant representing the state where the client is not yet connected
99 * to a POP3 server.
100 ***/
101 public static final int DISCONNECTED_STATE = -1;
102 /**** A constant representing the POP3 authorization state. ***/
103 public static final int AUTHORIZATION_STATE = 0;
104 /**** A constant representing the POP3 transaction state. ***/
105 public static final int TRANSACTION_STATE = 1;
106 /**** A constant representing the POP3 update state. ***/
107 public static final int UPDATE_STATE = 2;
108
109 static final String _OK = "+OK";
110 static final String _ERROR = "-ERR";
111
112 private int __popState;
113 private BufferedWriter __writer;
114 private StringBuffer __commandBuffer;
115
116 BufferedReader _reader;
117 int _replyCode;
118 String _lastReplyLine;
119 Vector _replyLines;
120
121 /****
122 * A ProtocolCommandSupport object used to manage the registering of
123 * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
124 ***/
125 protected ProtocolCommandSupport _commandSupport_;
126
127 /****
128 * The default POP3Client constructor. Initializes the state
129 * to <code>DISCONNECTED_STATE</code>.
130 ***/
131 public POP3()
132 {
133 setDefaultPort(DEFAULT_PORT);
134 __commandBuffer = new StringBuffer();
135 __popState = DISCONNECTED_STATE;
136 _reader = null;
137 __writer = null;
138 _replyLines = new Vector();
139 _commandSupport_ = new ProtocolCommandSupport(this);
140 }
141
142 private void __getReply() throws IOException
143 {
144 String line;
145
146 _replyLines.setSize(0);
147 line = _reader.readLine();
148
149 if (line == null)
150 throw new EOFException("Connection closed without indication.");
151
152 if (line.startsWith(_OK))
153 _replyCode = POP3Reply.OK;
154 else if (line.startsWith(_ERROR))
155 _replyCode = POP3Reply.ERROR;
156 else
157 throw new
158 MalformedServerReplyException(
159 "Received invalid POP3 protocol response from server.");
160
161 if (_commandSupport_.getListenerCount() > 0)
162 _commandSupport_.fireReplyReceived(_replyCode, getReplyString());
163
164 _replyLines.addElement(line);
165 _lastReplyLine = line;
166 }
167
168
169 /****
170 * Performs connection initialization and sets state to
171 * <code> AUTHORIZATION_STATE </code>.
172 ***/
173 protected void _connectAction_() throws IOException
174 {
175 super._connectAction_();
176 _reader = new BufferedReader(new InputStreamReader(_input_));
177 __writer = new BufferedWriter(new OutputStreamWriter(_output_));
178 __getReply();
179 setState(AUTHORIZATION_STATE);
180 }
181
182
183 /****
184 * Adds a ProtocolCommandListener. Delegates this task to
185 * <a href="#_commandSupport_"> _commandSupport_ </a>.
186 * <p>
187 * @param listener The ProtocolCommandListener to add.
188 ***/
189 public void addProtocolCommandListener(ProtocolCommandListener listener)
190 {
191 _commandSupport_.addProtocolCommandListener(listener);
192 }
193
194 /****
195 * Removes a ProtocolCommandListener. Delegates this task to
196 * <a href="#_commandSupport_"> _commandSupport_ </a>.
197 * <p>
198 * @param listener The ProtocolCommandListener to remove.
199 ***/
200 public void removeProtocolCommandistener(ProtocolCommandListener listener)
201 {
202 _commandSupport_.removeProtocolCommandListener(listener);
203 }
204
205
206 /****
207 * Sets POP3 client state. This must be one of the
208 * <code>_STATE</code> constants.
209 * <p>
210 * @param state The new state.
211 ***/
212 public void setState(int state)
213 {
214 __popState = state;
215 }
216
217
218 /****
219 * Returns the current POP3 client state.
220 * <p>
221 * @return The current POP3 client state.
222 ***/
223 public int getState()
224 {
225 return __popState;
226 }
227
228
229 /****
230 * Retrieves the additional lines of a multi-line server reply.
231 ***/
232 public void getAdditionalReply() throws IOException
233 {
234 String line;
235
236 line = _reader.readLine();
237 while (line != null)
238 {
239 _replyLines.addElement(line);
240 if (line.equals("."))
241 break;
242 line = _reader.readLine();
243 }
244 }
245
246
247 /****
248 * Disconnects the client from the server, and sets the state to
249 * <code> DISCONNECTED_STATE </code>. The reply text information
250 * from the last issued command is voided to allow garbage collection
251 * of the memory used to store that information.
252 * <p>
253 * @exception IOException If there is an error in disconnecting.
254 ***/
255 public void disconnect() throws IOException
256 {
257 super.disconnect();
258 _reader = null;
259 __writer = null;
260 _lastReplyLine = null;
261 _replyLines.setSize(0);
262 setState(DISCONNECTED_STATE);
263 }
264
265
266 /****
267 * Sends a command an arguments to the server and returns the reply code.
268 * <p>
269 * @param command The POP3 command to send.
270 * @param args The command arguments.
271 * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
272 ***/
273 public int sendCommand(String command, String args) throws IOException
274 {
275 String message;
276
277 __commandBuffer.setLength(0);
278 __commandBuffer.append(command);
279
280 if (args != null)
281 {
282 __commandBuffer.append(' ');
283 __commandBuffer.append(args);
284 }
285 __commandBuffer.append(SocketClient.NETASCII_EOL);
286
287 __writer.write(message = __commandBuffer.toString());
288 __writer.flush();
289
290 if (_commandSupport_.getListenerCount() > 0)
291 _commandSupport_.fireCommandSent(command, message);
292
293 __getReply();
294 return _replyCode;
295 }
296
297 /****
298 * Sends a command with no arguments to the server and returns the
299 * reply code.
300 * <p>
301 * @param command The POP3 command to send.
302 * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
303 ***/
304 public int sendCommand(String command) throws IOException
305 {
306 return sendCommand(command, null);
307 }
308
309 /****
310 * Sends a command an arguments to the server and returns the reply code.
311 * <p>
312 * @param command The POP3 command to send
313 * (one of the POP3Command constants).
314 * @param args The command arguments.
315 * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
316 ***/
317 public int sendCommand(int command, String args) throws IOException
318 {
319 return sendCommand(POP3Command._commands[command], args);
320 }
321
322 /****
323 * Sends a command with no arguments to the server and returns the
324 * reply code.
325 * <p>
326 * @param command The POP3 command to send
327 * (one of the POP3Command constants).
328 * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR).
329 ***/
330 public int sendCommand(int command) throws IOException
331 {
332 return sendCommand(POP3Command._commands[command], null);
333 }
334
335
336 /****
337 * Returns an array of lines received as a reply to the last command
338 * sent to the server. The lines have end of lines truncated. If
339 * the reply is a single line, but its format ndicates it should be
340 * a multiline reply, then you must call
341 * <a href="#getAdditionalReply"> getAdditionalReply() </a> to
342 * fetch the rest of the reply, and then call <code>getReplyStrings</code>
343 * again. You only have to worry about this if you are implementing
344 * your own client using the <a href="#sendComand"> sendCommand </a> methods.
345 * <p>
346 * @return The last server response.
347 ***/
348 public String[] getReplyStrings()
349 {
350 String[] lines;
351 lines = new String[_replyLines.size()];
352 _replyLines.copyInto(lines);
353 return lines;
354 }
355
356 /****
357 * Returns the reply to the last command sent to the server.
358 * The value is a single string containing all the reply lines including
359 * newlines. If the reply is a single line, but its format ndicates it
360 * should be a multiline reply, then you must call
361 * <a href="#getAdditionalReply"> getAdditionalReply() </a> to
362 * fetch the rest of the reply, and then call <code>getReplyString</code>
363 * again. You only have to worry about this if you are implementing
364 * your own client using the <a href="#sendComand"> sendCommand </a> methods.
365 * <p>
366 * @return The last server response.
367 ***/
368 public String getReplyString()
369 {
370 Enumeration enum;
371 StringBuffer buffer = new StringBuffer(256);
372
373 enum = _replyLines.elements();
374 while (enum.hasMoreElements())
375 {
376 buffer.append((String)enum.nextElement());
377 buffer.append(SocketClient.NETASCII_EOL);
378 }
379
380 return buffer.toString();
381 }
382
383 }
384
This page was automatically generated by Maven