KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Drafts.java
3  *
4  * Copyright (C) 2002 Peter Graves
5  * $Id: Drafts.java,v 1.2 2002/10/11 01:42:37 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.BufferedReader JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStreamReader JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import javax.swing.SwingUtilities JavaDoc;
32 import org.armedbear.j.Buffer;
33 import org.armedbear.j.BufferIterator;
34 import org.armedbear.j.Debug;
35 import org.armedbear.j.Editor;
36 import org.armedbear.j.EditorIterator;
37 import org.armedbear.j.File;
38 import org.armedbear.j.FastStringBuffer;
39 import org.armedbear.j.Headers;
40 import org.armedbear.j.Line;
41 import org.armedbear.j.Log;
42 import org.armedbear.j.View;
43
44 public final class Drafts extends Mailbox
45 {
46     private final File directory;
47
48     public Drafts(LocalMailboxURL url)
49     {
50         super();
51         this.url = url;
52         this.directory = url.getFile();
53         supportsUndo = false;
54         type = TYPE_MAILBOX;
55         mode = MailboxMode.getMode();
56         formatter = mode.getFormatter(this);
57         readOnly = true;
58         title = "drafts";
59         setInitialized(true);
60     }
61
62     public File getDirectory()
63     {
64         return directory;
65     }
66
67     public String JavaDoc getName()
68     {
69         return directory.canonicalPath();
70     }
71
72     public int getMessageCount()
73     {
74         return 0;
75     }
76
77     public void getNewMessages()
78     {
79         reload();
80     }
81
82     public void createFolder()
83     {
84         notImplemented("Drafts.createFolder");
85     }
86
87     public void deleteFolder()
88     {
89         notImplemented("Drafts.deleteFolder");
90     }
91
92     public void saveToFolder()
93     {
94         notImplemented("Drafts.saveToFolder");
95     }
96
97     public void moveToFolder()
98     {
99         notImplemented("Drafts.moveToFolder");
100     }
101
102     public void delete()
103     {
104         final Editor editor = Editor.currentEditor();
105         boolean advanceDot = false;
106         List JavaDoc list = getTaggedEntries();
107         if (list == null) {
108             Line line = editor.getDotLine();
109             if (!(line instanceof MailboxLine))
110                 return;
111             advanceDot = true;
112             list = new ArrayList JavaDoc();
113             list.add(((MailboxLine)line).getMailboxEntry());
114         }
115         Iterator JavaDoc iter = list.iterator();
116         while (iter.hasNext()) {
117             DraftsEntry entry = (DraftsEntry) iter.next();
118             if (entry == null)
119                 continue;
120             File file = entry.getFile();
121             if (file == null)
122                 continue;
123             if (!file.isFile())
124                 continue;
125             String JavaDoc name = file.getName();
126             if (name.endsWith(".deleted"))
127                 continue; // Already deleted.
128
File deleted =
129                 File.getInstance(directory, name.concat(".deleted"));
130             if (deleted.isFile()) {
131                 Debug.bug();
132                 return;
133             }
134             Log.debug("delete renaming " + file.getName() + " to " +
135                 deleted.getName());
136             if (file.renameTo(deleted)) {
137                 entry.setFile(deleted);
138                 entry.setFlags(entry.getFlags() | MailboxEntry.DELETED);
139                 updateEntry(entry);
140             }
141         }
142         if (advanceDot)
143             advanceDot(editor.getDotLine());
144     }
145
146     public void undelete()
147     {
148         final Editor editor = Editor.currentEditor();
149         boolean advanceDot = false;
150         List JavaDoc list = getTaggedEntries();
151         if (list == null) {
152             Line line = editor.getDotLine();
153             if (!(line instanceof MailboxLine))
154                 return;
155             advanceDot = true;
156             list = new ArrayList JavaDoc();
157             list.add(((MailboxLine)line).getMailboxEntry());
158         }
159         Iterator JavaDoc iter = list.iterator();
160         while (iter.hasNext()) {
161             DraftsEntry entry = (DraftsEntry) iter.next();
162             if (entry == null)
163                 continue;
164             File file = entry.getFile();
165             if (file == null)
166                 continue;
167             if (!file.isFile())
168                 continue;
169             String JavaDoc name = file.getName();
170             if (!name.endsWith(".deleted"))
171                 continue; // Not deleted.
172
File undeleted = File.getInstance(directory,
173                 name.substring(0, name.length()-8));
174             if (undeleted.isFile()) {
175                 Debug.bug();
176                 return;
177             }
178             Log.debug("undelete renaming " + file.getName() + " to " +
179                 undeleted.getName());
180             if (file.renameTo(undeleted)) {
181                 entry.setFile(undeleted);
182                 entry.setFlags(entry.getFlags() & ~MailboxEntry.DELETED);
183                 updateEntry(entry);
184             }
185         }
186         if (advanceDot)
187             advanceDot(editor.getDotLine());
188     }
189
190     public void markRead()
191     {
192         notImplemented("Drafts.markRead");
193     }
194
195     public void markUnread()
196     {
197         notImplemented("Drafts.markUnread");
198     }
199
200     public void flag()
201     {
202         notImplemented("Drafts.flag");
203     }
204
205     public void setAnsweredFlag(MailboxEntry entry)
206     {
207         notImplemented("Drafts.setAnsweredFlag");
208     }
209
210     public void expunge()
211     {
212         if (lock()) {
213             setBusy(true);
214             for (EditorIterator it = new EditorIterator(); it.hasNext();) {
215                 Editor ed = it.nextEditor();
216                 if (ed.getBuffer() == this)
217                     ed.saveView();
218             }
219             new Thread JavaDoc(expungeRunnable).start();
220         }
221     }
222
223     private Runnable JavaDoc expungeRunnable = new Runnable JavaDoc() {
224         public void run()
225         {
226             try {
227                 if (expungeInternal())
228                     loadInternal();
229             }
230             finally {
231                 setBusy(false);
232                 unlock();
233                 updateDisplay();
234             }
235         }
236     };
237
238     // Returns true if at least one message is expunged.
239
private boolean expungeInternal()
240     {
241         boolean result = false;
242         entries = new ArrayList JavaDoc();
243         String JavaDoc[] names = directory.list();
244         if (names != null) {
245             for (int i = 0; i < names.length; i++) {
246                 final String JavaDoc name = names[i];
247                 if (name.indexOf(".deleted") >= 0) {
248                     File file = File.getInstance(directory, name);
249                     Log.debug("deleting " + file);
250                     file.delete();
251                     result = true;
252                 }
253             }
254         }
255         return result;
256     }
257
258     public int load()
259     {
260         if (lock()) {
261             setBusy(true);
262             setLoaded(true);
263             new Thread JavaDoc(loadRunnable).start();
264             return LOAD_PENDING;
265         } else
266             return LOAD_FAILED;
267     }
268
269     public void reload()
270     {
271         if (lock()) {
272             setBusy(true);
273             for (EditorIterator it = new EditorIterator(); it.hasNext();) {
274                 Editor ed = it.nextEditor();
275                 if (ed.getBuffer() == this)
276                     ed.saveView();
277             }
278             new Thread JavaDoc(reloadRunnable).start();
279         }
280     }
281
282     private Runnable JavaDoc loadRunnable = new Runnable JavaDoc() {
283         public void run()
284         {
285             try {
286                 loadInternal();
287             }
288             finally {
289                 unlock();
290                 setBusy(false);
291                 Runnable JavaDoc completionRunnable = new Runnable JavaDoc() {
292                     public void run()
293                     {
294                         for (EditorIterator it = new EditorIterator(); it.hasNext();) {
295                             Editor ed = it.nextEditor();
296                             View view = new View();
297                             view.setDotEntry(getInitialEntry());
298                             ed.setView(Drafts.this, view);
299                             if (ed.getBuffer() == Drafts.this) {
300                                 ed.bufferActivated(true);
301                                 ed.updateDisplay();
302                             }
303                         }
304                     }
305                 };
306                 SwingUtilities.invokeLater(completionRunnable);
307             }
308         }
309     };
310
311     private Runnable JavaDoc reloadRunnable = new Runnable JavaDoc() {
312         public void run()
313         {
314             try {
315                 loadInternal();
316                 updateDisplay();
317             }
318             finally {
319                 unlock();
320                 setBusy(false);
321             }
322         }
323     };
324
325     private void loadInternal()
326     {
327         entries = new ArrayList JavaDoc();
328         String JavaDoc[] names = directory.list();
329         if (names != null) {
330             for (int i = 0; i < names.length; i++) {
331                 final String JavaDoc name = names[i];
332                 DraftsEntry entry =
333                     DraftsEntry.parseEntry(directory, name);
334                 if (entry != null) {
335                     if (name.endsWith(".deleted"))
336                         entry.setFlags(entry.getFlags() | MailboxEntry.DELETED);
337                     entries.add(entry);
338                 }
339             }
340         }
341         refreshBuffer();
342     }
343
344     public MailboxEntry getInitialEntry()
345     {
346         Line line = getFirstLine();
347         if (line == null)
348             return null;
349         while (true) {
350             if (line.next() == null)
351                 break; // Reached last line.
352
line = line.next();
353         }
354         return ((MailboxLine)line).getMailboxEntry();
355     }
356
357     public void readMessage(Line line)
358     {
359         readMessage(line, false);
360     }
361
362     public void readMessageOtherWindow(Line line)
363     {
364         readMessage(line, true);
365     }
366
367     // useOtherWindow is ignored. Since it's a mail composition buffer, it's
368
// opened full-height.
369
private void readMessage(Line line, boolean useOtherWindow)
370     {
371         DraftsEntry entry = (DraftsEntry) ((MailboxLine)line).getMailboxEntry();
372         if (entry == null)
373             return;
374         File file = entry.getFile();
375         if (file == null)
376             return;
377         Buffer buf = null;
378         for (BufferIterator it = new BufferIterator(); it.hasNext();) {
379             Buffer b = it.nextBuffer();
380             if (b instanceof SendMail) {
381                 if (file.equals(b.getFile())) {
382                     buf = b;
383                     break;
384                 }
385             }
386         }
387         if (buf == null)
388             buf = new SendMail(file);
389         Editor editor = Editor.currentEditor();
390         editor.makeNext(buf);
391         editor.switchToBuffer(buf);
392     }
393
394     public File getCurrentDirectory()
395     {
396         return directory;
397     }
398
399     public String JavaDoc toString()
400     {
401         return "drafts";
402     }
403
404     private static class DraftsEntry extends MailboxEntry
405     {
406         private File file;
407
408         DraftsEntry(File file)
409         {
410             this.file = file;
411         }
412
413         public final File getFile()
414         {
415             return file;
416         }
417
418         public final void setFile(File file)
419         {
420             this.file = file;
421         }
422
423         public static DraftsEntry parseEntry(File directory, String JavaDoc fileName)
424         {
425             File file = File.getInstance(directory, fileName);
426             if (file != null && file.isFile()) {
427                 FastStringBuffer sb = new FastStringBuffer();
428                 try {
429                     BufferedReader JavaDoc reader =
430                         new BufferedReader JavaDoc(new InputStreamReader JavaDoc(file.getInputStream()));
431                     while (true) {
432                         String JavaDoc s = reader.readLine();
433                         if (s == null)
434                             break;
435                         if (s.length() == 0)
436                             break;
437                         char c = s.charAt(0);
438                         if (c == '-')
439                             break; // Header separator line.
440
if (c != ' ' && c != '\t' && s.indexOf(':') < 0)
441                             break; // Not a header line.
442
sb.append(s);
443                         sb.append("\r\n");
444                     }
445                     reader.close();
446                 }
447                 catch (IOException JavaDoc e) {
448                     Log.error(e);
449                 }
450                 Headers headers = Headers.parse(sb.toString());
451                 if (headers == null)
452                     return null;
453                 DraftsEntry entry = new DraftsEntry(file);
454                 entry.subject =
455                     RFC2047.decode(headers.getValue(Headers.SUBJECT));
456                 String JavaDoc dateString = headers.getValue(Headers.DATE);
457                 if (dateString != null)
458                     entry.date = RFC822Date.parseDate(dateString);
459                 else
460                     entry.date = new RFC822Date(new Date JavaDoc(file.lastModified()));
461                 entry.size = (int) file.length();
462                 String JavaDoc fromString = RFC2047.decode(headers.getValue(Headers.FROM));
463                 if (fromString != null)
464                     entry.from = MailAddress.parseAddresses(fromString);
465                 else {
466                     MailAddress ma = Mail.getUserMailAddress();
467                     if (ma != null)
468                         entry.from = new MailAddress[]{ma};
469                 }
470                 entry.replyTo = MailAddress.parseAddresses(RFC2047.decode(
471                     headers.getValue(Headers.REPLY_TO)));
472                 entry.to = MailAddress.parseAddresses(RFC2047.decode(
473                     headers.getValue(Headers.TO)));
474                 entry.cc = MailAddress.parseAddresses(RFC2047.decode(
475                     headers.getValue(Headers.CC)));
476                 entry.messageId = headers.getValue(Headers.MESSAGE_ID);
477                 entry.inReplyTo =
478                     parseInReplyTo(headers.getValue(Headers.IN_REPLY_TO));
479                 String JavaDoc refs = headers.getValue(Headers.REFERENCES);
480                 if (refs != null)
481                     entry.references = parseReferences(refs);
482                 entry.flags = SEEN;
483                 return entry;
484             }
485             return null;
486         }
487     }
488 }
489
Popular Tags