1 17 package org.columba.mail.folder.imap; 18 19 import java.util.logging.Logger ; 20 21 import org.columba.api.command.ICommand; 22 import org.columba.api.command.IStatusObservable; 23 import org.columba.core.command.Command; 24 import org.columba.core.command.CommandProcessor; 25 import org.columba.core.command.NullWorkerStatusController; 26 import org.columba.core.command.StatusObservableImpl; 27 import org.columba.core.connectionstate.ConnectionStateImpl; 28 import org.columba.core.filter.Filter; 29 import org.columba.mail.command.MailFolderCommandReference; 30 import org.columba.mail.config.AccountItem; 31 import org.columba.mail.config.FolderItem; 32 import org.columba.mail.config.IFolderItem; 33 import org.columba.mail.config.MailConfig; 34 import org.columba.mail.config.SpecialFoldersItem; 35 import org.columba.mail.folder.AbstractFolder; 36 import org.columba.mail.folder.IMailFolder; 37 import org.columba.mail.folder.RootFolder; 38 import org.columba.mail.gui.tree.FolderTreeModel; 39 import org.columba.mail.imap.FetchSubFolderListCommand; 40 import org.columba.mail.imap.IExistsChangedAction; 41 import org.columba.mail.imap.IFirstLoginAction; 42 import org.columba.mail.imap.IImapServer; 43 import org.columba.mail.imap.IMAPServer; 44 import org.columba.mail.imap.IMAPServerOwner; 45 import org.columba.mail.imap.IUpdateFlagAction; 46 import org.columba.mail.util.MailResourceLoader; 47 import org.columba.ristretto.imap.IMAPFlags; 48 import org.columba.ristretto.imap.ListInfo; 49 50 53 public class IMAPRootFolder extends AbstractFolder implements RootFolder, 54 IMAPServerOwner { 55 56 57 private static final Logger LOG = Logger 58 .getLogger("org.columba.mail.folder.imap"); 59 60 private static final String [] SPECIAL_FOLDER_NAMES = { "trash", "drafts", 61 "templates", "sent" }; 62 63 private AccountItem accountItem; 65 66 private IImapServer server; 67 68 private IMAPRootFolder thisFolder = this; 69 70 75 private String parentPath; 76 77 83 protected IStatusObservable observable; 84 85 public IMAPRootFolder(FolderItem folderItem, String path) { 86 super(folderItem); 88 89 parentPath = path; 92 93 observable = new StatusObservableImpl(); 94 95 accountItem = MailConfig.getInstance().getAccountList().uidGet( 96 folderItem.getInteger("account_uid")); 97 98 updateConfiguration(); 99 } 100 101 public IMAPRootFolder(AccountItem accountItem, String path) { 102 super(accountItem.get("name"), "IMAPRootFolder"); 105 observable = new StatusObservableImpl(); 106 107 parentPath = path; 110 111 this.accountItem = accountItem; 112 113 getConfiguration().setInteger("account_uid", 114 accountItem.getInteger("uid")); 115 116 updateConfiguration(); 117 } 118 119 122 130 public String getDefaultChild() { 131 return "IMAPFolder"; 132 } 133 134 137 public IStatusObservable getObservable() { 138 return observable; 139 } 140 141 protected void syncFolder(AbstractFolder parent, String name, ListInfo info) 142 throws Exception { 143 144 if ((name.indexOf(server.getDelimiter()) != -1) 145 && (name.indexOf(server.getDelimiter()) != (name.length() - 1))) { 146 String subchild = name.substring(0, name.indexOf(server 150 .getDelimiter())); 151 AbstractFolder subFolder = (AbstractFolder) parent 152 .findChildWithName(subchild, false, IMAPFolder.class); 153 154 if (subFolder == null) { 156 subFolder = new IMAPFolder(subchild, "IMAPFolder", 157 getParentPath()); 158 parent.add(subFolder); 159 parent.getConfiguration().getRoot().addElement( 160 subFolder.getConfiguration().getRoot()); 161 FolderTreeModel.getInstance().insertNodeInto(subFolder, parent, 162 parent.getIndex(subFolder)); 163 164 ((IMAPFolder) subFolder).existsOnServer = true; 165 subFolder.getConfiguration().setString("selectable", "false"); 166 167 } else { 170 if (!((IMAPFolder) subFolder).existsOnServer) { 171 ((IMAPFolder) subFolder).existsOnServer = true; 172 subFolder.getConfiguration().setString("selectable", 173 "false"); 174 } 175 } 176 177 syncFolder(subFolder, name.substring(name.indexOf(server 179 .getDelimiter()) 180 + server.getDelimiter().length()), info); 181 } else { 182 AbstractFolder subFolder = (AbstractFolder) parent 186 .findChildWithName(name, false, IMAPFolder.class); 187 188 if (subFolder == null) { 189 subFolder = new IMAPFolder(name, "IMAPFolder", getParentPath()); 190 parent.add(subFolder); 191 parent.getConfiguration().getRoot().addElement( 192 subFolder.getConfiguration().getRoot()); 193 FolderTreeModel.getInstance().insertNodeInto(subFolder, parent, 194 parent.getIndex(subFolder)); 195 } 196 ((IMAPFolder) subFolder).existsOnServer = true; 197 198 if (info.getParameter(ListInfo.NOSELECT)) { 200 subFolder.getConfiguration().setString("selectable", "false"); 201 } else { 202 subFolder.getConfiguration().setString("selectable", "true"); 203 } 204 205 if (info.getParameter(ListInfo.NOINFERIORS) 207 && info.getDelimiter() != null) { 208 subFolder.getConfiguration().setString("noinferiors", "true"); 209 } else { 210 subFolder.getConfiguration().setString("noinferiors", "false"); 211 } 212 } 213 } 214 215 protected void markAllSubfoldersAsExistOnServer(AbstractFolder parent, 216 boolean value) { 217 AbstractFolder child; 218 219 for (int i = 0; i < parent.getChildCount(); i++) { 220 child = (AbstractFolder) parent.getChildAt(i); 221 222 if (child instanceof IMAPFolder) { 223 markAllSubfoldersAsExistOnServer(child, value); 224 } 225 } 226 227 if (parent instanceof IMAPFolder) { 228 ((IMAPFolder) parent).existsOnServer = value; 229 } 230 } 231 232 private boolean removeNotMarkedSubfolders(AbstractFolder parent) 233 throws Exception { 234 AbstractFolder child; 235 236 for (int i = 0; i < parent.getChildCount(); i++) { 238 child = (AbstractFolder) parent.getChildAt(i); 239 240 if (child instanceof IMAPFolder) { 241 if (removeNotMarkedSubfolders(child)) { 242 i--; 245 } 246 } 247 } 248 249 if (parent instanceof IMAPFolder) { 251 if (!((IMAPFolder) parent).existsOnServer) { 252 FolderTreeModel.getInstance().removeNodeFromParent(parent); 253 parent.removeFolder(); 254 return true; 255 } 256 } 257 258 return false; 259 } 260 261 public void findSpecialFolders() { 262 SpecialFoldersItem folders = accountItem.getSpecialFoldersItem(); 263 264 for (int i = 0; i < SPECIAL_FOLDER_NAMES.length; i++) { 265 String specialUid = folders.get(SPECIAL_FOLDER_NAMES[i]); 267 268 if (this.findChildWithUID(specialUid, true) == null) { 270 AbstractFolder specialFolder = this.findChildWithName( 273 MailResourceLoader.getString("tree", 274 SPECIAL_FOLDER_NAMES[i]), true); 275 276 if (specialFolder == null) { 277 specialFolder = this.findChildWithName( 279 SPECIAL_FOLDER_NAMES[i], true); 280 } 281 282 if (specialFolder != null) { 283 folders.setString(SPECIAL_FOLDER_NAMES[i], specialFolder 285 .getId()); 286 } 287 } 288 } 289 } 290 291 public void syncSubscribedFolders() throws Exception { 292 markAllSubfoldersAsExistOnServer(this, false); 294 295 IMAPFolder inbox = (IMAPFolder) this.findChildWithName("INBOX", false); 296 inbox.existsOnServer = true; 297 298 try { 299 ListInfo[] listInfo = getServer().fetchSubscribedFolders(); 301 302 for (int i = 0; i < listInfo.length; i++) { 303 ListInfo info = listInfo[i]; 304 LOG.fine("delimiter=" + getServer().getDelimiter()); 305 306 String folderPath = info.getName(); 307 308 syncFolder(this, folderPath, info); 309 } 310 311 } catch (Exception ex) { 312 ex.printStackTrace(); 313 } 314 315 inbox.getConfiguration().setString("selectable", "true"); 318 319 removeNotMarkedSubfolders(this); 320 321 findSpecialFolders(); 322 } 323 324 public IImapServer getServer() { 325 return server; 326 } 327 328 public void updateConfiguration() { 329 try { 330 if (server != null) 331 server.logout(); 332 } catch (Exception e1) { 333 } 335 server = new IMAPServer(accountItem.getImapItem()); 336 server.setObservable(observable); 337 338 server.setFirstLoginAction(new IFirstLoginAction() { 339 public void actionPerformed() { 340 if (ConnectionStateImpl.getInstance().isOnline()) { 343 ICommand c = new FetchSubFolderListCommand( 344 new MailFolderCommandReference(thisFolder)); 345 try { 346 c.execute(NullWorkerStatusController.getInstance()); 348 c.updateGUI(); 349 } catch (Exception e) { 350 e.printStackTrace(); 351 } 352 } 353 } 354 355 }); 356 357 server.setExistsChangedAction(new IExistsChangedAction() { 358 359 public void actionPerformed(IMailFolder folder) { 360 Command updateFolderCommand = new CheckForNewMessagesCommand( 362 null, new MailFolderCommandReference(folder)); 363 CommandProcessor.getInstance().addOp(updateFolderCommand); 364 } 365 366 }); 367 368 server.setUpdateFlagAction(new IUpdateFlagAction() { 369 370 public void actionPerformed(IMailFolder folder, IMAPFlags flags) { 371 Command updateFlagCommand = new UpdateFlagCommand( 373 new MailFolderCommandReference(folder), flags); 374 CommandProcessor.getInstance().addOp(updateFlagCommand); 375 376 } 377 378 }); 379 } 380 381 385 public Object [] searchMessages(Filter filter, Object [] uids) 386 throws Exception { 387 return null; 388 } 389 390 394 public Object [] searchMessages(Filter filter) throws Exception { 395 return null; 396 } 397 398 401 public AccountItem getAccountItem() { 402 return accountItem; 403 } 404 405 410 public void addSubfolder(IMailFolder child) throws Exception { 411 if (child instanceof IMAPFolder) { 412 getServer().createMailbox(child.getName(), null); 413 } 414 415 416 super.addSubfolder(child); 417 } 418 419 public void setInbox(IMAPFolder inbox) throws Exception { 420 super.addSubfolder(inbox); 421 super.add(inbox); 422 } 423 424 429 public void save() throws Exception { 430 LOG.info("Logout from IMAPServer " + getName()); 431 432 getServer().logout(); 433 } 434 435 440 public AbstractFolder getTrashFolder() { 441 AbstractFolder ret = findChildWithUID(accountItem 442 .getSpecialFoldersItem().get("trash"), true); 443 444 if (ret == null) { 446 ret = (AbstractFolder) FolderTreeModel.getInstance() 447 .getTrashFolder(); 448 } 449 450 return ret; 451 } 452 453 458 public AbstractFolder getInboxFolder() { 459 return (IMAPFolder) this.findChildWithName("INBOX", false); 460 } 461 462 469 public String getParentPath() { 470 return parentPath; 471 } 472 473 476 public boolean supportsAddFolder(String folder) { 477 return true; 478 } 479 } | Popular Tags |