Search in sources :

Example 1 with MailItem

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

the class CalDavDataImport method sync.

private void sync(OperationContext octxt, CalendarFolder cf) throws ServiceException, IOException, DavException {
    Folder syncFolder = cf.folder;
    // hack alert: caldav import uses sync date field to store sync token
    int lastSync = (int) syncFolder.getLastSyncDate();
    int currentSync = lastSync;
    boolean allDone = false;
    HashMap<Integer, Integer> modifiedFromRemote = new HashMap<Integer, Integer>();
    ArrayList<Integer> deletedFromRemote = new ArrayList<Integer>();
    // loop through as long as there are un'synced local changes
    while (!allDone) {
        allDone = true;
        if (lastSync > 0) {
            // Don't push local changes during initial sync.
            // push local deletion
            List<Integer> deleted = new ArrayList<Integer>();
            for (int itemId : mbox.getTombstones(lastSync).getAllIds()) {
                if (deletedFromRemote.contains(itemId)) {
                    // was just deleted from sync
                    continue;
                }
                deleted.add(itemId);
            }
            // move to trash is equivalent to delete
            HashSet<Integer> fid = new HashSet<Integer>();
            fid.add(Mailbox.ID_FOLDER_TRASH);
            List<Integer> trashed = mbox.getModifiedItems(octxt, lastSync, MailItem.Type.UNKNOWN, fid).getFirst();
            deleted.addAll(trashed);
            if (!deleted.isEmpty()) {
                // pushDelete returns true if one or more items were deleted
                allDone &= !pushDelete(deleted);
            }
            // push local modification
            fid.clear();
            fid.add(syncFolder.getId());
            List<Integer> modified = mbox.getModifiedItems(octxt, lastSync, MailItem.Type.UNKNOWN, fid).getFirst();
            for (int itemId : modified) {
                MailItem item = mbox.getItemById(octxt, itemId, MailItem.Type.UNKNOWN);
                if (modifiedFromRemote.containsKey(itemId) && modifiedFromRemote.get(itemId).equals(item.getModifiedSequence()))
                    // was just downloaded from remote
                    continue;
                try {
                    pushModify(item);
                } catch (Exception e) {
                    ZimbraLog.datasource.info("Failed to push item " + item.getId(), e);
                }
                allDone = false;
            }
        }
        if (cf.ctagMatched) {
            currentSync = mbox.getLastChangeID();
            break;
        }
        // pull in the changes from the remote server
        List<RemoteItem> remoteItems = getRemoteItems(syncFolder);
        for (RemoteItem item : remoteItems) {
            MailItem localItem = applyRemoteItem(item, syncFolder);
            if (localItem != null) {
                if (item.status == Status.deleted)
                    deletedFromRemote.add(localItem.getId());
                else
                    modifiedFromRemote.put(localItem.getId(), localItem.getModifiedSequence());
            }
        }
        currentSync = mbox.getLastChangeID();
        lastSync = currentSync;
    }
    mbox.setSyncDate(octxt, syncFolder.getId(), currentSync);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Folder(com.zimbra.cs.mailbox.Folder) ServiceException(com.zimbra.common.service.ServiceException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) IOException(java.io.IOException) DavException(com.zimbra.cs.dav.DavException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) MailItem(com.zimbra.cs.mailbox.MailItem) HashSet(java.util.HashSet)

Example 2 with MailItem

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

the class MailItemResource method moveORcopyWithOverwrite.

public void moveORcopyWithOverwrite(DavContext ctxt, Collection dest, String newName, boolean deleteOriginal) throws DavException {
    try {
        if (deleteOriginal)
            move(ctxt, dest, newName);
        else
            copy(ctxt, dest, newName);
    } catch (DavException e) {
        if (e.getStatus() == HttpServletResponse.SC_PRECONDITION_FAILED) {
            // in case of name conflict, delete the existing mail item and
            // attempt the move operation again.
            // return if the error is not ALREADY_EXISTS
            ServiceException se = (ServiceException) e.getCause();
            int id = 0;
            try {
                if (se.getCode().equals(MailServiceException.ALREADY_EXISTS) == false)
                    throw e;
                else {
                    // get the conflicting item-id
                    if (se instanceof SoapFaultException) {
                        // destination belongs other mailbox.
                        String itemIdStr = ((SoapFaultException) se).getArgumentValue("id");
                        ItemId itemId = new ItemId(itemIdStr, dest.getItemId().getAccountId());
                        id = itemId.getId();
                    } else {
                        // destination belongs to same mailbox.
                        String name = null;
                        for (Argument arg : se.getArgs()) {
                            if (arg.name != null && arg.value != null && arg.value.length() > 0) {
                                if (arg.name.equals("name"))
                                    name = arg.value;
                            /* commented out since the exception is giving wrong itemId for copy.
                                       If the the item is conflicting with an existing item we want the
                                       id of the existing item. But, the exception has the proposed id of
                                       the new item which does not exist yet.
                                     else if (arg.mName.equals("itemId"))
                                        id = Integer.parseInt(arg.mValue);
                                     */
                            }
                        }
                        if (id <= 0) {
                            if (name == null && !deleteOriginal) {
                                // in case of copy get the id from source name since we don't support copy with rename.
                                name = ctxt.getItem();
                            }
                            if (name != null) {
                                Mailbox mbox = getMailbox(ctxt);
                                MailItem item = mbox.getItemByPath(ctxt.getOperationContext(), name, dest.getId());
                                id = item.getId();
                            } else
                                throw e;
                        }
                    }
                }
                deleteDestinationItem(ctxt, dest, id);
            } catch (ServiceException se1) {
                throw new DavException("cannot move/copy item", HttpServletResponse.SC_FORBIDDEN, se1);
            }
            if (deleteOriginal)
                move(ctxt, dest, newName);
            else
                copy(ctxt, dest, newName);
        } else {
            throw e;
        }
    }
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Argument(com.zimbra.common.service.ServiceException.Argument) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) DavException(com.zimbra.cs.dav.DavException) ItemId(com.zimbra.cs.service.util.ItemId) SoapFaultException(com.zimbra.common.soap.SoapFaultException)

Example 3 with MailItem

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

the class MailItemResource method getAce.

public List<Ace> getAce(DavContext ctxt) throws ServiceException, DavException {
    ArrayList<Ace> aces = new ArrayList<Ace>();
    Mailbox mbox = getMailbox(ctxt);
    MailItem item = mbox.getItemById(ctxt.getOperationContext(), mId, MailItem.Type.UNKNOWN);
    Folder f = null;
    if (item.getType() == MailItem.Type.FOLDER)
        f = (Folder) item;
    else
        f = mbox.getFolderById(ctxt.getOperationContext(), item.getParentId());
    ACL effectiveAcl = f.getEffectiveACL();
    if (effectiveAcl == null) {
        return aces;
    }
    List<Grant> grants = effectiveAcl.getGrants();
    if (grants == null) {
        return aces;
    }
    for (ACL.Grant g : grants) {
        if (!g.hasGrantee())
            continue;
        aces.add(new Ace(g.getGranteeId(), g.getGrantedRights(), g.getGranteeType()));
    }
    return aces;
}
Also used : Grant(com.zimbra.cs.mailbox.ACL.Grant) Ace(com.zimbra.cs.dav.property.Acl.Ace) MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ArrayList(java.util.ArrayList) ACL(com.zimbra.cs.mailbox.ACL) Folder(com.zimbra.cs.mailbox.Folder) Grant(com.zimbra.cs.mailbox.ACL.Grant)

Example 4 with MailItem

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

the class Collection method createItem.

// create Document at the URI
public DavResource createItem(DavContext ctxt, String name) throws DavException, IOException {
    Mailbox mbox = null;
    try {
        mbox = getMailbox(ctxt);
    } catch (ServiceException e) {
        throw new DavException("cannot get mailbox", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null);
    }
    FileUploadServlet.Upload upload = ctxt.getUpload();
    String ctype = upload.getContentType();
    if (ctype != null && (ctype.startsWith(DavProtocol.VCARD_CONTENT_TYPE) || ctype.startsWith(MimeConstants.CT_TEXT_VCARD_LEGACY) || ctype.startsWith(MimeConstants.CT_TEXT_VCARD_LEGACY2))) {
        // vCard MIME types such as text/x-vcard or text/directory.
        return createVCard(ctxt, name);
    }
    String author = ctxt.getAuthAccount().getName();
    try {
        // add a revision if the resource already exists
        MailItem item = mbox.getItemByPath(ctxt.getOperationContext(), ctxt.getPath());
        if (item.getType() != MailItem.Type.DOCUMENT && item.getType() != MailItem.Type.WIKI) {
            throw new DavException("no DAV resource for " + item.getType(), HttpServletResponse.SC_NOT_ACCEPTABLE, null);
        }
        Document doc = mbox.addDocumentRevision(ctxt.getOperationContext(), item.getId(), author, name, null, upload.getInputStream());
        return new Notebook(ctxt, doc);
    } catch (ServiceException e) {
        if (!(e instanceof NoSuchItemException))
            throw new DavException("cannot get item ", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null);
    }
    // create
    try {
        Document doc = mbox.createDocument(ctxt.getOperationContext(), mId, name, ctype, author, null, upload.getInputStream());
        Notebook notebook = new Notebook(ctxt, doc);
        notebook.mNewlyCreated = true;
        return notebook;
    } catch (ServiceException se) {
        throw new DavException("cannot create ", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, se);
    }
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DavException(com.zimbra.cs.dav.DavException) Document(com.zimbra.cs.mailbox.Document) FileUploadServlet(com.zimbra.cs.service.FileUploadServlet) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)

Example 5 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)

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