Search in sources :

Example 11 with CalendarItem

use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.

the class CalSummaryCache method notifyCommittedChanges.

void notifyCommittedChanges(PendingLocalModifications mods, int changeId) {
    if (mods.created != null) {
        for (Map.Entry<ModificationKey, BaseItemInfo> entry : mods.created.entrySet()) {
            BaseItemInfo item = entry.getValue();
            if (item instanceof CalendarItem) {
                CalendarItem calItem = (CalendarItem) item;
                int folderId = calItem.getFolderId();
                invalidateItem(calItem.getMailbox(), folderId, calItem.getId());
            }
        }
    }
    if (mods.modified != null) {
        for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
            Change change = entry.getValue();
            Object whatChanged = change.what;
            if (whatChanged instanceof CalendarItem) {
                CalendarItem item = (CalendarItem) whatChanged;
                Mailbox mbox = item.getMailbox();
                int folderId = item.getFolderId();
                int itemId = item.getId();
                invalidateItem(mbox, folderId, itemId);
                // If this is a folder move, invalidate the item from the old folder too.
                if ((change.why & Change.FOLDER) != 0) {
                    String accountId = mbox.getAccountId();
                    int prevFolderId;
                    synchronized (mSummaryCache) {
                        prevFolderId = mSummaryCache.getFolderForItem(accountId, itemId);
                    }
                    if (prevFolderId != folderId && prevFolderId != SummaryLRU.FOLDER_NOT_FOUND) {
                        invalidateItem(mbox, prevFolderId, itemId);
                    }
                }
            }
        }
    }
    if (mods.deleted != null) {
        String lastAcctId = null;
        Mailbox lastMbox = null;
        for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
            MailItem.Type type = (MailItem.Type) entry.getValue().what;
            if (type == MailItem.Type.APPOINTMENT || type == MailItem.Type.TASK) {
                // We only have item id.  Look up the folder id of the item in the cache.
                Mailbox mbox = null;
                String acctId = entry.getKey().getAccountId();
                // just to be safe
                if (acctId == null)
                    continue;
                if (acctId.equals(lastAcctId)) {
                    // Deletion by id list usually happens because of a folder getting emptied.
                    // It's highly likely the items all belong to the same mailbox, let alone folder.
                    mbox = lastMbox;
                } else {
                    try {
                        mbox = MailboxManager.getInstance().getMailboxByAccountId(acctId, FetchMode.DO_NOT_AUTOCREATE);
                    } catch (ServiceException e) {
                        ZimbraLog.calendar.error("Error looking up the mailbox of account in delete notification: account=" + acctId, e);
                        continue;
                    }
                }
                if (mbox != null) {
                    lastAcctId = acctId;
                    lastMbox = mbox;
                    int itemId = entry.getKey().getItemId();
                    String accountId = mbox.getAccountId();
                    int folderId;
                    synchronized (mSummaryCache) {
                        folderId = mSummaryCache.getFolderForItem(accountId, itemId);
                    }
                    if (folderId != SummaryLRU.FOLDER_NOT_FOUND) {
                        invalidateItem(mbox, folderId, itemId);
                    }
                }
            }
        }
    }
    if (MemcachedConnector.isConnected()) {
        mMemcachedCache.notifyCommittedChanges(mods, changeId);
    }
}
Also used : BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) ModificationKey(com.zimbra.cs.session.PendingModifications.ModificationKey) Change(com.zimbra.cs.session.PendingModifications.Change) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 12 with CalendarItem

use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.

the class ModifyInvitePartStat method redo.

@Override
public void redo() throws Exception {
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(getMailboxId());
    CalendarItem calItem = mbox.getCalendarItemById(null, mCalItemId);
    RecurId recurId = null;
    if (mRecurIdDt != null)
        recurId = new RecurId(ParsedDateTime.parse(mRecurIdDt, calItem.getTimeZoneMap()), mRecurIdRange);
    mbox.modifyPartStat(getOperationContext(), mCalItemId, recurId, mCnStr, mAddressStr, mCUTypeStr, mRoleStr, mPartStatStr, mRsvp, mSeqNo, mDtStamp);
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) RecurId(com.zimbra.cs.mailbox.calendar.RecurId)

Example 13 with CalendarItem

use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.

the class ArchiveFormatter method addItem.

