Search in sources :

Example 6 with MailItem

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

the class UrlNamespace method getMailItemResource.

/**
     *
     * @param ctxt
     * @param user
     * @param path - May contain parameters
     * @return
     */
private static DavResource getMailItemResource(DavContext ctxt, String user, String path) throws ServiceException, DavException {
    Provisioning prov = Provisioning.getInstance();
    Account account = prov.get(AccountBy.name, user);
    if (account == null) {
        // Anti-account name harvesting.
        ZimbraLog.dav.info("Failing GET of mail item resource - no such account '%s' path '%s'", user, path);
        throw new DavException("Request denied", HttpServletResponse.SC_NOT_FOUND, null);
    }
    if (ctxt.getUser().compareTo(user) != 0 || !Provisioning.onLocalServer(account)) {
        try {
            return new RemoteCollection(ctxt, path, account);
        } catch (MailServiceException.NoSuchItemException e) {
            return null;
        }
    }
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
    int id = 0;
    int index = path.indexOf('?');
    if (index > 0) {
        Map<String, String> params = HttpUtil.getURIParams(path.substring(index + 1));
        path = path.substring(0, index);
        if (params.containsKey("id")) {
            try {
                id = Integer.parseInt(params.get("id"));
            } catch (NumberFormatException e) {
            }
        }
    }
    // At this point, path will have had any parameters stripped from it
    OperationContext octxt = ctxt.getOperationContext();
    MailItem item = null;
    // simple case.  root folder or if id is specified.
    if (path.equals("/")) {
        item = mbox.getFolderByPath(octxt, "/");
    } else if (id > 0) {
        item = mbox.getItemById(octxt, id, MailItem.Type.UNKNOWN);
    }
    if (item != null) {
        return getResourceFromMailItem(ctxt, item);
    }
    // check for named items (folders, documents)
    try {
        return getResourceFromMailItem(ctxt, mbox.getItemByPath(octxt, path));
    } catch (MailServiceException.NoSuchItemException e) {
    }
    // check if the this is renamed folder.
    DavResource rs = checkRenamedResource(user, path);
    if (rs != null)
        return rs;
    // look up the item from path
    if (path.endsWith("/")) {
        path = path.substring(0, path.length() - 1);
    }
    index = path.lastIndexOf('/');
    String folderPath = path.substring(0, index);
    String baseName = path.substring(index + 1);
    Folder f = null;
    if (index != -1) {
        try {
            f = mbox.getFolderByPath(octxt, folderPath);
        } catch (MailServiceException.NoSuchItemException e) {
        }
    }
    if (f != null) {
        /* First check whether the default name has been over-ridden - perhaps because the name was
             * chosen by a DAV client via PUT to a URL when creating the item. */
        DavNames.DavName davName = null;
        if (DebugConfig.enableDAVclientCanChooseResourceBaseName) {
            davName = DavNames.DavName.create(mbox.getId(), f.getId(), baseName);
        }
        if (davName != null) {
            Integer itemId = DavNames.get(davName);
            if (itemId != null) {
                item = mbox.getItemById(octxt, itemId, MailItem.Type.UNKNOWN);
                if ((item != null) && (f.getId() == item.getFolderId())) {
                    return getResourceFromMailItem(ctxt, item);
                }
                item = null;
            }
        }
        if (baseName.toLowerCase().endsWith(CalendarObject.CAL_EXTENSION)) {
            String uid = baseName.substring(0, baseName.length() - CalendarObject.CAL_EXTENSION.length());
            // Unescape the name (It was encoded in DavContext intentionally)
            uid = HttpUtil.urlUnescape(uid);
            index = uid.indexOf(',');
            if (index > 0) {
                try {
                    id = Integer.parseInt(uid.substring(index + 1));
                } catch (NumberFormatException e) {
                }
            }
            if (id > 0) {
                item = mbox.getItemById(octxt, id, MailItem.Type.UNKNOWN);
            } else {
                item = mbox.getCalendarItemByUid(octxt, uid);
            }
            if ((item != null) && (f.getId() != item.getFolderId())) {
                item = null;
            }
        } else if (baseName.toLowerCase().endsWith(AddressObject.VCARD_EXTENSION)) {
            rs = AddressObject.getAddressObjectByUID(ctxt, baseName, account, f);
            if (rs != null) {
                return rs;
            }
        } else if (f.getId() == Mailbox.ID_FOLDER_INBOX || f.getId() == Mailbox.ID_FOLDER_SENT) {
            ctxt.setActingAsDelegateFor(baseName);
            // delegated scheduling and notification handling
            return getResourceFromMailItem(ctxt, f);
        }
    }
    return getResourceFromMailItem(ctxt, item);
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Account(com.zimbra.cs.account.Account) DavException(com.zimbra.cs.dav.DavException) Folder(com.zimbra.cs.mailbox.Folder) Provisioning(com.zimbra.cs.account.Provisioning) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) DavNames(com.zimbra.cs.mailbox.DavNames) MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) MailServiceException(com.zimbra.cs.mailbox.MailServiceException)

