KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > cache > ChangeCache


1 package net.suberic.pooka.cache;
2 import javax.mail.*;
3 import java.io.*;
4 import java.util.ArrayList JavaDoc;
5
6 /**
7  * A utility class that saves the changes made to messages into a file.
8  * Then when we reconnect to the server, we can make all of the changes
9  * in batch.
10  */

11 public class ChangeCache {
12
13   File cacheFile = null;
14   File cacheDir = null;
15   File tmpFile = null;
16   
17   public static String JavaDoc EXPUNGE_MSG = "FOLDER EXPUNGE";
18   public static String JavaDoc DONE_MSG = "INPUT DONE";
19   public static String JavaDoc APPEND_MSG = "APPEND";
20
21   boolean lock = false;
22   
23   /**
24    * Creates a new ChangeCache object based out of the given directory.
25    */

26   public ChangeCache(File dir) {
27     cacheDir = dir;
28     cacheFile = new File(dir, "changeLog");
29   }
30   
31   /**
32    * Opens the cache file. Actually creates a temporary file, copies the
33    * contents of the original cache file into there, and returns a writer
34    * to that file.
35    */

36   private BufferedWriter openCacheFile() throws IOException {
37     boolean hasLock = false;
38     while (! hasLock) {
39       synchronized(this) {
40     if (! lock ) {
41       lock = true;
42       hasLock = true;
43     }
44       }
45       
46       if (! hasLock )
47     try {
48       Thread.sleep(1000);
49     } catch (Exception JavaDoc e) { }
50     }
51     tmpFile = new File(cacheDir, "changeLog.tmp");
52     
53     // if there's a temp file, assume it's an old one left
54
// over from before.
55
if (tmpFile.exists())
56       tmpFile.delete();
57     tmpFile.createNewFile();
58     
59     BufferedWriter out = new BufferedWriter(new FileWriter(tmpFile));
60     if (cacheFile.exists()) {
61       BufferedReader in = new BufferedReader(new FileReader(cacheFile));
62       String JavaDoc nextLine = in.readLine();
63       while (nextLine != null) {
64     out.write(nextLine);
65     out.newLine();
66     nextLine = in.readLine();
67       }
68       
69       in.close();
70     }
71     return out;
72   }
73   
74   private void closeCacheFile(BufferedWriter out) throws IOException {
75     try {
76       out.flush();
77       out.close();
78       
79       if (cacheFile.exists())
80     cacheFile.delete();
81       
82       tmpFile.renameTo(cacheFile);
83       tmpFile = null;
84     } finally {
85       lock = false;
86     }
87   }
88   
89   /**
90    * Writes out the given flags to be set to value value on the message with
91    * the given uid.
92    */

93   public void setFlags(long uid, Flags f, boolean value) throws IOException {
94     BufferedWriter out = null;
95     try {
96       out = openCacheFile();
97       
98       out.write(Long.toString(uid));
99       out.newLine();
100       
101       Flags.Flag[] systemFlags = f.getSystemFlags();
102       for (int i = 0; i < systemFlags.length; i++) {
103     if (systemFlags[i] == Flags.Flag.ANSWERED) {
104       out.write("Answered");
105       out.newLine();
106     } else if (systemFlags[i] == Flags.Flag.DELETED) {
107       out.write("Deleted");
108       out.newLine();
109     } else if (systemFlags[i] == Flags.Flag.DRAFT) {
110       out.write("Draft");
111       out.newLine();
112     } else if (systemFlags[i] == Flags.Flag.FLAGGED) {
113       out.write("Flagged");
114       out.newLine();
115     } else if (systemFlags[i] == Flags.Flag.RECENT) {
116       out.write("Recent");
117       out.newLine();
118     } else if (systemFlags[i] == Flags.Flag.SEEN) {
119       out.write("Seen");
120       out.newLine();
121     }
122     
123       }
124       
125       String JavaDoc[] userFlags = f.getUserFlags();
126       for (int i = 0; i < userFlags.length; i++) {
127     out.write(userFlags[i]);
128     out.newLine();
129       }
130       
131       out.write(DONE_MSG);
132       out.newLine();
133       
134       if (value)
135     out.write("true");
136       else
137     out.write("false");
138       
139       out.newLine();
140       
141       out.write(DONE_MSG);
142       out.newLine();
143       
144     } finally {
145       if (out != null)
146     closeCacheFile(out);
147       else
148     lock = false;
149     }
150     
151   }
152   
153   
154   /**
155    * Notes the given uid's as needing to be appended to the server.
156    */

157   public void appendMessages(long[] uids) throws IOException {
158     BufferedWriter out = null;
159     try {
160       out = openCacheFile();
161       if (uids.length > 0) {
162     out.write(APPEND_MSG);
163     out.newLine();
164     for (int i = 0; i < uids.length; i++) {
165       out.write(Long.toString(uids[i]));
166       out.newLine();
167     }
168     out.write(DONE_MSG);
169     out.newLine();
170       }
171     } finally {
172       if (out != null)
173     closeCacheFile(out);
174       else
175     lock = false;
176     }
177     
178   }
179     
180   public void expunge() throws IOException {
181     BufferedWriter out = null;
182     try {
183       out = openCacheFile();
184       
185       out.write(EXPUNGE_MSG);
186       out.newLine();
187         
188     } finally {
189       if (out != null)
190     closeCacheFile(out);
191       else
192     lock = false;
193     }
194   }
195   
196   /**
197    * Invalidates the changes to the server's cache. Basically removes
198    * the change file.
199    */

200   public void invalidate() {
201     boolean hasLock = false;
202     while (! hasLock) {
203       synchronized(this) {
204     if (! lock ) {
205       lock = true;
206       hasLock = true;
207     }
208       }
209       
210       if (! hasLock )
211     try {
212       Thread.sleep(1000);
213     } catch (Exception JavaDoc e ) { }
214     }
215     
216     try {
217       if (cacheFile.exists())
218     cacheFile.delete();
219     } finally {
220       lock = false;
221     }
222   }
223
224   /**
225    * Writes the changes in the file back to the server.
226    */

227   public void writeChanges(UIDFolder f, CachingFolderInfo cfi) throws IOException, MessagingException {
228     boolean hasLock = false;
229     while (! hasLock) {
230       synchronized(this) {
231     if (! lock ) {
232       lock = true;
233       hasLock = true;
234     }
235       }
236       
237       if (! hasLock )
238     try {
239       Thread.sleep(1000);
240     } catch (Exception JavaDoc e ) { }
241     }
242     
243     try {
244       if (cacheFile.exists()) {
245     BufferedReader in = new BufferedReader(new FileReader(cacheFile));
246     
247     String JavaDoc nextLine = in.readLine();
248     while (nextLine != null) {
249       if (nextLine.equalsIgnoreCase(APPEND_MSG)) {
250         // get the UID's we want to append.
251
nextLine = in.readLine();
252         ArrayList JavaDoc messageList = new ArrayList JavaDoc();
253         ArrayList JavaDoc uidList = new ArrayList JavaDoc();
254         while (! nextLine.equalsIgnoreCase("DONE_MSG")) {
255           long uid = Long.parseLong(nextLine);
256           uidList.add(new Long JavaDoc(uid));
257           net.suberic.pooka.MessageInfo m = cfi.getMessageInfoByUid(uid);
258           if (m != null)
259         messageList.add(m.getMessage());
260           nextLine = in.readLine();
261         }
262         Message[] messages = new Message[messageList.size()];
263         for (int i = 0; i < messageList.size(); i++) {
264           messages[i] = (Message)messageList.get(i);
265         }
266         
267         ((javax.mail.Folder JavaDoc)f).appendMessages(messages);
268         
269         long[] invalidatedUids = new long[uidList.size()];;
270         for (int i = 0; i < uidList.size(); i++) {
271           invalidatedUids[i] = ((Long JavaDoc) uidList.get(i)).longValue();
272         }
273         cfi.getCache().invalidateCache(invalidatedUids, MessageCache.MESSAGE);
274         
275         nextLine = in.readLine();
276       } else if (nextLine.equalsIgnoreCase(EXPUNGE_MSG))
277         try {
278           
279           ((Folder) f).expunge();
280         } catch (MessagingException me) { }
281       else if (nextLine.length() > 0) {
282         // adding flags
283

284         boolean value;
285         Flags newFlags = new Flags();
286         
287         long uid = Long.parseLong(nextLine);
288         nextLine = in.readLine();
289         while (nextLine != null && ! nextLine.equals(DONE_MSG)) {
290           
291           if (nextLine.equalsIgnoreCase("Deleted")) {
292         newFlags.add(Flags.Flag.DELETED);
293           } else if (nextLine.equalsIgnoreCase("Answered"))
294         newFlags.add(Flags.Flag.ANSWERED);
295           else if (nextLine.equalsIgnoreCase("Draft"))
296         newFlags.add(Flags.Flag.DRAFT);
297           else if (nextLine.equalsIgnoreCase("Flagged"))
298         newFlags.add(Flags.Flag.FLAGGED);
299           else if (nextLine.equalsIgnoreCase("Recent"))
300         newFlags.add(Flags.Flag.RECENT);
301           else if (nextLine.equalsIgnoreCase("SEEN"))
302         newFlags.add(Flags.Flag.SEEN);
303           else
304         newFlags.add(new Flags(nextLine));
305           
306           nextLine = in.readLine();
307         }
308         
309         nextLine = in.readLine();
310         if (nextLine.equalsIgnoreCase("true")) {
311           value = true;
312         } else
313           value = false;
314         
315         try {
316           Message m = f.getMessageByUID(uid);
317           if (m != null) {
318         m.setFlags(newFlags, value);
319           }
320           // should be a done
321
nextLine = in.readLine();
322         } catch (MessagingException me) { }
323       }
324       
325       nextLine = in.readLine();
326     }
327     
328     in.close();
329     cacheFile.delete();
330       }
331     } finally {
332       lock = false;
333     }
334   }
335   
336   
337   /**
338    * Writes out the given flags to be set to value value on the message with
339    * the given uid.
340    */

341   public void setFlags(String JavaDoc uid, Flags f, boolean value) throws IOException {
342     BufferedWriter out = null;
343     try {
344       out = openCacheFile();
345       
346       out.write(uid);
347       out.newLine();
348       
349       Flags.Flag[] systemFlags = f.getSystemFlags();
350       for (int i = 0; i < systemFlags.length; i++) {
351     if (systemFlags[i] == Flags.Flag.ANSWERED) {
352       out.write("Answered");
353       out.newLine();
354     } else if (systemFlags[i] == Flags.Flag.DELETED) {
355       out.write("Deleted");
356       out.newLine();
357     } else if (systemFlags[i] == Flags.Flag.DRAFT) {
358       out.write("Draft");
359       out.newLine();
360     } else if (systemFlags[i] == Flags.Flag.FLAGGED) {
361       out.write("Flagged");
362       out.newLine();
363     } else if (systemFlags[i] == Flags.Flag.RECENT) {
364       out.write("Recent");
365       out.newLine();
366     } else if (systemFlags[i] == Flags.Flag.SEEN) {
367       out.write("Seen");
368       out.newLine();
369     }
370     
371       }
372       
373       String JavaDoc[] userFlags = f.getUserFlags();
374       for (int i = 0; i < userFlags.length; i++) {
375     out.write(userFlags[i]);
376     out.newLine();
377       }
378       
379       out.write(DONE_MSG);
380       out.newLine();
381       
382       if (value)
383     out.write("true");
384       else
385     out.write("false");
386       
387       out.newLine();
388       
389       out.write(DONE_MSG);
390       out.newLine();
391       
392     } finally {
393       if (out != null)
394     closeCacheFile(out);
395       else
396     lock = false;
397     }
398     
399   }
400   
401   /**
402    * Writes the changes in the file back to the server.
403    */

404   public void writeChanges(com.sun.mail.pop3.POP3Folder f) throws IOException, MessagingException {
405     boolean hasLock = false;
406     while (! hasLock) {
407       synchronized(this) {
408     if (! lock ) {
409       lock = true;
410       hasLock = true;
411     }
412       }
413       
414       if (! hasLock )
415     try {
416       Thread.sleep(1000);
417     } catch (Exception JavaDoc e ) { }
418     }
419     
420     try {
421       if (cacheFile.exists()) {
422     
423     Message[] msgs = f.getMessages();
424     
425     BufferedReader in = new BufferedReader(new FileReader(cacheFile));
426     String JavaDoc nextLine = in.readLine();
427     while (nextLine != null) {
428       if (nextLine.equalsIgnoreCase(EXPUNGE_MSG))
429         try {
430           
431           ((Folder) f).expunge();
432         } catch (MessagingException me) { }
433       else if (nextLine.length() > 0) {
434         // adding flags
435

436         boolean value;
437         Flags newFlags = new Flags();
438         
439         String JavaDoc uid = nextLine;
440         nextLine = in.readLine();
441         while (nextLine != null && ! nextLine.equals(DONE_MSG)) {
442           
443           if (nextLine.equalsIgnoreCase("Deleted")) {
444         newFlags.add(Flags.Flag.DELETED);
445           } else if (nextLine.equalsIgnoreCase("Answered"))
446         newFlags.add(Flags.Flag.ANSWERED);
447           else if (nextLine.equalsIgnoreCase("Draft"))
448         newFlags.add(Flags.Flag.DRAFT);
449           else if (nextLine.equalsIgnoreCase("Flagged"))
450         newFlags.add(Flags.Flag.FLAGGED);
451           else if (nextLine.equalsIgnoreCase("Recent"))
452         newFlags.add(Flags.Flag.RECENT);
453           else if (nextLine.equalsIgnoreCase("SEEN"))
454         newFlags.add(Flags.Flag.SEEN);
455           else
456         newFlags.add(new Flags(nextLine));
457           
458           nextLine = in.readLine();
459         }
460         
461         nextLine = in.readLine();
462         if (nextLine.equalsIgnoreCase("true")) {
463           value = true;
464         } else
465           value = false;
466         
467         try {
468           Message m = getMessageByPopUID(uid, f, msgs);
469           if (m != null) {
470         m.setFlags(newFlags, value);
471           }
472           // should be a done
473
nextLine = in.readLine();
474         } catch (MessagingException me) { }
475       }
476       
477       nextLine = in.readLine();
478     }
479     
480     in.close();
481     cacheFile.delete();
482       }
483     } finally {
484       lock = false;
485     }
486   }
487   
488   /**
489    * Gets the message from the pop folder indicated by the given uid.
490    */

491   public Message getMessageByPopUID(String JavaDoc uid, com.sun.mail.pop3.POP3Folder f, Message[] msgs) throws MessagingException {
492     // this is a really dumb algorithm. we can do much better, especially
493
// if you consider that pop uids are sequential. well, except for
494
// the fact that they're not. :)
495
for (int i = msgs.length - 1; i >=0; i--) {
496       String JavaDoc currentUid = f.getUID(msgs[i]);
497       if (f.getUID(msgs[i]).equals(uid))
498     return msgs[i];
499     }
500     
501     return null;
502   }
503   
504 }
505
506
Popular Tags