use of com.zimbra.common.calendar.ICalTimeZone in project zm-mailbox by Zimbra.
the class CalDavDataImport method putAppointment.
private String putAppointment(CalendarItem calItem, DataSourceItem dsItem) throws ServiceException, IOException, DavException {
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.common.calendar.ICalTimeZone in project zm-mailbox by Zimbra.
the class CalendarItem method decodeMetadata.
@Override
void decodeMetadata(Metadata meta) throws ServiceException {
super.decodeMetadata(meta);
mUid = Invite.fixupIfOutlookUid(meta.get(Metadata.FN_UID, null));
mInvites = new ArrayList<Invite>();
ICalTimeZone accountTZ = Util.getAccountTimeZone(getMailbox().getAccount());
if (meta.containsKey(Metadata.FN_TZMAP)) {
try {
Set<String> tzids = new HashSet<String>();
mTzMap = Util.decodeFromMetadata(meta.getMap(Metadata.FN_TZMAP), accountTZ);
// appointment/task start and end
mStartTime = meta.getLong(Metadata.FN_CALITEM_START, 0);
mEndTime = meta.getLong(Metadata.FN_CALITEM_END, 0);
// invite ID's
long numComp = meta.getLong(Metadata.FN_NUM_COMPONENTS);
for (int i = 0; i < numComp; i++) {
Metadata md = meta.getMap(Metadata.FN_INV + i);
Invite inv = Invite.decodeMetadata(getMailboxId(), md, this, accountTZ);
mInvites.add(inv);
tzids.addAll(inv.getReferencedTZIDs());
mTzMap.add(inv.getTimeZoneMap());
}
Metadata metaRecur = meta.getMap(FN_CALITEM_RECURRENCE, true);
if (metaRecur != null) {
mRecurrence = Recurrence.decodeMetadata(metaRecur, mTzMap);
if (mRecurrence != null) {
tzids.addAll(Recurrence.getReferencedTZIDs(mRecurrence));
}
}
if (meta.containsKey(Metadata.FN_REPLY_LIST)) {
mReplyList = ReplyList.decodeFromMetadata(meta.getMap(Metadata.FN_REPLY_LIST), mTzMap);
// Get all TZIDs referenced by replies.
for (ReplyInfo ri : mReplyList.mReplies) {
if (ri.mRecurId != null) {
ParsedDateTime dt = ri.mRecurId.getDt();
if (dt != null && dt.hasTime()) {
ICalTimeZone tz = dt.getTimeZone();
if (tz != null)
tzids.add(tz.getID());
}
}
}
} else {
mReplyList = new ReplyList();
}
Metadata metaAlarmData = meta.getMap(Metadata.FN_ALARM_DATA, true);
if (metaAlarmData != null)
mAlarmData = AlarmData.decodeMetadata(metaAlarmData);
// Reduce tzmap to minimal set of TZIDs referenced by invites, recurrence, and replies.
mTzMap.reduceTo(tzids);
} catch (ServiceException se) {
if (ServiceException.INVALID_REQUEST.equals(se.getCode()) && this.getChangeDate() < new GregorianCalendar(2006, 0, 1).getTimeInMillis()) {
//could have been metadata version 3, 4 or 5.
//All of those versions have FN_TZMAP, but different format for other fields
//these are edge cases that should only appear in dev/df/cf
mStartTime = 0;
mEndTime = 0;
} else {
throw se;
}
}
} else {
//version 2 or earlier
mStartTime = 0;
mEndTime = 0;
}
}
use of com.zimbra.common.calendar.ICalTimeZone in project zm-mailbox by Zimbra.
the class CancelCalendarItem method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Account acct = getRequestedAccount(zsc);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
if (!iid.hasSubpart())
throw ServiceException.INVALID_REQUEST("missing invId subpart: id should be specified as \"item-inv\"", null);
int compNum = (int) request.getAttributeLong(MailConstants.E_INVITE_COMPONENT);
CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
if (calItem == null)
throw MailServiceException.NO_SUCH_CALITEM(iid.getId(), " for CancelCalendarItemRequest(" + iid + "," + compNum + ")");
if (calItem.inTrash())
throw ServiceException.INVALID_REQUEST("cannot cancel a calendar item under trash", null);
// We probably don't want to bother with conflict check for a cancel request...
Invite inv = calItem.getInvite(iid.getSubpartId(), compNum);
if (inv == null)
throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
MailSendQueue sendQueue = new MailSendQueue();
try {
Element recurElt = request.getOptionalElement(MailConstants.E_INSTANCE);
if (recurElt != null) {
TimeZoneMap tzmap = inv.getTimeZoneMap();
Element tzElem = request.getOptionalElement(MailConstants.E_CAL_TZ);
ICalTimeZone tz = null;
if (tzElem != null) {
tz = CalendarUtils.parseTzElement(tzElem);
tzmap.add(tz);
}
RecurId recurId = CalendarUtils.parseRecurId(recurElt, tzmap);
// trace logging
ZimbraLog.calendar.info("<CancelCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s, recurId=%s", calItem.getId(), calItem.getFolderId(), inv.isPublic() ? inv.getName() : "(private)", calItem.getUid(), recurId.getDtZ());
Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
cancelInstance(zsc, octxt, msgElem, acct, mbox, calItem, inv, recurId, inv.getAttendees(), sendQueue);
} else {
// if recur is not set, then we're canceling the entire calendar item...
// trace logging
ZimbraLog.calendar.info("<CancelCalendarItem> id=%d, folderId=%d, subject=\"%s\", UID=%s", calItem.getId(), calItem.getFolderId(), inv.isPublic() ? inv.getName() : "(private)", calItem.getUid());
Invite seriesInv = calItem.getDefaultInviteOrNull();
if (seriesInv != null) {
if (seriesInv.getMethod().equals(ICalTok.REQUEST.toString()) || seriesInv.getMethod().equals(ICalTok.PUBLISH.toString())) {
if (seriesInv.isOrganizer()) {
// Send cancel notice to attendees who were invited to exception instances only.
// These attendees need to be notified separately because they aren't included in the series
// cancel notice.
List<ZAttendee> atsSeries = seriesInv.getAttendees();
Invite[] invs = calItem.getInvites();
long now = octxt != null ? octxt.getTimestamp() : System.currentTimeMillis();
for (Invite exceptInv : invs) {
if (exceptInv != seriesInv) {
String mthd = exceptInv.getMethod();
if ((mthd.equals(ICalTok.REQUEST.toString()) || mthd.equals(ICalTok.PUBLISH.toString())) && inviteIsAfterTime(exceptInv, now)) {
List<ZAttendee> atsExcept = exceptInv.getAttendees();
// Find exception instance attendees who aren't series attendees.
List<ZAttendee> ats = CalendarUtils.getRemovedAttendees(atsExcept, atsSeries, false, acct);
if (!ats.isEmpty()) {
// notify ats
cancelInstance(zsc, octxt, null, acct, mbox, calItem, exceptInv, exceptInv.getRecurId(), ats, sendQueue);
}
}
}
}
}
// Finally, cancel the series.
Element msgElem = request.getOptionalElement(MailConstants.E_MSG);
cancelInvite(zsc, octxt, msgElem, acct, mbox, calItem, seriesInv, sendQueue);
}
// disable change constraint checking since we've just successfully done a modify
octxt = new OperationContext(octxt).unsetChangeConstraint();
}
}
} finally {
sendQueue.send();
}
Element response = getResponseElement(zsc);
return response;
}
use of com.zimbra.common.calendar.ICalTimeZone in project zm-mailbox by Zimbra.
the class CalendarUtils method parseTimeZones.
static void parseTimeZones(Element parent, TimeZoneMap tzMap) throws ServiceException {
assert (tzMap != null);
for (Iterator iter = parent.elementIterator(MailConstants.E_CAL_TZ); iter.hasNext(); ) {
Element tzElem = (Element) iter.next();
ICalTimeZone tz = parseTzElement(tzElem);
tzMap.add(tz);
}
}
use of com.zimbra.common.calendar.ICalTimeZone in project zm-mailbox by Zimbra.
the class Mailbox method writeICalendarForCalendarItems.
public void writeICalendarForCalendarItems(Writer writer, OperationContext octxt, Collection<CalendarItem> calItems, Folder f, boolean useOutlookCompatMode, boolean ignoreErrors, boolean needAppleICalHacks, boolean trimCalItemsList, boolean escapeHtmlTags, boolean includeAttaches) throws ServiceException {
lock.lock();
try {
writer.write("BEGIN:VCALENDAR\r\n");
if (f != null) {
writer.write("X-WR-CALNAME:");
writer.write(f.getName());
writer.write("\r\n");
writer.write("X-WR-CALID:");
writer.write(new ItemId(f).toString());
writer.write("\r\n");
}
ZProperty prop;
prop = new ZProperty(ICalTok.PRODID, ZCalendar.sZimbraProdID);
prop.toICalendar(writer, needAppleICalHacks);
prop = new ZProperty(ICalTok.VERSION, ZCalendar.sIcalVersion);
prop.toICalendar(writer, needAppleICalHacks);
prop = new ZProperty(ICalTok.METHOD, ICalTok.PUBLISH.toString());
prop.toICalendar(writer, needAppleICalHacks);
// timezones
ICalTimeZone localTz = Util.getAccountTimeZone(getAccount());
TimeZoneMap tzmap = new TimeZoneMap(localTz);
for (CalendarItem calItem : calItems) {
tzmap.add(calItem.getTimeZoneMap());
}
// iterate the tzmap and add all the VTimeZone's
for (Iterator<ICalTimeZone> iter = tzmap.tzIterator(); iter.hasNext(); ) {
ICalTimeZone tz = iter.next();
tz.newToVTimeZone().toICalendar(writer, needAppleICalHacks);
}
// help keep memory consumption low
tzmap = null;
// build all the event components and add them to the Calendar
for (Iterator<CalendarItem> iter = calItems.iterator(); iter.hasNext(); ) {
CalendarItem calItem = iter.next();
boolean allowPrivateAccess = calItem.isPublic() || calItem.allowPrivateAccess(octxt.getAuthenticatedUser(), octxt.isUsingAdminPrivileges());
if (trimCalItemsList) {
// help keep memory consumption low
iter.remove();
}
Invite[] invites = calItem.getInvites();
if (invites != null && invites.length > 0) {
boolean appleICalExdateHack = LC.calendar_apple_ical_compatible_canceled_instances.booleanValue();
ZComponent[] comps = null;
try {
comps = Invite.toVComponents(invites, allowPrivateAccess, useOutlookCompatMode, appleICalExdateHack, includeAttaches);
} catch (ServiceException e) {
if (ignoreErrors) {
ZimbraLog.calendar.warn("Error retrieving iCalendar data for item %s: %s", calItem.getId(), e.getMessage(), e);
} else {
throw e;
}
}
if (comps != null) {
for (ZComponent comp : comps) {
comp.toICalendar(writer, needAppleICalHacks, escapeHtmlTags);
}
}
}
}
writer.write("END:VCALENDAR\r\n");
} catch (IOException e) {
throw ServiceException.FAILURE("Error writing iCalendar", e);
} finally {
lock.release();
}
}
Aggregations