| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.commons.net.pop3.POP3 |
|
|
| 1 | /* |
|
| 2 | * Copyright 2001-2005 The Apache Software Foundation |
|
| 3 | * |
|
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 | * you may not use this file except in compliance with the License. |
|
| 6 | * You may obtain a copy of the License at |
|
| 7 | * |
|
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 | * |
|
| 10 | * Unless required by applicable law or agreed to in writing, software |
|
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 | * See the License for the specific language governing permissions and |
|
| 14 | * limitations under the License. |
|
| 15 | */ |
|
| 16 | package org.apache.commons.net.pop3; |
|
| 17 | ||
| 18 | import java.io.BufferedReader; |
|
| 19 | import java.io.BufferedWriter; |
|
| 20 | import java.io.EOFException; |
|
| 21 | import java.io.IOException; |
|
| 22 | import java.io.InputStreamReader; |
|
| 23 | import java.io.OutputStreamWriter; |
|
| 24 | import java.lang.StringBuffer; |
|
| 25 | import java.util.Enumeration; |
|
| 26 | import java.util.Vector; |
|
| 27 | import org.apache.commons.net.MalformedServerReplyException; |
|
| 28 | import org.apache.commons.net.ProtocolCommandListener; |
|
| 29 | import org.apache.commons.net.ProtocolCommandSupport; |
|
| 30 | import org.apache.commons.net.SocketClient; |
|
| 31 | ||
| 32 | /*** |
|
| 33 | * The POP3 class is not meant to be used by itself and is provided |
|
| 34 | * only so that you may easily implement your own POP3 client if |
|
| 35 | * you so desire. If you have no need to perform your own implementation, |
|
| 36 | * you should use {@link org.apache.commons.net.pop3.POP3Client}. |
|
| 37 | * <p> |
|
| 38 | * Rather than list it separately for each method, we mention here that |
|
| 39 | * every method communicating with the server and throwing an IOException |
|
| 40 | * can also throw a |
|
| 41 | * {@link org.apache.commons.net.MalformedServerReplyException} |
|
| 42 | * , which is a subclass |
|
| 43 | * of IOException. A MalformedServerReplyException will be thrown when |
|
| 44 | * the reply received from the server deviates enough from the protocol |
|
| 45 | * specification that it cannot be interpreted in a useful manner despite |
|
| 46 | * attempts to be as lenient as possible. |
|
| 47 | * <p> |
|
| 48 | * <p> |
|
| 49 | * @author Daniel F. Savarese |
|
| 50 | * @see POP3Client |
|
| 51 | * @see org.apache.commons.net.MalformedServerReplyException |
|
| 52 | ***/ |
|
| 53 | ||
| 54 | public class POP3 extends SocketClient |
|
| 55 | { |
|
| 56 | /*** The default POP3 port. Set to 110 according to RFC 1288. ***/ |
|
| 57 | public static final int DEFAULT_PORT = 110; |
|
| 58 | /*** |
|
| 59 | * A constant representing the state where the client is not yet connected |
|
| 60 | * to a POP3 server. |
|
| 61 | ***/ |
|
| 62 | public static final int DISCONNECTED_STATE = -1; |
|
| 63 | /*** A constant representing the POP3 authorization state. ***/ |
|
| 64 | public static final int AUTHORIZATION_STATE = 0; |
|
| 65 | /*** A constant representing the POP3 transaction state. ***/ |
|
| 66 | public static final int TRANSACTION_STATE = 1; |
|
| 67 | /*** A constant representing the POP3 update state. ***/ |
|
| 68 | public static final int UPDATE_STATE = 2; |
|
| 69 | ||
| 70 | static final String _OK = "+OK"; |
|
| 71 | static final String _ERROR = "-ERR"; |
|
| 72 | ||
| 73 | // We have to ensure that the protocol communication is in ASCII |
|
| 74 | // but we use ISO-8859-1 just in case 8-bit characters cross |
|
| 75 | // the wire. |
|
| 76 | private static final String __DEFAULT_ENCODING = "ISO-8859-1"; |
|
| 77 | ||
| 78 | private int __popState; |
|
| 79 | private BufferedWriter __writer; |
|
| 80 | private StringBuffer __commandBuffer; |
|
| 81 | ||
| 82 | BufferedReader _reader; |
|
| 83 | int _replyCode; |
|
| 84 | String _lastReplyLine; |
|
| 85 | Vector _replyLines; |
|
| 86 | ||
| 87 | /*** |
|
| 88 | * A ProtocolCommandSupport object used to manage the registering of |
|
| 89 | * ProtocolCommandListeners and te firing of ProtocolCommandEvents. |
|
| 90 | ***/ |
|
| 91 | protected ProtocolCommandSupport _commandSupport_; |
|
| 92 | ||
| 93 | /*** |
|
| 94 | * The default POP3Client constructor. Initializes the state |
|
| 95 | * to <code>DISCONNECTED_STATE</code>. |
|
| 96 | ***/ |
|
| 97 | public POP3() |
|
| 98 | 0 | { |
| 99 | 0 | setDefaultPort(DEFAULT_PORT); |
| 100 | 0 | __commandBuffer = new StringBuffer(); |
| 101 | 0 | __popState = DISCONNECTED_STATE; |
| 102 | 0 | _reader = null; |
| 103 | 0 | __writer = null; |
| 104 | 0 | _replyLines = new Vector(); |
| 105 | 0 | _commandSupport_ = new ProtocolCommandSupport(this); |
| 106 | 0 | } |
| 107 | ||
| 108 | private void __getReply() throws IOException |
|
| 109 | { |
|
| 110 | String line; |
|
| 111 | ||
| 112 | 0 | _replyLines.setSize(0); |
| 113 | 0 | line = _reader.readLine(); |
| 114 | ||
| 115 | 0 | if (line == null) |
| 116 | 0 | throw new EOFException("Connection closed without indication."); |
| 117 | ||
| 118 | 0 | if (line.startsWith(_OK)) |
| 119 | 0 | _replyCode = POP3Reply.OK; |
| 120 | 0 | else if (line.startsWith(_ERROR)) |
| 121 | 0 | _replyCode = POP3Reply.ERROR; |
| 122 | else |
|
| 123 | 0 | throw new |
| 124 | MalformedServerReplyException( |
|
| 125 | "Received invalid POP3 protocol response from server."); |
|
| 126 | ||
| 127 | 0 | _replyLines.addElement(line); |
| 128 | 0 | _lastReplyLine = line; |
| 129 | ||
| 130 | 0 | if (_commandSupport_.getListenerCount() > 0) |
| 131 | 0 | _commandSupport_.fireReplyReceived(_replyCode, getReplyString()); |
| 132 | 0 | } |
| 133 | ||
| 134 | ||
| 135 | /*** |
|
| 136 | * Performs connection initialization and sets state to |
|
| 137 | * <code> AUTHORIZATION_STATE </code>. |
|
| 138 | ***/ |
|
| 139 | protected void _connectAction_() throws IOException |
|
| 140 | { |
|
| 141 | 0 | super._connectAction_(); |
| 142 | 0 | _reader = |
| 143 | new BufferedReader(class="keyword">new InputStreamReader(_input_, |
|
| 144 | __DEFAULT_ENCODING)); |
|
| 145 | 0 | __writer = |
| 146 | new BufferedWriter(class="keyword">new OutputStreamWriter(_output_, |
|
| 147 | __DEFAULT_ENCODING)); |
|
| 148 | 0 | __getReply(); |
| 149 | 0 | setState(AUTHORIZATION_STATE); |
| 150 | 0 | } |
| 151 | ||
| 152 | ||
| 153 | /*** |
|
| 154 | * Adds a ProtocolCommandListener. Delegates this task to |
|
| 155 | * {@link #_commandSupport_ _commandSupport_ }. |
|
| 156 | * <p> |
|
| 157 | * @param listener The ProtocolCommandListener to add. |
|
| 158 | ***/ |
|
| 159 | public void addProtocolCommandListener(ProtocolCommandListener listener) |
|
| 160 | { |
|
| 161 | 0 | _commandSupport_.addProtocolCommandListener(listener); |
| 162 | 0 | } |
| 163 | ||
| 164 | /*** |
|
| 165 | * Removes a ProtocolCommandListener. Delegates this task to |
|
| 166 | * {@link #_commandSupport_ _commandSupport_ }. |
|
| 167 | * <p> |
|
| 168 | * @param listener The ProtocolCommandListener to remove. |
|
| 169 | ***/ |
|
| 170 | public void removeProtocolCommandistener(ProtocolCommandListener listener) |
|
| 171 | { |
|
| 172 | 0 | _commandSupport_.removeProtocolCommandListener(listener); |
| 173 | 0 | } |
| 174 | ||
| 175 | ||
| 176 | /*** |
|
| 177 | * Sets POP3 client state. This must be one of the |
|
| 178 | * <code>_STATE</code> constants. |
|
| 179 | * <p> |
|
| 180 | * @param state The new state. |
|
| 181 | ***/ |
|
| 182 | public void setState(int state) |
|
| 183 | { |
|
| 184 | 0 | __popState = state; |
| 185 | 0 | } |
| 186 | ||
| 187 | ||
| 188 | /*** |
|
| 189 | * Returns the current POP3 client state. |
|
| 190 | * <p> |
|
| 191 | * @return The current POP3 client state. |
|
| 192 | ***/ |
|
| 193 | public int getState() |
|
| 194 | { |
|
| 195 | 0 | return __popState; |
| 196 | } |
|
| 197 | ||
| 198 | ||
| 199 | /*** |
|
| 200 | * Retrieves the additional lines of a multi-line server reply. |
|
| 201 | ***/ |
|
| 202 | public void getAdditionalReply() throws IOException |
|
| 203 | { |
|
| 204 | String line; |
|
| 205 | ||
| 206 | 0 | line = _reader.readLine(); |
| 207 | 0 | while (line != null) |
| 208 | { |
|
| 209 | 0 | _replyLines.addElement(line); |
| 210 | 0 | if (line.equals(".")) |
| 211 | 0 | break; |
| 212 | 0 | line = _reader.readLine(); |
| 213 | } |
|
| 214 | 0 | } |
| 215 | ||
| 216 | ||
| 217 | /*** |
|
| 218 | * Disconnects the client from the server, and sets the state to |
|
| 219 | * <code> DISCONNECTED_STATE </code>. The reply text information |
|
| 220 | * from the last issued command is voided to allow garbage collection |
|
| 221 | * of the memory used to store that information. |
|
| 222 | * <p> |
|
| 223 | * @exception IOException If there is an error in disconnecting. |
|
| 224 | ***/ |
|
| 225 | public void disconnect() throws IOException |
|
| 226 | { |
|
| 227 | 0 | super.disconnect(); |
| 228 | 0 | _reader = null; |
| 229 | 0 | __writer = null; |
| 230 | 0 | _lastReplyLine = null; |
| 231 | 0 | _replyLines.setSize(0); |
| 232 | 0 | setState(DISCONNECTED_STATE); |
| 233 | 0 | } |
| 234 | ||
| 235 | ||
| 236 | /*** |
|
| 237 | * Sends a command an arguments to the server and returns the reply code. |
|
| 238 | * <p> |
|
| 239 | * @param command The POP3 command to send. |
|
| 240 | * @param args The command arguments. |
|
| 241 | * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). |
|
| 242 | ***/ |
|
| 243 | public int sendCommand(String command, String args) throws IOException |
|
| 244 | { |
|
| 245 | String message; |
|
| 246 | ||
| 247 | 0 | __commandBuffer.setLength(0); |
| 248 | 0 | __commandBuffer.append(command); |
| 249 | ||
| 250 | 0 | if (args != null) |
| 251 | { |
|
| 252 | 0 | __commandBuffer.append(' '); |
| 253 | 0 | __commandBuffer.append(args); |
| 254 | } |
|
| 255 | 0 | __commandBuffer.append(SocketClient.NETASCII_EOL); |
| 256 | ||
| 257 | 0 | __writer.write(message = __commandBuffer.toString()); |
| 258 | 0 | __writer.flush(); |
| 259 | ||
| 260 | 0 | if (_commandSupport_.getListenerCount() > 0) |
| 261 | 0 | _commandSupport_.fireCommandSent(command, message); |
| 262 | ||
| 263 | 0 | __getReply(); |
| 264 | 0 | return _replyCode; |
| 265 | } |
|
| 266 | ||
| 267 | /*** |
|
| 268 | * Sends a command with no arguments to the server and returns the |
|
| 269 | * reply code. |
|
| 270 | * <p> |
|
| 271 | * @param command The POP3 command to send. |
|
| 272 | * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). |
|
| 273 | ***/ |
|
| 274 | public int sendCommand(String command) throws IOException |
|
| 275 | { |
|
| 276 | 0 | return sendCommand(command, null); |
| 277 | } |
|
| 278 | ||
| 279 | /*** |
|
| 280 | * Sends a command an arguments to the server and returns the reply code. |
|
| 281 | * <p> |
|
| 282 | * @param command The POP3 command to send |
|
| 283 | * (one of the POP3Command constants). |
|
| 284 | * @param args The command arguments. |
|
| 285 | * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). |
|
| 286 | ***/ |
|
| 287 | public int sendCommand(class="keyword">int command, String args) throws IOException |
|
| 288 | { |
|
| 289 | 0 | return sendCommand(POP3Command._commands[command], args); |
| 290 | } |
|
| 291 | ||
| 292 | /*** |
|
| 293 | * Sends a command with no arguments to the server and returns the |
|
| 294 | * reply code. |
|
| 295 | * <p> |
|
| 296 | * @param command The POP3 command to send |
|
| 297 | * (one of the POP3Command constants). |
|
| 298 | * @return The server reply code (either POP3Reply.OK or POP3Reply.ERROR). |
|
| 299 | ***/ |
|
| 300 | public int sendCommand(class="keyword">int command) throws IOException |
|
| 301 | { |
|
| 302 | 0 | return sendCommand(POP3Command._commands[command], null); |
| 303 | } |
|
| 304 | ||
| 305 | ||
| 306 | /*** |
|
| 307 | * Returns an array of lines received as a reply to the last command |
|
| 308 | * sent to the server. The lines have end of lines truncated. If |
|
| 309 | * the reply is a single line, but its format ndicates it should be |
|
| 310 | * a multiline reply, then you must call |
|
| 311 | * {@link #getAdditionalReply getAdditionalReply() } to |
|
| 312 | * fetch the rest of the reply, and then call <code>getReplyStrings</code> |
|
| 313 | * again. You only have to worry about this if you are implementing |
|
| 314 | * your own client using the {@link #sendCommand sendCommand } methods. |
|
| 315 | * <p> |
|
| 316 | * @return The last server response. |
|
| 317 | ***/ |
|
| 318 | public String[] getReplyStrings() |
|
| 319 | { |
|
| 320 | String[] lines; |
|
| 321 | 0 | lines = new String[_replyLines.size()]; |
| 322 | 0 | _replyLines.copyInto(lines); |
| 323 | 0 | return lines; |
| 324 | } |
|
| 325 | ||
| 326 | /*** |
|
| 327 | * Returns the reply to the last command sent to the server. |
|
| 328 | * The value is a single string containing all the reply lines including |
|
| 329 | * newlines. If the reply is a single line, but its format ndicates it |
|
| 330 | * should be a multiline reply, then you must call |
|
| 331 | * {@link #getAdditionalReply getAdditionalReply() } to |
|
| 332 | * fetch the rest of the reply, and then call <code>getReplyString</code> |
|
| 333 | * again. You only have to worry about this if you are implementing |
|
| 334 | * your own client using the {@link #sendCommand sendCommand } methods. |
|
| 335 | * <p> |
|
| 336 | * @return The last server response. |
|
| 337 | ***/ |
|
| 338 | public String getReplyString() |
|
| 339 | { |
|
| 340 | Enumeration en; |
|
| 341 | 0 | StringBuffer buffer = new StringBuffer(256); |
| 342 | ||
| 343 | 0 | en = _replyLines.elements(); |
| 344 | 0 | while (en.hasMoreElements()) |
| 345 | { |
|
| 346 | 0 | buffer.append((String)en.nextElement()); |
| 347 | 0 | buffer.append(SocketClient.NETASCII_EOL); |
| 348 | } |
|
| 349 | ||
| 350 | 0 | return buffer.toString(); |
| 351 | } |
|
| 352 | ||
| 353 | } |
|
| 354 |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |