Search in sources :

Example 1 with Appointment

use of com.zimbra.cs.dav.client.CalDavClient.Appointment in project zm-mailbox by Zimbra.

the class CalDavDataImport method putAppointment.

private String putAppointment(CalendarItem calItem, DataSourceItem dsItem) throws ServiceException, IOException, DavException, HttpException {
    StringBuilder buf = new StringBuilder();
    ArrayList<String> recipients = new ArrayList<String>();
    buf.append("BEGIN:VCALENDAR\r\n");
    buf.append("VERSION:").append(ZCalendar.sIcalVersion).append("\r\n");
    buf.append("PRODID:").append(ZCalendar.sZimbraProdID).append("\r\n");
    Iterator<ICalTimeZone> iter = calItem.getTimeZoneMap().tzIterator();
    while (iter.hasNext()) {
        ICalTimeZone tz = iter.next();
        CharArrayWriter wr = new CharArrayWriter();
        tz.newToVTimeZone().toICalendar(wr, true);
        wr.flush();
        buf.append(wr.toCharArray());
        wr.close();
    }
    boolean appleICalExdateHack = LC.calendar_apple_ical_compatible_canceled_instances.booleanValue();
    ZComponent[] vcomps = Invite.toVComponents(calItem.getInvites(), true, false, appleICalExdateHack);
    if (vcomps != null) {
        CharArrayWriter wr = new CharArrayWriter();
        for (ZComponent vcomp : vcomps) {
            ZProperty organizer = vcomp.getProperty(ZCalendar.ICalTok.ORGANIZER);
            if (organizer != null)
                organizer.setValue(getUsername());
            vcomp.toICalendar(wr, true);
        }
        wr.flush();
        buf.append(wr.toCharArray());
        wr.close();
    }
    buf.append("END:VCALENDAR\r\n");
    String etag = dsItem.md.get(METADATA_KEY_ETAG, null);
    if (recipients.isEmpty())
        recipients = null;
    Appointment appt = new Appointment(dsItem.remoteId, etag, buf.toString(), recipients);
    return getClient().sendCalendarData(appt);
}
Also used : ZComponent(com.zimbra.common.calendar.ZCalendar.ZComponent) Appointment(com.zimbra.cs.dav.client.CalDavClient.Appointment) ArrayList(java.util.ArrayList) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) CharArrayWriter(java.io.CharArrayWriter)

Example 2 with Appointment

use of com.zimbra.cs.dav.client.CalDavClient.Appointment in project zm-mailbox by Zimbra.

the class CalDavDataImport method getRemoteItems.

private List<RemoteItem> getRemoteItems(Folder folder) throws ServiceException, IOException, DavException, HttpException {
    ZimbraLog.datasource.debug("Refresh folder %s", folder.getPath());
    DataSource ds = getDataSource();
    DataSourceItem item = DbDataSource.getMapping(ds, folder.getId());
    if (item.md == null)
        throw ServiceException.FAILURE("Mapping for folder " + folder.getPath() + " not found", null);
    // CalDAV doesn't provide delete tombstone.  in order to check for deleted appointments
    // we need to cross reference the current result with what we have from last sync
    // and check for any appointment that has disappeared since last sync.
    HashMap<String, DataSourceItem> allItems = new HashMap<String, DataSourceItem>();
    for (DataSourceItem localItem : DbDataSource.getAllMappingsInFolder(getDataSource(), folder.getId())) allItems.put(localItem.remoteId, localItem);
    ArrayList<RemoteItem> ret = new ArrayList<RemoteItem>();
    CalDavClient client = getClient();
    Collection<Appointment> appts = client.getEtags(item.remoteId);
    for (Appointment a : appts) {
        ret.add(new RemoteCalendarItem(a.href, a.etag));
        allItems.remove(a.href);
    }
    ArrayList<Integer> deletedIds = new ArrayList<Integer>();
    for (DataSourceItem deletedItem : allItems.values()) {
        // what's left in the collection are previous mapping that has disappeared.
        // we need to delete the appointments that are mapped locally.
        RemoteCalendarItem rci = new RemoteCalendarItem(deletedItem.remoteId, null);
        rci.status = Status.deleted;
        rci.itemId = deletedItem.itemId;
        ret.add(rci);
        deletedIds.add(deletedItem.itemId);
        ZimbraLog.datasource.debug("deleting: %d (%s) ", deletedItem.itemId, deletedItem.remoteId);
    }
    if (!deletedIds.isEmpty())
        DbDataSource.deleteMappings(ds, deletedIds);
    return ret;
}
Also used : Appointment(com.zimbra.cs.dav.client.CalDavClient.Appointment) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CalDavClient(com.zimbra.cs.dav.client.CalDavClient) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem)

