001: /*
002: * ImapMailboxCache.java
003: *
004: * Copyright (C) 2000-2002 Peter Graves
005: * $Id: ImapMailboxCache.java,v 1.1.1.1 2002/09/24 16:10:11 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.mail;
023:
024: import java.io.BufferedInputStream;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.io.ObjectInputStream;
028: import java.io.ObjectOutputStream;
029: import java.io.OutputStream;
030: import java.io.Serializable;
031: import java.util.ArrayList;
032: import java.util.Enumeration;
033: import java.util.List;
034: import java.util.Properties;
035: import org.armedbear.j.Debug;
036: import org.armedbear.j.Directories;
037: import org.armedbear.j.File;
038: import org.armedbear.j.Log;
039: import org.armedbear.j.Utilities;
040:
041: public final class ImapMailboxCache implements Serializable {
042: private static Properties catalog;
043:
044: private transient ImapMailbox mailbox;
045: private final String mailboxName;
046: private final int uidValidity;
047: private final ArrayList entries;
048:
049: // Force serialization to be dependent on ImapMailboxEntry.
050: private final ImapMailboxEntry dummy = new ImapMailboxEntry(0);
051:
052: public ImapMailboxCache(ImapMailbox mailbox) {
053: this .mailbox = mailbox;
054: mailboxName = mailbox.getName();
055: uidValidity = mailbox.getUidValidity();
056: entries = new ArrayList(mailbox.getEntries());
057: }
058:
059: private final void setMailbox(ImapMailbox mailbox) {
060: this .mailbox = mailbox;
061: }
062:
063: public final List getEntries() {
064: return entries;
065: }
066:
067: public void writeCache() {
068: Runnable r = new Runnable() {
069: public void run() {
070: writeCacheInternal();
071: }
072: };
073: new Thread(r).start();
074: }
075:
076: private void writeCacheInternal() {
077: try {
078: Log.debug("ImapMailboxCache.writeCacheInternal "
079: + entries.size() + " entries");
080: Debug.assertTrue(uidValidity != 0);
081: File temp = Utilities.getTempFile();
082: ObjectOutputStream objectOut = new ObjectOutputStream(temp
083: .getOutputStream());
084: objectOut.writeObject(this );
085: objectOut.flush();
086: objectOut.close();
087: Utilities.deleteRename(temp, getCacheFile(mailbox));
088: Log.debug("ImapMailboxCache.writeCacheInternal completed");
089: } catch (IOException e) {
090: Log.error(e);
091: }
092: }
093:
094: public static ImapMailboxCache readCache(ImapMailbox mb) {
095: File file = ImapMailboxCache.getCacheFile(mb);
096: if (file == null || !file.isFile())
097: return null;
098: ObjectInputStream in = null;
099: try {
100: in = new ObjectInputStream(new BufferedInputStream(file
101: .getInputStream()));
102: ImapMailboxCache cache = (ImapMailboxCache) in.readObject();
103: cache.setMailbox(mb);
104: return cache;
105: } catch (Exception e) {
106: Log.debug("ImapMailboxCache.readCache returning null");
107: return null;
108: } finally {
109: if (in != null) {
110: try {
111: in.close();
112: } catch (IOException e) {
113: Log.error(e);
114: }
115: }
116: }
117: }
118:
119: public boolean isValid() {
120: if (entries == null)
121: return false;
122: if (entries.size() == 0)
123: return false;
124: if (mailboxName == null)
125: return false;
126: if (!mailboxName.equals(mailbox.getName()))
127: return false;
128: return uidValidity == mailbox.getSession().getUidValidity();
129: }
130:
131: private static synchronized File getCacheFile(ImapMailbox mb) {
132: File directory = File.getInstance(Directories
133: .getMailDirectory(), "imap");
134: if (!directory.isDirectory()) {
135: directory.mkdirs();
136: if (!directory.isDirectory()) {
137: Log.error("can't create imap dir");
138: return null;
139: }
140: }
141: boolean modified = false;
142: File catalogFile = File.getInstance(directory, "catalog");
143: if (catalog == null) {
144: catalog = new Properties();
145: // Load the catalog.
146: try {
147: if (catalogFile.isFile()) {
148: InputStream in = catalogFile.getInputStream();
149: catalog.load(in);
150: in.close();
151: }
152: } catch (IOException e) {
153: Log.error(e);
154: }
155: // Remove obsolete entries from catalog.
156: Properties temp = new Properties();
157: Enumeration keys = catalog.keys();
158: while (keys.hasMoreElements()) {
159: String key = (String) keys.nextElement();
160: String value = (String) catalog.get(key);
161: // Make sure key is canonical name.
162: if (key.indexOf('@') < 0 || key.indexOf(':') < 0) {
163: Log.debug("removing obsolete entry " + key + '='
164: + value);
165: // Not canonical name. Delete corresponding file.
166: File file = File.getInstance(directory, value);
167: if (file != null && file.isFile())
168: file.delete();
169: modified = true;
170: } else
171: temp.put(key, value);
172: }
173: if (modified)
174: catalog = temp;
175: }
176: final String mailboxName = mb.getUrl().getCanonicalName();
177: final String fileName = catalog.getProperty(mailboxName);
178: File file;
179: if (fileName != null)
180: file = File.getInstance(directory, fileName);
181: else {
182: file = Utilities.getTempFile(directory);
183: catalog.put(mailboxName, file.getName());
184: modified = true;
185: }
186: if (modified) {
187: try {
188: OutputStream out = catalogFile.getOutputStream();
189: catalog.save(out, null);
190: out.flush();
191: out.close();
192: } catch (IOException e) {
193: Log.error(e);
194: }
195: }
196: return file;
197: }
198: }
|