KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > pop3 > client > Session


1 package com.quadcap.pop3.client;
2
3 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.util.Enumeration JavaDoc;
42 import java.util.Vector JavaDoc;
43
44 import java.net.Socket JavaDoc;
45 import java.net.UnknownHostException JavaDoc;
46
47 import java.io.BufferedInputStream JavaDoc;
48 import java.io.BufferedOutputStream JavaDoc;
49 import java.io.ByteArrayOutputStream JavaDoc;
50 import java.io.FileOutputStream JavaDoc;
51 import java.io.IOException JavaDoc;
52 import java.io.InputStream JavaDoc;
53 import java.io.OutputStream JavaDoc;
54
55 import com.quadcap.util.Debug;
56 import com.quadcap.util.Util;
57
58 import com.quadcap.io.DotStuffInputStream;
59 import com.quadcap.io.LogInputStream;
60 import com.quadcap.io.LogOutputStream;
61
62
63 /**
64  * This class implementes a simple mapping of the POP3 protocol onto methods
65  * of a java class.
66  *
67  * @author Stan Bailes
68  */

69 public class Session {
70     /**
71      * server portion of host address.
72      */

73     String JavaDoc host = null;
74     /**
75      * the port portion of the host address.
76      */

77     int port = -1;
78
79     /**
80      * Sockect used to communicate with the server.
81      */

82     Socket JavaDoc socket = null;
83
84     /**
85      * Input (responses) from server.
86      */

87     InputStream JavaDoc in = null;
88
89     /**
90      * Output (commands) to the server.
91      */

92     OutputStream JavaDoc out = null;
93
94     /**
95      * A temporary area used to collect server responses.
96      */

97     ByteArrayOutputStream JavaDoc resp = new ByteArrayOutputStream JavaDoc();
98
99     /**
100      * The last response, as a string.
101      */

102     String JavaDoc response = null;
103
104     /**
105      * Construct a POP3 client object.
106      * Initialize the host/port information, but don't actually open the
107      * socket.
108      *
109      * @param host the server's host name
110      * @param port the server's port number
111      */

112     public Session(String JavaDoc host, int port) {
113     this.host = host;
114     this.port = port;
115     }
116
117     /**
118      * Open the socket to the server and return the status code for the
119      * server's greeting.
120      */

121     public int connect() throws IOException JavaDoc, UnknownHostException JavaDoc {
122     socket = new Socket JavaDoc(host, port);
123     // XXX Not buffered, why?
124
in = new BufferedInputStream JavaDoc(socket.getInputStream());
125     out = new BufferedOutputStream JavaDoc(socket.getOutputStream());
126
127         if (true) {
128             FileOutputStream JavaDoc log = new FileOutputStream JavaDoc("pop3.log", true);
129             in = new LogInputStream(in, log, "S: ");
130             out = new LogOutputStream(out, log, "C: ");
131         }
132         int ret = getResponse();
133     return ret;
134     }
135
136     /** Useful constant for CR. */
137     public static final int CR = '\r';
138     /** Useful constant for LF. */
139     public static final int LF = '\n';
140
141     /** Useful constant for OK status. */
142     public static final int OK = 0;
143     /** Useful constant for ERR status. */
144     public static final int ERR = 1;
145
146     /**
147      * Read a response line from the server. We expect this to be a string
148      * of the form '+OK ...' or '-ERR ...'.
149      *
150      * @return OK or ERR.
151      */

152     public int getResponse() throws IOException JavaDoc {
153     out.flush();
154     resp.reset();
155     int state = 0;
156     ByteArrayOutputStream JavaDoc bo = new ByteArrayOutputStream JavaDoc();
157     while (state < 2) {
158         int c = in.read();
159         if (c < 0) {
160         throw new IOException JavaDoc("End of file in getResponse()");
161         }
162         bo.write(c);
163         resp.write(c);
164         switch(state) {
165         case 0:
166         if (c == CR) state = 1;
167         break;
168         case 1:
169         if (c == LF) state = 2;
170         break;
171         }
172     }
173     response = resp.toString();
174     if (response.indexOf("+OK") == 0) {
175         return OK;
176     } else if (response.indexOf("-ERR") == 0) {
177         return ERR;
178     } else {
179         Debug.println("getResponse: ???");
180         return ERR;
181     }
182     }
183
184     /**
185      * Prepare to read multi-line response. Return an input stream
186      * which must be read to actually get the response.
187      */

188     public InputStream JavaDoc getResponse(boolean get) throws IOException JavaDoc {
189     int ret = getResponse();
190     return (get && ret == OK) ? new DotStuffInputStream(in) : null;
191     }
192
193     /** Handy constant for CRLF sequence. */
194     private static final byte[] CRLF = { CR, LF };
195
196     /**
197      * Write a POP3 command and arguments.
198      * @param cmd a byte array containing the command literal
199      * @param val a String to be appended to the 'cmd'
200      */

201     void writeCmd(byte[]cmd, String JavaDoc val) throws IOException JavaDoc {
202     out.write(cmd);
203     out.write(Util.bytes(val));
204     out.write(CRLF);
205     }
206
207     /**
208      * Execute a simple command which just expects an OR or ERR response.
209      */

210     int simpleCmd(byte[] cmd, String JavaDoc val) throws IOException JavaDoc {
211     writeCmd(cmd, val);
212     return getResponse();
213     }
214
215     /**
216      * Execute a command which expects a multi-line response.
217      */

218     InputStream JavaDoc responseCmd(byte[] cmd, String JavaDoc val) throws IOException JavaDoc {
219     writeCmd(cmd, val);
220     return getResponse(true);
221     }
222
223     /**
224      * Execute a command which needs to parse the response line.
225      */

226     Vector JavaDoc vectorCmd(byte[] cmd, String JavaDoc val) throws IOException JavaDoc {
227     writeCmd(cmd, val);
228     int ret = getResponse();
229     return Util.split(response, ' ');
230     }
231
232     /** The USER command. */
233     private static final byte[] userBytes = {(byte)'U',(byte)'S',
234                            (byte)'E',(byte)'R',
235                            (byte)' '};
236     public int user(String JavaDoc name) throws IOException JavaDoc {
237     return simpleCmd(userBytes, name);
238     }
239
240     /** The PASS command. */
241     private static final byte[] passBytes = {(byte)'P',(byte)'A',
242                            (byte)'S',(byte)'S',
243                            (byte)' '};
244     public int pass(String JavaDoc pass) throws IOException JavaDoc {
245     return simpleCmd(passBytes, pass);
246     }
247
248     /** The LIST command. */
249     private static final byte[] listBytes = {(byte)'L',(byte)'I',
250                            (byte)'S',(byte)'T',
251                            (byte)' '};
252     public InputStream JavaDoc list() throws IOException JavaDoc {
253     return responseCmd(listBytes, "");
254     }
255     public Vector JavaDoc list(String JavaDoc msg) throws IOException JavaDoc {
256     return vectorCmd(listBytes, msg);
257     }
258
259     /** The STAT command. */
260     private static final byte[] statBytes = {(byte)'S',(byte)'T',
261                            (byte)'A',(byte)'T',
262                            (byte)' '};
263     public Vector JavaDoc stat() throws IOException JavaDoc {
264     return vectorCmd(statBytes, "");
265     }
266
267     /** The UIDL command. */
268     private static final byte[] uidlBytes = {(byte)'U',(byte)'I',
269                            (byte)'D',(byte)'L',
270                            (byte)' '};
271     public InputStream JavaDoc uidl() throws IOException JavaDoc {
272     return responseCmd(uidlBytes, "");
273     }
274     public Vector JavaDoc uidl(String JavaDoc msg) throws IOException JavaDoc {
275     return vectorCmd(uidlBytes, msg);
276     }
277
278     /** The RETR command. */
279     private static final byte[] retrBytes = {(byte)'R',(byte)'E',
280                            (byte)'T',(byte)'R',
281                            (byte)' '};
282     public InputStream JavaDoc retr(String JavaDoc msg) throws IOException JavaDoc {
283     return responseCmd(retrBytes, msg);
284     }
285     public InputStream JavaDoc retr(int i) throws IOException JavaDoc { return retr("" + i); }
286
287     /** The DELE command. */
288     private static final byte[] deleBytes = {(byte)'D',(byte)'E',
289                            (byte)'L',(byte)'E',
290                            (byte)' '};
291     public int dele(String JavaDoc msg) throws IOException JavaDoc {
292     return simpleCmd(deleBytes, msg);
293     }
294     public int dele(int i) throws IOException JavaDoc { return dele("" + i); }
295
296     /** The TOP command. */
297     private static final byte[] topBytes = {(byte)'T',(byte)'O',
298                            (byte)'P',(byte)' '};
299     public InputStream JavaDoc top(String JavaDoc msg, int lines) throws IOException JavaDoc {
300     return responseCmd(topBytes, msg + " " + lines);
301     }
302
303     /** The RSET command. */
304     private static final byte[] rsetBytes = {(byte)'R',(byte)'S',
305                            (byte)'E',(byte)'T',
306                            (byte)' '};
307     public int rset() throws IOException JavaDoc {
308     return simpleCmd(rsetBytes, "");
309     }
310
311     /** THE QUIT command. */
312     private static final byte[] quitBytes = {(byte)'Q', (byte)'U',
313                            (byte)'I', (byte)'T',
314                            (byte)' '};
315     public int quit() throws IOException JavaDoc {
316     try {
317         simpleCmd(quitBytes, "");
318     } finally {
319         socket.close();
320     }
321     return OK;
322     }
323
324     /** The NOOP command. */
325     private static final byte[] noopBytes = {(byte)'N', (byte)'O',
326                            (byte)'O', (byte)'P',
327                            (byte)' '};
328
329     /** THE APOP command. */
330     private static final byte[] apopBytes = {(byte)'A', (byte)'P',
331                            (byte)'O', (byte)'P',
332                            (byte)' '};
333
334 }
335
Popular Tags