KickJava   Java API By Example, From Geeks To Geeks.

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


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.ArrayList JavaDoc;
42 import java.util.Date JavaDoc;
43 import java.util.Enumeration JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.Properties JavaDoc;
47 import java.util.List JavaDoc;
48
49 import java.io.DataInputStream JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.io.InputStream JavaDoc;
52 import java.io.OutputStream JavaDoc;
53
54 import java.net.InetAddress JavaDoc;
55
56 import com.quadcap.io.HeaderEnumeration;
57 import com.quadcap.io.IO;
58
59 import com.quadcap.util.Debug;
60
61 /**
62  * This simple Pop3 agent transfers all new messages in a remote Pop3
63  * mailbox into the specified folder in the quadcap message store.
64  *
65  * <p>A more sophisticated agent would scan the headers first and apply
66  * filters to certain messages without having to fetch the bodies.
67  *
68  * @author Stan Bailes
69  */

70 public class Pop3Agent {
71     HashMap JavaDoc uidlMap = new HashMap JavaDoc();
72     String JavaDoc hostName = null;
73     int portNumber = 110;
74     String JavaDoc login = null;
75     String JavaDoc passwd = null;
76     int daysKeep = 999999;
77     boolean enabled = true;
78     
79     Session pop3 = null;
80
81     public void write(OutputStream JavaDoc w) throws IOException JavaDoc {
82         Iterator JavaDoc iter = uidlMap.keySet().iterator();
83         while (iter.hasNext()) {
84             UidlEntry u = (UidlEntry)uidlMap.get(iter.next());
85             IO.write(w, "UIDL: " + u.toString() + "\n");
86         }
87     }
88
89     public void read(InputStream JavaDoc r) throws IOException JavaDoc {
90         DataInputStream JavaDoc d = new DataInputStream JavaDoc(r);
91         String JavaDoc line;
92         while ((line = d.readLine()) != null) {
93             if (line.startsWith("UIDL: ")) {
94                 line = line.substring(6).trim();
95                 UidlEntry uidl = new UidlEntry(line);
96                 uidlMap.put(uidl.getUidl(), uidl);
97             }
98         }
99     }
100
101     /**
102      * Default constructor for factory
103      */

104     public Pop3Agent() {
105     }
106
107     /**
108      * Check for mail
109      */

110     public void run(Properties JavaDoc props, MessageHook hook) {
111         try {
112             hostName = props.getProperty("host");
113             portNumber = Integer.parseInt(props.getProperty("port", "110"));
114             login = props.getProperty("user");
115             passwd = props.getProperty("passwd");
116             daysKeep = Integer.parseInt(props.getProperty("daysKeep", "3"));
117             enabled = "true".equalsIgnoreCase(props.getProperty("enabled",
118                                                                 "true"));
119             if (!enabled) return;
120
121             if (pop3 == null) {
122                 pop3 = new Session(hostName, portNumber);
123             }
124             pop3.connect();
125
126             int ret = pop3.user(login);
127             if (ret != Session.OK) {
128                 throw new IOException JavaDoc("login failed");
129             }
130
131             ret = pop3.pass(passwd);
132             if (ret != Session.OK) {
133                 throw new IOException JavaDoc("login (passwd) failed");
134             }
135         
136             getMail(hook);
137         } catch (Throwable JavaDoc t) {
138             Debug.print(t);
139         } finally {
140             try {
141                 if (pop3 != null) pop3.quit();
142             } catch (IOException JavaDoc e) {
143                 Debug.print(e);
144             }
145             // ---- we're about to "go to sleep", potentially for a long time,
146
// ---- so allow these objects to be gc'ed.
147
pop3 = null;
148         }
149     }
150
151
152     /**
153      * Figure out what's new and deliver it. Figure out what's old
154      * and delete it.
155      */

156     void getMail(MessageHook hook) throws IOException JavaDoc {
157     InputStream JavaDoc uidls = pop3.uidl();
158     ArrayList JavaDoc newMessages = new ArrayList JavaDoc(); // list of uidls
159
ArrayList JavaDoc delMessages = new ArrayList JavaDoc(); // list of msgnums
160
int msgNum = 0;
161     String JavaDoc uidl = null;
162     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
163     Date JavaDoc now = new Date JavaDoc();
164     long ms = daysKeep * 24L * 60 * 60 * 1000;
165     Date JavaDoc windowStart = new Date JavaDoc(now.getTime() - ms);
166     int c = uidls.read();
167     while (c >= 0) {
168         while (Character.isDigit((char)c)) {
169         sb.append((char)c);
170         c = uidls.read();
171         }
172         if (sb.length() == 0) {
173         if (c < 0) break;
174         else {
175             c = uidls.read();
176             continue;
177         }
178         }
179         msgNum = Integer.parseInt(sb.toString());
180
181         sb.setLength(0);
182         while (Character.isWhitespace((char)c)) {
183         c = uidls.read();
184         }
185         if (c < 0) continue;
186         while (c >= 0x21 && c <= 0x7e) {
187         sb.append((char)c);
188         c = uidls.read();
189         }
190         uidl = sb.toString();
191         sb.setLength(0);
192         UidlEntry e = getUidlEntry(uidl);
193         if (e == null) {
194         e = putUidlEntry(uidl, msgNum, now);
195         newMessages.add(e);
196         } else {
197         e.setMessageNumber(msgNum);
198         if (e.getFirstSeen().before(windowStart)) {
199                     if (!e.markedForDeletion) {
200                         delMessages.add(e);
201                         e.markedForDeletion = true;
202                     }
203         }
204         }
205         while (c >= 0 && c != 0x0a) {
206         c = uidls.read();
207         }
208         if (c == 0x0a) c = uidls.read();
209     }
210     getMessages(hook, newMessages);
211     deleteMessages(delMessages);
212     }
213
214     /**
215      * Get the specified list of messages.
216      *
217      * @param v a ArrayList of UidlEntry types, specifying the messages to get.
218      */

219     void getMessages(MessageHook hook, ArrayList JavaDoc v) throws IOException JavaDoc {
220     for (int i = 0; i < v.size(); i++) {
221         UidlEntry e = (UidlEntry)v.get(i);
222         int msg = e.getMessageNumber();
223             boolean pass = hook.passAllHeaders();
224             if (!pass) {
225                 InputStream JavaDoc is = pop3.top("" + msg, 0);
226                 try {
227                     HashMap JavaDoc map = new HashMap JavaDoc();
228                     new HeaderEnumeration(is).getHeaderMap(map);
229                     pass = hook.passHeaders(map);
230                 } finally {
231                     is.close();
232                 }
233             }
234             if (pass) {
235                 InputStream JavaDoc body = pop3.retr("" + msg);
236                 try {
237                     if (hook.passMessage(body)) {
238                         if (!e.markedForDeletion) {
239                             pop3.dele(msg);
240                             e.markedForDeletion = true;
241                         }
242                     }
243                 } catch (IOException JavaDoc e1) {
244                     Debug.print(e1);
245                     throw e1;
246                 } catch (Exception JavaDoc e2) {
247                     //#ifdef DEBUG
248
Debug.print(e2);
249                     //#endif
250
throw new IOException JavaDoc(e2.toString());
251                 } finally {
252                     body.close();
253                 }
254             }
255     }
256     }
257
258     /**
259      * Delete the specified list of messages.
260      *
261      * @param v a ArrayList of UidlEntry types, specifying the
262      * messages to delete.
263      */

264     void deleteMessages(ArrayList JavaDoc v) throws IOException JavaDoc {
265     for (int i = 0; i < v.size(); i++) {
266         UidlEntry e = (UidlEntry)v.get(i);
267         int msg = e.getMessageNumber();
268         pop3.dele(msg);
269             uidlMap.remove(e.getUidl());
270     }
271     }
272     
273     /**
274      * Search the map for a specified <b>UIDL</b> entry.
275      *
276      * @param uidl the UIDL text to search for
277      *
278      * @return if found, the corresponding entry in the map. Otherwise, null.
279      */

280     UidlEntry getUidlEntry(String JavaDoc uidl) {
281     return (UidlEntry)uidlMap.get(uidl);
282     }
283
284     /**
285      * Create and store a new UidlEntry in the map.
286      *
287      * @param uidl the UIDL text
288      * @param msgNum the current POP3 session's message number.
289      * @param d the date for this entry.
290      *
291      * @return the new UidlEntry
292      */

293     UidlEntry putUidlEntry(String JavaDoc uidl, int msgNum, Date JavaDoc d) {
294     UidlEntry e = new UidlEntry(uidl, msgNum, d);
295     uidlMap.put(uidl, e);
296     return e;
297     }
298 }
299
Popular Tags