All Downloads are FREE. Search and download functionalities are using the official Maven repository.

panda.net.pop3.POP3 Maven / Gradle / Ivy

There is a newer version: 1.8.0
Show newest version
package panda.net.pop3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

import panda.net.MalformedServerReplyException;
import panda.net.ProtocolCommandSupport;
import panda.net.SocketClient;
import panda.net.io.CRLFLineReader;

/***
 * The POP3 class is not meant to be used by itself and is provided only so that you may easily
 * implement your own POP3 client if you so desire. If you have no need to perform your own
 * implementation, you should use {@link panda.net.pop3.POP3Client}.
 * 

* Rather than list it separately for each method, we mention here that every method communicating * with the server and throwing an IOException can also throw a * {@link panda.net.MalformedServerReplyException} , which is a subclass of IOException. A * MalformedServerReplyException will be thrown when the reply received from the server deviates * enough from the protocol specification that it cannot be interpreted in a useful manner despite * attempts to be as lenient as possible. * * @see POP3Client * @see panda.net.MalformedServerReplyException ***/ public class POP3 extends SocketClient { /*** The default POP3 port. Set to 110 according to RFC 1288. ***/ public static final int DEFAULT_PORT = 110; /*** * A constant representing the state where the client is not yet connected to a POP3 server. ***/ public static final int DISCONNECTED_STATE = -1; /*** A constant representing the POP3 authorization state. ***/ public static final int AUTHORIZATION_STATE = 0; /*** A constant representing the POP3 transaction state. ***/ public static final int TRANSACTION_STATE = 1; /*** A constant representing the POP3 update state. ***/ public static final int UPDATE_STATE = 2; static final String _OK = "+OK"; // The reply indicating intermediate response to a command. static final String _OK_INT = "+ "; static final String _ERROR = "-ERR"; // We have to ensure that the protocol communication is in ASCII // but we use ISO-8859-1 just in case 8-bit characters cross // the wire. static final String _DEFAULT_ENCODING = "ISO-8859-1"; private int __popState; BufferedWriter _writer; BufferedReader _reader; int _replyCode; String _lastReplyLine; List _replyLines; /** * A ProtocolCommandSupport object used to manage the registering of ProtocolCommandListeners * and te firing of ProtocolCommandEvents. */ protected ProtocolCommandSupport _commandSupport_; /*** * The default POP3Client constructor. Initializes the state to DISCONNECTED_STATE. ***/ public POP3() { setDefaultPort(DEFAULT_PORT); __popState = DISCONNECTED_STATE; _reader = null; _writer = null; _replyLines = new ArrayList(); _commandSupport_ = new ProtocolCommandSupport(this); } private void __getReply() throws IOException { String line; _replyLines.clear(); line = _reader.readLine(); if (line == null) { throw new EOFException("Connection closed without indication."); } if (line.startsWith(_OK)) { _replyCode = POP3Reply.OK; } else if (line.startsWith(_ERROR)) { _replyCode = POP3Reply.ERROR; } else if (line.startsWith(_OK_INT)) { _replyCode = POP3Reply.OK_INT; } else { throw new MalformedServerReplyException("Received invalid POP3 protocol response from server." + line); } _replyLines.add(line); _lastReplyLine = line; fireReplyReceived(_replyCode, getReplyString()); } /*** * Performs connection initialization and sets state to AUTHORIZATION_STATE . ***/ @Override protected void _connectAction_() throws IOException { super._connectAction_(); _reader = new CRLFLineReader(new InputStreamReader(_input_, _DEFAULT_ENCODING)); _writer = new BufferedWriter(new OutputStreamWriter(_output_, _DEFAULT_ENCODING)); __getReply(); setState(AUTHORIZATION_STATE); } /** * Set the internal POP3 state. * * @param state the new state. This must be one of the _STATE constants. */ public void setState(int state) { __popState = state; } /*** * Returns the current POP3 client state. * * @return The current POP3 client state. ***/ public int getState() { return __popState; } /*** * Retrieves the additional lines of a multi-line server reply. * * @throws IOException on error ***/ public void getAdditionalReply() throws IOException { String line; line = _reader.readLine(); while (line != null) { _replyLines.add(line); if (line.equals(".")) { break; } line = _reader.readLine(); } } /*** * Disconnects the client from the server, and sets the state to * DISCONNECTED_STATE . The reply text information from the last issued command is * voided to allow garbage collection of the memory used to store that information. * * @exception IOException If there is an error in disconnecting. ***/ @Override public void disconnect() throws IOException { super.disconnect(); _reader = null; _writer = null; _lastReplyLine = null; _replyLines.clear(); setState(DISCONNECTED_STATE); } /*** * Sends a command an arguments to the server and returns the reply code. * * @param command The POP3 command to send. * @param args The command arguments. * @return The server reply code (either POP3Reply.OK, POP3Reply.ERROR or POP3Reply.OK_INT). * @throws IOException on error ***/ public int sendCommand(String command, String args) throws IOException { if (_writer == null) { throw new IllegalStateException("Socket is not connected"); } StringBuilder __commandBuffer = new StringBuilder(); __commandBuffer.append(command); if (args != null) { __commandBuffer.append(' '); __commandBuffer.append(args); } __commandBuffer.append(SocketClient.NETASCII_EOL); String message = __commandBuffer.toString(); _writer.write(message); _writer.flush(); fireCommandSent(command, message); __getReply(); return _replyCode; } /*** * Sends a command with no arguments to the server and returns the reply code. * * @param command The POP3 command to send. * @return The server reply code (either POP3Reply.OK, POP3Reply.ERROR or POP3Reply.OK_INT). * @throws IOException on error ***/ public int sendCommand(String command) throws IOException { return sendCommand(command, null); } /*** * Sends a command an arguments to the server and returns the reply code. * * @param command The POP3 command to send (one of the POP3Command constants). * @param args The command arguments. * @return The server reply code (either POP3Reply.OK, POP3Reply.ERROR or POP3Reply.OK_INT). * @throws IOException on error ***/ public int sendCommand(int command, String args) throws IOException { return sendCommand(POP3Command._commands[command], args); } /*** * Sends a command with no arguments to the server and returns the reply code. * * @param command The POP3 command to send (one of the POP3Command constants). * @return The server reply code (either POP3Reply.OK, POP3Reply.ERROR or POP3Reply.OK_INT). * @throws IOException on error ***/ public int sendCommand(int command) throws IOException { return sendCommand(POP3Command._commands[command], null); } /*** * Returns an array of lines received as a reply to the last command sent to the server. The * lines have end of lines truncated. If the reply is a single line, but its format ndicates it * should be a multiline reply, then you must call {@link #getAdditionalReply * getAdditionalReply() } to fetch the rest of the reply, and then call * getReplyStrings again. You only have to worry about this if you are implementing * your own client using the {@link #sendCommand sendCommand } methods. * * @return The last server response. ***/ public String[] getReplyStrings() { return _replyLines.toArray(new String[_replyLines.size()]); } /*** * Returns the reply to the last command sent to the server. The value is a single string * containing all the reply lines including newlines. If the reply is a single line, but its * format ndicates it should be a multiline reply, then you must call * {@link #getAdditionalReply getAdditionalReply() } to fetch the rest of the reply, and then * call getReplyString again. You only have to worry about this if you are * implementing your own client using the {@link #sendCommand sendCommand } methods. * * @return The last server response. ***/ public String getReplyString() { StringBuilder buffer = new StringBuilder(256); for (String entry : _replyLines) { buffer.append(entry); buffer.append(SocketClient.NETASCII_EOL); } return buffer.toString(); } /** * Removes a ProtocolCommandListener. Delegates this incorrectly named method - * removeProtocolCommandistener (note the missing "L")- to the correct method * {@link SocketClient#removeProtocolCommandListener} * * @param listener The ProtocolCommandListener to remove */ public void removeProtocolCommandistener(panda.net.ProtocolCommandListener listener) { removeProtocolCommandListener(listener); } /** * Provide command support to super-class */ @Override protected ProtocolCommandSupport getCommandSupport() { return _commandSupport_; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy