From: Timo S. <ts...@us...> - 2005-08-28 19:53:05
|
Update of /cvsroot/columba/columba/src/mail/core/org/columba/mail/folder/imap In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30273/src/mail/core/org/columba/mail/folder/imap Modified Files: IMAPFolder.java Log Message: [intern]Refactoring of the HeaderCacheFramework. Now HeaderList and its persistance are transparently handeled. Now we can even start into looking to use BerkelyDB in the future. Unplanned but not unwelcome this refactoring also includes some IMAP speedus :-) Index: IMAPFolder.java =================================================================== RCS file: /cvsroot/columba/columba/src/mail/core/org/columba/mail/folder/imap/IMAPFolder.java,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** IMAPFolder.java 28 Aug 2005 10:34:58 -0000 1.139 --- IMAPFolder.java 28 Aug 2005 19:52:16 -0000 1.140 *************** *** 41,53 **** import org.columba.mail.config.IFolderItem; import org.columba.mail.config.ImapItem; ! import org.columba.mail.folder.AbstractHeaderListStorage; import org.columba.mail.folder.AbstractRemoteFolder; - import org.columba.mail.folder.IHeaderListStorage; import org.columba.mail.folder.IMailFolder; import org.columba.mail.folder.IMailbox; import org.columba.mail.folder.RootFolder; import org.columba.mail.folder.command.ApplyFilterCommand; ! import org.columba.mail.folder.headercache.AbstractHeaderCache; import org.columba.mail.folder.headercache.CachedHeaderfields; import org.columba.mail.folder.headercache.RemoteHeaderCache; import org.columba.mail.folder.search.DefaultSearchEngine; --- 41,54 ---- import org.columba.mail.config.IFolderItem; import org.columba.mail.config.ImapItem; ! import org.columba.mail.folder.AbstractFolder; import org.columba.mail.folder.AbstractRemoteFolder; import org.columba.mail.folder.IMailFolder; import org.columba.mail.folder.IMailbox; import org.columba.mail.folder.RootFolder; import org.columba.mail.folder.command.ApplyFilterCommand; ! import org.columba.mail.folder.event.FolderEvent; ! import org.columba.mail.folder.event.IFolderListener; import org.columba.mail.folder.headercache.CachedHeaderfields; + import org.columba.mail.folder.headercache.PersistantHeaderList; import org.columba.mail.folder.headercache.RemoteHeaderCache; import org.columba.mail.folder.search.DefaultSearchEngine; *************** *** 55,62 **** import org.columba.mail.imap.IMAPServer; import org.columba.mail.message.ColumbaHeader; - import org.columba.mail.message.ColumbaMessage; - import org.columba.mail.message.HeaderList; import org.columba.mail.message.IColumbaHeader; - import org.columba.mail.message.IColumbaMessage; import org.columba.mail.message.IHeaderList; import org.columba.mail.parser.PassiveHeaderParserInputStream; --- 56,60 ---- *************** *** 80,98 **** .getLogger("org.columba.mail.folder.imap"); - // private boolean select=false; - // private boolean fetch=false; - // private StringBuffer cache; - private Object aktMessageUid; - - /** - * - */ - private IColumbaMessage aktMessage; - - /** - * - */ - private boolean mailcheck = false; - /** * --- 78,81 ---- *************** *** 103,120 **** * */ - protected IHeaderList headerList; - - /** - * - */ protected boolean existsOnServer = true; - /** - * - */ - private IHeaderListStorage attributeStorage; - private boolean readOnly; /** * @see org.columba.mail.folder.IMailbox#isReadOnly() --- 86,95 ---- * */ protected boolean existsOnServer = true; private boolean readOnly; + private PersistantHeaderList headerList; + /** * @see org.columba.mail.folder.IMailbox#isReadOnly() *************** *** 135,138 **** --- 110,115 ---- // setChanged(true); + + headerList = new PersistantHeaderList(new RemoteHeaderCache(this)); } *************** *** 203,207 **** * @see org.columba.mail.folder.Folder#getHeaderList(org.columba.api.command.IWorkerStatusController) */ ! public IHeaderList getHeaderList() throws Exception { ensureFolderIsSynced(); --- 180,184 ---- * @see org.columba.mail.folder.Folder#getHeaderList(org.columba.api.command.IWorkerStatusController) */ ! public IHeaderList getHeaderList() throws Exception{ ensureFolderIsSynced(); *************** *** 217,223 **** private synchronized void ensureFolderIsSynced() throws IOException, IMAPException, CommandCancelledException, Exception { ! if (headerList == null || !getServer().isSelected(this)) { synchronizeHeaderlist(); ! synchronizeFlags(); } } --- 194,214 ---- private synchronized void ensureFolderIsSynced() throws IOException, IMAPException, CommandCancelledException, Exception { ! if( !headerList.isRestored() ) { ! try { ! headerList.restore(); ! } catch (IOException e) { ! // Will be fixed in the upcoming synchroniyation process ! } synchronizeHeaderlist(); ! ! // Only do a flag sync if this folder is selected ! // -> Big speedup ! if( getServer().isSelected(this) ) synchronizeFlags(); ! } else if (!getServer().isSelected(this)) { ! synchronizeHeaderlist(); ! ! // Only do a flag sync if this folder is selected ! // -> Big speedup ! if( getServer().isSelected(this) ) synchronizeFlags(); } } *************** *** 254,272 **** public void synchronizeHeaderlist() throws Exception, IOException, CommandCancelledException, IMAPException { - headerList = super.getHeaderList(); - // Check if the mailbox has changed MailboxStatus status = getServer().getStatus(this); ! List localUids = extractUids(headerList); // Sort the uid list Collections.sort(localUids); int newMessages = 0; ! int largestLocalUid = -1; int largestLocalUidIndex = -1; ! int largestRemoteUid = -1; printStatusMessage(MailResourceLoader.getString("statusbar", "message", "sync_messages")); --- 245,272 ---- public void synchronizeHeaderlist() throws Exception, IOException, CommandCancelledException, IMAPException { // Check if the mailbox has changed MailboxStatus status = getServer().getStatus(this); ! if( status.getMessages() == 0 ) { ! headerList.clear(); ! return; ! } ! ! List localUids = new LinkedList(Arrays.asList(headerList.getUids())); // Sort the uid list Collections.sort(localUids); int newMessages = 0; ! ! int largestLocalUid = ((Integer)localUids.get(localUids.size()-1)).intValue(); int largestLocalUidIndex = -1; ! int largestRemoteUid = (int)status.getUidNext() - 1; + if( localUids.size() == status.getMessages() && largestRemoteUid == largestLocalUid) { + // Seems to be no change! + return; + } + printStatusMessage(MailResourceLoader.getString("statusbar", "message", "sync_messages")); *************** *** 274,278 **** if (status.getMessages() > 0) { largestRemoteUid = getServer().fetchUid( ! new SequenceSet(SequenceEntry.STAR), this); if (largestRemoteUid == -1) { largestRemoteUid = getServer().fetchUid( --- 274,278 ---- if (status.getMessages() > 0) { largestRemoteUid = getServer().fetchUid( ! new SequenceSet(SequenceEntry.STAR), this); if (largestRemoteUid == -1) { largestRemoteUid = getServer().fetchUid( *************** *** 345,351 **** LOG.severe("Folder " + getName() + " is out of sync -> recreating the cache!"); ! getHeaderListStorage().reset(); ! ! headerList = super.getHeaderList(); // all messages are new --- 345,349 ---- LOG.severe("Folder " + getName() + " is out of sync -> recreating the cache!"); ! headerList.clear(); // all messages are new *************** *** 394,398 **** // fire message added updates for (int i = 0; i < newFlags.length; i++) { ! fireMessageAdded(newFlags[i].getUid()); } --- 392,396 ---- // fire message added updates for (int i = 0; i < newFlags.length; i++) { ! fireMessageAdded(newFlags[i]); } *************** *** 433,438 **** && ((Integer) localUids.get(localUids.size() - 1)) .intValue() > largestRemoteUid) { ! Flags flags = ((ColumbaHeader) headerList.remove(localUids ! .get(localUids.size() - 1))).getFlags(); fireMessageRemoved(localUids.remove(localUids.size() - 1), flags); --- 431,436 ---- && ((Integer) localUids.get(localUids.size() - 1)) .intValue() > largestRemoteUid) { ! Flags flags = headerList.remove(localUids ! .get(localUids.size() - 1)).getFlags(); fireMessageRemoved(localUids.remove(localUids.size() - 1), flags); *************** *** 472,476 **** // -> remove it from the headerlist headerList.remove(localUids.get(localPointer)); ! found++; localPointer--; --- 470,474 ---- // -> remove it from the headerlist headerList.remove(localUids.get(localPointer)); ! found++; localPointer--; *************** *** 503,510 **** } public void synchronizeFlags() throws Exception, IOException, CommandCancelledException, IMAPException { - headerList = super.getHeaderList(); - printStatusMessage(MailResourceLoader.getString("statusbar", "message", "sync_flags")); --- 501,539 ---- } + /** + * Propagates an event to all registered listeners notifying them of a + * message addition. + */ + private void fireMessageAdded(IMAPFlags flags) { + getMessageFolderInfo().incExists(); + try { + if (flags.getRecent()) { + getMessageFolderInfo().incRecent(); + } + if (!flags.getSeen()) { + getMessageFolderInfo().incUnseen(); + } + } catch (Exception e) { + } + setChanged(true); + + // update treenode + fireFolderPropertyChanged(); + + FolderEvent e = new FolderEvent(this, flags.getUid()); + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == IFolderListener.class) { + ((IFolderListener) listeners[i + 1]).messageAdded(e); + } + } + } + public void synchronizeFlags() throws Exception, IOException, CommandCancelledException, IMAPException { printStatusMessage(MailResourceLoader.getString("statusbar", "message", "sync_flags")); *************** *** 576,580 **** * @param flagsList */ ! protected void setFlags(Flags[] flagsList) { for (int i = 0; i < flagsList.length; i++) { IMAPFlags flags = (IMAPFlags) flagsList[i]; --- 605,609 ---- * @param flagsList */ ! protected void setFlags(Flags[] flagsList) throws Exception { for (int i = 0; i < flagsList.length; i++) { IMAPFlags flags = (IMAPFlags) flagsList[i]; *************** *** 582,586 **** Integer uid = (Integer) flags.getUid(); ! ColumbaHeader header = (ColumbaHeader) headerList.get(uid); Flags localFlags = header.getFlags(); --- 611,615 ---- Integer uid = (Integer) flags.getUid(); ! IColumbaHeader header = headerList.get(uid); Flags localFlags = header.getFlags(); *************** *** 595,627 **** /** - * Method save. - */ - public void save() throws Exception { - // make sure that messagefolderinfo(total/unread/recent count) - // is saved in tree.xml file - saveMessageFolderInfo(); - - // only save header-cache if folder data changed - if (hasChanged()) { - getHeaderListStorage().save(); - setChanged(false); - } - } - - /** - * @param headerList - * @return - */ - private List extractUids(IHeaderList headerList) { - LinkedList headerUids = new LinkedList(); - Enumeration keys = headerList.keys(); - - while (keys.hasMoreElements()) { - headerUids.add(keys.nextElement()); - } - return headerUids; - } - - /** * Method existsRemotely. * --- 624,627 ---- *************** *** 657,663 **** * @throws Exception */ ! protected boolean existsLocally(String uid, HeaderList list) throws Exception { ! for (Enumeration e = headerList.keys(); e.hasMoreElements();) { String localUID = (String) e.nextElement(); --- 657,663 ---- * @throws Exception */ ! protected boolean existsLocally(String uid, PersistantHeaderList list) throws Exception { ! for (Enumeration e = getHeaderList().keys(); e.hasMoreElements();) { String localUID = (String) e.nextElement(); *************** *** 689,693 **** public void innerCopy(IMailbox destiny, Object[] uids) throws Exception { IMAPFolder destFolder = (IMAPFolder) destiny; ! Object[] destUids = getServer().copy(destFolder, uids, this); --- 689,695 ---- public void innerCopy(IMailbox destiny, Object[] uids) throws Exception { IMAPFolder destFolder = (IMAPFolder) destiny; ! IHeaderList srcHeaderList = getHeaderList(); ! IHeaderList destHeaderList = destFolder.getHeaderList(); ! Object[] destUids = getServer().copy(destFolder, uids, this); *************** *** 696,714 **** .warning("Some messages could not be copied because they do not exist anymore!"); } ! // update headerlist of destination-folder // -> this is necessary to reflect the changes visually int j = 0; for (int i = 0; i < uids.length; i++) { ! ColumbaHeader header = (ColumbaHeader) getHeaderList().get(uids[i]); // Was this message actually copied? ! if (header != null) { ! destFolder.getHeaderListStorage().addMessage(destUids[j], ! header.getHeader(), header.getAttributes(), ! header.getFlags()); ! destFolder.fireMessageAdded(destUids[j]); ! j++; ! } } --- 698,718 ---- .warning("Some messages could not be copied because they do not exist anymore!"); } ! // update headerlist of destination-folder // -> this is necessary to reflect the changes visually int j = 0; for (int i = 0; i < uids.length; i++) { ! IColumbaHeader destHeader = new ColumbaHeader(srcHeaderList.get(uids[i])); // Was this message actually copied? ! destHeader.set("columba.uid", destUids[j]); ! destHeaderList.add(destHeader, destUids[j]); ! ! // We need IMAPFlags ! IMAPFlags flags = new IMAPFlags(destHeader.getFlags().getFlags()); ! flags.setUid( destUids[j]); ! ! destFolder.fireMessageAdded( flags ); ! j++; } *************** *** 744,765 **** */ public IColumbaHeader getMessageHeader(Object uid) throws Exception { ! if (headerList == null) { ! getHeaderList(); ! } ! ! return (ColumbaHeader) headerList.get(uid); } - /** - * Method getMessage. - * - * @param uid - * @param worker - * @return AbstractMessage - * @throws Exception - */ - public IColumbaMessage getMessage(Object uid) throws Exception { - return new ColumbaMessage((ColumbaHeader) headerList.get((String) uid)); - } /** --- 748,754 ---- */ public IColumbaHeader getMessageHeader(Object uid) throws Exception { ! return getHeaderList().get(uid); } /** *************** *** 878,882 **** // update the HeaderList ! getHeaderListStorage().addMessage(uid, header, attributes, imapFlags); return uid; --- 867,873 ---- // update the HeaderList ! IColumbaHeader cHeader = new ColumbaHeader(header, attributes, imapFlags); ! header.set("columba.uid", uid); ! getHeaderList().add(cHeader, uid); return uid; *************** *** 891,895 **** public Header getHeaderFields(Object uid, String[] keys) throws Exception { // get header with UID ! ColumbaHeader header = (ColumbaHeader) getHeaderList().get(uid); if (header == null) --- 882,886 ---- public Header getHeaderFields(Object uid, String[] keys) throws Exception { // get header with UID ! IColumbaHeader header = getHeaderList().get(uid); if (header == null) *************** *** 995,1000 **** Header header = withHeaderInputStream.getHeader(); ColumbaHeader h = new ColumbaHeader(header); ! getHeaderListStorage().addMessage(uid, header, h.getAttributes(), ! h.getFlags()); return uid; --- 986,990 ---- Header header = withHeaderInputStream.getHeader(); ColumbaHeader h = new ColumbaHeader(header); ! getHeaderList().add(h,uid ); return uid; *************** *** 1004,1007 **** --- 994,998 ---- * @see org.columba.mail.folder.Folder#getHeaderListStorage() */ + /* public IHeaderListStorage getHeaderListStorage() { if (attributeStorage == null) *************** *** 1009,1013 **** return attributeStorage; ! } /** --- 1000,1004 ---- return attributeStorage; ! }*/ /** *************** *** 1047,1051 **** * @throws IMAPException */ ! public void updateFlag(IMAPFlags flag) throws IOException, IMAPException, CommandCancelledException { if (getServer().isSelected(this)) { --- 1038,1042 ---- * @throws IMAPException */ ! public void updateFlag(IMAPFlags flag) throws Exception, CommandCancelledException { if (getServer().isSelected(this)) { *************** *** 1064,1068 **** this.readOnly = readOnly; } ! class RemoteHeaderListStorage extends AbstractHeaderListStorage { --- 1055,1060 ---- this.readOnly = readOnly; } ! ! /* class RemoteHeaderListStorage extends AbstractHeaderListStorage { *************** *** 1071,1077 **** private IMAPFolder folder; - /** - * - */ public RemoteHeaderListStorage(IMAPFolder folder) { super(); --- 1063,1066 ---- *************** *** 1080,1086 **** } - /** - * @see org.columba.mail.folder.AbstractHeaderListStorage#getHeaderCacheInstance() - */ public AbstractHeaderCache getHeaderCacheInstance() { if (headerCache == null) --- 1069,1072 ---- *************** *** 1090,1094 **** } ! } /* --- 1076,1080 ---- } ! }*/ /* *************** *** 1113,1115 **** --- 1099,1110 ---- return super.searchMessages(filter); } + + /* (non-Javadoc) + * @see org.columba.mail.folder.AbstractMessageFolder#save() + */ + public void save() throws Exception { + super.save(); + + headerList.persist(); + } } \ No newline at end of file |