Search in sources :

Example 16 with ParsedDateTime

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;
}
Also used : Element(com.zimbra.common.soap.Element) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 17 with ParsedDateTime

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();
}
Also used : ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 18 with ParsedDateTime

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());
}
Also used : ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) Period(com.zimbra.cs.mailbox.calendar.Period) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException)

Example 19 with ParsedDateTime

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);
                }
            }
        }
    }
}
Also used : Account(com.zimbra.cs.account.Account) ParsedMessageOptions(com.zimbra.cs.mime.ParsedMessageOptions) Options(com.zimbra.client.ZMailbox.Options) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) IOException(java.io.IOException) SetCalendarItem(com.zimbra.cs.redolog.op.SetCalendarItem) ZMailbox(com.zimbra.client.ZMailbox) RenameMailbox(com.zimbra.cs.redolog.op.RenameMailbox) DbMailbox(com.zimbra.cs.db.DbMailbox) CreateMailbox(com.zimbra.cs.redolog.op.CreateMailbox) ZMailbox(com.zimbra.client.ZMailbox) DeleteMailbox(com.zimbra.cs.redolog.op.DeleteMailbox) StringWriter(java.io.StringWriter) AccountAddressMatcher(com.zimbra.cs.util.AccountUtil.AccountAddressMatcher) AuthToken(com.zimbra.cs.account.AuthToken) ZAuthToken(com.zimbra.common.auth.ZAuthToken) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) CreateInvite(com.zimbra.cs.redolog.op.CreateInvite) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 20 with ParsedDateTime

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);
}
Also used : ZComponent(com.zimbra.common.calendar.ZCalendar.ZComponent) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone)

Aggregations

ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)66 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)23 Invite (com.zimbra.cs.mailbox.calendar.Invite)20 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)18 ParseException (java.text.ParseException)16 ArrayList (java.util.ArrayList)16 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)15 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)14 Element (com.zimbra.common.soap.Element)13 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)11 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)10 Account (com.zimbra.cs.account.Account)10 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)10 ZVCalendar (com.zimbra.common.calendar.ZCalendar.ZVCalendar)9 ICalTok (com.zimbra.common.calendar.ZCalendar.ICalTok)8 ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)8 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)7 ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)7 ServiceException (com.zimbra.common.service.ServiceException)7 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)7