Java tutorial
/* * webtop-mail is a WebTop Service developed by Sonicle S.r.l. * Copyright (C) 2014 Sonicle S.r.l. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY SONICLE, SONICLE DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Sonicle S.r.l. at email address sonicle@sonicle.com * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Sonicle WebTop" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Sonicle WebTop". */ package com.sonicle.webtop.mail; import com.sonicle.commons.LangUtils; import com.sonicle.mail.imap.SonicleIMAPFolder; import com.sonicle.webtop.core.app.PrivateEnvironment; import com.sun.mail.imap.ACL; import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; import com.sun.mail.imap.Rights; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.mail.Flags; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.NoSuchProviderException; import javax.mail.Provider; import javax.mail.Quota; import javax.mail.Session; import javax.mail.Store; import javax.mail.search.HeaderTerm; import org.apache.commons.lang3.StringUtils; /** * * @author gabriele.bulfon */ public class MailAccount { private String id; private Service ms; private PrivateEnvironment environment; private int port; private String mailHost; private String mailUsername; private String mailPassword; private String authorizationId = null; private boolean isImpersonated = false; private String vmailSecret = null; private String replyTo = null; private boolean readonly = false; private Session session; private Store store; private String storeProtocol; private boolean disconnecting = false; private String sharedPrefixes[] = null; private char folderSeparator = 0; private String folderPrefix = null; private String folderSent = null; private String folderDrafts = null; private String folderTrash = null; private String folderSpam = null; private String folderArchive = null; private boolean validated = false; private boolean hasAnnotations = false; private boolean hasInboxFolder = false; private boolean isDovecot = false; private boolean hasDifferentDefaultFolder = false; private String defaultFolderName = null; private HashMap<String, FolderCache> foldersCache = new HashMap<String, FolderCache>(); private FolderCache fcRoot = null; private FolderCache[] fcShared = null; private String skipReplyFolders[] = new String[] {}; private String skipForwardFolders[] = new String[] {}; private MailFoldersThread mft = null; public MailAccount(String id, Service mailService, PrivateEnvironment environment) { this.id = id; this.ms = mailService; this.environment = environment; } public String getId() { return id; } public MailFoldersThread getFoldersThread() { return mft; } public void setFoldersThread(MailFoldersThread mft) { this.mft = mft; } public void setFolderPrefix(String folderPrefix) { this.folderPrefix = folderPrefix; } public String getFolderPrefix() { return folderPrefix; } public void setProtocol(String protocol) { this.storeProtocol = protocol; } public String getProtocol() { return storeProtocol; } public boolean isDovecot() { return isDovecot; } public boolean isReadOnly() { return readonly; } public void setReadOnly(boolean b) { readonly = b; } public void setHasInboxFolder(boolean b) { hasInboxFolder = b; } public boolean hasInboxFolder() { return hasInboxFolder; } public void setDifferentDefaultFolder(String defaultFolderName) { if (defaultFolderName != null) { this.hasDifferentDefaultFolder = true; this.defaultFolderName = defaultFolderName; } else { this.hasDifferentDefaultFolder = false; this.defaultFolderName = null; } } public boolean hasDifferentDefaultFolder() { return hasDifferentDefaultFolder; } public void setMailSession(Session session) { this.session = session; try { session.setProvider(new Provider(Provider.Type.STORE, "imap", "com.sonicle.mail.imap.SonicleIMAPStore", "Sonicle", "1.0")); session.setProvider(new Provider(Provider.Type.STORE, "imaps", "com.sonicle.mail.imap.SonicleIMAPSSLStore", "Sonicle", "1.0")); } catch (NoSuchProviderException exc) { Service.logger.error("Cannot create mail session", exc); } } public Session getMailSession() { return session; } public void setHost(String host) { this.mailHost = host; } public String getHost() { return mailHost; } public void setPort(int port) { this.port = port; } public int getPort() { return port; } public void setUsername(String username) { this.mailUsername = username; } public String getUsername() { return mailUsername; } public void setPassword(String password) { this.mailPassword = password; } public String getPassword() { return mailPassword; } public void setReplyTo(String replyTo) { this.replyTo = replyTo; } public String getReplyTo() { return replyTo; } public void setSaslRFCImpersonate(String authorizationId, String adminUser, String adminPassword) { isImpersonated = true; session.getProperties().setProperty("mail.imap.sasl.authorizationid", authorizationId); mailUsername = adminUser; mailPassword = adminPassword; } public void setNethImpersonate(String username, String vmailSecret) { isImpersonated = true; this.mailUsername = username + "*vmail"; this.mailPassword = vmailSecret; this.vmailSecret = vmailSecret; } public boolean isImpersonated() { return isImpersonated; } public void setFolderSent(String folderSent) { this.folderSent = folderSent; } public String getFolderSent() { return hasDifferentDefaultFolder ? defaultFolderName + folderSeparator + folderSent : folderSent; } public void setFolderDrafts(String folderDrafts) { this.folderDrafts = folderDrafts; } public String getFolderDrafts() { return hasDifferentDefaultFolder ? defaultFolderName + folderSeparator + folderDrafts : folderDrafts; } public void setFolderTrash(String folderTrash) { this.folderTrash = folderTrash; } public String getFolderTrash() { return hasDifferentDefaultFolder ? defaultFolderName + folderSeparator + folderTrash : folderTrash; } public void setFolderSpam(String folderSpam) { this.folderSpam = folderSpam; } public String getFolderSpam() { return hasDifferentDefaultFolder ? defaultFolderName + folderSeparator + folderSpam : folderSpam; } public void setFolderArchive(String folderArchive) { this.folderArchive = folderArchive; } public String getFolderArchive() { return hasDifferentDefaultFolder ? defaultFolderName + folderSeparator + folderArchive : folderArchive; } public void setFolderSeparator(char folderSeparator) { this.folderSeparator = folderSeparator; } public char getFolderSeparator() { return folderSeparator; } public void setHasAnnotations(boolean b) { this.hasAnnotations = b; } public boolean hasAnnotations() { return hasAnnotations; } public void setSkipReplyFolders(String[] skipReplyFolders) { this.skipReplyFolders = skipReplyFolders; } public void setSkipForwardFolders(String[] skipForwardFolders) { this.skipForwardFolders = skipForwardFolders; } public String[] getSharedPrefixes() { return sharedPrefixes; } protected Folder getDefaultFolder() throws MessagingException { if (hasDifferentDefaultFolder) return store.getFolder(defaultFolderName); else return store.getDefaultFolder(); } protected Folder getRealDefaultFolder() throws MessagingException { return store.getDefaultFolder(); } public boolean isValid() throws MessagingException { if (!validated) { if (environment == null) { return false; } validateUser(); } return validated; } public boolean checkStoreConnected() throws MessagingException { if (environment == null) { return false; } synchronized (this) { if (!isConnected()) { return validateUser(); } return true; } } private boolean connect() { try { if (store != null && store.isConnected()) { disconnecting = true; store.close(); } store = session.getStore(storeProtocol); } catch (Exception exc) { Service.logger.error("Exception", exc); } boolean sucess = true; disconnecting = false; try { //warning: trace mode shows credentials Service.logger.trace(" accessing " + storeProtocol + "://" + mailUsername + ":" + mailPassword + "@" + mailHost + ":" + port); if (isImpersonated) Service.logger.info(" impersonating " + authorizationId); if (port > 0) { store.connect(mailHost, port, mailUsername, mailPassword); } else { store.connect(mailHost, mailUsername, mailPassword); } folderSeparator = getDefaultFolder().getSeparator(); Folder un[] = store.getUserNamespaces(""); sharedPrefixes = new String[un.length]; int ix = 0; for (Folder sp : un) { String s = sp.getFullName(); //if (s.endsWith(""+folderSeparator)) s=s.substring(0,s.length()-1); sharedPrefixes[ix] = s; ++ix; } hasAnnotations = ((IMAPStore) store).hasCapability("ANNOTATEMORE"); if (((IMAPStore) store).hasCapability("ID")) { Map<String, String> map = ((IMAPStore) store).id(null); isDovecot = (map != null && map.containsKey("name") && map.get("name").equalsIgnoreCase("dovecot")); //leave hasInboxFolder as it was set in case it's not Dovecot if (isDovecot) hasInboxFolder = true; } } catch (MessagingException exc) { Service.logger.error("Error connecting to the mail server " + mailHost, exc); sucess = false; } return sucess; } private boolean isConnected() { if (store == null) { return false; } return store.isConnected(); } public boolean disconnect() { try { if (store != null && store.isConnected()) { disconnecting = true; store.close(); } } catch (MessagingException ex) { Service.logger.error("Exception", ex); } return true; } /** * Validate the user login and password through the email server * */ private boolean validateUser() throws MessagingException { validated = connect(); return validated; } public void createSpecialFolders() throws MessagingException { checkCreateFolder(getFolderSent()); checkCreateFolder(getFolderDrafts()); checkCreateFolder(getFolderTrash()); checkCreateFolder(getFolderSpam()); checkCreateFolder(getFolderArchive()); } private FolderCache createFolderCache(Folder f) throws MessagingException { FolderCache fc = new FolderCache(this, f, ms, environment); String fname = fc.getFolderName(); foldersCache.put(fname, fc); return fc; } protected FolderCache addFoldersCache(FolderCache parent, Folder child) throws MessagingException { //Service.logger.trace("adding {} to {}",child.getName(),parent.getFolderName()); FolderCache fcChild = addSingleFoldersCache(parent, child); boolean leaf = fcChild.isStartupLeaf(); if (!leaf) { _loadFoldersCache(fcChild); } return fcChild; } public void destroyFolderCache(String foldername) throws MessagingException { destroyFolderCache(getFolderCache(foldername)); } public void destroyFolderCache(FolderCache fc) { ArrayList<FolderCache> fcc = fc.getChildren(); if (fcc != null) { FolderCache afc[] = null; int len = fcc.size(); if (len > 0) { afc = new FolderCache[len]; fc.getChildren().toArray(afc); for (FolderCache child : afc) { destroyFolderCache(child); } } } FolderCache fcp = fc.getParent(); if (fcp != null) { fcp.removeChild(fc); } fc.cleanup(true); try { fc.close(); } catch (Exception exc) { } } public boolean hasFolderCache() { return fcRoot != null; } public void loadFoldersCache(final Object lock, boolean waitLoad) throws MessagingException { Folder froot = getDefaultFolder(); fcRoot = createFolderCache(froot); fcRoot.setIsRoot(true); Folder children[] = fcRoot.getFolder().list(); final ArrayList<FolderCache> rootParents = new ArrayList<FolderCache>(); for (Folder child : children) { if (ms.isFolderHidden(this, child.getFullName())) continue; if (!fcRoot.hasChild(child.getName())) { FolderCache fcc = addSingleFoldersCache(fcRoot, child); if (!fcc.isStartupLeaf()) rootParents.add(fcc); } } if (hasDifferentDefaultFolder) { //check for other shared folders to be added Folder rfolders[] = store.getDefaultFolder().list(); for (int i = 0; i < sharedPrefixes.length; ++i) { for (int j = 0; j < rfolders.length; ++j) { if (rfolders[j].getFullName().equals(sharedPrefixes[i])) { FolderCache fcc = addSingleFoldersCache(fcRoot, rfolders[j]); rootParents.add(fcc); } } } } Thread engine = new Thread(new Runnable() { public void run() { synchronized (lock) { try { for (FolderCache fc : rootParents) { _loadFoldersCache(fc); } } catch (MessagingException exc) { Service.logger.error("Exception", exc); } } } }); engine.start(); try { if (waitLoad) engine.join(); } catch (InterruptedException exc) { Service.logger.error("Error waiting folder cache load", exc); } } private void _loadFoldersCache(FolderCache fc) throws MessagingException { Folder f = fc.getFolder(); Folder children[] = f.list(); for (Folder child : children) { String cname = child.getFullName(); if (ms.isFolderHidden(this, cname)) continue; if (hasDifferentDefaultFolder && cname.equals(fcRoot.getFolderName())) continue; FolderCache fcc = addFoldersCache(fc, child); } //If shared folders, check for same descriptions and in case add login if (isSharedFolder(f.getFullName()) && fc.hasChildren()) { HashMap<String, ArrayList<FolderCache>> hm = new HashMap<String, ArrayList<FolderCache>>(); //map descriptions to list of folders for (FolderCache child : fc.getChildren()) { String desc = child.getDescription(); ArrayList<FolderCache> al = hm.get(desc); if (al == null) { al = new ArrayList<FolderCache>(); al.add(child); hm.put(desc, al); } else { al.add(child); } } //for folders with list>1 change description to all elements for (ArrayList<FolderCache> al : hm.values()) { if (al.size() > 1) { for (FolderCache fcc : al) { SharedPrincipal sip = fcc.getSharedInboxPrincipal(); String user = sip.getUserId(); fcc.setWebTopUser(user); fcc.setDescription(fcc.getDescription() + " [" + user + "]"); } } } } } protected synchronized FolderCache addSingleFoldersCache(FolderCache parent, Folder child) throws MessagingException { String cname = child.getFullName(); FolderCache fcChild = foldersCache.get(cname); if (fcChild == null) { fcChild = createFolderCache(child); if (parent != null) { fcChild.setParent(parent); parent.addChild(fcChild); } fcChild.setStartupLeaf(isLeaf((IMAPFolder) child)); } return fcChild; } public FolderCache[] getSharedFoldersCache() throws MessagingException { if (fcShared == null) { if (sharedPrefixes != null) { String sf[] = sharedPrefixes; fcShared = new FolderCache[sf.length]; for (int i = 0; i < sf.length; ++i) { fcShared[i] = getFolderCache(sf[i]); } } } return fcShared; } public FolderCache getRootFolderCache() { return fcRoot; } public boolean isRoot(FolderCache fc) { return fcRoot != null && fc == fcRoot; } public Set<Map.Entry<String, FolderCache>> getFolderCacheEntries() { return foldersCache.entrySet(); } public Collection<FolderCache> getFolderCacheValues() { return foldersCache.values(); } public Set<String> getFolderCacheKeys() { return foldersCache.keySet(); } public Quota[] getQuota(String foldername) throws MessagingException { return ((IMAPStore) store).getQuota(foldername); } public FolderCache getFolderCache(String foldername) throws MessagingException { return foldersCache.get(foldername); } public String getShortFolderName(String fullname) { String shortname = fullname; if (StringUtils.startsWithIgnoreCase(fullname, folderPrefix)) { shortname = fullname.substring(folderPrefix.length()); } return shortname; } public String getLastFolderName(String fullname) { String lasttname = fullname; if (lasttname.indexOf(folderSeparator) >= 0) { lasttname = lasttname.substring(lasttname.lastIndexOf(folderSeparator) + 1); } return lasttname; } protected String getInboxFolderFullName() { String inboxFolder = "INBOX"; try { if (hasDifferentDefaultFolder) { inboxFolder = getDefaultFolder().getFullName(); if (hasInboxFolder) inboxFolder += folderSeparator + "INBOX"; } } catch (MessagingException exc) { } return inboxFolder; } protected Folder getFolder(String foldername) throws MessagingException { return store.getFolder(foldername); } public Folder checkCreateFolder(String foldername) throws MessagingException { Folder folder = store.getFolder(foldername); if (!folder.exists()) { folder.create(Folder.HOLDS_MESSAGES | Folder.HOLDS_FOLDERS); } return folder; } public FolderCache checkCreateAndCacheFolder(String fullname) throws MessagingException { Folder folder = checkCreateFolder(fullname); FolderCache fc = getFolderCache(fullname); if (fc == null) { FolderCache parent = fcRoot; int ix = fullname.lastIndexOf(folderSeparator); if (ix > 0) parent = getFolderCache(fullname.substring(0, ix)); fc = addFoldersCache(parent, folder); } return fc; } public FolderCache checkCreateAndCacheFolders(String fullname) throws MessagingException { int x = fullname.indexOf(folderSeparator); while (x > 0) { String fname = fullname.substring(0, x); checkCreateAndCacheFolder(fname); x = fullname.indexOf(folderSeparator, x + 1); } return checkCreateAndCacheFolder(fullname); } public boolean checkFolder(String foldername) throws MessagingException { Folder folder = store.getFolder(foldername); return folder.exists(); } public boolean deleteFolder(String fullname) throws MessagingException { return deleteFolder(getFolder(fullname)); } public boolean deleteFolder(Folder folder) throws MessagingException { for (Folder subfolder : folder.list()) { deleteFolder(subfolder); } try { folder.close(false); } catch (Throwable exc) { } boolean retval = folder.delete(true); if (retval) { destroyFolderCache(folder.getFullName()); } return retval; } private boolean isLeaf(IMAPFolder folder) throws MessagingException { String atts[] = folder.getAttributes(); boolean leaf = true; boolean noinferiors = false; for (String att : atts) { if (att.equals("\\HasChildren")) { leaf = false; } else if (att.equals("\\Noinferiors")) { noinferiors = true; } } if (noinferiors) { leaf = true; } return leaf; } public boolean isSentFolder(String fullname) { String lastname = getLastFolderName(fullname); String plastname = getLastFolderName(folderSent); if (lastname.equals(plastname)) { return true; } return false; } public boolean isTrashFolder(String fullname) { String lastname = getLastFolderName(fullname); String plastname = getLastFolderName(folderTrash); if (lastname.equals(plastname)) { return true; } return false; } public boolean isDraftsFolder(String fullname) { String lastname = getLastFolderName(fullname); String plastname = getLastFolderName(folderDrafts); if (lastname.equals(plastname)) { return true; } return false; } public boolean isArchiveFolder(String fullname) { if (folderArchive != null) { String lastname = getLastFolderName(fullname); String plastname = getLastFolderName(folderArchive); if (lastname.equals(plastname)) { return true; } } return false; } public boolean isSpamFolder(String fullname) { String lastname = getLastFolderName(fullname); String plastname = getLastFolderName(folderSpam); if (lastname.equals(plastname)) { return true; } return false; } public boolean isSpecialFolder(String foldername) { boolean retval = isTrashFolder(foldername) || isDraftsFolder(foldername) || isInboxFolder(foldername) || isSentFolder(foldername) || isArchiveFolder(foldername) || isSpamFolder(foldername); return retval; } public boolean isInboxFolder(String foldername) { if (!hasDifferentDefaultFolder) { //if is root inbox if (foldername.equals("INBOX") || //or a shared inbox (isUnderSharedFolder(foldername) && LangUtils.charOccurrences(folderSeparator, foldername) == 2 && getLastFolderName(foldername).equals("INBOX"))) return true; } else { if (hasInboxFolder) return foldername.endsWith(folderSeparator + "INBOX"); return (isDefaultFolder(foldername) || (isUnderSharedFolder(foldername) && LangUtils.charOccurrences(folderSeparator, foldername) == 2 && getLastFolderName(foldername).equals("INBOX"))); } return false; } public boolean isDefaultFolder(String foldername) { Folder df = null; try { df = getDefaultFolder(); } catch (MessagingException exc) { Service.logger.error("Error getting default folder", exc); } if (df != null) return df.getFullName().equals(foldername); return false; } public boolean isUnderTrashFolder(String foldername) { String str = folderTrash + folderSeparator; return foldername.startsWith(str); } public boolean isUnderSharedFolder(String foldername) { boolean b = false; String str = null; for (String fn : sharedPrefixes) { str = fn + folderSeparator; if (foldername.startsWith(str)) { b = true; break; } } return b; } public boolean isUnderFolder(String parentname, String foldername) { if (!parentname.endsWith("" + folderSeparator)) parentname = parentname + folderSeparator; return (foldername.startsWith(parentname)); } public boolean isSharedFolder(String foldername) { boolean b = false; for (String fn : sharedPrefixes) { if (foldername.equals(fn)) { b = true; break; } } return b; } public boolean isSharedFolderContainer(IMAPFolder folder) { // If passed folder matches a shared prefix, we have taken shared // folders' container folder for (String prefix : sharedPrefixes) { if (folder.getFullName().equals(prefix)) return true; } return false; } public boolean isUnderSentFolder(String foldername) { String str = getFolderSent() + folderSeparator; return foldername.startsWith(str); } public String getMainSharedFolder(String foldername) { if (!foldername.endsWith("" + folderSeparator)) foldername += folderSeparator; for (String fn : sharedPrefixes) { String str = fn + folderSeparator; if (foldername.startsWith(str)) { int ix = foldername.indexOf(folderSeparator, str.length()); if (ix >= 0) return foldername.substring(0, ix); } } return null; } public void deleteByHeaderValue(String header, String value) throws MessagingException { FolderCache fc = getFolderCache(getFolderDrafts()); fc.open(); Folder folder = fc.getFolder(); Message[] oldmsgs = folder.search(new HeaderTerm(header, value)); if (oldmsgs != null && oldmsgs.length > 0) { for (Message m : oldmsgs) m.setFlag(Flags.Flag.DELETED, true); folder.expunge(); } } public boolean emptyFolder(String fullname) throws MessagingException { FolderCache fc = getFolderCache(fullname); for (Folder child : fc.getFolder().list()) { deleteFolder(child); } fc.deleteAllMessages(); return true; } public FolderCache trashFolder(String fullname) throws MessagingException { if (!isUnderTrashFolder(fullname)) { String foldertrash = getFolderTrash(); if (isUnderSharedFolder(fullname)) { String mainfolder = getMainSharedFolder(fullname); if (mainfolder != null) { foldertrash = mainfolder + folderSeparator + getLastFolderName(foldertrash); } } return moveFolder(fullname, foldertrash); } else { deleteFolder(fullname); return null; } } public FolderCache moveFolder(String source, String dest) throws MessagingException { Folder oldfolder = getFolder(source); String oldname = oldfolder.getName(); //System.out.println("moveFolder "+source+" -> "+dest); Folder newfolder; if (dest != null && dest.trim().length() > 0) { String newname = dest + folderSeparator + oldname; newfolder = getFolder(newname); } else { if (hasDifferentDefaultFolder) { String prefix = getDefaultFolder().getFullName(); String newname = oldname; if (prefix != null) newname = prefix + folderSeparator + newname; newfolder = getFolder(newname); } else { String newname = oldname; if (folderPrefix != null) { newname = folderPrefix + newname; } newfolder = getFolder(newname); } } FolderCache fcsrc = getFolderCache(source); if (fcsrc != null) { destroyFolderCache(fcsrc); } boolean done = oldfolder.renameTo(newfolder); if (done) { if (dest != null) { FolderCache tfc = getFolderCache(newfolder.getParent().getFullName()); return addFoldersCache(tfc, newfolder); } else { return addFoldersCache(fcRoot, newfolder); } } return null; } public String renameFolder(String orig, String newname) throws MessagingException { FolderCache fc = getFolderCache(orig); FolderCache fcparent = fc.getParent(); Folder oldfolder = fc.getFolder(); destroyFolderCache(fc); Folder newfolder = fcparent.getFolder().getFolder(newname); boolean done = oldfolder.renameTo(newfolder); if (!done) { throw new MessagingException("Rename failed"); } //trick for Dovecot on NethServer: under shared folders, create and destroy a fake folder //or rename will not work correctly if (isUnderSharedFolder(newfolder.getFullName())) { Map<String, String> map = ((IMAPStore) store).id(null); if (map != null && map.containsKey("name") && map.get("name").equalsIgnoreCase("dovecot")) { String trickName = "_________" + System.currentTimeMillis(); Folder trickFolder = fcparent.getFolder().getFolder(trickName); try { trickFolder.create(Folder.READ_ONLY); trickFolder.delete(true); } catch (MessagingException exc) { } } } addFoldersCache(fcparent, newfolder); return newfolder.getFullName(); } public void cleanup() { Service.logger.trace("clean up account " + id); if (fcRoot != null) { fcRoot.cleanup(true); } fcRoot = null; for (FolderCache fc : foldersCache.values()) { fc.cleanup(true); } foldersCache.clear(); try { Service.logger.trace("-disconnecting imap"); disconnect(); Service.logger.trace("-done"); } catch (Exception e) { Service.logger.error("Exception", e); } validated = false; } public String normalizeName(String name) throws MessagingException { String sep = "" + folderSeparator; while (name.contains(sep)) { name = name.replace(sep, "_"); } return name; } public SonicleIMAPFolder.RecursiveSearchResult recursiveSearchByMessageID(String foldername, String id) throws MessagingException { SonicleIMAPFolder f = (SonicleIMAPFolder) getFolder(foldername); return f.recursiveSearchByMessageID(id, skipReplyFolders); } public void removeFolderSharing(String foldername, String acluser, boolean recursive) throws MessagingException { Folder folders[] = null; if (StringUtils.isEmpty(foldername)) { folders = getDefaultFolder().list(); } else { folders = new IMAPFolder[1]; folders[0] = (IMAPFolder) getFolderCache(foldername).getFolder(); } for (Folder folder : folders) _removeFolderSharing((IMAPFolder) folder, acluser, recursive); } private void _removeFolderSharing(IMAPFolder folder, String acluser, boolean recursive) throws MessagingException { if (isSharedFolderContainer(folder)) return; // Skip shared folder container if (recursive && !isLeaf(folder)) { Folder children[] = folder.list(); for (Folder child : children) { _removeFolderSharing((IMAPFolder) child, acluser, true); } } try { folder.removeACL(acluser); } catch (MessagingException exc) { Service.logger.error("Error removing acl on folder " + folder.getFullName(), exc); } } public void setFolderSharing(String foldername, String acluser, String rights, boolean recursive) throws MessagingException { Folder folders[] = null; if (StringUtils.isEmpty(foldername)) { folders = getDefaultFolder().list(); } else { folders = new IMAPFolder[1]; folders[0] = (IMAPFolder) getFolderCache(foldername).getFolder(); } for (Folder folder : folders) _setFolderSharing((IMAPFolder) folder, acluser, rights, recursive); } private void _setFolderSharing(IMAPFolder folder, String acluser, String rights, boolean recursive) throws MessagingException { if (isSharedFolderContainer(folder)) return; // Skip shared folder container if (recursive && !isLeaf(folder)) { Folder children[] = folder.list(); for (Folder child : children) { _setFolderSharing((IMAPFolder) child, acluser, rights, true); } } try { folder.removeACL(acluser); folder.addACL(new ACL(acluser, new Rights(rights))); } catch (MessagingException exc) { Service.logger.error("Error setting acl on folder " + folder.getFullName(), exc); } } private Comparator<Folder> wtufComp = new Comparator<Folder>() { public int compare(Folder f1, Folder f2) { int ret = 0; try { FolderCache fc1 = getFolderCache(f1.getFullName()); FolderCache fc2 = getFolderCache(f2.getFullName()); String u1 = fc1.getWebTopUser(); String u2 = fc2.getWebTopUser(); ret = u1.compareTo(u2); } catch (MessagingException exc) { Service.logger.error("Exception", exc); } return ret; } }; public Comparator<Folder> getWebTopUserFolderComparator() { return wtufComp; } private Comparator<Folder> fdComp = new Comparator<Folder>() { public int compare(Folder f1, Folder f2) { int ret = 0; try { FolderCache fc1 = getFolderCache(f1.getFullName()); FolderCache fc2 = getFolderCache(f2.getFullName()); String desc1 = fc1.getDescription(); String desc2 = fc2.getDescription(); ret = desc1.compareTo(desc2); } catch (MessagingException exc) { Service.logger.error("Exception", exc); } return ret; } }; public Comparator<Folder> getDescriptionFolderComparator() { return fdComp; } }