Example 3 with Appointment

use of com.zimbra.cs.dav.client.CalDavClient.Appointment in project zm-mailbox by Zimbra.

the class CalDavDataImport method applyRemoteItem.

private MailItem applyRemoteItem(RemoteItem remoteItem, Folder where) throws ServiceException, IOException, HttpException {
    if (!(remoteItem instanceof RemoteCalendarItem)) {
        ZimbraLog.datasource.warn("applyRemoteItem: not a calendar item: %s", remoteItem);
        return null;
    }
    RemoteCalendarItem item = (RemoteCalendarItem) remoteItem;
    DataSource ds = getDataSource();
    DataSourceItem dsItem = DbDataSource.getReverseMapping(ds, item.href);
    OperationContext octxt = new OperationContext(mbox);
    MailItem mi = null;
    boolean isStale = false;
    boolean isCreate = false;
    if (dsItem.md == null && item.status != Status.deleted) {
        dsItem.md = new Metadata();
        dsItem.md.put(METADATA_KEY_TYPE, METADATA_TYPE_APPOINTMENT);
    }
    if (dsItem.itemId == 0) {
        isStale = true;
        isCreate = true;
    } else {
        String etag = dsItem.md.get(METADATA_KEY_ETAG, null);
        try {
            mi = mbox.getItemById(octxt, dsItem.itemId, MailItem.Type.UNKNOWN);
        } catch (MailServiceException.NoSuchItemException se) {
            ZimbraLog.datasource.warn("applyRemoteItem: calendar item not found: ", remoteItem);
        }
        if (item.etag == null) {
            ZimbraLog.datasource.warn("No Etag returned for item %s", item.href);
            isStale = true;
        } else if (etag == null) {
            ZimbraLog.datasource.warn("Empty etag for item %d", dsItem.itemId);
            isStale = true;
        } else {
            isStale = !item.etag.equals(etag);
        }
        if (mi == null)
            isStale = true;
    }
    if (item.status == Status.deleted) {
        ZimbraLog.datasource.debug("Deleting appointment %s", item.href);
        try {
            mi = mbox.getItemById(octxt, item.itemId, MailItem.Type.UNKNOWN);
        } catch (NoSuchItemException se) {
            mi = null;
        }
        try {
            mbox.delete(octxt, item.itemId, MailItem.Type.UNKNOWN);
        } catch (ServiceException se) {
            ZimbraLog.datasource.warn("Error deleting remotely deleted item %d (%s)", item.itemId, dsItem.remoteId);
        }
    } else if (isStale) {
        ZimbraLog.datasource.debug("Updating stale appointment %s", item.href);
        ZCalendar.ZVCalendar vcalendar;
        SetCalendarItemData main = new SetCalendarItemData();
        SetCalendarItemData[] exceptions = null;
        CalDavClient client = null;
        try {
            client = getClient();
        } catch (DavException e) {
            throw ServiceException.FAILURE("error creating CalDAV client", e);
        }
        Appointment appt = client.getCalendarData(new Appointment(item.href, item.etag));
        if (appt.data == null) {
            ZimbraLog.datasource.warn("No appointment found at " + item.href);
            return null;
        }
        dsItem.md.put(METADATA_KEY_ETAG, appt.etag);
        try {
            vcalendar = ZCalendar.ZCalendarBuilder.build(appt.data);
            List<Invite> invites = Invite.createFromCalendar(mbox.getAccount(), null, vcalendar, true);
            if (invites.size() > 1)
                exceptions = new SetCalendarItemData[invites.size() - 1];
            int pos = 0;
            boolean first = true;
            for (Invite i : invites) {
                if (first) {
                    main.invite = i;
                    first = false;
                } else {
                    SetCalendarItemData scid = new SetCalendarItemData();
                    scid.invite = i;
                    exceptions[pos++] = scid;
                }
            }
        } catch (Exception e) {
            ZimbraLog.datasource.warn("Error parsing appointment ", e);
            return null;
        }
        mi = mbox.setCalendarItem(octxt, where.getId(), 0, null, main, exceptions, null, CalendarItem.NEXT_ALARM_KEEP_CURRENT);
        dsItem.itemId = mi.getId();
        dsItem.folderId = mi.getFolderId();
        if (isCreate) {
            DbDataSource.addMapping(ds, dsItem);
        } else {
            DbDataSource.updateMapping(ds, dsItem);
        }
    } else {
        ZimbraLog.datasource.debug("Appointment up to date %s", item.href);
        try {
            mi = mbox.getItemById(octxt, dsItem.itemId, MailItem.Type.UNKNOWN);
        } catch (NoSuchItemException se) {
            // item not found.  delete the mapping so it can be downloaded again if needed.
            ArrayList<Integer> deletedIds = new ArrayList<Integer>();
            deletedIds.add(dsItem.itemId);
            DbDataSource.deleteMappings(ds, deletedIds);
        }
    }
    return mi;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Appointment(com.zimbra.cs.dav.client.CalDavClient.Appointment) DavException(com.zimbra.cs.dav.DavException) Metadata(com.zimbra.cs.mailbox.Metadata) ArrayList(java.util.ArrayList) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) CalDavClient(com.zimbra.cs.dav.client.CalDavClient) ServiceException(com.zimbra.common.service.ServiceException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) IOException(java.io.IOException) HttpException(org.apache.http.HttpException) DavException(com.zimbra.cs.dav.DavException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource) SetCalendarItemData(com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData) MailItem(com.zimbra.cs.mailbox.MailItem) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ArrayList(java.util.ArrayList) List(java.util.List) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 4 with Appointment

