Search in sources :

Example 21 with ParsedDuration

use of com.zimbra.common.calendar.ParsedDuration in project zm-mailbox by Zimbra.

the class Invite method decodeMetadata.

/**
     * This API is public for RedoLogging to call into it -- you probably don't want to call it from
     * anywhere else!
     *
     * @param mailboxId
     * @param meta
     * @param calItem
     * @param accountTZ
     * @return
     * @throws ServiceException
     */
public static Invite decodeMetadata(int mailboxId, Metadata meta, CalendarItem calItem, ICalTimeZone accountTZ) throws ServiceException {
    byte btype = (byte) meta.getLong(FN_ITEMTYPE, -1);
    MailItem.Type type = btype >= 0 ? MailItem.Type.of(btype) : MailItem.Type.APPOINTMENT;
    String uid = meta.get(FN_UID, null);
    int mailItemId = (int) meta.getLong(FN_INVMSGID);
    int componentNum = (int) meta.getLong(FN_COMPNUM);
    String classProp = meta.get(FN_CLASS, IcalXmlStrMap.CLASS_PUBLIC);
    boolean classPropSetByMe = meta.getBool(FN_CLASS_SETBYME, false);
    String status = meta.get(FN_STATUS, IcalXmlStrMap.STATUS_CONFIRMED);
    String freebusy = meta.get(FN_APPT_FREEBUSY, null);
    String transp = meta.get(FN_TRANSP, IcalXmlStrMap.TRANSP_OPAQUE);
    boolean sentByMe = meta.getBool(FN_SENTBYME);
    String fragment = meta.get(FN_FRAGMENT, "");
    // default to false for backward compat
    boolean descInMeta = meta.getBool(FN_DESC_IN_META, false);
    String desc = descInMeta ? meta.get(FN_DESC, null) : null;
    String descHtml = descInMeta ? meta.get(FN_DESC_HTML, null) : null;
    long completed = meta.getLong(FN_COMPLETED, 0);
    ParsedDateTime dtStart = null;
    ParsedDateTime dtEnd = null;
    ParsedDuration duration = null;
    RecurId recurrenceId = null;
    TimeZoneMap tzMap = Util.decodeFromMetadata(meta.getMap(FN_TZMAP), accountTZ);
    Metadata metaRecur = meta.getMap(FN_RECURRENCE, true);
    Recurrence.IRecurrence recurrence = null;
    if (metaRecur != null) {
        recurrence = Recurrence.decodeMetadata(metaRecur, tzMap);
    }
    String methodStr = meta.get(FN_METHOD, ICalTok.PUBLISH.toString());
    if (ICalTok.CANCEL.toString().equals(methodStr))
        status = IcalXmlStrMap.STATUS_CANCELLED;
    int flags = (int) meta.getLong(FN_APPT_FLAGS, 0);
    try {
        // DtStart
        dtStart = ParsedDateTime.parse(meta.get(FN_START, null), tzMap);
        // DtEnd
        dtEnd = ParsedDateTime.parse(meta.get(FN_END, null), tzMap);
        if ((flags & APPT_FLAG_ALLDAY) != 0) {
            // Fixup historic data with incorrect all-day start/end format.
            if (dtStart != null)
                dtStart.forceDateOnly();
            if (dtEnd != null)
                dtEnd.forceDateOnly();
        }
        // Duration
        duration = ParsedDuration.parse(meta.get(FN_DURATION, null));
        if (meta.containsKey(FN_RECUR_ID)) {
            Metadata rdata = meta.getMap(FN_RECUR_ID);
            recurrenceId = RecurId.decodeMetadata(rdata, tzMap);
        }
    } catch (ParseException e) {
        throw ServiceException.FAILURE(String.format("Error parsing metadata for invite %s-%s in calItem %s", mailItemId, componentNum, (calItem != null) ? Integer.toString(calItem.getId()) : "(null)"), e);
    }
    String name = meta.get(FN_NAME, "");
    String loc = meta.get(FN_LOCATION, null);
    // For existing invites with no partstat, default to ACCEPTED status.
    String partStat = meta.get(FN_PARTSTAT, IcalXmlStrMap.PARTSTAT_ACCEPTED);
    // For existing invites with no RSVP, default to true.
    boolean rsvp = meta.getBool(FN_RSVP, true);
    long dtstamp = meta.getLong(FN_DTSTAMP, 0);
    long lastModified = meta.getLong(FN_LAST_MODIFIED, 0);
    int seqno = (int) meta.getLong(FN_SEQ_NO, 0);
    int lastFullSeqno = (int) meta.getLong(FN_LAST_FULL_SEQ_NO, seqno);
    ZOrganizer org = null;
    try {
        Metadata metaOrg = meta.getMap(FN_ORGANIZER, true);
        org = metaOrg != null ? new ZOrganizer(metaOrg) : null;
    } catch (ServiceException e) {
        sLog.warn("Problem decoding organizer for calItem %s invite %s-%s", (calItem != null) ? Integer.toString(calItem.getId()) : "(null)", mailItemId, componentNum);
    }
    long numAts = meta.getLong(FN_NUM_ATTENDEES, 0);
    ArrayList<ZAttendee> attendees = new ArrayList<ZAttendee>((int) numAts);
    for (int i = 0; i < numAts; i++) {
        try {
            Metadata metaAttendee = meta.getMap(FN_ATTENDEE + i, true);
            if (metaAttendee != null)
                attendees.add(new ZAttendee(metaAttendee));
        } catch (ServiceException e) {
            ZimbraLog.calendar.warn("Problem decoding attendee %s for calendar item %s invite %s-%s", i, (calItem != null) ? Integer.toString(calItem.getId()) : "(null)", mailItemId, componentNum);
        }
    }
    boolean isOrganizer = false;
    if (meta.containsKey(FN_IS_ORGANIZER)) {
        isOrganizer = meta.getBool(FN_IS_ORGANIZER);
    } else {
        // backward compat for invites created before FN_IS_ORGANIZER was introduced
        if (org != null) {
            String orgAddr = org.getAddress();
            Account account = MailboxManager.getInstance().getMailboxById(mailboxId).getAccount();
            AccountAddressMatcher acctMatcher = new AccountAddressMatcher(account);
            isOrganizer = acctMatcher.matches(orgAddr);
        } else {
            // If there are other attendees, it's an Outlook POP/IMAP bug.  If not,
            // it's a properly formatted single-user event.  See isOrganizer()
            // method for more info.
            isOrganizer = numAts < 1;
        }
    }
    String priority = meta.get(FN_PRIORITY, null);
    String pctComplete = meta.get(FN_PCT_COMPLETE, null);
    List<String> comments = null;
    int numComm = (int) meta.getLong(FN_NUM_COMMENTS, 0);
    if (numComm > 0) {
        comments = new ArrayList<String>(numComm);
        for (int i = 0; i < numComm; i++) {
            String comm = meta.get(FN_COMMENT + i, null);
            if (comm != null)
                comments.add(comm);
        }
    }
    List<String> contacts = null;
    int numContacts = (int) meta.getLong(FN_NUM_CONTACTS, 0);
    if (numContacts > 0) {
        contacts = new ArrayList<String>(numContacts);
        for (int i = 0; i < numContacts; i++) {
            String contact = meta.get(FN_CONTACT + i, null);
            if (contact != null)
                contacts.add(contact);
        }
    }
    List<String> categories = null;
    int numCat = (int) meta.getLong(FN_NUM_CATEGORIES, 0);
    if (numCat > 0) {
        categories = new ArrayList<String>(numCat);
        for (int i = 0; i < numCat; i++) {
            String cat = meta.get(FN_CATEGORY + i, null);
            if (cat != null)
                categories.add(cat);
        }
    }
    Geo geo = null;
    Metadata metaGeo = meta.getMap(FN_GEO, true);
    if (metaGeo != null)
        geo = Util.decodeGeoFromMetadata(metaGeo);
    String url = meta.get(FN_URL, null);
    Invite invite = new Invite(type, methodStr, tzMap, calItem, uid, status, priority, pctComplete, completed, freebusy, transp, classProp, dtStart, dtEnd, duration, recurrence, isOrganizer, org, attendees, name, loc, flags, partStat, rsvp, recurrenceId, dtstamp, lastModified, seqno, lastFullSeqno, mailboxId, mailItemId, componentNum, sentByMe, desc, descHtml, fragment, comments, categories, contacts, geo, url);
    // a little hacky, but necessary
    invite.mDescInMeta = descInMeta;
    invite.setClassPropSetByMe(classPropSetByMe);
    long numAlarms = meta.getLong(FN_NUM_ALARMS, 0);
    for (int i = 0; i < numAlarms; i++) {
        try {
            Metadata metaAlarm = meta.getMap(FN_ALARM + i, true);
            if (metaAlarm != null) {
                Alarm alarm = Alarm.decodeMetadata(metaAlarm);
                if (alarm != null)
                    invite.addAlarm(alarm);
            }
        } catch (ServiceException e) {
            ZimbraLog.calendar.warn("Problem decoding alarm %s for calendar item %s invite %s-%s", i, (calItem != null) ? Integer.toString(calItem.getId()) : "(null)", mailItemId, componentNum, e);
        }
    }
    List<ZProperty> xprops = Util.decodeXPropsFromMetadata(meta);
    if (xprops != null) {
        for (ZProperty xprop : xprops) {
            boolean isHtmlDesc = false;
            if (ICalTok.X_ALT_DESC.equals(xprop.getToken())) {
                // Backward compat.  We used to save X-ALT-DESC property as an x-prop.  Now we use it
                // for HTML description, when FMTTYPE=text/html.
                ZParameter fmttype = xprop.getParameter(ICalTok.FMTTYPE);
                if (fmttype != null && MimeConstants.CT_TEXT_HTML.equalsIgnoreCase(fmttype.getValue())) {
                    isHtmlDesc = true;
                    invite.mDescHtml = xprop.getValue();
                }
            }
            if (!isHtmlDesc)
                invite.addXProp(xprop);
        }
    }
    invite.setDontIndexMimeMessage(meta.getBool(FN_DONT_INDEX_MM, false));
    boolean localOnly = meta.getBool(FN_LOCAL_ONLY, false);
    invite.setLocalOnly(localOnly);
    invite.sanitize(false);
    return invite;
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Account(com.zimbra.cs.account.Account) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Metadata(com.zimbra.cs.mailbox.Metadata) ArrayList(java.util.ArrayList) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter) Geo(com.zimbra.common.calendar.Geo) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) AccountAddressMatcher(com.zimbra.cs.util.AccountUtil.AccountAddressMatcher) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParseException(java.text.ParseException)

