SenderList recalculateMetadata(List<Message> msgs) throws ServiceException { Collections.sort(msgs, new Message.SortDateAscending()); markItemModified(RECALCULATE_CHANGE_MASK); mEncodedSenders = null; mSenderList = new SenderList(msgs); mData.size = msgs.size(); mData.tags = mData.flags = mData.unreadCount = 0; mExtendedData = null; for (Message msg : msgs) { // unread count is updated via MailItem.addChild() for some reason... super.addChild(msg); mData.unreadCount += (msg.isUnread() ? 1 : 0); mData.flags |= msg.getInternalFlagBitmask(); mData.tags |= msg.getTagBitmask(); mExtendedData = MetadataCallback.duringConversationAdd(mExtendedData, msg); } // need to rewrite the overview metadata ZimbraLog.mailbox.debug( "resetting metadata: cid=" + mId + ", size was=" + mData.size + " is=" + mSenderList.size()); saveData(null); return mSenderList; }
/** please call this *after* adding the child row to the DB */ @Override void addChild(MailItem child) throws ServiceException { if (!(child instanceof Message)) throw MailServiceException.CANNOT_PARENT(); Message msg = (Message) child; super.addChild(msg); // update inherited flags int oldFlags = mData.flags; mData.flags |= msg.getInternalFlagBitmask(); if (mData.flags != oldFlags) markItemModified(Change.MODIFIED_FLAGS); // update inherited tags long oldTags = mData.tags; mData.tags |= msg.getTagBitmask(); if (mData.tags != oldTags) markItemModified(Change.MODIFIED_TAGS); // update unread counts if (msg.isUnread()) { markItemModified(Change.MODIFIED_UNREAD); updateUnread( child.mData.unreadCount, child.isTagged(Flag.ID_FLAG_DELETED) ? child.mData.unreadCount : 0); } markItemModified(Change.MODIFIED_SIZE | Change.MODIFIED_SENDERS | Change.MODIFIED_METADATA); MetadataCallback.duringConversationAdd(mExtendedData, msg); // FIXME: this ordering is to work around the fact that when getSenderList has to // recalc the metadata, it uses the already-updated DB message state to do it... mData.date = mMailbox.getOperationTimestamp(); mData.contentChanged(mMailbox); if (!mMailbox.hasListeners(Session.Type.SOAP)) { instantiateSenderList(); mData.size++; try { if (mSenderList != null) mSenderList.add(msg); } catch (SenderList.RefreshException slre) { mSenderList = null; } saveMetadata(); } else { boolean recalculated = loadSenderList(); if (!recalculated) { mData.size++; try { mSenderList.add(msg); saveMetadata(); } catch (SenderList.RefreshException slre) { recalculateMetadata(); } } } }
protected void inheritedCustomDataChanged(Message msg, CustomMetadata custom) throws ServiceException { if (custom == null) return; markItemModified(Change.MODIFIED_METADATA); if (!custom.isEmpty()) { mExtendedData = MetadataCallback.duringConversationAdd(mExtendedData, msg); saveMetadata(); } else { recalculateMetadata(); } }
static Conversation create(Mailbox mbox, int id, Message[] msgs) throws ServiceException { if (ZimbraLog.mailop.isDebugEnabled()) { StringBuilder msgIds = new StringBuilder(); for (int i = 0; i < msgs.length; i++) msgIds.append(i > 0 ? "," : "").append(msgs[i].getId()); ZimbraLog.mailop.debug("Adding Conversation: id=%d, message(s): %s.", id, msgIds); } assert (id != Mailbox.ID_AUTO_INCREMENT && msgs.length > 0); Arrays.sort(msgs, new Message.SortDateAscending()); int date = 0, unread = 0, flags = 0; long tags = 0; CustomMetadataList extended = null; for (int i = 0; i < msgs.length; i++) { Message msg = msgs[i]; if (msg == null) throw ServiceException.FAILURE("null Message in list", null); date = Math.max(date, msg.mData.date); unread += msg.mData.unreadCount; flags |= msg.mData.flags; tags |= msg.mData.tags; extended = MetadataCallback.duringConversationAdd(extended, msg); } UnderlyingData data = new UnderlyingData(); data.id = id; data.type = TYPE_CONVERSATION; data.folderId = Mailbox.ID_FOLDER_CONVERSATIONS; data.subject = msgs.length > 0 ? DbMailItem.truncateSubjectToMaxAllowedLength(msgs[0].getSubject()) : ""; data.date = date; data.size = msgs.length; data.unreadCount = unread; data.flags = flags; data.tags = tags; data.metadata = encodeMetadata(DEFAULT_COLOR_RGB, 1, extended, new SenderList(msgs)); data.contentChanged(mbox); DbMailItem.create(mbox, data, null); Conversation conv = new Conversation(mbox, data); conv.finishCreation(null); DbMailItem.setParent(msgs, conv); for (int i = 0; i < msgs.length; i++) { mbox.markItemModified(msgs[i], Change.MODIFIED_PARENT); msgs[i].mData.parentId = id; msgs[i].mData.metadataChanged(mbox); } return conv; }