use of com.zimbra.cs.mailbox.VirtualConversation in project zm-mailbox by Zimbra.
the class ItemAction method handleTrashOperation.
protected String handleTrashOperation(OperationContext octxt, Element request, Mailbox mbox, SoapProtocol responseProto, List<Integer> local, MailItem.Type type, TargetConstraint tcon) throws ServiceException {
String localResults;
// determine if any of the items should be moved to an IMAP trash folder
Map<String, LinkedList<Integer>> remoteTrashIds = new HashMap<String, LinkedList<Integer>>();
LinkedList<Integer> localTrashIds = new LinkedList<Integer>();
Map<String, String> msgToConvId = new HashMap<String, String>();
MailItem[] items = mbox.getItemById(octxt, local, MailItem.Type.UNKNOWN);
for (MailItem item : items) {
String dsId = null;
boolean doneDistributingTrash = false;
if (item instanceof Message) {
dsId = getDataSourceOfItem(octxt, mbox, item);
} else if (item instanceof VirtualConversation) {
VirtualConversation vConv = (VirtualConversation) item;
Message msg = mbox.getMessageById(octxt, vConv.getMessageId());
dsId = getDataSourceOfItem(octxt, mbox, msg);
} else if (item instanceof Conversation) {
Set<String> dsIds = new HashSet<String>();
boolean hasLocal = false;
List<Message> messages = mbox.getMessagesByConversation(octxt, item.getId());
for (Message msg : messages) {
String msgDsId = getDataSourceOfItem(octxt, mbox, msg);
if (msgDsId == null) {
hasLocal = true;
} else {
dsIds.add(msgDsId);
}
}
// If it spans multiple accounts, delete it message-by-message
if (dsIds.isEmpty() && hasLocal) {
dsId = null;
} else if (!hasLocal && dsIds.size() == 1) {
dsId = dsIds.iterator().next();
} else {
type = MailItem.Type.MESSAGE;
for (Message msg : messages) {
String msgDsId = getDataSourceOfItem(octxt, mbox, msg);
msgToConvId.put(String.valueOf(msg.getId()), String.valueOf(item.getId()));
if (msgDsId == null) {
localTrashIds.add(msg.getId());
} else {
LinkedList<Integer> idsInDs = remoteTrashIds.get(dsId);
if (idsInDs == null) {
idsInDs = new LinkedList<Integer>();
remoteTrashIds.put(msgDsId, idsInDs);
}
idsInDs.add(msg.getId());
}
}
doneDistributingTrash = true;
}
}
if (!doneDistributingTrash) {
if (dsId != null) {
LinkedList<Integer> idsInDs = remoteTrashIds.get(dsId);
if (idsInDs == null) {
idsInDs = new LinkedList<Integer>();
remoteTrashIds.put(dsId, idsInDs);
}
idsInDs.add(item.getId());
} else {
localTrashIds.add(item.getId());
}
}
}
// move non-IMAP items to local trash
ItemId iidTrash = new ItemId(mbox, Mailbox.ID_FOLDER_TRASH);
List<String> trashResults = new LinkedList<String>();
String localTrashResults = ItemActionHelper.MOVE(octxt, mbox, responseProto, localTrashIds, type, tcon, iidTrash).getResult();
if (!Strings.isNullOrEmpty(localTrashResults)) {
trashResults.add(localTrashResults);
}
for (String dataSourceId : remoteTrashIds.keySet()) {
List<Integer> imapTrashIds = remoteTrashIds.get(dataSourceId);
Integer imapTrashId = getImapTrashFolder(mbox, dataSourceId);
if (null == imapTrashId) {
// e.g. for non-IMAP data sources like RSS feeds
imapTrashId = Mailbox.ID_FOLDER_TRASH;
}
ItemId iidImapTrash = new ItemId(mbox, imapTrashId);
String imapTrashResults = ItemActionHelper.MOVE(octxt, mbox, responseProto, imapTrashIds, type, tcon, iidImapTrash).getResult();
if (!Strings.isNullOrEmpty(imapTrashResults)) {
trashResults.add(imapTrashResults);
}
}
localResults = Joiner.on(",").join(trashResults);
if (!msgToConvId.isEmpty()) {
String[] ids = localResults.split(",");
Set<String> reconstructedConvIds = new HashSet<String>();
for (String id : ids) {
String convId = msgToConvId.get(id);
if (convId != null) {
reconstructedConvIds.add(convId);
} else {
reconstructedConvIds.add(id);
}
}
localResults = Joiner.on(",").join(reconstructedConvIds);
}
return localResults;
}
Aggregations