private void addItem(UserServletContext context, Folder fldr, Map<Object, Folder> fmap, FolderDigestInfo digestInfo, Map<Integer, Integer> idMap, int[] ids, Set<MailItem.Type> types, Resolve r, ItemData id, ArchiveInputStream ais, ArchiveInputEntry aie, List<ServiceException> errs) throws ServiceException {
    try {
        Mailbox mbox = fldr.getMailbox();
        MailItem mi = MailItem.constructItem(mbox, id.ud);
        MailItem newItem = null, oldItem = null;
        OperationContext octxt = context.opContext;
        String path;
        ParsedMessage pm;
        boolean root = fldr.getId() == Mailbox.ID_FOLDER_ROOT || fldr.getId() == Mailbox.ID_FOLDER_USER_ROOT || id.path.startsWith(fldr.getPath() + '/');
        if ((ids != null && Arrays.binarySearch(ids, id.ud.id) < 0) || (types != null && !types.contains(MailItem.Type.of(id.ud.type))))
            return;
        if (id.ud.getBlobDigest() != null && aie == null) {
            addError(errs, FormatterServiceException.MISSING_BLOB(id.path));
            return;
        }
        if (root) {
            path = id.path;
        } else {
            path = fldr.getPath() + id.path;
        }
        if (path.endsWith("/") && !path.equals("/")) {
            path = path.substring(0, path.length() - 1);
        }
        if (mbox.isImmutableSystemFolder(id.ud.folderId))
            return;
        switch(mi.getType()) {
            case APPOINTMENT:
            case TASK:
                CalendarItem ci = (CalendarItem) mi;
                fldr = createPath(context, fmap, path, ci.getType() == MailItem.Type.APPOINTMENT ? MailItem.Type.APPOINTMENT : MailItem.Type.TASK);
                if (!root || r != Resolve.Reset) {
                    CalendarItem oldCI = null;
                    try {
                        oldCI = mbox.getCalendarItemByUid(octxt, ci.getUid());
                    } catch (Exception e) {
                    }
                    if (oldCI != null && r == Resolve.Replace) {
                        mbox.delete(octxt, oldCI.getId(), oldCI.getType());
                    } else {
                        oldItem = oldCI;
                    }
                }
                if (oldItem == null || r != Resolve.Skip) {
                    CalendarItem.AlarmData ad = ci.getAlarmData();
                    byte[] data = readArchiveEntry(ais, aie);
                    Map<Integer, MimeMessage> blobMimeMsgMap = data == null ? null : CalendarItem.decomposeBlob(data);
                    SetCalendarItemData defScid = new SetCalendarItemData();
                    SetCalendarItemData[] exceptionScids = null;
                    Invite[] invs = ci.getInvites();
                    MimeMessage mm;
                    if (invs != null && invs.length > 0) {
                        defScid.invite = invs[0];
                        if (blobMimeMsgMap != null && (mm = blobMimeMsgMap.get(defScid.invite.getMailItemId())) != null) {
                            defScid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
                        }
                        if (invs.length > 1) {
                            exceptionScids = new SetCalendarItemData[invs.length - 1];
                            for (int i = 1; i < invs.length; i++) {
                                SetCalendarItemData scid = new SetCalendarItemData();
                                scid.invite = invs[i];
                                if (blobMimeMsgMap != null && (mm = blobMimeMsgMap.get(defScid.invite.getMailItemId())) != null) {
                                    scid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
                                }
                                exceptionScids[i - 1] = scid;
                            }
                        }
                        newItem = mbox.setCalendarItem(octxt, oldItem != null && r == Resolve.Modify ? oldItem.getFolderId() : fldr.getId(), ci.getFlagBitmask(), ci.getTags(), defScid, exceptionScids, ci.getAllReplies(), ad == null ? CalendarItem.NEXT_ALARM_KEEP_CURRENT : ad.getNextAt());
                    }
                }
                break;
            case CHAT:
                Chat chat = (Chat) mi;
                byte[] content = readArchiveEntry(ais, aie);
                pm = new ParsedMessage(content, mi.getDate(), mbox.attachmentsIndexingEnabled());
                fldr = createPath(context, fmap, path, MailItem.Type.CHAT);
                if (root && r != Resolve.Reset) {
                    Chat oldChat = null;
                    try {
                        oldChat = mbox.getChatById(octxt, chat.getId());
                        if (oldChat.getFolderId() != fldr.getId()) {
                            oldChat = null;
                        }
                    } catch (Exception e) {
                    }
                    if (oldChat != null && chat.getSender().equals(oldChat.getSender()) && chat.getSubject().equals(oldChat.getSubject())) {
                        if (r == Resolve.Replace) {
                            mbox.delete(octxt, oldChat.getId(), oldChat.getType());
                        } else {
                            oldItem = oldChat;
                            if (r == Resolve.Modify)
                                newItem = mbox.updateChat(octxt, pm, oldItem.getId());
                        }
                    }
                }
                if (oldItem == null)
                    newItem = mbox.createChat(octxt, pm, fldr.getId(), chat.getFlagBitmask(), chat.getTags());
                break;
            case CONVERSATION:
                Conversation cv = (Conversation) mi;
                if (r != Resolve.Reset && r != Resolve.Skip) {
                    try {
                        oldItem = mbox.getConversationByHash(octxt, Mailbox.getHash(cv.getSubject()));
                    } catch (Exception e) {
                    }
                }
                break;
            case CONTACT:
                Contact ct = (Contact) mi;
                fldr = createPath(context, fmap, path, Folder.Type.CONTACT);
                if (root && r != Resolve.Reset) {
                    Contact oldContact = null;
                    oldContact = findContact(octxt, mbox, ct, fldr);
                    if (oldContact != null) {
                        String email = string(ct.get(ContactConstants.A_email));
                        String first = string(ct.get(ContactConstants.A_firstName));
                        String name = string(ct.get(ContactConstants.A_fullName));
                        String oldemail = string(oldContact.get(ContactConstants.A_email));
                        String oldfirst = string(oldContact.get(ContactConstants.A_firstName));
                        String oldname = string(oldContact.get(ContactConstants.A_fullName));
                        if (email.equals(oldemail) && first.equals(oldfirst) && name.equals(oldname)) {
                            if (r == Resolve.Replace) {
                                mbox.delete(octxt, oldContact.getId(), oldContact.getType());
                            } else {
                                oldItem = oldContact;
                                if (r == Resolve.Modify) {
                                    mbox.modifyContact(octxt, oldItem.getId(), new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)));
                                }
                            }
                        }
                    }
                }
                if (oldItem == null) {
                    newItem = mbox.createContact(octxt, new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)), fldr.getId(), ct.getTags());
                }
                break;
            case DOCUMENT:
            case WIKI:
                Document doc = (Document) mi;
                Document oldDoc = null;
                Integer oldId = idMap.get(mi.getId());
                fldr = createParent(context, fmap, path, doc.getType() == MailItem.Type.DOCUMENT ? MailItem.Type.DOCUMENT : MailItem.Type.WIKI);
                if (oldId == null) {
                    try {
                        for (Document listDoc : mbox.getDocumentList(octxt, fldr.getId())) {
                            if (doc.getName().equals(listDoc.getName())) {
                                oldDoc = listDoc;
                                idMap.put(doc.getId(), oldDoc.getId());
                                break;
                            }
                        }
                    } catch (Exception e) {
                    }
                } else {
                    oldDoc = mbox.getDocumentById(octxt, oldId);
                }
                if (oldDoc != null) {
                    if (r == Resolve.Replace && oldId == null) {
                        mbox.delete(octxt, oldDoc.getId(), oldDoc.getType());
                    } else if (doc.getVersion() < oldDoc.getVersion()) {
                        return;
                    } else {
                        oldItem = oldDoc;
                        if (doc.getVersion() > oldDoc.getVersion()) {
                            newItem = mbox.addDocumentRevision(octxt, oldDoc.getId(), doc.getCreator(), doc.getName(), doc.getDescription(), doc.isDescriptionEnabled(), ais.getInputStream());
                        }
                        if (r != Resolve.Skip) {
                            mbox.setDate(octxt, oldDoc.getId(), doc.getType(), doc.getDate());
                        }
                    }
                }
                if (oldItem == null) {
                    if (mi.getType() == MailItem.Type.DOCUMENT) {
                        newItem = mbox.createDocument(octxt, fldr.getId(), doc.getName(), doc.getContentType(), doc.getCreator(), doc.getDescription(), ais.getInputStream());
                    } else {
                        WikiItem wi = (WikiItem) mi;
                        newItem = mbox.createWiki(octxt, fldr.getId(), wi.getWikiWord(), wi.getCreator(), wi.getDescription(), ais.getInputStream());
                    }
                    mbox.setDate(octxt, newItem.getId(), doc.getType(), doc.getDate());
                    idMap.put(doc.getId(), newItem.getId());
                }
                break;
            case FLAG:
                return;
            case FOLDER:
                String aclParam = context.params.get("acl");
                boolean doACL = aclParam == null || !aclParam.equals("0");
                Folder f = (Folder) mi;
                ACL acl = f.getACL();
                Folder oldF = null;
                MailItem.Type view = f.getDefaultView();
                if (view == MailItem.Type.CONVERSATION || view == MailItem.Type.FLAG || view == MailItem.Type.TAG)
                    break;
                try {
                    oldF = mbox.getFolderByPath(octxt, path);
                } catch (Exception e) {
                }
                if (oldF != null) {
                    oldItem = oldF;
                    if (r != Resolve.Skip) {
                        if (!f.getUrl().equals(oldF.getUrl())) {
                            mbox.setFolderUrl(octxt, oldF.getId(), f.getUrl());
                        }
                        if (doACL) {
                            ACL oldACL = oldF.getACL();
                            if ((acl == null && oldACL != null) || (acl != null && (oldACL == null || !acl.equals(oldACL)))) {
                                mbox.setPermissions(octxt, oldF.getId(), acl);
                            }
                        }
                    }
                }
                if (oldItem == null) {
                    fldr = createParent(context, fmap, path, Folder.Type.UNKNOWN);
                    Folder.FolderOptions fopt = new Folder.FolderOptions();
                    fopt.setDefaultView(f.getDefaultView()).setFlags(f.getFlagBitmask()).setColor(f.getColor()).setUrl(f.getUrl());
                    newItem = fldr = mbox.createFolder(octxt, f.getName(), fldr.getId(), fopt);
                    if (doACL && acl != null) {
                        mbox.setPermissions(octxt, fldr.getId(), acl);
                    }
                    fmap.put(fldr.getId(), fldr);
                    fmap.put(fldr.getPath(), fldr);
                }
                break;
            case MESSAGE:
                Message msg = (Message) mi;
                Message oldMsg = null;
                fldr = createPath(context, fmap, path, Folder.Type.MESSAGE);
                if (root && r != Resolve.Reset) {
                    try {
                        oldMsg = mbox.getMessageById(octxt, msg.getId());
                        if (!msg.getDigest().equals(oldMsg.getDigest()) || oldMsg.getFolderId() != fldr.getId()) {
                            oldMsg = null;
                        }
                    } catch (Exception e) {
                    }
                }
                if (oldMsg == null) {
                    Integer digestId = digestInfo.getIdForDigest(fldr, mi.getDigest());
                    if (digestId != null) {
                        oldMsg = mbox.getMessageById(octxt, digestId);
                        if (!msg.getDigest().equals(oldMsg.getDigest())) {
                            oldMsg = null;
                        }
                    }
                }
                if (oldMsg != null) {
                    if (r == Resolve.Replace) {
                        ZimbraLog.misc.debug("Deleting old msg with id=%s as has same digest='%s'", oldMsg.getId(), mi.getDigest());
                        mbox.delete(octxt, oldMsg.getId(), oldMsg.getType());
                    } else {
                        oldItem = oldMsg;
                    }
                }
                if (oldItem != null) {
                    ZimbraLog.misc.debug("Message with id=%s has same digest='%s' - not re-adding", oldItem.getId(), mi.getDigest());
                } else {
                    DeliveryOptions opt = new DeliveryOptions().setFolderId(fldr.getId()).setNoICal(true).setFlags(msg.getFlagBitmask()).setTags(msg.getTags());
                    newItem = mbox.addMessage(octxt, ais.getInputStream(), (int) aie.getSize(), msg.getDate(), opt, null, id);
                }
                break;
            case MOUNTPOINT:
                Mountpoint mp = (Mountpoint) mi;
                MailItem oldMP = null;
                try {
                    oldMP = mbox.getItemByPath(octxt, path);
                    if (oldMP.getType() == mi.getType()) {
                        oldMP = null;
                    }
                } catch (Exception e) {
                }
                if (oldMP != null) {
                    if (r == Resolve.Modify || r == Resolve.Replace) {
                        mbox.delete(octxt, oldMP.getId(), oldMP.getType());
                    } else {
                        oldItem = oldMP;
                    }
                }
                if (oldItem == null) {
                    fldr = createParent(context, fmap, path, Folder.Type.UNKNOWN);
                    newItem = mbox.createMountpoint(context.opContext, fldr.getId(), mp.getName(), mp.getOwnerId(), mp.getRemoteId(), mp.getRemoteUuid(), mp.getDefaultView(), mp.getFlagBitmask(), mp.getColor(), mp.isReminderEnabled());
                }
                break;
            case NOTE:
                Note note = (Note) mi;
                Note oldNote = null;
                fldr = createPath(context, fmap, path, MailItem.Type.NOTE);
                try {
                    for (Note listNote : mbox.getNoteList(octxt, fldr.getId())) {
                        if (note.getSubject().equals(listNote.getSubject())) {
                            oldNote = listNote;
                            break;
                        }
                    }
                } catch (Exception e) {
                }
                if (oldNote != null) {
                    if (r == Resolve.Replace) {
                        mbox.delete(octxt, oldNote.getId(), oldNote.getType());
                    } else {
                        oldItem = oldNote;
                        if (r == Resolve.Modify) {
                            mbox.editNote(octxt, oldItem.getId(), new String(readArchiveEntry(ais, aie), UTF8));
                        }
                    }
                    break;
                }
                if (oldItem == null) {
                    newItem = mbox.createNote(octxt, new String(readArchiveEntry(ais, aie), UTF8), note.getBounds(), note.getColor(), fldr.getId());
                }
                break;
            case SEARCHFOLDER:
                SearchFolder sf = (SearchFolder) mi;
                MailItem oldSF = null;
                try {
                    oldSF = mbox.getItemByPath(octxt, path);
                    if (oldSF.getType() == mi.getType()) {
                        oldSF = null;
                    }
                } catch (Exception e) {
                }
                if (oldSF != null) {
                    if (r == Resolve.Modify) {
                        mbox.modifySearchFolder(octxt, oldSF.getId(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField());
                    } else if (r == Resolve.Replace) {
                        mbox.delete(octxt, oldSF.getId(), oldSF.getType());
                    } else {
                        oldItem = oldSF;
                    }
                }
                if (oldItem == null) {
                    fldr = createParent(context, fmap, path, MailItem.Type.UNKNOWN);
                    newItem = mbox.createSearchFolder(octxt, fldr.getId(), sf.getName(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField(), sf.getFlagBitmask(), sf.getColor());
                }
                break;
            case TAG:
                Tag tag = (Tag) mi;
                try {
                    Tag oldTag = mbox.getTagByName(octxt, tag.getName());
                    oldItem = oldTag;
                } catch (Exception e) {
                }
                if (oldItem == null) {
                    newItem = mbox.createTag(octxt, tag.getName(), tag.getColor());
                }
                break;
            case VIRTUAL_CONVERSATION:
                return;
        }
        if (newItem != null) {
            if (mi.getColor() != newItem.getColor()) {
                mbox.setColor(octxt, newItem.getId(), newItem.getType(), mi.getColor());
            }
            if (!id.flags.equals(newItem.getFlagString()) || !id.tagsEqual(newItem)) {
                mbox.setTags(octxt, newItem.getId(), newItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
            }
        } else if (oldItem != null && r == Resolve.Modify) {
            if (mi.getColor() != oldItem.getColor()) {
                mbox.setColor(octxt, oldItem.getId(), oldItem.getType(), mi.getColor());
            }
            if (!id.flags.equals(oldItem.getFlagString()) || !id.tagsEqual(oldItem)) {
                mbox.setTags(octxt, oldItem.getId(), oldItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
            }
        }
    } catch (MailServiceException e) {
        if (e.getCode() == MailServiceException.QUOTA_EXCEEDED) {
            throw e;
        } else if (r != Resolve.Skip || e.getCode() != MailServiceException.ALREADY_EXISTS) {
            addError(errs, e);
        }
    } catch (Exception e) {
        String path = id.path;
        // When importing items into, e.g. the Inbox, often path is just "/Inbox" which isn't that useful
        if ((aie != null) && !Strings.isNullOrEmpty(aie.getName())) {
            path = aie.getName();
        }
        addError(errs, FormatterServiceException.UNKNOWN_ERROR(path, e));
    }
}
Also used : MimeMessage(javax.mail.internet.MimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Message(com.zimbra.cs.mailbox.Message) Conversation(com.zimbra.cs.mailbox.Conversation) Document(com.zimbra.cs.mailbox.Document) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) SetCalendarItemData(com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) ParsedContact(com.zimbra.cs.mime.ParsedContact) Mailbox(com.zimbra.cs.mailbox.Mailbox) MimeMessage(javax.mail.internet.MimeMessage) Chat(com.zimbra.cs.mailbox.Chat) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DeliveryOptions(com.zimbra.cs.mailbox.DeliveryOptions) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) OperationContext(com.zimbra.cs.mailbox.OperationContext) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) ACL(com.zimbra.cs.mailbox.ACL) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ExportPeriodNotSpecifiedException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodNotSpecifiedException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ExportPeriodTooLongException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodTooLongException) UserServletException(com.zimbra.cs.service.UserServletException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) ParsedContact(com.zimbra.cs.mime.ParsedContact) Contact(com.zimbra.cs.mailbox.Contact) MailItem(com.zimbra.cs.mailbox.MailItem) WikiItem(com.zimbra.cs.mailbox.WikiItem) Note(com.zimbra.cs.mailbox.Note) Tag(com.zimbra.cs.mailbox.Tag) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 14 with CalendarItem