Example 7 with MailItem

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

the class UrlNamespace method getResourceFromMailItem.

/* Returns DavResource for the MailItem. */
public static DavResource getResourceFromMailItem(DavContext ctxt, MailItem item) throws DavException {
    DavResource resource = null;
    if (item == null) {
        return resource;
    }
    MailItem.Type itemType = item.getType();
    try {
        MailItem.Type viewType;
        switch(itemType) {
            case MOUNTPOINT:
                Mountpoint mp = (Mountpoint) item;
                viewType = mp.getDefaultView();
                // don't expose mounted calendars when using iCal style delegation model.
                if (!ctxt.useIcalDelegation() && viewType == MailItem.Type.APPOINTMENT) {
                    resource = new RemoteCalendarCollection(ctxt, mp);
                } else {
                    resource = new RemoteCollection(ctxt, mp);
                }
                break;
            case FOLDER:
                Folder f = (Folder) item;
                viewType = f.getDefaultView();
                if (f.getId() == Mailbox.ID_FOLDER_INBOX && DavResource.isSchedulingEnabled()) {
                    resource = new ScheduleInbox(ctxt, f);
                } else if (f.getId() == Mailbox.ID_FOLDER_SENT && DavResource.isSchedulingEnabled()) {
                    resource = new ScheduleOutbox(ctxt, f);
                } else if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
                    resource = getCalendarCollection(ctxt, f);
                } else if (viewType == MailItem.Type.CONTACT) {
                    resource = new AddressbookCollection(ctxt, f);
                } else {
                    resource = new Collection(ctxt, f);
                }
                break;
            case DOCUMENT:
                resource = new Notebook(ctxt, (Document) item);
                break;
            case APPOINTMENT:
            case TASK:
                resource = new CalendarObject.LocalCalendarObject(ctxt, (CalendarItem) item);
                break;
            case MESSAGE:
                resource = getCalendarItemForMessage(ctxt, (Message) item);
                break;
            case CONTACT:
                resource = new AddressObject(ctxt, (Contact) item);
                break;
        }
    } catch (ServiceException e) {
        resource = null;
        ZimbraLog.dav.info("cannot create DavResource", e);
    }
    return resource;
}
Also used : Message(com.zimbra.cs.mailbox.Message) Folder(com.zimbra.cs.mailbox.Folder) Document(com.zimbra.cs.mailbox.Document) Contact(com.zimbra.cs.mailbox.Contact) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 8 with MailItem

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

the class DbMailItem method icopy.

