1 package net.suberic.pooka; 2 import javax.mail.*; 3 import javax.mail.internet.*; 4 import javax.mail.event.MessageCountEvent ; 5 import javax.mail.event.MessageChangedEvent ; 6 import java.io.*; 7 import java.util.Vector ; 8 import java.util.HashSet ; 9 import java.util.Set ; 10 import java.util.List ; 11 import net.suberic.pooka.cache.ChangeCache; 12 import net.suberic.pooka.gui.MessageProxy; 13 14 18 public class PopInboxFolderInfo extends FolderInfo { 19 20 Store popStore; 21 Folder popInbox; 22 ChangeCache changeAdapter; 23 String mailHome; 24 25 Set uidsRead = new HashSet (); 26 27 public static String UID_HEADER = "X-Pooka-Pop-UID"; 28 29 33 34 public PopInboxFolderInfo(StoreInfo parent, String fname) { 35 super(parent, fname); 36 37 configurePopStore(parent.getStoreID()); 39 } 40 41 private void configurePopStore(String storeID) { 42 String user = Pooka.getProperty("Store." + storeID + ".user", ""); 43 String password = Pooka.getProperty("Store." + storeID + ".password", ""); 44 if (!password.equals("")) 45 password = net.suberic.util.gui.propedit.PasswordEditorPane.descrambleString(password); 46 String server = Pooka.getProperty("Store." + storeID + ".server", ""); 47 String protocol = Pooka.getProperty("Store." + storeID + ".protocol", ""); 48 if (Pooka.getProperty(getParentStore().getStoreProperty() + ".SSL", "false").equalsIgnoreCase("true")) { 49 protocol = "pop3s"; 50 } 51 52 URLName url = new URLName(protocol, server, -1, "", user, password); 53 54 mailHome = Pooka.getProperty("Store." + storeID + ".mailDir", ""); 55 if (mailHome.equals("")) { 56 mailHome = Pooka.getProperty("Pooka.defaultMailSubDir", ""); 57 if (mailHome.equals("")) 58 mailHome = System.getProperty("user.home") + File.separator + ".pooka"; 59 60 mailHome = mailHome + File.separator + storeID; 61 } 62 String inboxFileName = mailHome + File.separator + Pooka.getProperty("Pooka.inboxName", "INBOX"); 63 String userHomeName = mailHome + File.separator + Pooka.getProperty("Pooka.subFolderName", "folders"); 64 65 try { 66 File userHomeDir = new File(userHomeName); 67 if (! userHomeDir.exists()) 68 userHomeDir.mkdirs(); 69 70 File inboxFile = new File(inboxFileName); 71 if (! inboxFile.exists()) 72 inboxFile.createNewFile(); 73 } catch (Exception e) { 74 Pooka.getUIFactory().showError(Pooka.getProperty("error.cannotCreatePopFolders", "Error: could not create local folder."), e); 75 } 76 77 changeAdapter = new ChangeCache(new File(mailHome)); 78 79 try { 80 java.util.Properties props = new java.util.Properties (System.getProperties()); 81 82 if (Pooka.getProperty(getParentStore().getStoreProperty() + ".SSL", "false").equalsIgnoreCase("true")) { 83 props.setProperty("mail.pop3s.socketFactory.fallback", Pooka.getProperty(getParentStore().getStoreProperty() + ".SSL.fallback", "false")); 85 } 87 88 Session session = javax.mail.Session.getInstance(props, Pooka.getDefaultAuthenticator()); 89 90 if (Pooka.isDebug()) { 91 System.out.println("session.getProperty(mail.mbox.inbox) = " + session.getProperty("mail.mbox.inbox")); 92 System.out.println("url is " + url); 93 } 94 popStore = session.getStore(url); 95 } catch (NoSuchProviderException nspe) { 96 nspe.printStackTrace(); 97 } 99 } 100 101 102 112 public void openFolder(int mode, boolean pConnectStore) throws MessagingException { 113 116 if (Pooka.isDebug()) 117 System.out.println(this + ": checking parent store."); 118 119 if (!getParentStore().isConnected() && pConnectStore) { 120 if (Pooka.isDebug()) 121 System.out.println(this + ": parent store isn't connected. trying connection."); 122 getParentStore().connectStore(); 123 } 124 125 if (Pooka.isDebug()) 126 System.out.println(this + ": loading folder."); 127 128 if (! isLoaded() && status != CACHE_ONLY) 129 loadFolder(); 130 131 if (Pooka.isDebug()) 132 System.out.println(this + ": folder loaded. status is " + status); 133 134 if (Pooka.isDebug()) 135 System.out.println(this + ": checked on parent store. trying isLoaded() and isAvailable()."); 136 137 if (status == CLOSED || status == LOST_CONNECTION || status == DISCONNECTED) { 138 if (Pooka.isDebug()) 139 System.out.println(this + ": isLoaded() and isAvailable()."); 140 if (getFolder().isOpen()) { 141 return; 142 } else { 143 getFolder().open(mode); 144 updateFolderOpenStatus(true); 145 resetMessageCounts(); 146 } 147 } else if (status == INVALID) { 148 throw new MessagingException(Pooka.getProperty("error.folderInvalid", "Error: folder is invalid. ") + getFolderID()); 149 } 150 } 151 152 158 public synchronized void loadAllMessages() throws MessagingException { 159 if (folderTableModel == null) { 160 super.loadAllMessages(); 161 populateUidMap(); 163 checkFolder(); 164 } 165 } 166 167 170 void populateUidMap() { 171 if (folderTableModel != null) { 172 List v = folderTableModel.getAllProxies(); 173 for (int i = 0; i < v.size(); i++) { 174 MessageProxy mp = (MessageProxy) v.get(i); 175 try { 176 String uid = (String ) mp.getMessageInfo().getMessageProperty(UID_HEADER); 177 uidsRead.add(uid); 178 if (Pooka.isDebug()) 179 System.out.println("adding " + uid + " to read list."); 180 } catch (MessagingException me) { 181 Pooka.getUIFactory().showError("Error getting UID for message: ", me); 182 } 183 } 184 } 185 } 186 187 192 public void checkFolder() throws MessagingException { 193 if (Pooka.isDebug()) 194 System.out.println("checking folder " + getFolderName()); 195 196 Folder f = null; 197 198 if (isConnected() && popStore != null) { 199 if (Pooka.isDebug()) 200 System.out.println("checking folder " + getFolderName() + ": opening pop store."); 201 202 NetworkConnection connection = getParentStore().getConnection(); 203 int originalStatus = -1; 204 205 if (connection != null) { 206 originalStatus = connection.getStatus(); 207 if (connection.getStatus() == NetworkConnection.DISCONNECTED) { 208 connection.connect(); 209 } 210 211 if (connection.getStatus() != NetworkConnection.CONNECTED) { 212 throw new MessagingException(Pooka.getProperty("error.connectionDown", "Connection down for checking folder: ") + getFolderID()); 213 } 214 } 215 216 try { 217 popStore.connect(); 218 f = popStore.getDefaultFolder().getFolder("INBOX"); 219 if (f != null) { 220 f.open(Folder.READ_WRITE); 221 Message[] msgs = getNewMessages(f); 222 223 if (msgs != null && msgs.length > 0) { 224 MimeMessage[] msgsToAppend = new MimeMessage[msgs.length]; 225 Pooka.getUIFactory().showStatusMessage(getFolderID() + ": loading " + msgs.length + " messages..."); 226 for (int i = 0; i < msgs.length; i++) { 227 msgsToAppend[i] = new MimeMessage((MimeMessage) msgs[i]); 228 String uid = getUID(msgs[i], f); 229 msgsToAppend[i].addHeader(UID_HEADER, uid); 230 msgsToAppend[i].setFlag(Flags.Flag.RECENT, true); 231 uidsRead.add(uid); 232 if (Pooka.isDebug()) 233 System.out.println("adding " + uid + " to read list."); 234 Pooka.getUIFactory().showStatusMessage(getFolderID() + ": loading " + i + " of " + msgs.length + " messages..."); 235 236 } 237 if (Pooka.isDebug()) 238 System.out.println(Thread.currentThread() + ": running appendMessages; # of added messages is " + msgsToAppend.length); 239 240 Pooka.getUIFactory().showStatusMessage(getFolderID() + ": appending " + msgs.length + " messages to local folder..."); 241 242 getFolder().appendMessages(msgsToAppend); 243 244 Pooka.getUIFactory().clearStatus(); 245 246 if (! leaveMessagesOnServer()) { 247 if (Pooka.isDebug()) 248 System.out.println("removing all messages."); 249 250 for (int i = 0; i < msgs.length; i++) { 251 msgs[i].setFlag(Flags.Flag.DELETED, true); 252 if (Pooka.isDebug()) 253 System.out.println("marked message " + i + " to be deleted. isDelted = " + msgs[i].isSet(Flags.Flag.DELETED)); 254 } 255 } 256 } 257 258 if (isDeletingOnServer()) { 259 removeDeletedMessages(f); 260 } 261 262 f.close(true); 263 popStore.close(); 264 } 265 resetMessageCounts(); 266 } catch ( MessagingException me ) { 267 try { 268 if (f != null && f.isOpen()) 269 f.close(false); 270 } catch (Exception e ) { 271 } 272 throw me; 273 } finally { 274 try { 275 popStore.close(); 276 } catch (Exception e) { 277 } 278 279 if (connection != null) { 280 if (originalStatus == NetworkConnection.DISCONNECTED && originalStatus != connection.getStatus()) 281 connection.disconnect(); 282 } 283 } 284 } 285 286 } 287 288 293 protected void runMessagesRemoved(MessageCountEvent mce) { 294 if (folderTableModel != null) { 295 Message[] removedMessages = mce.getMessages(); 296 if (Pooka.isDebug()) 297 System.out.println("removedMessages was of size " + removedMessages.length); 298 MessageInfo mi; 299 Vector removedProxies=new Vector (); 300 for (int i = 0; i < removedMessages.length; i++) { 301 if (Pooka.isDebug()) 302 System.out.println("checking for existence of message."); 303 304 307 if (isDeletingOnServer()) { 308 try { 309 MimeMessage mm = (MimeMessage) removedMessages[i]; 310 String uid = mm.getHeader(UID_HEADER, ":"); 311 if (uid != null) 312 getChangeAdapter().setFlags(uid, new Flags(Flags.Flag.DELETED), true); 313 } catch (Exception e) { 314 } 315 } 316 317 mi = getMessageInfo(removedMessages[i]); 318 if (mi.getMessageProxy() != null) 319 mi.getMessageProxy().close(); 320 321 if (mi != null) { 322 if (Pooka.isDebug()) 323 System.out.println("message exists--removing"); 324 removedProxies.add(mi.getMessageProxy()); 325 messageToInfoTable.remove(mi); 326 } 327 } 328 if (getFolderDisplayUI() != null) { 329 if (removedProxies.size() > 0) 330 getFolderDisplayUI().removeRows(removedProxies); 331 resetMessageCounts(); 332 fireMessageCountEvent(mce); 333 } else { 334 resetMessageCounts(); 335 fireMessageCountEvent(mce); 336 if (removedProxies.size() > 0) 337 getFolderTableModel().removeRows(removedProxies); 338 } 339 } else { 340 resetMessageCounts(); 341 fireMessageCountEvent(mce); 342 } 343 } 344 345 348 public void fireMessageChangedEvent(MessageChangedEvent mce) { 349 if (! (mce instanceof net.suberic.pooka.event.MessageTableInfoChangedEvent)) { 351 try { 352 if (!mce.getMessage().isSet(Flags.Flag.DELETED) || ! Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true")) { 353 354 MessageInfo mi = getMessageInfo(mce.getMessage()); 355 MessageProxy mp = mi.getMessageProxy(); 356 if (mp != null) { 357 if (mce.getMessageChangeType() == MessageChangedEvent.FLAGS_CHANGED) { 358 mi.refreshFlags(); 359 } else if (mce.getMessageChangeType() == MessageChangedEvent.ENVELOPE_CHANGED) { 360 mi.refreshHeaders(); 361 } 362 mp.unloadTableInfo(); 363 mp.loadTableInfo(); 364 } 365 } 366 } catch (MessagingException me) { 367 } 370 } 371 372 super.fireMessageChangedEvent(mce); 373 374 } 375 376 379 public Message[] getNewMessages(Folder f) throws MessagingException { 380 if (Pooka.isDebug()) 381 System.out.println("getting new messages."); 382 Message[] newMessages = f.getMessages(); 383 384 if (newMessages.length > 0) { 385 int lastRead = newMessages.length - 1; 387 while (lastRead >=0 && ! alreadyRead(newMessages[lastRead], f)) { 388 lastRead--; 389 } 390 391 if (Pooka.isDebug()) 392 System.out.println("final lastRead is " + lastRead + "; for reference, newMessages.length = " + newMessages.length); 393 if (newMessages.length - lastRead < 2) { 394 if (Pooka.isDebug()) 396 System.out.println("no new messages."); 397 return new Message[0]; 398 } else { 399 if (Pooka.isDebug()) 400 System.out.println("returning " + (newMessages.length - lastRead - 1) + " new messages."); 401 Message[] returnValue = new Message[newMessages.length - lastRead - 1]; 402 System.arraycopy(newMessages, lastRead + 1, returnValue, 0, newMessages.length - lastRead - 1); 403 404 return returnValue; 405 } 406 } else { 407 if (Pooka.isDebug()) 408 System.out.println("no messages in folder."); 409 return newMessages; 411 } 412 } 413 414 public String readLastUid() throws IOException { 415 File uidFile = new File(mailHome + File.separator + ".pooka-lastUid"); 416 if (uidFile.exists()) { 417 BufferedReader br = new BufferedReader(new FileReader(uidFile)); 418 String lastUid = br.readLine(); 419 if (Pooka.isDebug()) 420 System.out.println("lastUid is " + lastUid); 421 422 br.close(); 423 424 return lastUid; 425 } 426 427 return null; 428 } 429 430 public void writeLastUid(String lastUid) throws IOException { 431 File uidFile = new File(mailHome + File.separator + ".pooka-lastUid"); 432 if (uidFile.exists()) { 433 uidFile.delete(); 434 } 435 436 uidFile.createNewFile(); 437 438 BufferedWriter bw = new BufferedWriter(new FileWriter(uidFile)); 439 440 bw.write(lastUid); 441 bw.newLine(); 442 443 bw.flush(); 444 bw.close(); 445 446 } 447 448 public String getUID(Message m, Folder f) throws MessagingException { 449 return ((com.sun.mail.pop3.POP3Folder)f).getUID(m); 450 } 451 452 public void removeDeletedMessages(Folder f) throws MessagingException { 453 try { 454 getChangeAdapter().writeChanges((com.sun.mail.pop3.POP3Folder)f); 455 } catch (java.io.IOException ioe) { 456 throw new MessagingException("Error", ioe); 457 } 458 } 459 460 public boolean isDeletingOnServer() { 461 return Pooka.getProperty(getParentStore().getStoreProperty() + ".deleteOnServerOnLocalDelete", "false").equalsIgnoreCase("true"); 462 463 } 464 465 public boolean leaveMessagesOnServer() { 466 return Pooka.getProperty(getParentStore().getStoreProperty() + ".leaveMessagesOnServer", "false").equalsIgnoreCase("true"); 467 } 468 469 public ChangeCache getChangeAdapter() { 470 return changeAdapter; 471 } 472 473 477 public boolean alreadyRead(Message m, Folder f) throws javax.mail.MessagingException { 478 String newUid = getUID(m, f); 479 if (Pooka.isDebug()) 480 System.out.println("checking to see if message with uid " + newUid + " is new."); 481 482 boolean returnValue = uidsRead.contains(newUid); 483 484 if (Pooka.isDebug()) 485 System.out.println(newUid + " already read = " + returnValue); 486 487 return returnValue; 488 489 } 490 } 491 492 | Popular Tags |