use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.

the class ArchiveFormatter method saveItem.

private ArchiveOutputStream saveItem(UserServletContext context, MailItem mi, Map<Integer, String> fldrs, Map<Integer, Integer> cnts, boolean version, ArchiveOutputStream aos, CharsetEncoder charsetEncoder, Set<String> names) throws ServiceException {
    String ext = null, name = null;
    String extra = null;
    Integer fid = mi.getFolderId();
    String fldr;
    InputStream is = null;
    String metaParam = context.params.get(UserServlet.QP_META);
    boolean meta = metaParam == null ? getDefaultMeta() : !metaParam.equals("0");
    if (!version && mi.isTagged(Flag.FlagInfo.VERSIONED)) {
        for (MailItem rev : context.targetMailbox.getAllRevisions(context.opContext, mi.getId(), mi.getType())) {
            if (mi.getVersion() != rev.getVersion())
                aos = saveItem(context, rev, fldrs, cnts, true, aos, charsetEncoder, names);
        }
    }
    switch(mi.getType()) {
        case APPOINTMENT:
            Appointment appt = (Appointment) mi;
            if (!appt.isPublic() && !appt.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
                return aos;
            }
            if (meta) {
                name = appt.getSubject();
                ext = "appt";
            } else {
                ext = "ics";
            }
            break;
        case CHAT:
            ext = "chat";
            break;
        case CONTACT:
            Contact ct = (Contact) mi;
            name = ct.getFileAsString();
            if (!meta) {
                ext = "vcf";
            }
            break;
        case FLAG:
            return aos;
        case FOLDER:
        case MOUNTPOINT:
        case SEARCHFOLDER:
            if (mi.getId() == Mailbox.ID_FOLDER_ROOT) {
                name = "ROOT";
            } else if (mi.getId() == Mailbox.ID_FOLDER_USER_ROOT) {
                name = "USER_ROOT";
            } else {
                name = mi.getName();
            }
            break;
        case MESSAGE:
            Message msg = (Message) mi;
            if (msg.hasCalendarItemInfos()) {
                Set<ItemId> calItems = Sets.newHashSet();
                for (Iterator<CalendarItemInfo> it = msg.getCalendarItemInfoIterator(); it.hasNext(); ) {
                    ItemId iid = it.next().getCalendarItemId();
                    if (iid != null) {
                        calItems.add(iid);
                    }
                }
                for (ItemId i : calItems) {
                    if (extra == null) {
                        extra = "calendar=" + i.toString();
                    } else {
                        extra += ',' + i.toString();
                    }
                }
            }
            ext = "eml";
            break;
        case NOTE:
            ext = "note";
            break;
        case TASK:
            Task task = (Task) mi;
            if (!task.isPublic() && !task.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
                return aos;
            }
            ext = "task";
            break;
        case VIRTUAL_CONVERSATION:
            return aos;
        case WIKI:
            ext = "wiki";
            break;
    }
    fldr = fldrs.get(fid);
    if (fldr == null) {
        Folder f = mi.getMailbox().getFolderById(context.opContext, fid);
        cnts.put(fid, 1);
        fldr = f.getPath();
        if (fldr.startsWith("/")) {
            fldr = fldr.substring(1);
        }
        fldr = sanitize(fldr, charsetEncoder);
        fldr = ILLEGAL_FOLDER_CHARS.matcher(fldr).replaceAll("_");
        fldrs.put(fid, fldr);
    } else if (!(mi instanceof Folder)) {
        final int BATCH = 500;
        int cnt = cnts.get(fid) + 1;
        cnts.put(fid, cnt);
        cnt /= BATCH;
        if (cnt > 0) {
            fldr = fldr + '!' + cnt;
        }
    }
    int targetBaseLength = 0;
    if (context.noHierarchy()) {
        // Parent hierarchy is not needed, so construct the folder names without parent hierarchy.
        // e.g> represent "inbox/subfolder/target" as "target".
        String targetPath = null;
        if (context.itemPath.endsWith("/")) {
            // inbox/subfolder/target/
            targetPath = context.itemPath.substring(0, context.itemPath.lastIndexOf("/"));
        } else {
            // inbox/subfolder/target
            targetPath = context.itemPath;
        }
        // "inbox/subfolder".length()
        targetBaseLength = targetPath.lastIndexOf('/');
        if (targetBaseLength >= fldr.length()) {
            // fldr is "inbox/subfolder"
            fldr = "";
        } else if (targetBaseLength > 0) {
            // fldr is "inbox/subfolder/target"
            fldr = fldr.substring(targetBaseLength + 1);
        }
    }
    try {
        ArchiveOutputEntry aoe;
        byte[] data = null;
        String path = mi instanceof Contact ? getEntryName(mi, fldr, name, ext, charsetEncoder, names) : getEntryName(mi, fldr, name, ext, charsetEncoder, !(mi instanceof Document));
        long miSize = mi.getSize();
        if (miSize == 0 && mi.getDigest() != null) {
            ZimbraLog.misc.debug("blob db size 0 for item %d", mi.getId());
            return aos;
        }
        try {
            is = mi.getContentStream();
        } catch (Exception e) {
            ZimbraLog.misc.error("missing blob for item %d: expected %d", mi.getId(), miSize);
            return aos;
        }
        if (aos == null) {
            aos = getOutputStream(context, charsetEncoder.charset().name());
        }
        if ((mi instanceof CalendarItem) && (context.getStartTime() != TIME_UNSPECIFIED || context.getEndTime() != TIME_UNSPECIFIED)) {
            Collection<Instance> instances = ((CalendarItem) mi).expandInstances(context.getStartTime(), context.getEndTime(), false);
            if (instances.isEmpty()) {
                return aos;
            }
        }
        aoe = aos.newOutputEntry(path + ".meta", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
        if (mi instanceof Message && (mi.getFlagBitmask() & Flag.ID_UNREAD) != 0) {
            aoe.setUnread();
        }
        if (meta) {
            ItemData itemData = new ItemData(mi, extra);
            if (context.noHierarchy()) {
                // itemData.path is of the form /Inbox/subfolder/target and after this step it becomes /target.
                if (targetBaseLength > 0 && ((targetBaseLength + 1) < itemData.path.length())) {
                    itemData.path = itemData.path.substring(targetBaseLength + 1);
                }
            }
            byte[] metaData = itemData.encode();
            aoe.setSize(metaData.length);
            aos.putNextEntry(aoe);
            aos.write(metaData);
            aos.closeEntry();
        } else if (mi instanceof CalendarItem) {
            Browser browser = HttpUtil.guessBrowser(context.req);
            List<CalendarItem> calItems = new ArrayList<CalendarItem>();
            boolean needAppleICalHacks = Browser.APPLE_ICAL.equals(browser);
            boolean useOutlookCompatMode = Browser.IE.equals(browser);
            OperationContext octxt = new OperationContext(context.getAuthAccount(), context.isUsingAdminPrivileges());
            StringWriter writer = new StringWriter();
            calItems.add((CalendarItem) mi);
            context.targetMailbox.writeICalendarForCalendarItems(writer, octxt, calItems, useOutlookCompatMode, true, needAppleICalHacks, true);
            data = writer.toString().getBytes(charsetEncoder.charset());
        } else if (mi instanceof Contact) {
            VCard vcf = VCard.formatContact((Contact) mi);
            data = vcf.getFormatted().getBytes(charsetEncoder.charset());
        } else if (mi instanceof Message) {
            if (context.hasPart()) {
                MimeMessage mm = ((Message) mi).getMimeMessage();
                Set<String> attachmentNames = new HashSet<String>();
                for (String part : context.getPart().split(",")) {
                    BufferStream bs;
                    MimePart mp = Mime.getMimePart(mm, part);
                    long sz;
                    if (mp == null) {
                        throw MailServiceException.NO_SUCH_PART(part);
                    }
                    name = Mime.getFilename(mp);
                    if (!Normalizer.isNormalized(name, Normalizer.Form.NFC)) {
                        name = Normalizer.normalize(name, Normalizer.Form.NFC);
                    }
                    ext = null;
                    sz = mp.getSize();
                    if (sz == -1) {
                        sz = miSize;
                    }
                    if (name == null) {
                        name = "attachment";
                    } else {
                        int dot = name.lastIndexOf('.');
                        if (dot != -1 && dot < name.length() - 1) {
                            ext = name.substring(dot + 1);
                            name = name.substring(0, dot);
                        }
                    }
                    bs = new BufferStream(sz, 1024 * 1024);
                    InputStream stream = mp.getInputStream();
                    try {
                        bs.readFrom(stream);
                    } finally {
                        // close the stream, it could be an instance of PipedInputStream.
                        ByteUtil.closeStream(stream);
                    }
                    aoe = aos.newOutputEntry(getEntryName(mi, "", name, ext, charsetEncoder, attachmentNames), mi.getType().toString(), mi.getType().toByte(), mi.getDate());
                    sz = bs.getSize();
                    aoe.setSize(sz);
                    aos.putNextEntry(aoe);
                    bs.copyTo(aos.getOutputStream());
                    bs.close();
                    aos.closeEntry();
                }
                return aos;
            }
        }
        aoe = aos.newOutputEntry(path, mi.getType().toString(), mi.getType().toByte(), mi.getDate());
        if (data != null) {
            aoe.setSize(data.length);
            aos.putNextEntry(aoe);
            aos.write(data);
            aos.closeEntry();
        } else if (is != null) {
            if (context.shouldReturnBody()) {
                byte[] buf = new byte[aos.getRecordSize() * 20];
                int in;
                long remain = miSize;
                aoe.setSize(miSize);
                aos.putNextEntry(aoe);
                while (remain > 0 && (in = is.read(buf)) >= 0) {
                    aos.write(buf, 0, remain < in ? (int) remain : in);
                    remain -= in;
                }
                if (remain != 0) {
                    ZimbraLog.misc.error("mismatched blob size for item %d: expected %d", mi.getId(), miSize);
                    if (remain > 0) {
                        Arrays.fill(buf, (byte) ' ');
                        while (remain > 0) {
                            aos.write(buf, 0, remain < buf.length ? (int) remain : buf.length);
                            remain -= buf.length;
                        }
                    }
                    aos.closeEntry();
                    aoe = aos.newOutputEntry(path + ".err", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
                    aoe.setSize(0);
                    aos.putNextEntry(aoe);
                }
            } else {
                // Read headers into memory to compute size
                byte[] headerData = HeadersOnlyInputStream.getHeaders(is);
                aoe.setSize(headerData.length);
                aos.putNextEntry(aoe);
                aos.write(headerData);
            }
            aos.closeEntry();
        }
    } catch (Exception e) {
        throw ServiceException.FAILURE("archive error", e);
    } finally {
        ByteUtil.closeStream(is);
    }
    return aos;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) Task(com.zimbra.cs.mailbox.Task) EnumSet(java.util.EnumSet) Set(java.util.Set) HashSet(java.util.HashSet) MimeMessage(javax.mail.internet.MimeMessage) ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Message(com.zimbra.cs.mailbox.Message) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) SearchFolder(com.zimbra.cs.mailbox.SearchFolder) Folder(com.zimbra.cs.mailbox.Folder) Document(com.zimbra.cs.mailbox.Document) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItemInfo(com.zimbra.cs.mailbox.Message.CalendarItemInfo) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) StringWriter(java.io.StringWriter) MimeMessage(javax.mail.internet.MimeMessage) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) OperationContext(com.zimbra.cs.mailbox.OperationContext) InputStream(java.io.InputStream) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ExportPeriodNotSpecifiedException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodNotSpecifiedException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ExportPeriodTooLongException(com.zimbra.cs.mailbox.MailServiceException.ExportPeriodTooLongException) UserServletException(com.zimbra.cs.service.UserServletException) ParsedContact(com.zimbra.cs.mime.ParsedContact) Contact(com.zimbra.cs.mailbox.Contact) BufferStream(com.zimbra.common.util.BufferStream) MailItem(com.zimbra.cs.mailbox.MailItem) MimePart(javax.mail.internet.MimePart) SetCalendarItemData(com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData) ItemData(com.zimbra.cs.service.util.ItemData) Browser(com.zimbra.common.util.HttpUtil.Browser)