public static void icopy(MailItem source, UnderlyingData data, boolean shared) throws ServiceException {
    Mailbox mbox = source.getMailbox();
    if (data == null || data.id <= 0 || data.folderId <= 0 || data.parentId == 0) {
        throw ServiceException.FAILURE("invalid data for DB item i-copy", null);
    }
    checkNamingConstraint(mbox, data.folderId, source.getName(), data.id);
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    try {
        String table = getMailItemTableName(mbox);
        String mailbox_id = DebugConfig.disableMailboxGroups ? "" : "mailbox_id, ";
        String flags;
        if (!shared) {
            flags = "flags";
        } else if (Db.supports(Db.Capability.BITWISE_OPERATIONS)) {
            flags = "flags | " + Flag.BITMASK_COPIED;
        } else {
            flags = "CASE WHEN " + Db.getInstance().bitAND("flags", String.valueOf(Flag.BITMASK_COPIED)) + " <> 0 THEN flags ELSE flags + " + Flag.BITMASK_COPIED + " END";
        }
        stmt = conn.prepareStatement("INSERT INTO " + table + "(" + mailbox_id + " id, type, parent_id, folder_id, prev_folders, index_id, imap_id, date, size, locator, blob_digest," + " unread, flags, tag_names, sender, subject, name, metadata, mod_metadata, change_date, mod_content) " + "SELECT " + mailbox_id + " ?, type, parent_id, ?, ?, ?, ?, date, size, ?, blob_digest," + " unread, " + flags + ", tag_names, sender, subject, name, metadata, ?, ?, ? FROM " + table + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
        int pos = 1;
        // ID
        stmt.setInt(pos++, data.id);
        // FOLDER_ID
        stmt.setInt(pos++, data.folderId);
        stmt.setString(pos++, data.getPrevFolders());
        if (data.indexId == MailItem.IndexStatus.NO.id()) {
            stmt.setNull(pos++, Types.INTEGER);
        } else {
            stmt.setInt(pos++, data.indexId);
        }
        // IMAP_ID
        stmt.setInt(pos++, data.imapId);
        stmt.setString(pos++, data.locator);
        // MOD_METADATA
        stmt.setInt(pos++, mbox.getOperationChangeID());
        // CHANGE_DATE
        stmt.setInt(pos++, mbox.getOperationTimestamp());
        // MOD_CONTENT
        stmt.setInt(pos++, mbox.getOperationChangeID());
        pos = setMailboxId(stmt, mbox, pos);
        stmt.setInt(pos++, source.getId());
        stmt.executeUpdate();
        stmt.close();
        boolean needsTag = shared && !source.isTagged(Flag.FlagInfo.COPIED);
        if (needsTag || source.getParentId() > 0) {
            boolean altersMODSEQ = source.getParentId() > 0;
            String updateChangeID = (altersMODSEQ ? ", mod_metadata = ?, change_date = ?" : "");
            stmt = conn.prepareStatement("UPDATE " + table + " SET parent_id = NULL, flags = " + flags + updateChangeID + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
            pos = 1;
            if (altersMODSEQ) {
                stmt.setInt(pos++, mbox.getOperationChangeID());
                stmt.setInt(pos++, mbox.getOperationTimestamp());
            }
            pos = setMailboxId(stmt, mbox, pos);
            stmt.setInt(pos++, source.getId());
            stmt.executeUpdate();
            stmt.close();
        }
        if (source instanceof Message && source.getParentId() <= 0) {
            changeOpenTargets(source, data.id);
        }
        MailItem.Type type = MailItem.Type.of(data.type);
        DbTag.storeTagReferences(mbox, data.id, type, data.getFlags() | (shared ? Flag.BITMASK_COPIED : 0), data.unreadCount > 0);
        DbTag.storeTagReferences(mbox, data.id, type, data.getTags());
    } catch (SQLException e) {
        // catch item_id uniqueness constraint violation and return failure
        if (Db.errorMatches(e, Db.Error.DUPLICATE_ROW)) {
            throw MailServiceException.ALREADY_EXISTS(data.id, e);
        } else {
            throw ServiceException.FAILURE("i-copying " + source.getType() + ": " + source.getId(), e);
        }
    } finally {
        DbPool.closeStatement(stmt);
    }
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ImapMessage(com.zimbra.cs.imap.ImapMessage) Message(com.zimbra.cs.mailbox.Message) Pop3Message(com.zimbra.cs.pop3.Pop3Message) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 9 with MailItem

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

the class ExportAndDeleteItems method handle.

@Override
public Element handle(Element requst, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    checkRight(zsc, context, null, AdminRight.PR_SYSTEM_ADMIN_ONLY);
    // Parse request.
    ExportAndDeleteItemsRequest req = JaxbUtil.elementToJaxb(requst);
    ExportAndDeleteMailboxSpec mailbox = req.getMailbox();
    if (mailbox == null) {
        throw ServiceException.INVALID_REQUEST("empty mbox id", null);
    }
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(mailbox.getId());
    Multimap<Integer, Integer> idRevs = HashMultimap.create();
    for (ExportAndDeleteItemSpec item : mailbox.getItems()) {
        idRevs.put(item.getId(), item.getVersion());
    }
    String dirPath = req.getExportDir();
    String prefix = req.getExportFilenamePrefix();
    // Lock the mailbox, to make sure that another thread doesn't modify the items we're exporting/deleting.
    mbox.lock.lock();
    try {
        DbConnection conn = null;
        try {
            conn = DbPool.getConnection();
            if (dirPath != null) {
                File exportDir = new File(dirPath);
                if (!exportDir.isDirectory()) {
                    DbPool.quietClose(conn);
                    throw ServiceException.INVALID_REQUEST(dirPath + " is not a directory", null);
                }
                String filePath = makePath(dirPath, DbMailItem.TABLE_MAIL_ITEM, prefix);
                export(conn, mbox, DbMailItem.TABLE_MAIL_ITEM, "id", idRevs, filePath);
                filePath = makePath(dirPath, DbMailItem.TABLE_MAIL_ITEM_DUMPSTER, prefix);
                export(conn, mbox, DbMailItem.TABLE_MAIL_ITEM_DUMPSTER, "id", idRevs, filePath);
                filePath = makePath(dirPath, DbMailItem.TABLE_REVISION, prefix);
                export(conn, mbox, DbMailItem.TABLE_REVISION, "item_id", idRevs, filePath);
                filePath = makePath(dirPath, DbMailItem.TABLE_REVISION_DUMPSTER, prefix);
                export(conn, mbox, DbMailItem.TABLE_REVISION_DUMPSTER, "item_id", idRevs, filePath);
                filePath = makePath(dirPath, DbMailItem.TABLE_APPOINTMENT, prefix);
                export(conn, mbox, DbMailItem.TABLE_APPOINTMENT, "item_id", idRevs, filePath);
                filePath = makePath(dirPath, DbMailItem.TABLE_APPOINTMENT_DUMPSTER, prefix);
                export(conn, mbox, DbMailItem.TABLE_APPOINTMENT_DUMPSTER, "item_id", idRevs, filePath);
            }
            // delete item from mail_item and revision table
            for (Integer itemId : idRevs.keySet()) {
                Collection<Integer> revs = idRevs.get(itemId);
                for (int rev : revs) {
                    if (rev == 0) {
                        // delete all revisions to make sure we delete all blobs
                        List<MailItem> list = null;
                        try {
                            list = mbox.getAllRevisions(null, itemId, MailItem.Type.UNKNOWN);
                        } catch (NoSuchItemException ex) {
                            // exception happens when we try to delete a mail_item which is already in mail_item_dumpster
                            continue;
                        }
                        for (MailItem item : list) {
                            if (item.getType() == MailItem.Type.DOCUMENT) {
                                mbox.purgeRevision(null, itemId, item.getVersion(), false);
                            }
                        }
                        mbox.delete(null, itemId, MailItem.Type.UNKNOWN, null);
                        break;
                    } else if (!revs.contains(0)) {
                        try {
                            mbox.purgeRevision(null, itemId, rev, false);
                        } catch (NoSuchItemException ex) {
                            // exception happens when we try to delete a revision which is already in revision_dumpster
                            continue;
                        }
                    }
                }
            }
            // Delete items from mail_item_dumpster & revision_dumpster tables just
            // incase moved to dumpster tables
            DbBlobConsistency.delete(conn, mbox, idRevs);
        } finally {
            conn.commit();
            DbPool.quietClose(conn);
        }
    } finally {
        mbox.lock.release();
    }
    return zsc.createElement(AdminConstants.EXPORT_AND_DELETE_ITEMS_RESPONSE);
}
Also used : ExportAndDeleteItemSpec(com.zimbra.soap.admin.type.ExportAndDeleteItemSpec) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) MailItem(com.zimbra.cs.mailbox.MailItem) DbMailItem(com.zimbra.cs.db.DbMailItem) ExportAndDeleteItemsRequest(com.zimbra.soap.admin.message.ExportAndDeleteItemsRequest) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) ExportAndDeleteMailboxSpec(com.zimbra.soap.admin.type.ExportAndDeleteMailboxSpec) File(java.io.File)

Example 10 with MailItem

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

the class GetMsg method getMsgs.

public static List<Message> getMsgs(OperationContext octxt, Mailbox mbox, List<Integer> iids, boolean read) throws ServiceException {
    int i = 0;
    int[] msgIdArray = new int[iids.size()];
    for (int id : iids) {
        msgIdArray[i++] = id;
    }
    List<Message> toRet = new ArrayList<Message>(msgIdArray.length);
    for (MailItem item : mbox.getItemById(octxt, msgIdArray, MailItem.Type.MESSAGE)) {
        toRet.add((Message) item);
        if (read && item.isUnread() && !RedoLogProvider.getInstance().isSlave()) {
            mbox.alterTag(octxt, item.getId(), MailItem.Type.MESSAGE, Flag.FlagInfo.UNREAD, false, null);
        }
    }
    return toRet;
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) Message(com.zimbra.cs.mailbox.Message) ArrayList(java.util.ArrayList)

Aggregations

MailItem (com.zimbra.cs.mailbox.MailItem)74 Mailbox (com.zimbra.cs.mailbox.Mailbox)36 ServiceException (com.zimbra.common.service.ServiceException)30 Folder (com.zimbra.cs.mailbox.Folder)23 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)23 Message (com.zimbra.cs.mailbox.Message)19 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)17 ArrayList (java.util.ArrayList)17 IOException (java.io.IOException)16 OperationContext (com.zimbra.cs.mailbox.OperationContext)15 NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)14 Element (com.zimbra.common.soap.Element)13 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)13 Account (com.zimbra.cs.account.Account)12 Document (com.zimbra.cs.mailbox.Document)12 ItemId (com.zimbra.cs.service.util.ItemId)11 HashMap (java.util.HashMap)11 ZMailbox (com.zimbra.client.ZMailbox)9 Contact (com.zimbra.cs.mailbox.Contact)9 HashSet (java.util.HashSet)9