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);
}
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;
}
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;
}
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;
}
}
Aggregations