Example 15 with CalendarItem

use of com.zimbra.cs.mailbox.CalendarItem in project zm-mailbox by Zimbra.

the class AtomFormatter method formatCallback.

@Override
public void formatCallback(UserServletContext context) throws IOException, ServiceException {
    Iterator<? extends MailItem> iterator = null;
    StringBuffer sb = new StringBuffer();
    Element.XMLElement feed = new Element.XMLElement("feed");
    int offset = context.getOffset();
    int limit = context.getLimit();
    try {
        iterator = getMailItems(context, context.getStartTime(), context.getEndTime(), limit - offset);
        context.resp.setCharacterEncoding("UTF-8");
        context.resp.setContentType("application/atom+xml");
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
        feed.addAttribute("xmlns", "http://www.w3.org/2005/Atom");
        feed.addElement("title").setText("Zimbra " + context.itemPath);
        feed.addElement("generator").setText("Zimbra Atom Feed Servlet");
        feed.addElement("id").setText(context.req.getRequestURL().toString());
        feed.addElement("updated").setText(DateUtil.toISO8601(new Date(context.targetMailbox.getLastChangeDate())));
        int curHit = 0;
        while (iterator.hasNext()) {
            MailItem itItem = iterator.next();
            curHit++;
            if (curHit > limit)
                break;
            if (curHit >= offset) {
                if (itItem instanceof CalendarItem) {
                    // Don't return private appointments/tasks if the requester is not the mailbox owner.
                    CalendarItem calItem = (CalendarItem) itItem;
                    if (calItem.isPublic() || calItem.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges())) {
                        addCalendarItem(calItem, feed, context);
                    }
                } else if (itItem instanceof Message) {
                    addMessage((Message) itItem, feed);
                }
            }
        }
    } finally {
        if (iterator instanceof QueryResultIterator)
            ((QueryResultIterator) iterator).finished();
    }
    sb.append(feed.toString());
    context.resp.getOutputStream().write(sb.toString().getBytes("UTF-8"));
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) Message(com.zimbra.cs.mailbox.Message) Element(com.zimbra.common.soap.Element) Date(java.util.Date)

Aggregations

CalendarItem (com.zimbra.cs.mailbox.CalendarItem)56 Mailbox (com.zimbra.cs.mailbox.Mailbox)36 Element (com.zimbra.common.soap.Element)27 OperationContext (com.zimbra.cs.mailbox.OperationContext)24 Invite (com.zimbra.cs.mailbox.calendar.Invite)23 ItemId (com.zimbra.cs.service.util.ItemId)22 Account (com.zimbra.cs.account.Account)19 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)17 ServiceException (com.zimbra.common.service.ServiceException)15 MailItem (com.zimbra.cs.mailbox.MailItem)14 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)13 Message (com.zimbra.cs.mailbox.Message)12 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)11 Folder (com.zimbra.cs.mailbox.Folder)9 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)9 Appointment (com.zimbra.cs.mailbox.Appointment)8 ArrayList (java.util.ArrayList)8 MimeMessage (javax.mail.internet.MimeMessage)8 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)7 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)5