use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.
the class DbTag method alterTag.
public static void alterTag(Tag tag, List<Integer> itemIds, boolean add) throws ServiceException {
if (itemIds == null || itemIds.isEmpty()) {
return;
}
Mailbox mbox = tag.getMailbox();
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
try {
boolean isFlag = tag instanceof Flag;
boolean altersModseq = !isFlag || !((Flag) tag).isSystemFlag();
String primaryUpdate, sanityCheckAnd;
if (isFlag) {
primaryUpdate = "flags = flags" + (add ? " + ?" : " - ?");
sanityCheckAnd = Db.getInstance().bitAND("flags", "?") + (add ? " = 0" : " <> 0") + " AND ";
} else {
if (add) {
primaryUpdate = "tag_names = CASE WHEN tag_names IS NULL THEN ? ELSE " + Db.getInstance().concat("tag_names", "?") + " END";
sanityCheckAnd = "(tag_names IS NULL OR tag_names NOT LIKE ?) AND ";
} else {
primaryUpdate = "tag_names = CASE tag_names WHEN ? THEN NULL ELSE REPLACE(tag_names, ?, '\0') END";
sanityCheckAnd = "";
}
}
String updateChangeID = altersModseq ? ", mod_metadata = ?, change_date = ?" : "";
for (int i = 0; i < itemIds.size(); i += Db.getINClauseBatchSize()) {
int count = Math.min(Db.getINClauseBatchSize(), itemIds.size() - i);
stmt = conn.prepareStatement("UPDATE " + DbMailItem.getMailItemTableName(mbox) + " SET " + primaryUpdate + updateChangeID + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + sanityCheckAnd + DbUtil.whereIn("id", count));
int pos = 1;
// primary update
if (isFlag) {
stmt.setLong(pos++, ((Flag) tag).toBitmask());
} else {
stmt.setString(pos++, delimitTagName(tag.getName()));
stmt.setString(pos++, delimitTagName(tag.getName()).substring(add ? 1 : 0));
}
// change ID update
if (altersModseq) {
stmt.setInt(pos++, mbox.getOperationChangeID());
stmt.setInt(pos++, mbox.getOperationTimestamp());
}
pos = DbMailItem.setMailboxId(stmt, mbox, pos);
// sanity check
if (isFlag) {
stmt.setLong(pos++, ((Flag) tag).toBitmask());
} else if (add) {
stmt.setString(pos++, tagLIKEPattern(tag.getName()));
}
// item IDs
for (int index = i; index < i + count; index++) {
stmt.setInt(pos++, itemIds.get(index));
}
stmt.executeUpdate();
stmt.close();
stmt = null;
if (add) {
addTaggedItemEntries(mbox, tag.getId(), itemIds.subList(i, i + count));
} else {
removeTaggedItemEntries(mbox, tag.getId(), itemIds.subList(i, i + count));
}
}
} catch (SQLException e) {
throw ServiceException.FAILURE("updating tag data for " + itemIds.size() + " items: " + DbMailItem.getIdListForLogging(itemIds), e);
} finally {
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.
the class GetTag method handle.
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);
List<Tag> tags = null;
try {
tags = mbox.getTagList(octxt);
} catch (ServiceException e) {
// just return no tags in the perm denied case (not considered an error here)...
if (!e.getCode().equals(ServiceException.PERM_DENIED))
throw e;
}
Element response = zsc.createElement(MailConstants.GET_TAG_RESPONSE);
if (tags != null) {
for (Tag tag : tags) {
if (tag == null || tag instanceof Flag)
continue;
ToXML.encodeTag(response, ifmt, octxt, tag);
}
}
return response;
}
use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.
the class SoapSession method putRefresh.
/**
* Serializes basic folder/tag structure to a SOAP response header.
* <p>
* Adds a <refresh> block to the existing <context> element.
* This <refresh> block contains the basic folder, tag, and mailbox
* size information needed to display and update the web UI's overview
* pane. The <refresh> block is sent when a new session is created.
*
* This API implicitly clears all cached notifications and therefore
* should only been used during session creation.
* @param ctxt An existing SOAP header <context> element
* @param zsc The SOAP request's encapsulated context
*/
public void putRefresh(Element ctxt, ZimbraSoapContext zsc) throws ServiceException {
Mailbox mbox = this.getMailboxOrNull();
if (mbox == null) {
return;
}
synchronized (sentChanges) {
for (QueuedNotifications ntfn : sentChanges) {
ntfn.clearMailboxChanges();
}
}
Element eRefresh = ctxt.addUniqueElement(ZimbraNamespace.E_REFRESH);
eRefresh.addAttribute(AccountConstants.E_VERSION, BuildInfo.FULL_VERSION, Element.Disposition.CONTENT);
OperationContext octxt = DocumentHandler.getOperationContext(zsc, this);
ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
// dump current mailbox status (currently just size)
ToXML.encodeMailbox(eRefresh, octxt, mbox);
// dump all tags under a single <tags> parent
List<Tag> tags = mbox.getTagList(octxt);
if (tags != null && tags.size() > 0) {
Element eTags = eRefresh.addUniqueElement(ZimbraNamespace.E_TAGS);
for (Tag tag : tags) {
if (tag != null && !(tag instanceof Flag)) {
ToXML.encodeTag(eTags, ifmt, octxt, tag);
}
}
}
// first, get the user's folder hierarchy
FolderNode root = mbox.getFolderTree(octxt, null, false);
OperationContextData.setNeedGranteeName(octxt, false);
GetFolder.encodeFolderNode(root, eRefresh, ifmt, octxt);
// The Boolean of the Pair indicates whether the mountpoint is found to be broken
Map<ItemId, Pair<Boolean, Element>> mountpoints = new HashMap<ItemId, Pair<Boolean, Element>>();
// for mountpoints pointing to this host, get the serialized folder subhierarchy
expandLocalMountpoints(octxt, root, eRefresh.getFactory(), mountpoints);
// for mountpoints pointing to other hosts, get the folder structure from the remote server
expandRemoteMountpoints(octxt, zsc, mountpoints);
// graft in subfolder trees from the other user's mailbox, making sure that mountpoints reflect the counts (etc.) of the target folder
if (!mountpoints.isEmpty()) {
transferMountpointContents(eRefresh.getOptionalElement(MailConstants.E_FOLDER), octxt, mountpoints);
}
}
use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.
the class DbSearch method encodeTag.
private boolean encodeTag(Set<Tag> tags, boolean bool, boolean useJoin, boolean and) {
if (tags.isEmpty()) {
return false;
}
if (useJoin) {
assert !dumpster;
assert bool;
}
if (dumpster) {
// There is no corresponding table to TAGGED_ITEM in dumpster, hence brute-force search.
int flags = 0;
for (Tag tag : tags) {
if (tag instanceof Flag) {
Flag flag = (Flag) tag;
if (flag.getId() == Flag.ID_UNREAD) {
if (and) {
sql.append(" AND ");
}
sql.append("mi.unread = ?");
and = true;
params.add(bool ? 1 : 0);
} else {
flags |= flag.toBitmask();
}
} else {
if (and) {
sql.append(" AND ");
}
and = true;
sql.append("(mi.tag_names");
if (!bool) {
// Include NULL because LIKE does not match NULL.
sql.append(" IS NULL OR mi.tag_names NOT");
}
sql.append(" LIKE ?)");
params.add(DbTag.tagLIKEPattern(tag.getName()));
}
}
if (flags != 0) {
sql.append(" AND ").append(Db.getInstance().bitAND("mi.flags", "?")).append(" = ?");
params.add(flags);
params.add(bool ? flags : 0);
}
} else if (bool) {
// Repeats "EXISTS (SELECT...)" as many times as tags.
if (useJoin) {
assert tags.size() == 1;
Tag tag = tags.iterator().next();
// AND (mi.id = ti.item_id AND mi.mailbox_id = ti.mailbox_id AND ti.tag_id = -10)
if (and) {
sql.append(" AND ");
}
sql.append("(mi.id = ti.item_id AND mi.mailbox_id = ti.mailbox_id AND ti.tag_id = ?)");
params.add(tag.getId());
and = true;
} else {
for (Tag tag : tags) {
if (and) {
sql.append(" AND ");
}
sql.append("EXISTS (SELECT * FROM ").append(DbTag.getTaggedItemTableName(mailbox, "ti"));
and = true;
sql.append(" WHERE ");
if (!DebugConfig.disableMailboxGroups) {
sql.append("mi.mailbox_id = ti.mailbox_id AND ");
}
sql.append("mi.id = ti.item_id AND ti.tag_id = ?)");
params.add(tag.getId());
}
}
} else {
// NOT EXISTS (SELECT... WHERE... tag_id IN...)
if (and) {
sql.append(" AND ");
}
sql.append("NOT EXISTS (SELECT * FROM ").append(DbTag.getTaggedItemTableName(mailbox, "ti"));
and = true;
sql.append(" WHERE ");
if (!DebugConfig.disableMailboxGroups) {
sql.append("mi.mailbox_id = ti.mailbox_id AND ");
}
sql.append("mi.id = ti.item_id AND ").append(DbUtil.whereIn("ti.tag_id", tags.size())).append(')');
for (Tag tag : tags) {
params.add(tag.getId());
}
}
return true;
}
Aggregations