KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > mail > MailboxEntry


1 /*
2  * MailboxEntry.java
3  *
4  * Copyright (C) 2000-2002 Peter Graves
5  * $Id: MailboxEntry.java,v 1.2 2003/05/30 15:09:50 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j.mail;
23
24 import java.io.Serializable JavaDoc;
25 import java.text.SimpleDateFormat JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Locale JavaDoc;
28 import org.armedbear.j.Debug;
29 import org.armedbear.j.Editor;
30 import org.armedbear.j.FastStringBuffer;
31 import org.armedbear.j.Log;
32 import org.armedbear.j.Property;
33 import org.armedbear.j.Utilities;
34
35 public abstract class MailboxEntry implements Serializable JavaDoc
36 {
37     // If DEBUG is true, formatDate() prints the time even if the entry is
38
// more than six months old.
39
private static final boolean DEBUG =
40         Editor.preferences().getBooleanProperty("MailboxEntry.debug", false);
41
42     protected static final boolean SHOW_MESSAGE_NUMBERS =
43         Editor.preferences().getBooleanProperty(Property.SHOW_MESSAGE_NUMBERS);
44
45     // Bit flags.
46
public static final int SEEN = 0x01;
47     public static final int RECENT = 0x02;
48     public static final int ANSWERED = 0x04;
49     public static final int DELETED = 0x08;
50     public static final int FLAGGED = 0x10;
51     public static final int TAGGED = 0x20; // Not persistent.
52

53     protected static final String JavaDoc STRING_DEFAULT = " ";
54     protected static final String JavaDoc STRING_DELETED = "D";
55     protected static final String JavaDoc STRING_REPLIED = "r";
56     protected static final String JavaDoc STRING_NEW = "N";
57     protected static final String JavaDoc STRING_OLD = "O";
58     protected static final String JavaDoc STRING_FLAGGED = "!";
59
60     protected int flags;
61     protected int messageNumber;
62     protected int size;
63     protected String JavaDoc subject;
64     protected RFC822Date date;
65     protected MailAddress[] from;
66     protected MailAddress[] replyTo;
67     protected MailAddress[] to;
68     protected MailAddress[] cc;
69     protected String JavaDoc messageId;
70     protected String JavaDoc inReplyTo;
71     protected String JavaDoc[] references;
72
73     // The message number displayed to the user.
74
private transient int sequenceNumber;
75
76     private transient boolean orphan;
77
78     public final int getFlags()
79     {
80         return flags;
81     }
82
83     public final void setFlags(int flags)
84     {
85         this.flags = flags;
86     }
87
88     public final int getSize()
89     {
90         return size;
91     }
92
93     public final void setSize(int size)
94     {
95         this.size = size;
96     }
97
98     public final int getMessageNumber()
99     {
100         return messageNumber;
101     }
102
103     public final int getSequenceNumber()
104     {
105         return sequenceNumber;
106     }
107
108     public final void setSequenceNumber(int n)
109     {
110         sequenceNumber = n;
111     }
112
113     public final RFC822Date getDate()
114     {
115         return date;
116     }
117
118     public final MailAddress[] getFrom()
119     {
120         return from;
121     }
122
123     public final MailAddress[] getReplyTo()
124     {
125         return replyTo;
126     }
127
128     public final MailAddress[] getTo()
129     {
130         return to;
131     }
132
133     public final MailAddress[] getCc()
134     {
135         return cc;
136     }
137
138     public final String JavaDoc getSubject()
139     {
140         if (subject != null && subject.length() > 0)
141             return subject;
142         return "(no subject)";
143     }
144
145     public final String JavaDoc getBaseSubject()
146     {
147         if (subject == null)
148             return null;
149         final int length = subject.length();
150         if (length == 0)
151             return null;
152         String JavaDoc s = subject.trim();
153         while (true) {
154             if (s.toLowerCase().startsWith("re:")) {
155                 s = s.substring(3).trim();
156                 continue;
157             }
158             if (s.length() > 0 && s.charAt(0) == '[') {
159                 int end = s.indexOf(']', 1);
160                 if (end >= 0) {
161                     s = s.substring(end+1).trim();
162                     continue;
163                 }
164             }
165             break;
166         }
167         while (s.toLowerCase().endsWith("(fwd)"))
168             s = s.substring(0, s.length()-5).trim();
169
170         // Some broken mailers (or MTAs) arbitrarily break the subject line
171
// after 74 characters. If this happens to be in the middle of a word,
172
// we'll end up with an extra LWSP char in the subject string when we
173
// unfold the header, meaning we won't get an exact match with the
174
// subject of the message being replied to, which is the whole point
175
// here. So we strip out all LWSP chars before returning the base
176
// subject.
177
FastStringBuffer sb = new FastStringBuffer();
178         for (int i = 0, limit = s.length(); i < limit; i++) {
179             char c = s.charAt(i);
180             if (c != ' ' && c != '\t')
181                 sb.append(c);
182         }
183         return sb.toString();
184     }
185
186     public final boolean subjectIsReply()
187     {
188         if (subject != null && subject.toLowerCase().startsWith("re:"))
189             return true;
190         return false;
191     }
192
193     public final String JavaDoc getMessageId()
194     {
195         return messageId;
196     }
197
198     public final String JavaDoc getInReplyTo()
199     {
200         return inReplyTo;
201     }
202
203     public final String JavaDoc[] getReferences()
204     {
205         return references;
206     }
207
208     public final void setOrphan(boolean b)
209     {
210         orphan = b;
211     }
212
213     public String JavaDoc getUidl()
214     {
215         return null;
216     }
217
218     public String JavaDoc formatSubject()
219     {
220         if (subject == null)
221             return "";
222         return subject;
223     }
224
225     public final boolean isDeleted()
226     {
227         return (flags & DELETED) == DELETED;
228     }
229
230     public final boolean isTagged()
231     {
232         return (flags & TAGGED) == TAGGED;
233     }
234
235     public final boolean isFlagged()
236     {
237         return (flags & FLAGGED) == FLAGGED;
238     }
239
240     public final boolean isAnswered()
241     {
242         return (flags & ANSWERED) == ANSWERED;
243     }
244
245     public final boolean isNew()
246     {
247         return (flags & (SEEN | DELETED | RECENT)) == RECENT;
248     }
249
250     public final boolean isRead()
251     {
252         return (flags & SEEN) != 0;
253     }
254
255     public final boolean isUnread()
256     {
257         return (flags & (SEEN | DELETED)) == 0;
258     }
259
260     public final void tag()
261     {
262         flags |= TAGGED;
263     }
264
265     public final void untag()
266     {
267         flags &= ~TAGGED;
268     }
269
270     public final void toggleTag()
271     {
272         if ((flags & TAGGED) != 0)
273             flags &= ~TAGGED;
274         else
275             flags |= TAGGED;
276     }
277
278     public final void flag()
279     {
280         flags |= FLAGGED;
281     }
282
283     public final void unflag()
284     {
285         flags &= ~FLAGGED;
286     }
287
288     public final void toggleFlag()
289     {
290         if ((flags & FLAGGED) != 0)
291             flags &= ~FLAGGED;
292         else
293             flags |= FLAGGED;
294     }
295
296     protected String JavaDoc formatSize()
297     {
298         if (size < 1000)
299             return Utilities.rightJustify(size, 4);
300         if (size < 10000) {
301             int k = size / 1000;
302             int remainder = size % 1000;
303             int h = remainder / 100;
304             if (remainder % 100 > 49) {
305                 ++h;
306                 if (h == 10) {
307                     ++k;
308                     h = 0;
309                 }
310             }
311             if (k < 10) {
312                 FastStringBuffer sb = new FastStringBuffer();
313                 sb.append(String.valueOf(k));
314                 sb.append('.');
315                 sb.append(String.valueOf(h));
316                 sb.append('K');
317                 return sb.toString();
318             }
319             // else fall through...
320
}
321         if (size < 1000000) {
322             int k = size / 1000;
323             if (size % 1000 > 499)
324                 ++k;
325             if (k < 1000)
326                 return Utilities.rightJustify(k, 3) + "K";
327             // else fall through...
328
}
329         int m = size / 1000000;
330         if (size % 1000000 > 499999)
331             ++m;
332         return Utilities.rightJustify(m, 3) + "M";
333     }
334
335     protected char getToChar()
336     {
337         if (isFlagged())
338             return '!';
339         if (isFromMe())
340             return 'F';
341         char c = ' ';
342         if (to != null) {
343             for (int i = to.length-1; i >= 0; i--) {
344                 MailAddress a = to[i];
345                 if (a.matches(Mail.getUserMailAddress())) {
346                     // Addressed to me.
347
if (to.length == 1)
348                         c = '+';
349                     else
350                         return 'T';
351                 }
352             }
353         }
354         if (c == '+') {
355             // Addressed to me alone.
356
if (cc != null && cc.length > 0) // Copied to others or to me.
357
return 'T';
358             return c;
359         }
360         if (cc != null) {
361             for (int i = cc.length-1; i >= 0; i--) {
362                 MailAddress a = cc[i];
363                 if (a.matches(Mail.getUserMailAddress())) {
364                     // Copied to me.
365
return 'C';
366                 }
367             }
368         }
369         return ' ';
370     }
371
372     private boolean isFromMe()
373     {
374         if (from != null) {
375             MailAddress a = from[0];
376             if (a.matches(Mail.getUserMailAddress()))
377                 return true;
378         }
379         return false;
380     }
381
382     protected String JavaDoc formatFlags()
383     {
384         if (isAnswered())
385             return STRING_REPLIED;
386         else if ((flags & (SEEN | RECENT)) == RECENT) // Might be deleted.
387
return STRING_NEW;
388         else if ((flags & SEEN) == 0) // Might be deleted.
389
return STRING_OLD;
390         else
391             return STRING_DEFAULT;
392     }
393
394     private static final SimpleDateFormat JavaDoc dateFormat1 =
395         new SimpleDateFormat JavaDoc("MMM dd HH:mm", Locale.US);
396
397     private static final SimpleDateFormat JavaDoc dateFormat2 =
398         new SimpleDateFormat JavaDoc("MMM dd yyyy", Locale.US);
399
400     private static final String JavaDoc NULL_DATE = "null ";
401
402     private static final long SIX_MONTHS = (long) 6 * 30 * 24 * 60 * 60 * 1000;
403
404     protected String JavaDoc formatDate()
405     {
406         if (date == null)
407             return NULL_DATE;
408         long millis = date.getTime();
409         if (millis == 0)
410             return NULL_DATE;
411         if (DEBUG || System.currentTimeMillis() - millis < SIX_MONTHS)
412             return dateFormat1.format(date.getDate());
413         return dateFormat2.format(date.getDate());
414     }
415
416     protected String JavaDoc formatFrom(int fieldWidth)
417     {
418         String JavaDoc s = null;
419         if (isFromMe() && to != null && to.length > 0) {
420             MailAddress a = to[0];
421             s = a.getPersonal();
422             if (s == null || s.length() == 0)
423                 s = a.getAddress();
424             if (s != null)
425                 s = "To: " + s;
426         } else if (from != null && from.length > 0) {
427             MailAddress a = from[0];
428             s = a.getPersonal();
429             if (s == null || s.length() == 0)
430                 s = a.getAddress();
431         }
432         if (s == null)
433             s = "";
434         final int length = s.length();
435         if (length > fieldWidth)
436             s = s.substring(0, fieldWidth);
437         else if (length < fieldWidth)
438             s = s + Utilities.spaces(fieldWidth - length);
439         return s;
440     }
441
442     public String JavaDoc toString()
443     {
444         return toString(1);
445     }
446
447     public String JavaDoc toString(int depth)
448     {
449         FastStringBuffer sb = new FastStringBuffer(128);
450         if (SHOW_MESSAGE_NUMBERS) {
451             sb.append(Utilities.rightJustify(sequenceNumber, 5));
452             sb.append(' ');
453         }
454         sb.append(getToChar());
455         sb.append(' ');
456         sb.append(formatFlags());
457         sb.append(" ");
458         sb.append(formatDate());
459         sb.append(" ");
460         sb.append(formatFrom(20));
461         sb.append(" ");
462         sb.append(formatSize());
463         sb.append(" ");
464         if (orphan)
465             sb.append("- ");
466         else if (depth > 1)
467             sb.append(Utilities.spaces((depth-1)*2));
468         sb.append(formatSubject());
469         return sb.toString();
470     }
471
472     protected static String JavaDoc parseInReplyTo(String JavaDoc s)
473     {
474         if (s != null) {
475             int begin = s.indexOf('<');
476             if (begin >= 0) {
477                 int end = s.indexOf('>', begin+1);
478                 if (end > begin)
479                     return s.substring(begin, end+1);
480             }
481         }
482         return null;
483     }
484
485     protected static String JavaDoc[] parseReferences(String JavaDoc s)
486     {
487         ArrayList JavaDoc list = null;
488         int begin = 0;
489         while (true) {
490             begin = s.indexOf('<', begin);
491             if (begin < 0)
492                 break;
493             int end = s.indexOf('>', begin+1);
494             if (end < 0)
495                 break;
496             if (list == null)
497                 list = new ArrayList JavaDoc();
498             list.add(s.substring(begin, ++end));
499             begin = end;
500         }
501         if (list == null)
502             return null;
503         String JavaDoc[] array = new String JavaDoc[list.size()];
504         return (String JavaDoc[]) list.toArray(array);
505     }
506 }
507
Popular Tags