use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class ToXML method encodeRecurId.
private static Element encodeRecurId(Element parent, RecurId recurId, boolean allDay) {
ParsedDateTime ridDt = recurId.getDt();
Element ridElem = parent.addElement(MailConstants.E_CAL_EXCEPTION_ID);
ridElem.addAttribute(MailConstants.A_CAL_DATETIME, ridDt.getDateTimePartString(false));
if (!allDay) {
ridElem.addAttribute(MailConstants.A_CAL_TIMEZONE, ridDt.getTZName());
}
int rangeType = recurId.getRange();
if (rangeType != RecurId.RANGE_NONE) {
ridElem.addAttribute(MailConstants.A_CAL_RECURRENCE_RANGE_TYPE, rangeType);
}
return ridElem;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class FreeBusy method toVCalendar.
/*
* attendee is required for METHOD == REQUEST || METHOD == REPLY
* url is required for METHOD == PUBLISH || METHOD == REPLY
*
*/
public String toVCalendar(Method m, String organizer, String attendee, String url) {
if (m == null || organizer == null) {
throw new IllegalArgumentException("missing method or organizer");
}
ParsedDateTime now = ParsedDateTime.fromUTCTime(System.currentTimeMillis());
ParsedDateTime startTime = ParsedDateTime.fromUTCTime(mStart);
ParsedDateTime endTime = ParsedDateTime.fromUTCTime(mEnd);
StringBuilder toRet = new StringBuilder("BEGIN:VCALENDAR").append(NL);
toRet.append("PRODID:").append(ZCalendar.sZimbraProdID).append(NL);
toRet.append("VERSION:").append(ZCalendar.sIcalVersion).append(NL);
toRet.append("METHOD:").append(m.name()).append(NL);
toRet.append("BEGIN:VFREEBUSY").append(NL);
toRet.append("ORGANIZER:");
if (!organizer.toLowerCase().startsWith(MAILTO) && !organizer.toLowerCase().startsWith(HTTP))
toRet.append(MAILTO);
toRet.append(organizer).append(NL);
if (attendee != null) {
toRet.append("ATTENDEE:");
if (!attendee.toLowerCase().startsWith(MAILTO) && !attendee.toLowerCase().startsWith(HTTP))
toRet.append(MAILTO);
toRet.append(attendee).append(NL);
}
toRet.append("DTSTAMP:").append(now.toString()).append(NL);
toRet.append("DTSTART:").append(startTime.toString()).append(NL);
toRet.append("DTEND:").append(endTime.toString()).append(NL);
if (url != null)
toRet.append("URL:").append(url).append(NL);
for (Iterator<Interval> iter = this.iterator(); iter.hasNext(); ) {
FreeBusy.Interval cur = iter.next();
String status = cur.getStatus();
if (status.equals(IcalXmlStrMap.FBTYPE_FREE)) {
continue;
} else if (status.equals(IcalXmlStrMap.FBTYPE_NODATA)) {
// Treat no-data case same as free, because other apps probably won't understand a non-standard fbtype value.
continue;
} else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY)) {
// default is BUSY, but let's be explicit about it and set FBTYPE to BUSY
toRet.append("FREEBUSY;FBTYPE=BUSY:");
} else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE)) {
toRet.append("FREEBUSY;FBTYPE=BUSY-TENTATIVE:");
} else if (status.equals(IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE)) {
toRet.append("FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:");
} else {
assert (false);
toRet.append(":");
}
ParsedDateTime curStart = ParsedDateTime.fromUTCTime(cur.getStart());
ParsedDateTime curEnd = ParsedDateTime.fromUTCTime(cur.getEnd());
toRet.append(curStart.toString()).append('/').append(curEnd.toString()).append(NL);
}
toRet.append("END:VFREEBUSY").append(NL);
toRet.append("END:VCALENDAR").append(NL);
return toRet.toString();
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class FreeBusy method parse.
/**
* Create a FreeBusy object from VFREEBUSY ZComponent.
* @param comp
* @return
* @throws ServiceException
*/
public static FreeBusy parse(ZComponent comp) throws ServiceException {
String name = null;
ParsedDateTime dtStart = null;
ParsedDateTime dtEnd = null;
List<Interval> intervals = new ArrayList<Interval>();
TimeZoneMap tzmap = new TimeZoneMap(ICalTimeZone.getUTC());
Iterator<ZProperty> propIter = comp.getPropertyIterator();
while (propIter.hasNext()) {
ZProperty prop = propIter.next();
ICalTok tok = prop.getToken();
if (tok == null)
continue;
switch(tok) {
case DTSTART:
try {
dtStart = ParsedDateTime.parse(prop, tzmap);
} catch (ParseException e) {
throw ServiceException.INVALID_REQUEST("bad DTSTART: " + prop.toString(), e);
}
break;
case DTEND:
try {
dtEnd = ParsedDateTime.parse(prop, tzmap);
} catch (ParseException e) {
throw ServiceException.INVALID_REQUEST("bad DTEND: " + prop.toString(), e);
}
break;
case ORGANIZER:
ZOrganizer att = new ZOrganizer(prop);
name = att.getAddress();
break;
case FREEBUSY:
String fbStatus = IcalXmlStrMap.FBTYPE_FREE;
ZParameter fbType = prop.getParameter(ICalTok.FBTYPE);
if (fbType != null)
fbStatus = IcalXmlStrMap.sFreeBusyMap.toXml(fbType.getValue());
List<String> vals = prop.getValueList();
for (String fbVal : vals) {
Period period;
try {
period = Period.parse(fbVal, ICalTimeZone.getUTC(), tzmap);
} catch (ParseException e) {
throw ServiceException.INVALID_REQUEST("bad period value: " + fbVal, e);
}
intervals.add(new Interval(period.getStart().getUtcTime(), period.getEnd().getUtcTime(), fbStatus));
}
break;
}
}
if (name == null)
throw ServiceException.INVALID_REQUEST("VFREEBUSY missing ORGANIZER", null);
if (dtStart == null || dtEnd == null)
throw ServiceException.INVALID_REQUEST("VFREEBUSY missing DTSTART/DTEND", null);
IntervalList ivalList = new IntervalList(dtStart.getUtcTime(), dtEnd.getUtcTime());
for (Interval ival : intervals) {
ivalList.addInterval(ival);
}
return new FreeBusy(name, ivalList, dtStart.getUtcTime(), dtEnd.getUtcTime());
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class Mailbox method processICalReplies.
private void processICalReplies(OperationContext octxt, ZVCalendar cal, String sender) throws ServiceException {
// Reply from Outlook will usually have PRODID set to the following:
//
// Outlook2007+ZCO: PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN
// Outlook2010+ZCO: PRODID:-//Microsoft Corporation//Outlook 14.0 MIMEDIR//EN
// Outlook20xx+Exchange: PRODID:Microsoft Exchange Server 2007
// (if Exchange is Exchange 2007; Exchange 2010 probably works similarly)
//
// Lowest common denominator is "Microsoft" substring.
String prodId = cal.getPropVal(ICalTok.PRODID, null);
boolean fromOutlook = prodId != null && prodId.toLowerCase().contains("microsoft");
AccountAddressMatcher acctMatcher = new AccountAddressMatcher(getAccount());
List<Invite> components = Invite.createFromCalendar(getAccount(), null, cal, false);
for (Invite inv : components) {
String orgAddress;
if (inv.hasOrganizer()) {
ZOrganizer org = inv.getOrganizer();
orgAddress = org.getAddress();
} else {
ZimbraLog.calendar.warn("No ORGANIZER found in REPLY. Assuming current mailbox.");
orgAddress = getAccount().getName();
}
if (acctMatcher.matches(orgAddress)) {
// RECURRENCE-ID.
if (fromOutlook && !inv.isAllDayEvent() && inv.hasRecurId()) {
RecurId rid = inv.getRecurId();
if (rid.getDt() != null && rid.getDt().hasZeroTime()) {
CalendarItem calItem = getCalendarItemByUid(octxt, inv.getUid());
if (calItem != null) {
Invite seriesInv = calItem.getDefaultInviteOrNull();
if (seriesInv != null) {
ParsedDateTime seriesDtStart = seriesInv.getStartTime();
if (seriesDtStart != null) {
ParsedDateTime fixedDt = seriesDtStart.cloneWithNewDate(rid.getDt());
RecurId fixedRid = new RecurId(fixedDt, rid.getRange());
ZimbraLog.calendar.debug("Fixed up invalid RECURRENCE-ID with zero time; before=[%s], after=[%s]", rid, fixedRid);
inv.setRecurId(fixedRid);
}
}
}
}
}
processICalReply(octxt, inv, sender);
} else {
Account orgAccount = inv.getOrganizerAccount();
// Unknown organizer
if (orgAccount == null) {
ZimbraLog.calendar.warn("Unknown organizer " + orgAddress + " in REPLY");
continue;
}
if (Provisioning.onLocalServer(orgAccount)) {
// Run in the context of organizer's mailbox.
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(orgAccount);
OperationContext orgOctxt = new OperationContext(mbox);
mbox.processICalReply(orgOctxt, inv, sender);
} else {
// Organizer's mailbox is on a remote server.
String uri = AccountUtil.getSoapUri(orgAccount);
if (uri == null) {
ZimbraLog.calendar.warn("Unable to determine URI for organizer account %s", orgAddress);
continue;
}
try {
// TODO: Get the iCalendar data from the
// MIME part since we already have it.
String ical;
StringWriter sr = null;
try {
sr = new StringWriter();
inv.setMethod(ICalTok.REPLY.toString());
inv.newToICalendar(true).toICalendar(sr);
ical = sr.toString();
} finally {
if (sr != null) {
sr.close();
}
}
Options options = new Options();
AuthToken authToken = AuthToken.getCsrfUnsecuredAuthToken(getAuthToken(octxt));
options.setAuthToken(authToken.toZAuthToken());
options.setTargetAccount(orgAccount.getName());
options.setTargetAccountBy(AccountBy.name);
options.setUri(uri);
options.setNoSession(true);
ZMailbox zmbox = ZMailbox.getMailbox(options);
zmbox.iCalReply(ical, sender);
} catch (IOException e) {
throw ServiceException.FAILURE("Error while posting REPLY to organizer mailbox host", e);
}
}
}
}
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class TestCalDav method simpleEvent.
public byte[] simpleEvent(Account organizer) throws IOException {
ZVCalendar vcal = new ZVCalendar();
vcal.addVersionAndProdId();
vcal.addProperty(new ZProperty(ICalTok.METHOD, ICalTok.PUBLISH.toString()));
ICalTimeZone tz = ICalTimeZone.lookupByTZID("Africa/Harare");
vcal.addComponent(tz.newToVTimeZone());
ZComponent vevent = new ZComponent(ICalTok.VEVENT);
ParsedDateTime dtstart = parsedDateTime(2020, java.util.Calendar.APRIL, 1, 9, 0, tz);
vevent.addProperty(dtstart.toProperty(ICalTok.DTSTART, false));
ParsedDateTime dtend = parsedDateTime(2020, java.util.Calendar.APRIL, 1, 13, 0, tz);
vevent.addProperty(dtend.toProperty(ICalTok.DTEND, false));
vevent.addProperty(new ZProperty(ICalTok.DTSTAMP, "20140108T224700Z"));
vevent.addProperty(new ZProperty(ICalTok.SUMMARY, "Simple Event"));
vevent.addProperty(new ZProperty(ICalTok.UID, "d1102-42a7-4283-b025-3376dabe53b3"));
vevent.addProperty(new ZProperty(ICalTok.STATUS, ICalTok.CONFIRMED.toString()));
vevent.addProperty(new ZProperty(ICalTok.SEQUENCE, "1"));
// vevent.addProperty(organizer(organizer));
vcal.addComponent(vevent);
return zvcalendarToBytes(vcal);
}
Aggregations