/** 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(); } } } }
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; }
void instantiateSenderList() { if (mSenderList != null && mSenderList.size() == mData.size) return; mSenderList = null; // first, attempt to decode the existing sender list (if there is one) if (mEncodedSenders != null) { String encoded = mEncodedSenders; mEncodedSenders = null; try { // if the first message has been removed, this should throw // an exception and force the list to be recalculated mSenderList = SenderList.parse(encoded); if (mSenderList.size() != mData.size) mSenderList = null; } catch (Exception e) { } } }
static String encodeMetadata( Color color, int version, CustomMetadataList extended, SenderList senders) { return encodeMetadata(new Metadata(), color, version, extended, senders.toString()).toString(); }
@Override Metadata encodeMetadata(Metadata meta) { String encoded = mEncodedSenders; if (encoded == null && mSenderList != null) encoded = mSenderList.toString(); return encodeMetadata(meta, mRGBColor, mVersion, mExtendedData, encoded); }