KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > answer


1 /*
2  * @(#)answer.java 1.10 01/10/26
3  *
4  * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  */

7
8 import java.util.*;
9 import java.io.*;
10 import javax.mail.*;
11 import javax.mail.search.*;
12 import javax.mail.internet.*;
13
14 /**
15  * Program to manage the javamail@Sun.COM mailing list by keeping track
16  * of which messages have been answered. Message that have been answered
17  * have the ANSWERED flag set. Messages that are replies to other messages
18  * have the FLAGGED flag set. <p>
19  *
20  * Note that this program operates on the log file directly and thus all
21  * access to the log file using this program must be through the same
22  * IMAP server so that the flags are handled consistently. <p>
23  *
24  * When run with no message number arguments it will list the unanswered
25  * messages. The -u flag will cause it to first update the mailbox to
26  * account for any recent replies. <p>
27  *
28  * When run with message number arguments it will mark those messages as
29  * answered. This is useful for marking spam and other random messages
30  * that will never be replied to. <p>
31  *
32  * The -a flag will cause it to mark all messages as answered. Useful for
33  * flushing the ever accumulating spam. <p>
34  *
35  * @author Bill Shannon
36  */

37
38 public class answer {
39
40     static String JavaDoc protocol = "imap";
41     static String JavaDoc host = "anybodys.sfbay";
42     static String JavaDoc user = "javamail";
43     static String JavaDoc password = "1javamail1";
44     static String JavaDoc mbox =
45     "/net/anybodys.sfbay/export6/javamail/logs/javamail.log";
46     static String JavaDoc url = null;
47     static boolean verbose = false;
48     static boolean update = false;
49     static boolean markAll = false;
50
51     public static void main(String JavaDoc argv[]) {
52     int optind;
53
54     for (optind = 0; optind < argv.length; optind++) {
55         if (argv[optind].equals("-T")) {
56         protocol = argv[++optind];
57         } else if (argv[optind].equals("-H")) {
58         host = argv[++optind];
59         } else if (argv[optind].equals("-U")) {
60         user = argv[++optind];
61         } else if (argv[optind].equals("-P")) {
62         password = argv[++optind];
63         } else if (argv[optind].equals("-v")) {
64         verbose = true;
65         } else if (argv[optind].equals("-f")) {
66         mbox = argv[++optind];
67         } else if (argv[optind].equals("-L")) {
68         url = argv[++optind];
69         } else if (argv[optind].equals("-u")) {
70         update = true;
71         } else if (argv[optind].equals("-a")) {
72         markAll = true;
73         update = true;
74         } else if (argv[optind].equals("--")) {
75         optind++;
76         break;
77         } else if (argv[optind].startsWith("-")) {
78         System.out.println(
79 "Usage: answer [-L url] [-T protocol] [-H host] [-U user] [-P password]\n" +
80 "\t[-f mailbox] [-v] [-u] [-a] [msgno ...]");
81         System.exit(1);
82         } else {
83         break;
84         }
85     }
86
87         try {
88         // Get a Properties object
89
Properties props = System.getProperties();
90
91         // Get a Session object
92
Session session = Session.getDefaultInstance(props,
93                     new TtyAuthenticator());
94
95         // Get a Store object
96
Store store = null;
97         if (url != null) {
98         URLName urln = new URLName(url);
99         store = session.getStore(urln);
100         store.connect();
101         } else {
102         if (protocol != null)
103             store = session.getStore(protocol);
104         else
105             store = session.getStore();
106
107         // Connect
108
if (host != null || user != null || password != null)
109             store.connect(host, user, password);
110         else
111             store.connect();
112         }
113         
114
115         // Open the Folder
116

117         Folder folder = store.getDefaultFolder();
118         if (folder == null) {
119             System.out.println("No default folder");
120             System.exit(1);
121         }
122
123         folder = folder.getFolder(mbox);
124         if (folder == null) {
125             System.out.println("Invalid folder");
126             System.exit(1);
127         }
128
129         if (optind < argv.length || update)
130         folder.open(Folder.READ_WRITE);
131         else
132         folder.open(Folder.READ_ONLY);
133         int totalMessages = folder.getMessageCount();
134
135         if (totalMessages == 0) {
136         System.out.println("Empty folder");
137         folder.close(false);
138         store.close();
139         System.exit(1);
140         }
141
142         if (verbose) {
143         int newMessages = folder.getNewMessageCount();
144         pv("Total messages = " + totalMessages);
145         pv("New messages = " + newMessages);
146         pv("-------------------------------");
147         }
148
149         if (optind >= argv.length) {
150         // get all messages that aren't answered or flagged
151
Flags f = new Flags();
152         f.add(Flags.Flag.ANSWERED);
153         f.add(Flags.Flag.FLAGGED);
154
155         // Use a suitable FetchProfile
156
FetchProfile fp = new FetchProfile();
157         fp.add(FetchProfile.Item.ENVELOPE);
158         fp.add(FetchProfile.Item.FLAGS);
159
160         Message[] msgs = folder.search(new FlagTerm(f, false));
161         folder.fetch(msgs, fp);
162
163         if (update) {
164             doUpdate(msgs);
165             // re-fetch messages
166
msgs = folder.search(new FlagTerm(f, false));
167             pv("");
168             pv("");
169         }
170
171         System.out.println("Unanswered messages:");
172         for (int i = 0; i < msgs.length; i++) {
173             Message msg = msgs[i];
174             System.out.println("--------------------------");
175             System.out.println("MESSAGE #" +
176             msg.getMessageNumber() + ":");
177             Question q = new Question(msg);
178             System.out.println(q);
179             if (q.isReply())
180             System.out.println(
181                 "A reply to a message we haven't seen");
182             if (markAll) {
183             int msgno = msg.getMessageNumber();
184             if (q.isReply()) {
185                 pv("Flagging message #" + msgno);
186                 msg.setFlag(Flags.Flag.FLAGGED, true);
187             } else {
188                 pv("Answering message #" + msgno);
189                 msg.setFlag(Flags.Flag.ANSWERED, true);
190             }
191             }
192         }
193
194         } else {
195         for (int i = optind; i < argv.length; i++) {
196             int msgno = Integer.parseInt(argv[i]);
197             Message msg = folder.getMessage(msgno);
198             Question q = new Question(msg);
199             if (q.isReply()) {
200             pv("Flagging message #" + msgno);
201             msg.setFlag(Flags.Flag.FLAGGED, true);
202             } else {
203             pv("Answering message #" + msgno);
204             msg.setFlag(Flags.Flag.ANSWERED, true);
205             }
206         }
207         }
208
209         folder.close(false);
210         store.close();
211     } catch (Exception JavaDoc ex) {
212         System.out.println("Oops, got exception! " + ex.getMessage());
213         ex.printStackTrace();
214         System.exit(1);
215     }
216     System.exit(0);
217     }
218
219     /**
220      * Update the mailbox to account for any replies.
221      */

222     static void doUpdate(Message[] msgs) throws MessagingException {
223     // a hash table of all the unanswered questions
224
Hashtable qt = new Hashtable();
225
226     Address javamailAddress = new InternetAddress("javamail@Sun.COM");
227     SearchTerm javamail = new OrTerm(
228         new RecipientTerm(Message.RecipientType.TO, javamailAddress),
229         new RecipientTerm(Message.RecipientType.CC, javamailAddress));
230
231     for (int i = 0; i < msgs.length; i++) {
232         Message msg = msgs[i];
233         pv("--------------------------");
234         pv("MESSAGE #" + msg.getMessageNumber() + ":");
235         Question q = new Question(msg);
236         pv(q.toString());
237         Question q0;
238         if ((q0 = (Question)qt.get(q)) != null) {
239         pv("Found in table");
240         if (q.isReply()) {
241             Message qm = q0.getMessage();
242             if (!qm.isSet(Flags.Flag.ANSWERED)) {
243             pv("Answered:");
244             pv(q0.toString());
245             qm.setFlag(Flags.Flag.ANSWERED, true);
246             }
247             pv("is reply, flagging it");
248             msg.setFlag(Flags.Flag.FLAGGED, true);
249         } else {
250             // a second copy of a message that's not a reply?
251
// shouldn't happen.
252
}
253         } else {
254         pv("NOT found in table");
255         if (q.isReply()) {
256             // a reply to a message we haven't seen?
257
pv("flagging, but no original msg");
258             msg.setFlag(Flags.Flag.FLAGGED, true);
259         } else {
260             // an original question, put it in the table
261
qt.put(q, q);
262             // if the message looks like spam, flag it
263
if (!javamail.match(msg)) {
264             pv("SPAM!!!");
265             msg.setFlag(Flags.Flag.FLAGGED, true);
266             }
267         }
268         }
269     }
270     }
271
272     /**
273      * Print verbose.
274      */

275     static void pv(String JavaDoc s) {
276     if (verbose)
277         System.out.println(s);
278     }
279 }
280
281 /**
282  * This class represents a single "question" sent to javamail@Sun.COM,
283  * or possibly a reply to such a question.
284  */