use of com.zimbra.cs.dav.client.CalDavClient.Appointment in project zm-mailbox by Zimbra.

the class CalDavDataImport method pushModify.

private void pushModify(MailItem mitem) throws ServiceException, IOException, DavException, HttpException {
    int itemId = mitem.getId();
    DataSource ds = getDataSource();
    DataSourceItem item = DbDataSource.getMapping(ds, itemId);
    boolean isCreate = false;
    if (item.remoteId == null) {
        // new item
        item.md = new Metadata();
        item.md.put(METADATA_KEY_TYPE, METADATA_TYPE_APPOINTMENT);
        item.remoteId = createTargetUrl(mitem);
        item.folderId = mitem.getFolderId();
        isCreate = true;
    }
    String type = item.md.get(METADATA_KEY_TYPE);
    if (METADATA_TYPE_FOLDER.equals(type)) {
        if (mitem.getType() != MailItem.Type.FOLDER) {
            ZimbraLog.datasource.warn("pushModify: item type doesn't match in metadata for item %d", itemId);
            return;
        }
    // detect and push rename
    } else if (METADATA_TYPE_APPOINTMENT.equals(type)) {
        if (mitem.getType() != MailItem.Type.APPOINTMENT) {
            ZimbraLog.datasource.warn("pushModify: item type doesn't match in metadata for item %d", itemId);
            return;
        }
        // push modified appt
        ZimbraLog.datasource.debug("pushModify: sending appointment %s", item.remoteId);
        String etag = putAppointment((CalendarItem) mitem, item);
        if (etag == null) {
            Appointment appt = mClient.getEtag(item.remoteId);
            etag = appt.etag;
        }
        item.md.put(METADATA_KEY_ETAG, etag);
        if (isCreate) {
            DbDataSource.addMapping(ds, item);
        } else {
            DbDataSource.updateMapping(ds, item);
        }
    } else {
        ZimbraLog.datasource.warn("pushModify: unrecognized item type for %d: %s", itemId, type);
        return;
    }
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) Appointment(com.zimbra.cs.dav.client.CalDavClient.Appointment) Metadata(com.zimbra.cs.mailbox.Metadata) DataSourceItem(com.zimbra.cs.db.DbDataSource.DataSourceItem) DbDataSource(com.zimbra.cs.db.DbDataSource) DataSource(com.zimbra.cs.account.DataSource)

Aggregations

Appointment (com.zimbra.cs.dav.client.CalDavClient.Appointment)4 DataSource (com.zimbra.cs.account.DataSource)3 DbDataSource (com.zimbra.cs.db.DbDataSource)3 DataSourceItem (com.zimbra.cs.db.DbDataSource.DataSourceItem)3 ArrayList (java.util.ArrayList)3 CalDavClient (com.zimbra.cs.dav.client.CalDavClient)2 Metadata (com.zimbra.cs.mailbox.Metadata)2 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)1 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)1 ServiceException (com.zimbra.common.service.ServiceException)1 DavException (com.zimbra.cs.dav.DavException)1 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)1 MailItem (com.zimbra.cs.mailbox.MailItem)1 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)1 NoSuchItemException (com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException)1 SetCalendarItemData (com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData)1 OperationContext (com.zimbra.cs.mailbox.OperationContext)1 Invite (com.zimbra.cs.mailbox.calendar.Invite)1 CharArrayWriter (java.io.CharArrayWriter)1