1 package net.suberic.pooka.cache; 2 import javax.mail.*; 3 import java.io.*; 4 import java.util.ArrayList ; 5 6 11 public class ChangeCache { 12 13 File cacheFile = null; 14 File cacheDir = null; 15 File tmpFile = null; 16 17 public static String EXPUNGE_MSG = "FOLDER EXPUNGE"; 18 public static String DONE_MSG = "INPUT DONE"; 19 public static String APPEND_MSG = "APPEND"; 20 21 boolean lock = false; 22 23 26 public ChangeCache(File dir) { 27 cacheDir = dir; 28 cacheFile = new File(dir, "changeLog"); 29 } 30 31 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 e) { } 50 } 51 tmpFile = new File(cacheDir, "changeLog.tmp"); 52 53 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 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 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 [] 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 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 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 e ) { } 214 } 215 216 try { 217 if (cacheFile.exists()) 218 cacheFile.delete(); 219 } finally { 220 lock = false; 221 } 222 } 223 224 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 e ) { } 241 } 242 243 try { 244 if (cacheFile.exists()) { 245 BufferedReader in = new BufferedReader(new FileReader(cacheFile)); 246 247 String nextLine = in.readLine(); 248 while (nextLine != null) { 249 if (nextLine.equalsIgnoreCase(APPEND_MSG)) { 250 nextLine = in.readLine(); 252 ArrayList messageList = new ArrayList (); 253 ArrayList uidList = new ArrayList (); 254 while (! nextLine.equalsIgnoreCase("DONE_MSG")) { 255 long uid = Long.parseLong(nextLine); 256 uidList.add(new Long (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 )f).appendMessages(messages); 268 269 long[] invalidatedUids = new long[uidList.size()];; 270 for (int i = 0; i < uidList.size(); i++) { 271 invalidatedUids[i] = ((Long ) 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 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 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 341 public void setFlags(String 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 [] 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 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 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 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 436 boolean value; 437 Flags newFlags = new Flags(); 438 439 String 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 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 491 public Message getMessageByPopUID(String uid, com.sun.mail.pop3.POP3Folder f, Message[] msgs) throws MessagingException { 492 for (int i = msgs.length - 1; i >=0; i--) { 496 String 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 |