1 21 22 package org.armedbear.j.mail; 23 24 import java.io.BufferedReader ; 25 import java.io.IOException ; 26 import java.io.InputStreamReader ; 27 import java.util.ArrayList ; 28 import java.util.Date ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import javax.swing.SwingUtilities ; 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 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 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 (); 113 list.add(((MailboxLine)line).getMailboxEntry()); 114 } 115 Iterator 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 name = file.getName(); 126 if (name.endsWith(".deleted")) 127 continue; 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 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 (); 157 list.add(((MailboxLine)line).getMailboxEntry()); 158 } 159 Iterator 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 name = file.getName(); 170 if (!name.endsWith(".deleted")) 171 continue; 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 (expungeRunnable).start(); 220 } 221 } 222 223 private Runnable expungeRunnable = new Runnable () { 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 private boolean expungeInternal() 240 { 241 boolean result = false; 242 entries = new ArrayList (); 243 String [] names = directory.list(); 244 if (names != null) { 245 for (int i = 0; i < names.length; i++) { 246 final String 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 (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 (reloadRunnable).start(); 279 } 280 } 281 282 private Runnable loadRunnable = new Runnable () { 283 public void run() 284 { 285 try { 286 loadInternal(); 287 } 288 finally { 289 unlock(); 290 setBusy(false); 291 Runnable completionRunnable = new Runnable () { 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 reloadRunnable = new Runnable () { 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 (); 328 String [] names = directory.list(); 329 if (names != null) { 330 for (int i = 0; i < names.length; i++) { 331 final String 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; 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 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 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 fileName) 424 { 425 File file = File.getInstance(directory, fileName); 426 if (file != null && file.isFile()) { 427 FastStringBuffer sb = new FastStringBuffer(); 428 try { 429 BufferedReader reader = 430 new BufferedReader (new InputStreamReader (file.getInputStream())); 431 while (true) { 432 String 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; if (c != ' ' && c != '\t' && s.indexOf(':') < 0) 441 break; sb.append(s); 443 sb.append("\r\n"); 444 } 445 reader.close(); 446 } 447 catch (IOException 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 dateString = headers.getValue(Headers.DATE); 457 if (dateString != null) 458 entry.date = RFC822Date.parseDate(dateString); 459 else 460 entry.date = new RFC822Date(new Date (file.lastModified())); 461 entry.size = (int) file.length(); 462 String 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 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 |