Example 22 with ParsedDuration

use of com.zimbra.common.calendar.ParsedDuration in project zm-mailbox by Zimbra.

the class InviteChanges method diffInvites.

private void diffInvites(Invite inv1, Invite inv2) {
    // Subject
    if (!StringUtil.equal(inv1.getName(), inv2.getName()))
        mChanges |= SUBJECT;
    // LOCATION
    if (!StringUtil.equal(inv1.getLocation(), inv2.getLocation()))
        mChanges |= LOCATION;
    // DTSTART
    boolean dtStartChanged;
    ParsedDateTime dtStart1 = inv1.getStartTime();
    ParsedDateTime dtStart2 = inv2.getStartTime();
    if (dtStart1 == null || dtStart2 == null)
        dtStartChanged = dtStart1 != dtStart2;
    else
        dtStartChanged = !StringUtil.equal(dtStart1.getDateTimePartString(false), dtStart2.getDateTimePartString(false));
    if (dtStartChanged) {
        mChanges |= TIME;
    } else {
        // DTEND
        boolean dtEndChanged;
        ParsedDateTime dtEnd1 = inv1.getEndTime();
        ParsedDateTime dtEnd2 = inv2.getEndTime();
        if (dtEnd1 == null || dtEnd2 == null)
            dtEndChanged = dtEnd1 != dtEnd2;
        else
            dtEndChanged = !StringUtil.equal(dtEnd1.getDateTimePartString(false), dtEnd2.getDateTimePartString(false));
        if (dtEndChanged) {
            mChanges |= TIME;
        } else {
            boolean durationChanged;
            ParsedDuration dur1 = inv1.getDuration();
            ParsedDuration dur2 = inv2.getDuration();
            if (dur1 == null || dur2 == null)
                durationChanged = dur1 != dur2;
            else
                durationChanged = !dur1.equals(dur2);
            if (durationChanged)
                mChanges |= TIME;
        }
    }
    // Recurrence
    boolean recurChanged;
    IRecurrence recur1 = inv1.getRecurrence();
    IRecurrence recur2 = inv2.getRecurrence();
    if (recur1 == null || recur2 == null) {
        recurChanged = recur1 != recur2;
    } else {
        recurChanged = !Recurrence.sameSeriesRules(recur1, recur2);
    }
    if (recurChanged)
        mChanges |= RECURRENCE;
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 23 with ParsedDuration

use of com.zimbra.common.calendar.ParsedDuration in project zm-mailbox by Zimbra.

the class Period method parse.

public static Period parse(String value, ICalTimeZone tz, TimeZoneMap tzmap) throws ServiceException, ParseException {
    String[] parsed = value.split("\\/", 2);
    if (parsed.length != 2 || parsed[0].length() == 0 || parsed[1].length() == 1)
        throw ServiceException.INVALID_REQUEST("Invalid PERIOD value \"" + value + "\"", null);
    ParsedDateTime startTime;
    startTime = ParsedDateTime.parse(parsed[0], tzmap, tz, tzmap.getLocalTimeZone());
    char ch = parsed[1].charAt(0);
    if (ch == 'P' || ch == '+' || ch == '-') {
        ParsedDuration duration = ParsedDuration.parse(parsed[1]);
        return new Period(startTime, duration);
    } else {
        ParsedDateTime endTime = ParsedDateTime.parse(parsed[1], tzmap, tz, tzmap.getLocalTimeZone());
        return new Period(startTime, endTime);
    }
}
Also used : ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Aggregations

ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)23 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)23 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)10 ParseException (java.text.ParseException)9 ArrayList (java.util.ArrayList)9 Element (com.zimbra.common.soap.Element)8 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)7 Invite (com.zimbra.cs.mailbox.calendar.Invite)6 Geo (com.zimbra.common.calendar.Geo)5 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)5 ServiceException (com.zimbra.common.service.ServiceException)5 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)5 ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)5 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)5 Attach (com.zimbra.common.calendar.Attach)4 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)4 ICalTok (com.zimbra.common.calendar.ZCalendar.ICalTok)4 ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)4 Account (com.zimbra.cs.account.Account)3 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)3