1 22 23 package gnu.mail.providers.imap4; 24 25 import java.io.ByteArrayOutputStream ; 26 import java.io.IOException ; 27 import java.util.List ; 28 import javax.mail.FetchProfile ; 29 import javax.mail.Flags ; 30 import javax.mail.Folder ; 31 import javax.mail.FolderNotFoundException ; 32 import javax.mail.IllegalWriteException ; 33 import javax.mail.Message ; 34 import javax.mail.MessagingException ; 35 import javax.mail.Store ; 36 import javax.mail.event.ConnectionEvent ; 37 import javax.mail.event.FolderEvent ; 38 import javax.mail.internet.MimeMessage ; 39 40 46 public class IMAPFolder 47 extends Folder 48 implements IMAPConstants 49 { 50 51 54 protected String path; 55 56 59 protected int type; 60 61 64 protected int mode; 65 66 protected Flags permanentFlags = new Flags (); 67 68 protected char delimiter = '\u0000'; 69 70 protected int messageCount = -1; 71 72 protected int newMessageCount = -1; 73 74 77 protected IMAPFolder(Store store, String path) 78 { 79 super(store); 80 this.path = path; 81 } 82 83 86 void update(MailboxStatus status, boolean fireEvents) 87 throws MessagingException 88 { 89 if (status==null) 90 throw new FolderNotFoundException (this); 91 mode = status.readWrite ? Folder.READ_WRITE : Folder.READ_ONLY; 92 if (status.permanentFlags!=null) 93 permanentFlags = readFlags(status.permanentFlags); 94 int oldMessageCount = messageCount; 96 messageCount = status.messageCount; 97 newMessageCount = status.newMessageCount; 98 if (fireEvents) 100 { 101 if (messageCount>oldMessageCount) 102 { 103 Message [] m = new Message [messageCount-oldMessageCount]; 104 for (int i=oldMessageCount; i<messageCount; i++) 105 m[i-oldMessageCount] = getMessage(i); 106 notifyMessageAddedListeners(m); 107 } 108 else if (messageCount<oldMessageCount) 109 { 110 Message [] m = new Message [oldMessageCount-messageCount]; 111 for (int i=messageCount; i<oldMessageCount; i++) 112 m[i-messageCount] = getMessage(i); 113 notifyMessageRemovedListeners(false, m); 114 } 115 } 116 } 117 118 Flags readFlags(List sflags) 119 { 120 Flags flags = new Flags (); 121 int len = sflags.size(); 122 for (int i=0; i<len; i++) 123 { 124 String flag = (String )sflags.get(i); 125 if (flag==FLAG_ANSWERED) 126 flags.add(Flags.Flag.ANSWERED); 127 else if (flag==FLAG_DELETED) 128 flags.add(Flags.Flag.DELETED); 129 else if (flag==FLAG_DRAFT) 130 flags.add(Flags.Flag.DRAFT); 131 else if (flag==FLAG_FLAGGED) 132 flags.add(Flags.Flag.FLAGGED); 133 else if (flag==FLAG_RECENT) 134 flags.add(Flags.Flag.RECENT); 135 else if (flag==FLAG_SEEN) 136 flags.add(Flags.Flag.SEEN); 137 } 139 return flags; 140 } 141 142 145 public String getName() 146 { 147 int di = path.lastIndexOf(delimiter); 148 return (di==-1) ? path : path.substring(di+1); 149 } 150 151 154 public String getFullName() 155 { 156 return path; 157 } 158 159 163 public int getType() 164 throws MessagingException 165 { 166 return type; 168 } 169 170 174 public boolean exists() 175 throws MessagingException 176 { 177 return false; } 179 180 184 public boolean hasNewMessages() 185 throws MessagingException 186 { 187 return getNewMessageCount()>0; } 189 190 194 public void open(int mode) 195 throws MessagingException 196 { 197 IMAPConnection connection = ((IMAPStore)store).connection; 198 try 199 { 200 MailboxStatus status = null; 201 switch (mode) 202 { 203 case Folder.READ_WRITE: 204 status = connection.select(getFullName()); 205 break; 206 case Folder.READ_ONLY: 207 status = connection.examine(getFullName()); 208 break; 209 default: 210 throw new MessagingException ("No such mode: "+mode); 211 } 212 update(status, false); 213 notifyConnectionListeners(ConnectionEvent.OPENED); 214 } 215 catch (IOException e) 216 { 217 throw new MessagingException (e.getMessage(), e); 218 } 219 } 220 221 224 public boolean create(int type) 225 throws MessagingException 226 { 227 IMAPConnection connection = ((IMAPStore)store).connection; 228 try 229 { 230 String path = this.path; 231 if (type==HOLDS_FOLDERS) 232 path = new StringBuffer (path) 233 .append(getSeparator()) 234 .toString(); 235 if (connection.create(path)) 236 { 237 notifyFolderListeners(FolderEvent.CREATED); 238 return true; 239 } 240 else 241 return false; 242 } 243 catch (IOException e) 244 { 245 throw new MessagingException (e.getMessage(), e); 246 } 247 } 248 249 252 public boolean delete(boolean flag) 253 throws MessagingException 254 { 255 IMAPConnection connection = ((IMAPStore)store).connection; 256 try 257 { 258 if (connection.delete(path)) 259 { 260 notifyFolderListeners(FolderEvent.DELETED); 261 return true; 262 } 263 else 264 return false; 265 } 266 catch (IOException e) 267 { 268 throw new MessagingException (e.getMessage(), e); 269 } 270 } 271 272 275 public boolean renameTo(Folder folder) 276 throws MessagingException 277 { 278 IMAPConnection connection = ((IMAPStore)store).connection; 279 try 280 { 281 if (connection.rename(path, folder.getFullName())) 282 { 283 notifyFolderRenamedListeners(folder); 285 return true; 286 } 287 else 288 return false; 289 } 290 catch (IOException e) 291 { 292 throw new MessagingException (e.getMessage(), e); 293 } 294 } 295 296 301 public void close(boolean expunge) 302 throws MessagingException 303 { 304 if (!isOpen()) 305 throw new MessagingException ("Folder is not open"); 306 if (expunge) 307 expunge(); 308 IMAPConnection connection = ((IMAPStore)store).connection; 309 try 310 { 311 connection.close(); 312 } 313 catch (IOException e) 314 { 315 throw new MessagingException (e.getMessage(), e); 316 } 317 mode = -1; 318 notifyConnectionListeners(ConnectionEvent.CLOSED); 319 } 320 321 326 public Message [] expunge() 327 throws MessagingException 328 { 329 if (!isOpen()) 330 throw new MessagingException ("Folder is not open"); 331 if (mode==Folder.READ_ONLY) 332 throw new MessagingException ("Folder was opened read-only"); 333 IMAPConnection connection = ((IMAPStore)store).connection; 334 try 335 { 336 int[] messageNumbers = connection.expunge(); 337 IMAPMessage[] messages = new IMAPMessage[messageNumbers.length]; 339 for (int i=0; i<messages.length; i++) 340 messages[i] = new IMAPMessage(this, messageNumbers[i]); 341 notifyMessageRemovedListeners(true, messages); 343 return messages; 344 } 345 catch (IOException e) 346 { 347 throw new MessagingException (e.getMessage(), e); 348 } 349 } 350 351 354 public boolean isOpen() 355 { 356 return (mode!=-1); 357 } 358 359 362 public Flags getPermanentFlags() 363 { 364 return permanentFlags; 365 } 366 367 371 public int getMessageCount() 372 throws MessagingException 373 { 374 if (mode==-1 || messageCount<0) 375 { 376 IMAPConnection connection = ((IMAPStore)store).connection; 377 try 378 { 379 String [] items = new String [1]; 380 items[0] = IMAPConnection.MESSAGES; 381 MailboxStatus ms = connection.status(path, items); 382 update(ms, true); 383 } 384 catch (IOException e) 385 { 386 throw new MessagingException (e.getMessage(), e); 387 } 388 } 389 return messageCount; 391 } 392 393 397 public int getNewMessageCount() 398 throws MessagingException 399 { 400 if (mode==-1 || newMessageCount<0) 401 { 402 IMAPConnection connection = ((IMAPStore)store).connection; 403 try 404 { 405 String [] items = new String [1]; 406 items[0] = IMAPConnection.RECENT; 407 MailboxStatus ms = connection.status(path, items); 408 update(ms, true); 409 } 410 catch (IOException e) 411 { 412 throw new MessagingException (e.getMessage(), e); 413 } 414 } 415 return newMessageCount; 417 } 418 419 427 public Message getMessage(int msgnum) 428 throws MessagingException 429 { 430 if (mode==-1) 431 throw new MessagingException ("Folder is not open"); 432 return new IMAPMessage(this, msgnum); 433 } 434 435 439 public void appendMessages(Message [] messages) 440 throws MessagingException 441 { 442 if (mode==Folder.READ_ONLY) 443 throw new IllegalWriteException ("Folder is read-only"); 444 MimeMessage [] m = new MimeMessage [messages.length]; 445 try 446 { 447 for (int i=0; i<messages.length; i++) 448 m[i] = (MimeMessage )messages[i]; 449 } 450 catch (ClassCastException e) 451 { 452 throw new MessagingException ("Only MimeMessages can be appended to "+ 453 "this folder"); 454 } 455 try 456 { 457 IMAPStore s = (IMAPStore)store; 458 for (int i=0; i<m.length; i++) 459 { 460 ByteArrayOutputStream out = new ByteArrayOutputStream (); 461 m[i].writeTo(out); 462 byte[] content = out.toByteArray(); 463 out = null; 464 s.connection.append(path, null, content); 465 } 466 } 467 catch (IOException e) 468 { 469 throw new MessagingException (e.getMessage(), e); 470 } 471 notifyMessageAddedListeners(m); 472 } 473 474 public void fetch(Message [] messages, FetchProfile fetchprofile) 475 throws MessagingException 476 { 477 } 479 480 483 public Folder [] list(String pattern) 484 throws MessagingException 485 { 486 IMAPConnection connection = ((IMAPStore)store).connection; 487 try 488 { 489 ListEntry[] entries = connection.list(path, pattern); 490 Folder [] folders = new Folder [entries.length]; 491 for (int i=0; i<folders.length; i++) 492 folders[i] = getFolder(entries[i].mailbox); 493 return folders; 494 } 495 catch (IOException e) 496 { 497 throw new MessagingException (e.getMessage(), e); 498 } 499 } 500 501 504 public Folder [] listSubscribed(String pattern) 505 throws MessagingException 506 { 507 IMAPConnection connection = ((IMAPStore)store).connection; 508 try 509 { 510 ListEntry[] entries = connection.lsub(path, pattern); 511 Folder [] folders = new Folder [entries.length]; 512 for (int i=0; i<folders.length; i++) 513 folders[i] = getFolder(entries[i].mailbox); 514 return folders; 515 } 516 catch (IOException e) 517 { 518 throw new MessagingException (e.getMessage(), e); 519 } 520 } 521 522 525 public Folder getParent() 526 throws MessagingException 527 { 528 IMAPConnection connection = ((IMAPStore)store).connection; 529 int di = path.lastIndexOf(getSeparator()); 530 if (di==-1) 531 return null; 532 return store.getFolder(path.substring(0, di)); 533 } 534 535 538 public Folder getFolder(String name) 539 throws MessagingException 540 { 541 IMAPConnection connection = ((IMAPStore)store).connection; 542 return store.getFolder(new StringBuffer (path) 543 .append(getSeparator()) 544 .append(name) 545 .toString()); 546 } 547 548 551 public char getSeparator() 552 throws MessagingException 553 { 554 if (delimiter=='\u0000') 555 { 556 try 557 { 558 IMAPConnection connection = ((IMAPStore)store).connection; 559 ListEntry[] entries = connection.list(path, null); 560 if (entries.length>0) 561 delimiter = entries[0].delimiter; 562 } 563 catch (IOException e) 564 { 565 throw new MessagingException (e.getMessage(), e); 566 } 567 } 568 return delimiter; 569 } 570 571 572 } 573 | Popular Tags |