001: package org.columba.mail.folder.headercache;
002:
003: import java.io.IOException;
004: import java.util.ArrayList;
005: import java.util.Arrays;
006: import java.util.Calendar;
007: import java.util.Date;
008:
009: import org.columba.core.base.ListTools;
010: import org.columba.mail.folder.AbstractLocalFolder;
011: import org.columba.mail.folder.AbstractMessageFolder;
012: import org.columba.mail.folder.IDataStorage;
013: import org.columba.mail.folder.IMailboxInfo;
014: import org.columba.mail.folder.MailboxInfoInvalidException;
015: import org.columba.mail.message.ColumbaHeader;
016: import org.columba.mail.message.IColumbaHeader;
017: import org.columba.mail.message.IHeaderList;
018: import org.columba.ristretto.io.Source;
019: import org.columba.ristretto.message.Flags;
020: import org.columba.ristretto.parser.HeaderParser;
021:
022: public class SyncHeaderList {
023:
024: private static final int WEEK = 1000 * 60 * 60 * 24 * 7;
025:
026: /**
027: * @param worker
028: * @throws Exception
029: */
030: public static void sync(AbstractMessageFolder folder,
031: IHeaderList headerList) throws IOException {
032: if (folder.getObservable() != null) {
033: folder.getObservable().setMessage(
034: folder.getName() + ": Syncing headercache...");
035: }
036:
037: IDataStorage ds = ((AbstractLocalFolder) folder)
038: .getDataStorageInstance();
039:
040: Object[] uids = ds.getMessageUids();
041: Object[] headerlistUids = headerList.getUids();
042:
043: // First remove all headers that are in the headerlist but
044: // not the Folder
045: ArrayList uidsToRemove = new ArrayList(Arrays
046: .asList(headerlistUids));
047: ListTools.substract(uidsToRemove, Arrays.asList(uids));
048: for (Object u : uidsToRemove) {
049: headerList.remove(u);
050: }
051:
052: Date today = Calendar.getInstance().getTime();
053:
054: // parse all message files to recreate the header cache
055: IColumbaHeader header = null;
056: IMailboxInfo messageFolderInfo = folder.getMessageFolderInfo();
057: messageFolderInfo.setExists(0);
058: messageFolderInfo.setRecent(0);
059: messageFolderInfo.setUnseen(0);
060: // headerList.clear();
061:
062: folder.setChanged(true);
063:
064: if (folder.getObservable() != null) {
065: folder.getObservable().setMax(uids.length);
066: folder.getObservable().resetCurrent();
067: }
068:
069: for (int i = 0; i < uids.length; i++) {
070:
071: if ((folder.getObservable() != null) && ((i % 100) == 0)) {
072: folder.getObservable().setCurrent(i);
073: }
074:
075: if (!headerList.exists(uids[i])) {
076: try {
077: Source source = ds.getMessageSource(uids[i]);
078:
079: if (source.length() == 0) {
080: ds.removeMessage(uids[i]);
081:
082: continue;
083: }
084:
085: header = new ColumbaHeader(HeaderParser
086: .parse(source));
087:
088: // make sure that we have a Message-ID
089: String messageID = (String) header
090: .get("Message-Id");
091: if (messageID != null)
092: header.set("Message-ID", header
093: .get("Message-Id"));
094:
095: header = CachedHeaderfields.stripHeaders(header);
096:
097: if (isOlderThanOneWeek(today, ((Date) header
098: .getAttributes().get("columba.date")))) {
099: header.getFlags().set(Flags.SEEN);
100: }
101:
102: // message size should be at least 1 KB
103: int size = Math.max(source.length() / 1024, 1);
104: header.getAttributes().put("columba.size",
105: new Integer(size));
106:
107: // set the attachment flag
108: header.getAttributes().put("columba.attachment",
109: header.hasAttachments());
110:
111: header.getAttributes().put("columba.uid", uids[i]);
112:
113: headerList.add(header, uids[i]);
114: source.close();
115: source = null;
116: } catch (Exception ex) {
117: ex.printStackTrace();
118: }
119: } else {
120: header = headerList.get(uids[i]);
121: }
122:
123: try {
124: messageFolderInfo.incExists();
125: if (header.getFlags().getRecent()) {
126: messageFolderInfo.incRecent();
127: }
128:
129: if (!header.getFlags().getSeen()) {
130: messageFolderInfo.incUnseen();
131: }
132: } catch (MailboxInfoInvalidException e) {
133: // Can't happen
134: }
135:
136: ((AbstractLocalFolder) folder)
137: .setNextMessageUid(((Integer) uids[uids.length - 1])
138: .intValue() + 1);
139:
140: if ((folder.getObservable() != null) && ((i % 100) == 0)) {
141: folder.getObservable().setCurrent(i);
142: }
143: }
144:
145: // we are done
146: if (folder.getObservable() != null) {
147: folder.getObservable().resetCurrent();
148: }
149: }
150:
151: private static boolean isOlderThanOneWeek(Date arg0, Date arg1) {
152: return (arg0.getTime() - WEEK) > arg1.getTime();
153: }
154:
155: }
|