KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > mail > ImapMessageCache


1 /*
2  * ImapMessageCache.java
3  *
4  * Copyright (C) 2002 Peter Graves
5  * $Id: ImapMessageCache.java,v 1.1.1.1 2002/09/24 16:09:53 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j.mail;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.BufferedWriter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.OutputStream JavaDoc;
30 import java.io.OutputStreamWriter JavaDoc;
31 import java.io.UnsupportedEncodingException JavaDoc;
32 import java.net.MalformedURLException JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Properties JavaDoc;
37 import org.armedbear.j.Directories;
38 import org.armedbear.j.File;
39 import org.armedbear.j.FastStringBuffer;
40 import org.armedbear.j.Headers;
41 import org.armedbear.j.Log;
42 import org.armedbear.j.Utilities;
43
44 public final class ImapMessageCache
45 {
46     private static Properties JavaDoc catalog;
47
48     private final File cacheDirectory;
49     private final int uidValidity;
50
51     private ImapMessageCache(File cacheDirectory, int uidValidity)
52     {
53         this.cacheDirectory = cacheDirectory;
54         this.uidValidity = uidValidity;
55     }
56
57     public int getUidValidity()
58     {
59         return uidValidity;
60     }
61
62     public static ImapMessageCache getMessageCache(ImapMailbox mb)
63     {
64         File cacheDirectory = getCacheDirectory(mb);
65         if (cacheDirectory == null)
66             return null;
67         // Directory exists.
68
final int uidValidity = mb.getSession().getUidValidity();
69         File file = File.getInstance(cacheDirectory, "uidvalidity");
70         boolean ok = false;
71         if (file.isFile()) {
72             try {
73                 BufferedReader JavaDoc reader =
74                     new BufferedReader JavaDoc(new InputStreamReader JavaDoc(file.getInputStream()));
75                 String JavaDoc s = reader.readLine();
76                 reader.close();
77                 int n = Integer.parseInt(s);
78                 if (n == uidValidity)
79                     ok = true;
80                 else
81                     Log.warn("getMessageCache UIDVALIDITY has changed");
82             }
83             catch (Exception JavaDoc e) {
84                 Log.error(e);
85             }
86         }
87         if (!ok) {
88             Log.debug("getMessageCache deleting old files");
89             String JavaDoc[] files = cacheDirectory.list();
90             for (int i = files.length-1; i >= 0; i--)
91                 File.getInstance(cacheDirectory, files[i]).delete();
92             Log.debug("getMessageCache writing UIDVALIDITY " + uidValidity);
93             try {
94                 BufferedWriter JavaDoc writer =
95                     new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(file.getOutputStream()));
96                 writer.write(String.valueOf(uidValidity));
97                 writer.flush();
98                 writer.close();
99             }
100             catch (IOException JavaDoc e) {
101                 Log.error(e);
102             }
103         }
104         return new ImapMessageCache(cacheDirectory, uidValidity);
105     }
106
107     public void store(int uid, String JavaDoc message, String JavaDoc encoding)
108     {
109         Log.debug("store encoding = |" + encoding + "|");
110         if (encoding == null)
111             encoding = "ISO-8859-1";
112         if (!cacheDirectory.isDirectory()) {
113             cacheDirectory.mkdirs();
114             if (!cacheDirectory.isDirectory()) {
115                 Log.error("ImapMessageCache.store can't create cache directory");
116                 return;
117             }
118         }
119         File file =
120             File.getInstance(cacheDirectory, String.valueOf(uid));
121         if (file == null)
122             return;
123         if (file.isFile()) {
124             Log.debug("ImapMessageCache.store message is already cached");
125             return;
126         }
127         try {
128             BufferedWriter JavaDoc writer = null;
129             writer =
130                 new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(file.getOutputStream(),
131                     encoding));
132             writer.write(message);
133             writer.flush();
134             writer.close();
135         }
136         catch (UnsupportedEncodingException JavaDoc e) {
137             Log.error(e);
138         }
139         catch (IOException JavaDoc e) {
140             Log.error(e);
141         }
142     }
143
144     public String JavaDoc getMessageText(int uid)
145     {
146         File file =
147             File.getInstance(cacheDirectory, String.valueOf(uid));
148         if (file == null)
149             return null;
150         if (!file.isFile())
151             return null;
152         FastStringBuffer sb = new FastStringBuffer();
153         try {
154             BufferedReader JavaDoc reader =
155                 new BufferedReader JavaDoc(new InputStreamReader JavaDoc(file.getInputStream()));
156             String JavaDoc s;
157             while ((s = reader.readLine()) != null) {
158                 if (s.length() == 0)
159                     break;
160                 sb.append(s);
161                 sb.append("\r\n");
162             }
163             reader.close();
164         }
165         catch (Exception JavaDoc e) {
166             Log.error(e);
167         }
168         Headers headers = Headers.parse(sb.toString());
169         String JavaDoc charset = null;
170         String JavaDoc contentType = headers.getValue(Headers.CONTENT_TYPE);
171         if (contentType != null)
172             charset = Utilities.getCharsetFromContentType(contentType);
173         String JavaDoc encoding = Utilities.getEncodingFromCharset(charset);
174         sb.setLength(0);
175         try {
176             BufferedReader JavaDoc reader =
177                 new BufferedReader JavaDoc(new InputStreamReader JavaDoc(file.getInputStream(), encoding));
178             String JavaDoc s;
179             while ((s = reader.readLine()) != null) {
180                 sb.append(s);
181                 sb.append("\r\n");
182             }
183             reader.close();
184         }
185         catch (Exception JavaDoc e) {
186             Log.error(e);
187         }
188         if (sb.length() > 0)
189             return sb.toString();
190         return null;
191     }
192
193     public void removeDeletedEntries(List JavaDoc mailboxEntries)
194     {
195         Log.debug("ImapMessageCache.removeDeletedEntries");
196         long start = System.currentTimeMillis();
197         Iterator JavaDoc it = mailboxEntries.iterator();
198         while (it.hasNext()) {
199             ImapMailboxEntry entry = (ImapMailboxEntry) it.next();
200             if (entry.isDeleted()) {
201                 File file = File.getInstance(cacheDirectory,
202                     String.valueOf(entry.getUid()));
203                 if (file != null && file.isFile()) {
204                     Log.debug("deleting " + file.netPath());
205                     file.delete();
206                 }
207             }
208         }
209         long elapsed = System.currentTimeMillis() - start;
210         Log.debug("ImapMessageCache.removeDeletedEntries " + elapsed + " ms");
211     }
212
213     private static synchronized File getCacheDirectory(ImapMailbox mb)
214     {
215         final File parentDirectory =
216             File.getInstance(Directories.getMailDirectory(), "imap/cache");
217         if (!parentDirectory.isDirectory()) {
218             parentDirectory.mkdirs();
219             if (!parentDirectory.isDirectory()) {
220                 Log.error("can't create IMAP cache directory");
221                 return null;
222             }
223         }
224         File catalogFile = File.getInstance(parentDirectory, "catalog");
225         boolean modified = false;
226         if (catalog == null) {
227             // Load the catalog.
228
catalog = new Properties JavaDoc();
229             try {
230                 if (catalogFile.isFile()) {
231                     InputStream JavaDoc in = catalogFile.getInputStream();
232                     catalog.load(in);
233                     in.close();
234                 }
235             }
236             catch (IOException JavaDoc e) {
237                 Log.error(e);
238             }
239             // Update obsolete catalog entries.
240
Properties JavaDoc temp = new Properties JavaDoc();
241             Enumeration JavaDoc keys = catalog.keys();
242             while (keys.hasMoreElements()) {
243                 String JavaDoc key = (String JavaDoc) keys.nextElement();
244                 String JavaDoc value = (String JavaDoc) catalog.get(key);
245                 if (key.indexOf('@') < 0 || key.indexOf(':') < 0) {
246                     // Obsolete format (i.e. not canonical mailbox name).
247
try {
248                         ImapURL url = new ImapURL(key);
249                         temp.put(url.getCanonicalName(), value);
250                     }
251                     catch (MalformedURLException JavaDoc e) {
252                         Log.error(e);
253                         Log.debug("deleting cached messages for " + key);
254                         File dir =
255                             File.getInstance(parentDirectory, value);
256                         if (dir != null && dir.isDirectory()) {
257                             File[] files = dir.listFiles();
258                             if (files != null) {
259                                 for (int i = files.length-1; i >= 0; i--) {
260                                     Log.debug("deleting " + files[i]);
261                                     files[i].delete();
262                                 }
263                             }
264                             Log.debug("removing directory " + dir);
265                             dir.delete();
266                         }
267                     }
268                     modified = true;
269                 } else
270                     temp.put(key, value);
271             }
272             if (modified)
273                 catalog = temp;
274         }
275         File cacheDirectory = null;
276         final String JavaDoc mailboxName = mb.getUrl().getCanonicalName();
277         final String JavaDoc directoryName = catalog.getProperty(mailboxName);
278         if (directoryName == null) {
279             // Not found.
280
cacheDirectory = Utilities.getTempFile(parentDirectory);
281             if (cacheDirectory != null) {
282                 boolean directoryExists = cacheDirectory.isDirectory();
283                 if (!directoryExists) {
284                     cacheDirectory.mkdirs();
285                     directoryExists = cacheDirectory.isDirectory();
286                 }
287                 if (directoryExists) {
288                     // Cache directory exists.
289
catalog.put(mailboxName, cacheDirectory.getName());
290                     modified = true;
291                 } else
292                     cacheDirectory = null;
293             }
294             if (cacheDirectory == null)
295                 Log.error("can't create IMAP cache directory");
296         } else
297             cacheDirectory = File.getInstance(parentDirectory, directoryName);
298         if (modified) {
299             Log.debug("saving modified catalog");
300             try {
301                 OutputStream JavaDoc out = catalogFile.getOutputStream();
302                 catalog.save(out, null);
303                 out.flush();
304                 out.close();
305             }
306             catch (IOException JavaDoc e) {
307                 Log.error(e);
308             }
309         }
310         return cacheDirectory;
311     }
312 }
313
Popular Tags