use of com.zimbra.cs.mailbox.SearchFolder in project zm-mailbox by Zimbra.
the class ToXML method encodeFolder.
public static Element encodeFolder(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Folder folder, int fields, boolean exposeAclAccessKey) throws ServiceException {
if (folder instanceof SearchFolder) {
return encodeSearchFolder(parent, ifmt, (SearchFolder) folder, fields);
} else if (folder instanceof Mountpoint) {
return encodeMountpoint(parent, ifmt, octxt, (Mountpoint) folder, fields);
}
Element elem = parent.addElement(MailConstants.E_FOLDER);
encodeFolderCommon(elem, ifmt, folder, fields);
if (needToOutput(fields, Change.SIZE)) {
int deleted = folder.getDeletedCount();
elem.addAttribute(MailConstants.A_NUM, folder.getItemCount() - deleted);
if (deleted > 0) {
elem.addAttribute(MailConstants.A_IMAP_NUM, folder.getItemCount());
}
elem.addAttribute(MailConstants.A_SIZE, folder.getTotalSize());
elem.addAttribute(MailConstants.A_IMAP_MODSEQ, folder.getImapMODSEQ());
elem.addAttribute(MailConstants.A_IMAP_UIDNEXT, folder.getImapUIDNEXT());
}
if (needToOutput(fields, Change.URL)) {
String url = folder.getUrl();
if (!url.isEmpty() || fields != NOTIFY_FIELDS) {
// Note: in this case, a url on a folder object
// is not a url to the folder, but the url to another item that's
// external of the mail system. In most cases this is a 'synced' folder
// that is either RSS or a remote calendar object
elem.addAttribute(MailConstants.A_URL, HttpUtil.sanitizeURL(url));
}
}
Mailbox mbox = folder.getMailbox();
boolean remote = octxt != null && octxt.isDelegatedRequest(mbox);
boolean canAdminister = !remote;
boolean canDelete = canAdminister;
if (remote) {
// return effective permissions only for remote folders
String perms = encodeEffectivePermissions(folder, octxt);
elem.addAttribute(MailConstants.A_RIGHTS, perms);
canAdminister = perms != null && perms.indexOf(ACL.ABBR_ADMIN) != -1;
// Need to know retention policy if grantees can delete from a folder so clients can warn
// them when they try to delete something within the retention period
canDelete = canAdminister || (perms != null && perms.indexOf(ACL.ABBR_DELETE) != -1);
}
if (canAdminister) {
// return full ACLs for folders we have admin rights on
if (needToOutput(fields, Change.ACL)) {
if (fields != NOTIFY_FIELDS || folder.isTagged(Flag.FlagInfo.NO_INHERIT)) {
encodeACL(octxt, elem, folder.getEffectiveACL(), exposeAclAccessKey);
}
}
}
if (canDelete) {
if (needToOutput(fields, Change.RETENTION_POLICY)) {
RetentionPolicy rp = folder.getRetentionPolicy();
if (fields != NOTIFY_FIELDS || rp.isSet()) {
// Only output retention policy if it's being modified, or if we're returning all
// folder data and policy is set.
encodeRetentionPolicy(elem, RetentionPolicyManager.getInstance().getCompleteRetentionPolicy(folder.getAccount(), rp));
}
}
}
return elem;
}
use of com.zimbra.cs.mailbox.SearchFolder in project zm-mailbox by Zimbra.
the class ImapSessionManager method openFolder.
Pair<ImapSession, InitialFolderValues> openFolder(ImapPath path, byte params, ImapHandler handler) throws ServiceException {
ZimbraLog.imap.debug("opening folder: %s", path);
if (!path.isSelectable()) {
throw ServiceException.PERM_DENIED("cannot select folder: " + path);
}
if ((params & ImapFolder.SELECT_CONDSTORE) != 0) {
handler.activateExtension(ImapExtension.CONDSTORE);
}
Folder folder = (Folder) path.getFolder();
int folderId = folder.getId();
Mailbox mbox = folder.getMailbox();
// don't have a session when the folder is loaded...
OperationContext octxt = handler.getCredentials().getContext();
mbox.beginTrackingImap();
List<ImapMessage> i4list = null;
// *always* recalculate the contents of search folders
if (folder instanceof SearchFolder) {
i4list = loadVirtualFolder(octxt, (SearchFolder) folder);
}
mbox.lock.lock();
try {
// need mInitialRecent to be set *before* loading the folder so we can determine what's \Recent
folder = mbox.getFolderById(octxt, folderId);
int recentCutoff = folder.getImapRECENTCutoff();
if (i4list == null) {
List<Session> listeners = mbox.getListeners(Session.Type.IMAP);
// first option is to duplicate an existing registered session
// (could try to just activate an inactive session, but this logic is simpler for now)
i4list = duplicateExistingSession(folderId, listeners);
// no matching session means we next check for serialized folder data
if (i4list == null) {
i4list = duplicateSerializedFolder(folder);
} else if (CONSISTENCY_CHECK) {
Collections.sort(i4list);
//sort only if using list from duplicated session which may be out of order
//if loaded from serialized folder order _should_ already be OK since no changes have occurred
}
// do the consistency check, if requested
if (CONSISTENCY_CHECK) {
i4list = consistencyCheck(i4list, mbox, octxt, folder);
}
// no matching serialized session means we have to go to the DB to get the messages
if (i4list == null) {
i4list = mbox.openImapFolder(octxt, folderId);
}
}
Collections.sort(i4list);
// check messages for imapUid <= 0 and assign new IMAP IDs if necessary
renumberMessages(octxt, mbox, i4list);
ImapFolder i4folder = new ImapFolder(path, params, handler);
// don't rely on the <code>Folder</code> object being updated in place
folder = mbox.getFolderById(octxt, folderId);
// can't set these until *after* loading the folder because UID renumbering affects them
InitialFolderValues initial = new InitialFolderValues(folder);
for (ImapMessage i4msg : i4list) {
i4folder.cache(i4msg, i4msg.imapUid > recentCutoff);
if (initial.firstUnread == -1 && (i4msg.flags & Flag.BITMASK_UNREAD) != 0) {
initial.firstUnread = i4msg.sequence;
}
}
i4folder.setInitialSize();
ZimbraLog.imap.debug("Folder with id=%s added message list %s", folderId, i4list);
ImapSession session = null;
try {
session = new ImapSession(i4folder, handler);
session.register();
sessions.put(session, session);
return new Pair<ImapSession, InitialFolderValues>(session, initial);
} catch (ServiceException e) {
if (session != null) {
session.unregister();
}
throw e;
}
} finally {
mbox.lock.release();
}
}
use of com.zimbra.cs.mailbox.SearchFolder in project zm-mailbox by Zimbra.
the class DBQueryOperation method expandLocalRemotePart.
@Override
QueryOperation expandLocalRemotePart(Mailbox mbox) throws ServiceException {
if (constraints instanceof DbSearchConstraints.Leaf) {
boolean added = false;
if (includeIsLocalFolders) {
// expanded!
includeIsLocalFolders = false;
DbSearchConstraints.Leaf leaf = (DbSearchConstraints.Leaf) constraints;
for (Folder f : mbox.getFolderById(null, Mailbox.ID_FOLDER_ROOT).getSubfolderHierarchy()) {
if (!(f instanceof Mountpoint) && !(f instanceof SearchFolder)) {
// add local folder ref
leaf.folders.add(f);
added = true;
}
}
if (!added) {
return new NoResultsQueryOperation();
} else {
return this;
}
} else if (includeIsRemoteFolders) {
UnionQueryOperation toRet = new UnionQueryOperation();
// expanded
includeIsRemoteFolders = false;
for (Folder f : mbox.getFolderById(null, Mailbox.ID_FOLDER_ROOT).getSubfolderHierarchy()) {
if (f instanceof Mountpoint) {
Mountpoint mpt = (Mountpoint) f;
if (!mpt.isLocal()) {
// add remote folder ref
DBQueryOperation db = new DBQueryOperation();
db.addInRemoteFolder(mpt.getTarget(), "", true, true);
toRet.add(db);
added = true;
}
}
}
if (!added) {
return new NoResultsQueryOperation();
} else {
return toRet;
}
} else {
return this;
}
} else {
throw new IllegalStateException("expandLocalRemotePart must be called before optimize() is called");
}
}
use of com.zimbra.cs.mailbox.SearchFolder in project zm-mailbox by Zimbra.
the class GetSearchFolder method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
Element response = zsc.createElement(MailConstants.GET_SEARCH_FOLDER_RESPONSE);
List<? extends MailItem> results = mbox.getItemList(octxt, MailItem.Type.SEARCHFOLDER, -1, SortBy.NONE);
if (results != null) {
for (MailItem item : results) ToXML.encodeSearchFolder(response, ifmt, (SearchFolder) item);
}
return response;
}
use of com.zimbra.cs.mailbox.SearchFolder in project zm-mailbox by Zimbra.
the class ImapHandler method getFolderAttrs.
private String getFolderAttrs(ImapPath path, byte returnOptions, Map<ImapPath, ItemId> paths, Set<String> subscriptions) throws ServiceException {
StringBuilder attrs = new StringBuilder();
ItemId iid = paths.get(path);
if (iid == null) {
attrs.append(attrs.length() == 0 ? "" : " ").append("\\NonExistent");
}
try {
if ((returnOptions & RETURN_SUBSCRIBED) != 0 && isPathSubscribed(path, subscriptions)) {
attrs.append(attrs.length() == 0 ? "" : " ").append("\\Subscribed");
}
} catch (NoSuchItemException nsie) {
ZimbraLog.imap.debug("Subscribed path \"%s\" is not available on server.", path.asImapPath());
}
if (iid == null) {
return attrs.toString();
}
boolean noinferiors = (iid.getId() == Mailbox.ID_FOLDER_SPAM);
if (noinferiors) {
attrs.append(attrs.length() == 0 ? "" : " ").append("\\NoInferiors");
}
if (!path.isSelectable()) {
attrs.append(attrs.length() == 0 ? "" : " ").append("\\NoSelect");
}
if (!noinferiors && (returnOptions & RETURN_CHILDREN) != 0) {
String prefix = path.asZimbraPath().toUpperCase() + '/';
boolean children = false;
for (ImapPath other : paths.keySet()) {
if (other.asZimbraPath().toUpperCase().startsWith(prefix) && other.isVisible()) {
children = true;
break;
}
}
attrs.append(attrs.length() == 0 ? "" : " ").append(children ? "\\HasChildren" : "\\HasNoChildren");
}
//we also keep support for non-standard XLIST attributes for legacy clients that may still use them
if ((DebugConfig.imapForceSpecialUse || (returnOptions & RETURN_XLIST) != 0) && path.belongsTo(credentials)) {
//return deprecated XLIST attrs if requested
boolean returnXList = (returnOptions & RETURN_XLIST) != 0;
switch(iid.getId()) {
case Mailbox.ID_FOLDER_INBOX:
if (returnXList) {
attrs.append(attrs.length() == 0 ? "" : " ").append("\\Inbox");
}
break;
case Mailbox.ID_FOLDER_DRAFTS:
attrs.append(attrs.length() == 0 ? "" : " ").append("\\Drafts");
break;
case Mailbox.ID_FOLDER_TRASH:
attrs.append(attrs.length() == 0 ? "" : " ").append("\\Trash");
break;
case Mailbox.ID_FOLDER_SENT:
attrs.append(attrs.length() == 0 ? "" : " ").append("\\Sent");
break;
case Mailbox.ID_FOLDER_SPAM:
attrs.append(attrs.length() == 0 ? "" : " ").append(returnXList ? "\\Spam" : "\\Junk");
break;
default:
String query = path.getFolder() instanceof SearchFolder ? ((SearchFolder) path.getFolder()).getQuery() : null;
if (query != null) {
if (query.equalsIgnoreCase("is:flagged")) {
attrs.append(attrs.length() == 0 ? "" : " ").append(returnXList ? "\\Starred" : "\\Flagged");
} else if (query.equalsIgnoreCase("is:local")) {
attrs.append(attrs.length() == 0 ? "" : " ").append(returnXList ? "\\AllMail" : "\\All");
}
}
break;
}
}
return attrs.toString();
}
Aggregations