use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class Mailbox method delete.
/**
* Delete the <tt>MailItem</tt>s with the given ids. If there is no <tt>MailItem</tt> for a given id, that id is
* ignored. If the id maps to an existing <tt>MailItem</tt> of an incompatible type, however, an error is thrown.
*
* @param octxt operation context or {@code null}
* @param itemIds item ids
* @param type item type or {@link MailItem.Type#UNKNOWN}
* @param tcon target constraint or {@code null}
* @param useEmptyForFolders empty folder {@code true} or {@code false}
* @param nonExistingItems object of {@link ArrayList} or {@code null}
*/
private void delete(OperationContext octxt, int[] itemIds, MailItem.Type type, TargetConstraint tcon, boolean useEmptyForFolders, List<Integer> nonExistingItems) throws ServiceException {
DeleteItem redoRecorder = new DeleteItem(mId, itemIds, type, tcon);
List<Integer> folderIds = Lists.newArrayList();
boolean success = false;
try {
beginTransaction("delete", octxt, redoRecorder);
setOperationTargetConstraint(tcon);
for (int id : itemIds) {
if (id == ID_AUTO_INCREMENT) {
continue;
}
MailItem item;
try {
item = getItemById(id, MailItem.Type.UNKNOWN);
} catch (NoSuchItemException nsie) {
if (nonExistingItems != null) {
nonExistingItems.add(id);
}
// trying to delete nonexistent things is A-OK!
continue;
}
// however, trying to delete messages and passing in a folder ID is not OK
if (!MailItem.isAcceptableType(type, item.getType())) {
throw MailItem.noSuchItem(id, type);
} else if (!checkItemChangeID(item) && item instanceof Tag) {
throw MailServiceException.MODIFY_CONFLICT();
}
if (useEmptyForFolders && MailItem.Type.FOLDER.equals(item.getType())) {
// removed later to allow batching delete of contents in there own transactions
folderIds.add(id);
} else {
// delete the item, but don't write the tombstone until we're finished...
item.delete(false);
}
}
// deletes have already been collected, so fetch the tombstones and write once
TypedIdList tombstones = collectPendingTombstones();
if (tombstones != null && !tombstones.isEmpty()) {
DbMailItem.writeTombstones(this, tombstones);
}
success = true;
} finally {
endTransaction(success);
}
for (Integer folderId : folderIds) {
emptyFolder(octxt, folderId, true, /* removeTopLevelFolder */
true, /* removeSubfolders */
tcon);
}
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class Sync method folderSync.
/**
* @param calendarStart start time of range, in milliseconds. {@code -1} means to leave the start time unconstrained.
*/
private static boolean folderSync(Element response, OperationContext octxt, ItemIdFormatter ifmt, Mailbox mbox, Folder folder, Set<Folder> visible, long calendarStart, long messageSyncStart, SyncPhase phase) throws ServiceException {
if (folder == null)
return false;
if (visible != null && visible.isEmpty())
return false;
boolean isVisible = visible == null || visible.remove(folder);
// short-circuit if we know that this won't be in the output
List<Folder> subfolders = folder.getSubfolders(null);
if (!isVisible && subfolders.isEmpty())
return false;
// write this folder's data to the response
boolean initial = phase == SyncPhase.INITIAL;
Element f = ToXML.encodeFolder(response, ifmt, octxt, folder, Change.ALL_FIELDS);
if (initial && isVisible && folder.getType() == MailItem.Type.FOLDER) {
// we're in the middle of an initial sync, so serialize the item ids
if (folder.getId() == Mailbox.ID_FOLDER_TAGS) {
initialTagSync(f, octxt, ifmt, mbox);
} else {
TypedIdList idlist = mbox.getItemIds(octxt, folder.getId());
initialMsgSync(f, idlist, octxt, mbox, folder, messageSyncStart);
initialItemSync(f, MailConstants.E_CHAT, idlist.getIds(MailItem.Type.CHAT));
initialItemSync(f, MailConstants.E_CONTACT, idlist.getIds(MailItem.Type.CONTACT));
initialItemSync(f, MailConstants.E_NOTE, idlist.getIds(MailItem.Type.NOTE));
initialCalendarSync(f, idlist, octxt, mbox, folder, calendarStart);
initialItemSync(f, MailConstants.E_DOC, idlist.getIds(MailItem.Type.DOCUMENT));
initialItemSync(f, MailConstants.E_WIKIWORD, idlist.getIds(MailItem.Type.WIKI));
initialCovSync(f, idlist, octxt, mbox, folder, messageSyncStart);
}
}
if (isVisible && visible != null && visible.isEmpty())
return true;
// write the subfolders' data to the response
for (Folder subfolder : subfolders) {
if (subfolder != null) {
isVisible |= folderSync(f, octxt, ifmt, mbox, subfolder, visible, calendarStart, messageSyncStart, phase);
}
}
// if this folder and all its subfolders are not visible (oops!), remove them from the response
if (!isVisible) {
f.detach();
}
return isVisible;
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class PagedDeleteTest method testRemoveBeforeCutoff.
@Test
public void testRemoveBeforeCutoff() {
TypedIdList tombstone = new TypedIdList();
tombstone.add(Type.MESSAGE, 3, "", 100);
tombstone.add(Type.MESSAGE, 4, "", 101);
tombstone.add(Type.APPOINTMENT, 1, "", 101);
tombstone.add(Type.APPOINTMENT, 5, "", 100);
tombstone.add(Type.APPOINTMENT, 9, "", 103);
tombstone.add(Type.MESSAGE, 2, "", 99);
tombstone.add(Type.MESSAGE, 22, "", 105);
tombstone.add(Type.MESSAGE, 24, "", 103);
PagedDelete pgDelete = new PagedDelete(tombstone, true);
pgDelete.removeBeforeCutoff(4, 101);
Collection<Integer> ids = pgDelete.getAllIds();
Assert.assertEquals(4, ids.size());
pgDelete.trimDeletesTillPageLimit(3);
ids = pgDelete.getAllIds();
Assert.assertEquals(3, ids.size());
Assert.assertTrue(ids.contains(4));
Assert.assertTrue(ids.contains(9));
Assert.assertTrue(ids.contains(24));
Assert.assertTrue(pgDelete.isDeleteOverFlow());
Assert.assertEquals(pgDelete.getCutOffModsequnce(), 105);
Assert.assertEquals(pgDelete.getLastItemId(), 22);
Multimap<Type, Integer> ids2Type = pgDelete.getTypedItemIds();
Assert.assertEquals(3, ids2Type.size());
Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 4));
Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 9));
Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 24));
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class PagedDeleteTest method testTrimDeletesTillPageLimit.
@Test
public void testTrimDeletesTillPageLimit() {
TypedIdList tombstone = new TypedIdList();
tombstone.add(Type.MESSAGE, 3, "", 100);
tombstone.add(Type.MESSAGE, 4, "", 101);
tombstone.add(Type.MESSAGE, 1, "", 101);
tombstone.add(Type.MESSAGE, 5, "", 100);
tombstone.add(Type.MESSAGE, 9, "", 103);
PagedDelete pgDelete = new PagedDelete(tombstone, false);
pgDelete.trimDeletesTillPageLimit(3);
Collection<Integer> ids = pgDelete.getAllIds();
Assert.assertEquals(3, ids.size());
Assert.assertTrue(ids.contains(3));
Assert.assertTrue(ids.contains(5));
Assert.assertTrue(ids.contains(1));
Assert.assertTrue(pgDelete.isDeleteOverFlow());
Assert.assertTrue(pgDelete.getCutOffModsequnce() == 101);
Assert.assertTrue(pgDelete.getLastItemId() == 4);
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class PagedDeleteTest method testTypedDeletesTillPageLimit.
@Test
public void testTypedDeletesTillPageLimit() {
TypedIdList tombstone = new TypedIdList();
tombstone.add(Type.MESSAGE, 3, "", 100);
tombstone.add(Type.MESSAGE, 4, "", 101);
tombstone.add(Type.APPOINTMENT, 1, "", 101);
tombstone.add(Type.APPOINTMENT, 5, "", 100);
tombstone.add(Type.MESSAGE, 9, "", 103);
PagedDelete pgDelete = new PagedDelete(tombstone, true);
pgDelete.trimDeletesTillPageLimit(3);
Collection<Integer> ids = pgDelete.getAllIds();
Assert.assertEquals(3, ids.size());
Assert.assertTrue(ids.contains(3));
Assert.assertTrue(ids.contains(5));
Assert.assertTrue(ids.contains(1));
Assert.assertTrue(pgDelete.isDeleteOverFlow());
Assert.assertTrue(pgDelete.getCutOffModsequnce() == 101);
Assert.assertTrue(pgDelete.getLastItemId() == 4);
Multimap<Type, Integer> ids2Type = pgDelete.getTypedItemIds();
Assert.assertEquals(3, ids2Type.size());
Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 3));
Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 5));
Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 1));
}
Aggregations