285 class Question {
286     Message msg;
287     Address sender;
288     Address[] recipients;
289     String JavaDoc subject;
290     Date date;
291     boolean reply = false;
292
293     Question(Message msg) throws MessagingException {
294     this.msg = msg;
295     sender = msg.getReplyTo()[0]; // XXX - assume only one
296
subject = msg.getSubject();
297     if (subject == null)
298         subject = "";
299     else if (subject.regionMatches(true, 0, "Re: ", 0, 4)) {
300         subject = subject.substring(4);
301         reply = true;
302         recipients = msg.getRecipients(Message.RecipientType.TO);
303     }
304     subject = subject.trim();
305     date = msg.getSentDate();
306     if (date == null)
307         date = msg.getReceivedDate();
308     }
309
310     public boolean isReply() {
311     return reply;
312     }
313
314     public Message getMessage() {
315     return msg;
316     }
317
318     public int hashCode() {
319     return subject.hashCode();
320     }
321
322     public boolean equals(Object JavaDoc obj) {
323     if (!(obj instanceof Question))
324         return false;
325     Question q = (Question)obj;
326     if (this.reply == q.reply)
327         return this.sender.equals(q.sender) &&
328             this.subject.equals(q.subject);
329
330     /*
331      * A reply is equal to a question if the sender of the question
332      * is one of the recipients of the reply.
333      */

334     Question qq, qr;
335     if (this.reply) {
336         qq = q;
337         qr = this;
338     } else {
339         qq = this;
340         qr = q;
341     }
342     for (int i = 0; i < qr.recipients.length; i++) {
343         if (qq.sender.equals(qr.recipients[i]))
344         return true;
345     }
346     return false;
347     }
348
349     public String JavaDoc toString() {
350     return "Date: " + date + "\nFrom: " + sender + "\nSubject: " + subject;
351     }
352 }
353
Popular Tags