KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > UIDFolderInfo


1 package net.suberic.pooka;
2 import javax.mail.*;
3 import javax.mail.event.MessageCountEvent JavaDoc;
4 import javax.mail.internet.MimeMessage JavaDoc;
5 import javax.mail.event.MessageChangedEvent JavaDoc;
6 import javax.mail.event.ConnectionEvent JavaDoc;
7 import net.suberic.pooka.*;
8 import java.util.Vector JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.StringTokenizer JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.Set JavaDoc;
13 import java.util.logging.Level JavaDoc;
14 import net.suberic.pooka.gui.MessageProxy;
15 import net.suberic.pooka.gui.FolderTableModel;
16
17 /**
18  * A FolderInfo which keeps track of its messages' UIDs. This allows
19  * it to recover if the connection to the server is lost.
20  * @author Allen Petersen
21  * @version $Revision: 1673 $
22  */

23
24 public class UIDFolderInfo extends FolderInfo {
25   protected HashMap JavaDoc uidToInfoTable = new HashMap JavaDoc();
26   protected long uidValidity = -1000;
27
28   // the resource for the folder disconnected message
29
protected static String JavaDoc disconnectedMessage = "error.UIDFolder.disconnected";
30
31   public UIDFolderInfo(StoreInfo parent, String JavaDoc fname) {
32     super(parent, fname);
33   }
34
35   public UIDFolderInfo(FolderInfo parent, String JavaDoc fname) {
36     super(parent, fname);
37   }
38
39   /**
40    * Loads the MessageInfos and MesageProxies. Returns a List of
41    * newly created MessageProxies.
42    */

43   protected List JavaDoc createInfosAndProxies() throws MessagingException {
44     int fetchBatchSize = 50;
45     try {
46       fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50"));
47     } catch (NumberFormatException JavaDoc nfe) {
48     }
49
50     Vector JavaDoc messageProxies = new Vector JavaDoc();
51
52     Folder f = getFolder();
53     if (f == null)
54       throw new MessagingException("Folder does not exist or is unavailable.");
55
56     Message JavaDoc[] msgs = getFolder().getMessages();
57
58     // get the UIDs first.
59
FetchProfile uidProfile = new FetchProfile();
60     uidProfile.add(UIDFolder.FetchProfileItem.UID);
61     // adding FLAGS to make getFirstUnreadMessage() more efficient
62
uidProfile.add(FetchProfile.Item.FLAGS);
63
64     getFolder().fetch(msgs, uidProfile);
65
66     Message JavaDoc[] toFetch = msgs;
67
68     // go ahead and fetch the first set of messages; the rest will be
69
// taken care of by the loaderThread.
70
if (msgs.length > fetchBatchSize) {
71       toFetch = new Message JavaDoc[fetchBatchSize];
72       System.arraycopy(msgs, msgs.length - fetchBatchSize, toFetch, 0, fetchBatchSize);
73     }
74
75     getFolder().fetch(toFetch, fetchProfile);
76
77     int firstFetched = Math.max(msgs.length - fetchBatchSize, 0);
78
79     MessageInfo mi;
80
81     for (int i = 0; i < msgs.length; i++) {
82       long uid = getUID(msgs[i]);
83       UIDMimeMessage newMessage = new UIDMimeMessage(this, uid);
84       mi = new MessageInfo(newMessage, this);
85
86       if ( i >= firstFetched)
87         mi.setFetched(true);
88
89       messageProxies.add(new MessageProxy(getColumnValues() , mi));
90       messageToInfoTable.put(newMessage, mi);
91       uidToInfoTable.put(new Long JavaDoc(uid), mi);
92     }
93
94     return messageProxies;
95   }
96
97   /**
98    * This just checks to see if we can get a NewMessageCount from the
99    * folder. As a brute force method, it also accesses the folder
100    * at every check. It's nasty, but it _should_ keep the Folder open..
101    */

102   public void checkFolder() throws javax.mail.MessagingException JavaDoc {
103     getLogger().log(Level.FINE, "checking folder " + getFolderName());
104
105     // i'm taking this almost directly from ICEMail; i don't know how
106
// to keep the stores/folders open, either. :)
107

108     StoreInfo s = null;
109     if (isConnected()) {
110       Folder current = getFolder();
111       if (current != null && current.isOpen()) {
112         current.getNewMessageCount();
113         current.getUnreadMessageCount();
114         resetMessageCounts();
115       }
116     } else if (isAvailable() && (status == PASSIVE || status == LOST_CONNECTION)) {
117       s = getParentStore();
118       if (! s.isConnected())
119         s.connectStore();
120
121       openFolder(Folder.READ_WRITE);
122
123       resetMessageCounts();
124
125       if (isAvailable() && preferredStatus == PASSIVE)
126         closeFolder(false);
127     }
128   }
129
130   protected void updateFolderOpenStatus(boolean isNowOpen) {
131     if (isNowOpen) {
132       setStatus(CONNECTED);
133       try {
134         if (uidValidity == -1000) {
135           uidValidity = ((UIDFolder) getFolder()).getUIDValidity();
136         }
137         if (getFolderTableModel() != null)
138           synchronizeCache();
139       } catch (Exception JavaDoc e) { }
140
141     } else
142       setStatus(CLOSED);
143   }
144
145   /**
146    * This synchronizes the cache with the new information from the
147    * Folder.
148    */

149   public void synchronizeCache() throws MessagingException {
150     getLogger().log(Level.FINE, "synchronizing cache.");
151
152     if (getFolderDisplayUI() != null)
153       getFolderDisplayUI().showStatusMessage(Pooka.getProperty("message.UIDFolder.synchronizing", "Re-synchronizing with folder..."));
154
155     long newValidity = ((UIDFolder)getFolder()).getUIDValidity();
156     if (uidValidity != newValidity) {
157       if (getFolderDisplayUI() != null)
158         getFolderDisplayUI().showStatusMessage(Pooka.getProperty("error.UIDFolder.validityMismatch", "Error: validity not correct. reloading..."));
159
160       folderTableModel = null;
161       loadAllMessages();
162       if (getFolderDisplayUI() != null)
163         getFolderDisplayUI().resetFolderTableModel(folderTableModel);
164
165       if (getFolderDisplayUI() != null)
166         getFolderDisplayUI().clearStatusMessage();
167
168     } else {
169       if (getFolderDisplayUI() != null)
170         getFolderDisplayUI().showStatusMessage(Pooka.getProperty("message.UIDFolder.synchronizing.loading", "Loading messages from folder..."));
171       FetchProfile fp = new FetchProfile();
172       //fp.add(FetchProfile.Item.ENVELOPE);
173
//fp.add(FetchProfile.Item.FLAGS);
174
fp.add(UIDFolder.FetchProfileItem.UID);
175       Message JavaDoc[] messages = getFolder().getMessages();
176       getFolder().fetch(messages, fp);
177
178       if (getFolderDisplayUI() != null)
179         getFolderDisplayUI().showStatusMessage(Pooka.getProperty("message.UIDFolder.synchronizing", "Comparing new messages to current list..."));
180
181       long[] uids = new long[messages.length];
182
183       for (int i = 0; i < messages.length; i++) {
184         uids[i] = getUID(messages[i]);
185       }
186
187       getLogger().log(Level.FINE, "synchronizing--uids.length = " + uids.length);
188
189       long[] addedUids = getAddedMessages(uids, uidValidity);
190       getLogger().log(Level.FINE, "synchronizing--addedUids.length = " + addedUids.length);
191
192       if (addedUids.length > 0) {
193         Message JavaDoc[] addedMsgs = ((UIDFolder)getFolder()).getMessagesByUID(addedUids);
194         MessageCountEvent JavaDoc mce = new MessageCountEvent JavaDoc(getFolder(), MessageCountEvent.ADDED, false, addedMsgs);
195         messagesAdded(mce);
196       }
197
198       long[] removedUids = getRemovedMessages(uids, uidValidity);
199       getLogger().log(Level.FINE, "synchronizing--removedUids.length = " + removedUids.length);
200
201       if (removedUids.length > 0) {
202         Message JavaDoc[] removedMsgs = new Message JavaDoc[removedUids.length];
203         for (int i = 0 ; i < removedUids.length; i++) {
204           // messagesRemoved() will handle moving between UIDMimeMessages
205
// and real messages.
206
removedMsgs[i] = getMessageInfoByUid(removedUids[i]).getMessage();
207         }
208         MessageCountEvent JavaDoc mce = new MessageCountEvent JavaDoc(getFolder(), MessageCountEvent.REMOVED, false, removedMsgs);
209         messagesRemoved(mce);
210
211       }
212
213       updateFlags(uids, messages, uidValidity);
214
215       if (getFolderDisplayUI() != null)
216         getFolderDisplayUI().clearStatusMessage();
217     }
218   }
219
220   /**
221    * Gets the added UIDs.
222    */

223   protected long[] getAddedMessages(long[] newUids, long uidValidity) {
224     long[] added = new long[newUids.length];
225     int addedCount = 0;
226     Set JavaDoc currentUids = uidToInfoTable.keySet();
227
228     for (int i = 0; i < newUids.length; i++) {
229       if (! currentUids.contains(new Long JavaDoc(newUids[i]))) {
230         added[addedCount++]=newUids[i];
231       }
232     }
233
234     long[] returnValue = new long[addedCount];
235     if (addedCount > 0)
236       System.arraycopy(added, 0, returnValue, 0, addedCount);
237
238     return returnValue;
239
240   }
241
242   /**
243    * Gets the removed UIDs.
244    */

245   protected long[] getRemovedMessages(long[] newUids, long uidValidity) {
246     Vector JavaDoc remainders = new Vector JavaDoc(uidToInfoTable.keySet());
247
248     for (int i = 0; i < newUids.length; i++) {
249       remainders.remove(new Long JavaDoc(newUids[i]));
250     }
251
252     long[] returnValue = new long[remainders.size()];
253     for (int i = 0; i < remainders.size(); i++)
254       returnValue[i] = ((Long JavaDoc) remainders.elementAt(i)).longValue();
255
256     return returnValue;
257   }
258
259   protected void updateFlags(long[] uids, Message JavaDoc[] messages, long uidValidity) throws MessagingException {
260     // sigh
261

262     Vector JavaDoc proxies = new Vector JavaDoc();
263     for (int i = 0; i < messages.length; i++) {
264       // FIXME
265
MessageInfo mi = getMessageInfo(messages[i]);
266       MessageProxy mp = mi.getMessageProxy();
267       mi.setFetched(false);
268       mp.setRefresh(true);
269       proxies.add(mp);
270     }
271
272     getLogger().log(Level.FINE, "updating flags for " + proxies.size() + " messages.");
273
274     //loaderThread.loadMessages(proxies);
275
mMessageLoader.loadMessages(proxies);
276
277   }
278
279   protected void runMessagesAdded(MessageCountEvent JavaDoc mce) {
280     if (folderTableModel != null) {
281       try {
282         Message JavaDoc[] addedMessages = mce.getMessages();
283         /*
284           FetchProfile fp = new FetchProfile();
285           fp.add(FetchProfile.Item.ENVELOPE);
286           fp.add(FetchProfile.Item.FLAGS);
287           fp.add(UIDFolder.FetchProfileItem.UID);
288         */

289
290         showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.fetchingMessages", "Fetching") + " " + addedMessages.length + " " + Pooka.getProperty("message.UIDFolder.synchronizing.messages", "messages."));
291         getLogger().log(Level.FINE, "UIDFolderInfo: runMessagesAdded(). getting " + addedMessages.length + " messages.");
292
293         if (fetchProfile != null) {
294           FetchProfile fp = null;
295           if (! fetchProfile.contains(UIDFolder.FetchProfileItem.UID)) {
296             // clone it. we could cache this, but i doubt it's a problem.
297
fp = new FetchProfile();
298             FetchProfile.Item[] items = fetchProfile.getItems();
299             String JavaDoc[] headers = fetchProfile.getHeaderNames();
300             if (items != null) {
301               for (int i = 0; i < items.length; i++) {
302                 fp.add(items[i]);
303               }
304             }
305
306             if (headers != null) {
307               for (int i = 0; i < headers.length; i++) {
308                 fp.add(headers[i]);
309               }
310             }
311
312             fp.add(UIDFolder.FetchProfileItem.UID);
313
314           } else {
315             fp = fetchProfile;
316           }
317           getFolder().fetch(addedMessages, fp);
318         } else {
319           FetchProfile fp = new FetchProfile();
320           fp.add(FetchProfile.Item.ENVELOPE);
321           fp.add(FetchProfile.Item.FLAGS);
322           fp.add(UIDFolder.FetchProfileItem.UID);
323
324           getFolder().fetch(addedMessages, fp);
325         }
326
327         MessageInfo mi;
328         Vector JavaDoc addedProxies = new Vector JavaDoc();
329         for (int i = 0; i < addedMessages.length; i++) {
330           UIDMimeMessage newMsg = getUIDMimeMessage(addedMessages[i]);
331           long uid = newMsg.getUID();
332           if (getMessageInfoByUid(uid) != null) {
333             getLogger().log(Level.FINE, getFolderID() + ": this is a duplicate. not making a new messageinfo for it.");
334           } else {
335             mi = new MessageInfo(newMsg, this);
336             // this has already been fetched; no need to do so again.
337
mi.setFetched(true);
338
339             addedProxies.add(new MessageProxy(getColumnValues(), mi));
340             messageToInfoTable.put(newMsg, mi);
341             uidToInfoTable.put(new Long JavaDoc(uid), mi);
342           }
343         }
344
345         getLogger().log(Level.FINE, "filtering proxies.");
346         addedProxies.removeAll(applyFilters(addedProxies));
347
348         getLogger().log(Level.FINE, "filters run; adding " + addedProxies.size() + " messages.");
349         if (addedProxies.size() > 0) {
350           getFolderTableModel().addRows(addedProxies);
351           setNewMessages(true);
352           resetMessageCounts();
353
354           // notify the message loaded thread.
355
MessageProxy[] addedArray = (MessageProxy[]) addedProxies.toArray(new MessageProxy[0]);
356           //loaderThread.loadMessages(addedArray, net.suberic.pooka.thread.LoadMessageThread.HIGH);
357
mMessageLoader.loadMessages(addedArray, net.suberic.pooka.thread.MessageLoader.HIGH);
358
359           // change the Message objects in the MessageCountEvent to
360
// our UIDMimeMessages.
361
Message JavaDoc[] newMsgs = new Message JavaDoc[addedProxies.size()];
362           for (int i = 0; i < addedProxies.size(); i++) {
363             newMsgs[i] = ((MessageProxy)addedProxies.elementAt(i)).getMessageInfo().getMessage();
364           }
365           MessageCountEvent JavaDoc newMce = new MessageCountEvent JavaDoc(getFolder(), mce.getType(), mce.isRemoved(), newMsgs);
366           fireMessageCountEvent(newMce);
367         }
368       } catch (MessagingException me) {
369         if (getFolderDisplayUI() != null)
370           getFolderDisplayUI().showError(Pooka.getProperty("error.handlingMessages", "Error handling messages."), Pooka.getProperty("error.handlingMessages.title", "Error handling messages."), me);
371       } finally {
372         clearStatusMessage(getFolderDisplayUI());
373       }
374     }
375
376   }
377
378   /**
379    * This does the real work when messages are removed.
380    */

381   protected void runMessagesRemoved(MessageCountEvent JavaDoc mce) {
382     getLogger().log(Level.FINE, "running MessagesRemoved on " + getFolderID());
383
384     MessageCountEvent JavaDoc newMce = null;
385     if (folderTableModel != null) {
386       Message JavaDoc[] removedMessages = mce.getMessages();
387       Message JavaDoc[] uidRemovedMessages = new Message JavaDoc[removedMessages.length];
388
389       getLogger().log(Level.FINE, "removedMessages was of size " + removedMessages.length);
390
391       MessageInfo mi;
392       Vector JavaDoc removedProxies=new Vector JavaDoc();
393       for (int i = 0; i < removedMessages.length; i++) {
394         getLogger().log(Level.FINE, "checking for existence of message " + removedMessages[i]);
395
396         try {
397           UIDMimeMessage removedMsg = getUIDMimeMessage(removedMessages[i]);
398
399           if (removedMsg != null)
400             uidRemovedMessages[i] = removedMsg;
401           else
402             uidRemovedMessages[i] = removedMessages[i];
403
404           mi = getMessageInfo(removedMsg);
405           if (mi != null) {
406             if (mi.getMessageProxy() != null)
407               mi.getMessageProxy().close();
408
409             getLogger().log(Level.FINE, "message exists--removing");
410             removedProxies.add(mi.getMessageProxy());
411             messageToInfoTable.remove(mi);
412             uidToInfoTable.remove(new Long JavaDoc(removedMsg.getUID()));
413           } else {
414             getLogger().log(Level.FINE, "message with uid " + removedMessages[i] + " not found; not removing.");
415           }
416         } catch (MessagingException me) {
417           getLogger().log(Level.FINE, "caught exception running messagesRemoved on " + removedMessages[i] + ": " + me.getMessage());
418         }
419       }
420       newMce = new MessageCountEvent JavaDoc(getFolder(), mce.getType(), mce.isRemoved(), uidRemovedMessages);
421       if (getFolderDisplayUI() != null) {
422         if (removedProxies.size() > 0)
423           getFolderDisplayUI().removeRows(removedProxies);
424         resetMessageCounts();
425         fireMessageCountEvent(newMce);
426       } else {
427         resetMessageCounts();
428         fireMessageCountEvent(newMce);
429         if (removedProxies.size() > 0)
430           getFolderTableModel().removeRows(removedProxies);
431       }
432     } else {
433       resetMessageCounts();
434       fireMessageCountEvent(mce);
435     }
436   }
437
438   protected void runMessageChanged(MessageChangedEvent JavaDoc mce) {
439     // if the message is getting deleted, then we don't
440
// really need to update the table info. for that
441
// matter, it's likely that we'll get MessagingExceptions
442
// if we do, anyway.
443
boolean updateInfo = false;
444     try {
445       updateInfo = (!mce.getMessage().isSet(Flags.Flag.DELETED) || ! Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true"));
446     } catch (MessagingException me) {
447       // if we catch a MessagingException, it just means
448
// that the message has already been expunged. in
449
// that case, assume it's ok if we don't update; it'll
450
// happen in the messagesRemoved().
451
}
452
453     if (updateInfo) {
454       try {
455         Message JavaDoc msg = mce.getMessage();
456         UIDMimeMessage changedMsg = getUIDMimeMessage(msg);
457         long uid = changedMsg.getUID();
458
459         MessageInfo mi = getMessageInfoByUid(uid);
460         if (mi != null) {
461           MessageProxy mp = mi.getMessageProxy();
462           if (mp != null) {
463             mp.unloadTableInfo();
464             mp.loadTableInfo();
465           }
466         }
467       } catch (MessagingException me) {
468         // if we catch a MessagingException, it just means
469
// that the message has already been expunged.
470
}
471
472       // if we're not just a tableinfochanged event, do a resetmessagecouts.
473
// don't do this if we're just a delete.
474
if (! (mce instanceof net.suberic.pooka.event.MessageTableInfoChangedEvent)) {
475         resetMessageCounts();
476       }
477     }
478
479     // now let's go ahead and get the UIDMimeMessage for the event so
480
// that we can fire that instead.
481

482     try {
483       Message JavaDoc msg = mce.getMessage();
484       UIDMimeMessage changedMsg = getUIDMimeMessage(msg);
485       if (changedMsg != null) {
486         MessageChangedEvent JavaDoc newMce = new MessageChangedEvent JavaDoc(mce.getSource(), mce.getMessageChangeType(), changedMsg);
487         fireMessageChangedEvent(newMce);
488       } else
489         fireMessageChangedEvent(mce);
490     } catch (MessagingException me) {
491       // if we catch a MessagingException, then we can just fire the
492
// original mce.
493
fireMessageChangedEvent(mce);
494
495     }
496   }
497
498
499   /**
500    * This updates the children of the current folder. Generally called
501    * when the folderList property is changed.
502    */

503   public void updateChildren() {
504     Vector JavaDoc newChildren = new Vector JavaDoc();
505
506     String JavaDoc childList = Pooka.getProperty(getFolderProperty() + ".folderList", "");
507     if (childList != "") {
508       StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(childList, ":");
509
510       String JavaDoc newFolderName;
511
512       for (int i = 0 ; tokens.hasMoreTokens() ; i++) {
513         newFolderName = (String JavaDoc)tokens.nextToken();
514         FolderInfo childFolder = getChild(newFolderName);
515         if (childFolder == null) {
516           childFolder = new UIDFolderInfo(this, newFolderName);
517           newChildren.add(childFolder);
518         } else {
519           newChildren.add(childFolder);
520         }
521       }
522
523       children = newChildren;
524
525       if (folderNode != null)
526         folderNode.loadChildren();
527     }
528   }
529
530   /**
531    * Fetches the information for the given messages using the given
532    * FetchProfile.
533    */

534   public void fetch(MessageInfo[] messages, FetchProfile profile) throws MessagingException {
535     if (messages == null)
536       getLogger().log(Level.FINE, "UIDFolderInfo: fetching with null messages.");
537     else
538       getLogger().log(Level.FINE, "UIDFolderInfo: fetching " + messages.length + " messages.");
539
540     // check the messages first; make sure we're just fetching 'real'
541
// messages.
542
java.util.ArrayList JavaDoc realMsgList = new java.util.ArrayList JavaDoc();
543     for (int i = 0; i < messages.length; i++) {
544       Message JavaDoc currentMsg = messages[i].getRealMessage();
545       if (currentMsg != null && currentMsg instanceof UIDMimeMessage) {
546         currentMsg = ((UIDMimeMessage)currentMsg).getMessage();
547       }
548       if (currentMsg != null)
549         realMsgList.add(currentMsg);
550     }
551
552     Message JavaDoc[] realMsgs = (Message JavaDoc[]) realMsgList.toArray(new Message JavaDoc[0]);
553
554     if (realMsgs == null)
555       getLogger().log(Level.FINE, "UIDFolderInfo: running fetch with null real messages.");
556     else
557       getLogger().log(Level.FINE, "UIDFolderInfo: fetching " + realMsgs.length + " messages.");
558
559     getFolder().fetch(realMsgs, profile);
560
561     for (int i = 0 ; i < messages.length; i++) {
562       messages[i].setFetched(true);
563     }
564   }
565
566   /**
567    * Unloads all messages. This should be run if ever the current message
568    * information becomes out of date, as can happen when the connection
569    * to the folder goes down.
570    *
571    * Note that for this implementation, we just keep everything; we only
572    * need to worry when we do the cache synchronization.
573    */

574   public void unloadAllMessages() {
575     //folderTableModel = null;
576
}
577
578   /**
579    * This method closes the Folder. If you open the Folder using
580    * openFolder (which you should), then you should use this method
581    * instead of calling getFolder.close(). If you don't, then the
582    * FolderInfo will try to reopen the folder.
583    */

584   public void closeFolder(boolean expunge, boolean closeDisplay) throws MessagingException {
585
586     if (closeDisplay && getFolderDisplayUI() != null)
587       getFolderDisplayUI().closeFolderDisplay();
588
589     /*
590     // should this be here? should we remove closed folders from
591     // the FolderTracker?
592     if (getFolderTracker() != null) {
593     getFolderTracker().removeFolder(this);
594     setFolderTracker(null);
595     }
596     */

597
598     if (isLoaded() && isAvailable()) {
599       if (isConnected()) {
600         try {
601           getFolder().close(expunge);
602         } catch (java.lang.IllegalStateException JavaDoc ise) {
603           throw new MessagingException(ise.getMessage(), ise);
604         }
605       }
606       setStatus(CLOSED);
607     }
608
609
610   }
611
612   // UID / UIDMimeMessage / etc. methods.
613

614   /**
615    * Returns the UIDMimeMessage for the given Message.
616    */

617   public UIDMimeMessage getUIDMimeMessage(Message JavaDoc m) throws MessagingException {
618     if (m instanceof UIDMimeMessage)
619       return (UIDMimeMessage) m;
620
621     // it's not a UIDMimeMessage, so it must be a 'real' message.
622
long uid = getUID(m);
623     MessageInfo mi = getMessageInfoByUid(uid);
624     if (mi != null)
625       return (UIDMimeMessage) mi.getMessage();
626
627     // doesn't already exist. just create a new one.
628
return new UIDMimeMessage(this, uid);
629   }
630
631   /**
632    * gets the 'real' message for the given MessageInfo.
633    */

634   public Message JavaDoc getRealMessage(MessageInfo mi) throws MessagingException {
635     Message JavaDoc wrappingMessage = mi.getMessage();
636     if (wrappingMessage instanceof UIDMimeMessage)
637       return ((UIDMimeMessage)wrappingMessage).getMessage();
638     else
639       return wrappingMessage;
640   }
641
642   /**
643    * Returns the "real" message from the underlying folder that matches up
644    * to the given UID. If no such message exists, returns null.
645    */

646   public javax.mail.internet.MimeMessage JavaDoc getRealMessageById(long uid) throws MessagingException {
647     Folder f = getFolder();
648     if (f != null && f instanceof UIDFolder) {
649       javax.mail.internet.MimeMessage JavaDoc m = null;
650       try {
651         m = (javax.mail.internet.MimeMessage JavaDoc) ((UIDFolder) f).getMessageByUID(uid);
652         return m;
653       } catch (IllegalStateException JavaDoc ise) {
654         throw new MessagingException(ise.getMessage());
655       }
656     } else {
657       throw new MessagingException("Error: Folder unavailable or is not a UIDFolder");
658     }
659   }
660
661   /**
662    * gets the MessageInfo for the given Message.
663    */

664   public MessageInfo getMessageInfo(Message JavaDoc m) {
665     if (m instanceof UIDMimeMessage)
666       return (MessageInfo) messageToInfoTable.get(m);
667     else {
668       try {
669         long uid = getUID(m);
670         return getMessageInfoByUid(uid);
671       } catch (MessagingException me) {
672         return null;
673       }
674     }
675   }
676
677   /**
678    * Returns the MessageInfo associated with the given uid.
679    */

680   public MessageInfo getMessageInfoByUid(long uid) {
681     return (MessageInfo) uidToInfoTable.get(new Long JavaDoc(uid));
682   }
683
684
685   /**
686    * Gets the UID for the given Message.
687    */

688   public long getUID(Message JavaDoc m) throws MessagingException {
689     if (m instanceof UIDMimeMessage)
690       return ((UIDMimeMessage)m).getUID();
691     else {
692       return ((UIDFolder)getFolder()).getUID(m);
693     }
694   }
695
696   public long getUIDValidity() {
697     return uidValidity;
698   }
699
700 }
701
702
Popular Tags