Search in sources :

Example 1 with Geo

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

the class CacheToXML method encodeInstanceData.

// SOAP SearchResponse format for calendar items
//
// <appt> or <task>
//     f - flags
//     t - tags
//     <or> - organizer
//       a - address
//       d - CN (display name)
//       sentBy - sent-by address
//     x-uid - UID
//     uid - UID
//     priority
//     ptst - PARTSTAT
//     fb - intended freebusy (appt only)
//     fba - actual freebusy (appt only)
//     transp - TRANSP (appt only)
//     percentComplete - PERCENT-COMPLETE (task only)
//     name - SUMMARY
//     loc - LOCATION
//     fr - fragment
//     otherAtt - has attendees ("other" meaning other than organizer)
//     isOrg - mailbox owner is organizer
//     id - "<calItemId>-<invId>" (or is it just calItemId?  can this be fully-qualified?)
//     invId - invite id
//     compNum - component number
//     l - folder id (can be fully-qualified)
//     status - STATUS
//     class - CLASS
//     dueDate - DUE (task only)
//     dur - DURATION
//     allDay - is this an all-day appt/task?
//     recur - is this recurring?
//     cat - CATEGORIES
//     geo - GEO
//     <inst>+ (attrs are given only when different from default value at <appt> level)
//         fba
//         ptst
//         s - DTSTART
//         tzo - timezone offset in millis (for all-day only)
//         dur
//         ex - instance is an exception
//         // begin exception block (following attrs are possible only when ex=1)
//         invId - "<calItemId>-<invId>" (notice this is different from invId at appt/task)
//         compNum
//         fr
//         priority
//         fb
//         transp
//         percentComplete
//         name
//         loc
//         otherAtt
//         isOrg
//         status
//         class
//         allDay
//         recur
//         cat
//         geo
//         // end exception block
//         // NOTE: Only invId is a new instance-level attribute.
//     <alarmData> (next alarm to fire)
//         nextAlarm - time at which the next alarm fires
//         alarmInstStart - start time of the instance for the alarm
//         name - SUMMARY of the instance
//         loc - LOCATION of the instance
//         invId - integer invite id of the instance
//         compNum - component number of the instance
//         <alarm> (details on the alarm itself)
//             action - alarm ACTION type
//             <trigger>
//                 <abs> (mutually exclusive with <rel>)
//                     d - absolute alarm trigger time
//                 <rel> (a duration, plus "related" attr)
//                     neg - value is negative
//                     w - weeks
//                     d - days
//                     h - hours
//                     m - minutes
//                     s - seconds
//                     related - duration is from start or end of instance
//                 <repeat> (a duration, plus "count" attr)
//                     neg - value is negative
//                     w - weeks
//                     d - days
//                     h - hours
//                     m - minutes
//                     s - seconds
//                     count - how many times to repeat after initial
//             <desc>text</desc> - DESCRIPTION
//             <attach> (attachment info)
//                 uri - URI of the external attachment
//                 ct - Content-Type of attachment
//             or, <attach>base64-encoded attachment data</attach> (Q: why not ct as well?)
//             <summary>email summary</summary> (action=email only)
//             <at>+ (Attendees, for email recipients)
//                 a - address
//                 url - address (for backward compat)
//                 d - display name
//                 sentBy - sent-by
//                 dir
//                 lang
//                 cutype
//                 role
//                 ptst
//                 member
//                 delTo - DELEGATED-TO
//                 delFrom - DELEGATED-FROM
//                 // Q: Do we really need anything other than "a", and possibly "d" and "sentBy"?
//
private static void encodeInstanceData(Element parent, ItemIdFormatter ifmt, int calItemId, InstanceData instance, FullInstanceData defaultInstance, boolean isException, boolean isAppointment, boolean allowPrivateAccess, boolean legacyFormat) throws ServiceException {
    if (isException && instance.getDtStart() != null) {
        parent.addAttribute(MailConstants.A_CAL_START_TIME, instance.getDtStart().longValue());
    }
    if (instance.getDuration() != null) {
        String attribute = !legacyFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION;
        parent.addAttribute(attribute, instance.getDuration().longValue());
    }
    //            parent.addAttribute(MailConstants.A_TASK_DUE_DATE, instance.getDtEnd().longValue());
    if (instance.getTZOffset() != null)
        parent.addAttribute(MailConstants.A_CAL_TZ_OFFSET, instance.getTZOffset().longValue());
    parent.addAttribute(MailConstants.A_CAL_PARTSTAT, instance.getPartStat());
    if (isAppointment)
        parent.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, instance.getFreeBusyActual());
    else
        parent.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, instance.getPercentComplete());
    parent.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, instance.getRecurIdZ());
    if (!(instance instanceof FullInstanceData))
        return;
    FullInstanceData fullInstance = (FullInstanceData) instance;
    boolean showAll = allowPrivateAccess || fullInstance.isPublic(defaultInstance);
    if (isException) {
        parent.addAttribute(MailConstants.A_CAL_IS_EXCEPTION, true);
        // HACK: ZWC insists on receiving recur=false on exceptions.
        parent.addAttribute(MailConstants.A_CAL_RECUR, false);
    }
    // Organizer
    ZOrganizer organizer = fullInstance.getOrganizer();
    if (organizer != null) {
        Element orgElt = parent.addUniqueElement(MailConstants.E_CAL_ORGANIZER);
        String addr = IDNUtil.toUnicode(organizer.getAddress());
        orgElt.addAttribute(MailConstants.A_ADDRESS, addr);
        orgElt.addAttribute(MailConstants.A_URL, addr);
        orgElt.addAttribute(MailConstants.A_DISPLAY, organizer.getCn());
        orgElt.addAttribute(MailConstants.A_CAL_SENTBY, organizer.getSentBy());
    }
    if (showAll) {
        parent.addAttribute(MailConstants.A_CAL_PRIORITY, fullInstance.getPriority());
        parent.addAttribute(MailConstants.A_CAL_PARTSTAT, fullInstance.getPartStat());
        if (isAppointment) {
            parent.addAttribute(MailConstants.A_APPT_FREEBUSY, fullInstance.getFreeBusyIntended());
            parent.addAttribute(MailConstants.A_APPT_TRANSPARENCY, fullInstance.getTransparency());
        }
        parent.addAttribute(MailConstants.A_NAME, fullInstance.getSummary());
        parent.addAttribute(MailConstants.A_CAL_LOCATION, fullInstance.getLocation());
        List<String> categories = fullInstance.getCategories();
        if (categories != null) {
            for (String cat : categories) {
                parent.addElement(MailConstants.E_CAL_CATEGORY).setText(cat);
            }
        }
        Geo geo = fullInstance.getGeo();
        if (geo != null)
            geo.toXml(parent);
        // fragment has already been sanitized...
        String fragment = fullInstance.getFragment();
        if (fragment != null && !fragment.equals(""))
            parent.addAttribute(MailConstants.E_FRAG, fragment, Element.Disposition.CONTENT);
        Integer numAttendees = fullInstance.getNumAttendees();
        if (numAttendees != null)
            parent.addAttribute(MailConstants.A_CAL_OTHER_ATTENDEES, numAttendees.intValue() > 0);
        if (fullInstance.hasAlarm() != null)
            parent.addAttribute(MailConstants.A_CAL_ALARM, fullInstance.hasAlarm().booleanValue());
    }
    if (fullInstance.isOrganizer() != null)
        parent.addAttribute(MailConstants.A_CAL_ISORG, fullInstance.isOrganizer().booleanValue());
    if (!isException)
        parent.addAttribute(MailConstants.A_ID, ifmt.formatItemId(calItemId));
    parent.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(calItemId, fullInstance.getInvId()));
    parent.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, fullInstance.getCompNum());
    parent.addAttribute(MailConstants.A_CAL_STATUS, fullInstance.getStatus());
    parent.addAttribute(MailConstants.A_CAL_CLASS, fullInstance.getClassProp());
    if (fullInstance.isAllDay() != null)
        parent.addAttribute(MailConstants.A_CAL_ALLDAY, fullInstance.isAllDay().booleanValue());
    if (fullInstance.isDraft() != null)
        parent.addAttribute(MailConstants.A_CAL_DRAFT, fullInstance.isDraft().booleanValue());
    if (fullInstance.isNeverSent() != null)
        parent.addAttribute(MailConstants.A_CAL_NEVER_SENT, fullInstance.isNeverSent().booleanValue());
}
Also used : Geo(com.zimbra.common.calendar.Geo) Element(com.zimbra.common.soap.Element) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer)

Example 2 with Geo

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

the class Invite method encodeMetadata.

/**
     * This is only really public to support serializing RedoOps -- you
     * really don't want to call this API from anywhere else
     *
     * @param inv
     * @return
     */
public static Metadata encodeMetadata(Invite inv) {
    Metadata meta = new Metadata();
    // looked before local-only flag was introduced.
    if (inv.isLocalOnly())
        meta.put(FN_LOCAL_ONLY, true);
    meta.put(FN_ITEMTYPE, inv.getItemType().toByte());
    meta.put(FN_UID, inv.getUid());
    meta.put(FN_INVMSGID, inv.getMailItemId());
    meta.put(FN_COMPNUM, inv.getComponentNum());
    meta.put(FN_SENTBYME, inv.mSentByMe);
    if (!inv.isPublic())
        meta.put(FN_CLASS, inv.getClassProp());
    meta.put(FN_CLASS_SETBYME, inv.classPropSetByMe());
    meta.put(FN_STATUS, inv.getStatus());
    if (inv.hasFreeBusy())
        meta.put(FN_APPT_FREEBUSY, inv.getFreeBusy());
    meta.put(FN_TRANSP, inv.getTransparency());
    meta.put(FN_START, inv.mStart);
    meta.put(FN_END, inv.mEnd);
    if (inv.mCompleted != 0)
        meta.put(FN_COMPLETED, inv.mCompleted);
    meta.put(FN_DURATION, inv.mDuration);
    meta.put(FN_METHOD, inv.mMethod.toString());
    meta.put(FN_FRAGMENT, inv.mFragment);
    // Put mDescription in metadata if it's short enough.
    if (inv.mDescInMeta) {
        meta.put(FN_DESC_IN_META, inv.mDescInMeta);
        if (inv.mDescription != null)
            meta.put(FN_DESC, inv.mDescription);
        if (inv.mDescHtml != null)
            meta.put(FN_DESC_HTML, inv.mDescHtml);
    }
    if (inv.mRecurrence != null) {
        meta.put(FN_RECURRENCE, inv.mRecurrence.encodeMetadata());
    }
    meta.put(FN_NAME, inv.getName());
    meta.put(FN_LOCATION, inv.mLocation);
    meta.put(FN_APPT_FLAGS, inv.getFlags());
    meta.put(FN_PARTSTAT, inv.getPartStat());
    meta.put(FN_RSVP, inv.getRsvp());
    meta.put(FN_TZMAP, Util.encodeAsMetadata(inv.mTzMap));
    if (inv.hasRecurId()) {
        meta.put(FN_RECUR_ID, inv.getRecurId().encodeMetadata());
    }
    meta.put(FN_DTSTAMP, inv.getDTStamp());
    if (inv.getLastModified() != 0)
        meta.put(FN_LAST_MODIFIED, inv.getLastModified());
    meta.put(FN_SEQ_NO, inv.getSeqNo());
    meta.put(FN_LAST_FULL_SEQ_NO, inv.getLastFullSeqNo());
    if (inv.hasOrganizer()) {
        meta.put(FN_ORGANIZER, inv.getOrganizer().encodeMetadata());
    }
    meta.put(FN_IS_ORGANIZER, inv.isOrganizer());
    List<ZAttendee> ats = inv.getAttendees();
    meta.put(FN_NUM_ATTENDEES, String.valueOf(ats.size()));
    int i = 0;
    for (Iterator<ZAttendee> iter = ats.iterator(); iter.hasNext(); i++) {
        ZAttendee at = iter.next();
        meta.put(FN_ATTENDEE + i, at.encodeAsMetadata());
    }
    meta.put(FN_PRIORITY, inv.getPriority());
    meta.put(FN_PCT_COMPLETE, inv.getPercentComplete());
    List<String> comments = inv.getComments();
    if (comments != null) {
        int numComm = comments.size();
        if (numComm > 0) {
            meta.put(FN_NUM_COMMENTS, numComm);
            int idx = 0;
            for (String comm : comments) {
                meta.put(FN_COMMENT + idx, comm);
                idx++;
            }
        }
    }
    List<String> contacts = inv.getContacts();
    if (contacts != null) {
        int numContacts = contacts.size();
        if (numContacts > 0) {
            meta.put(FN_NUM_CONTACTS, numContacts);
            int idx = 0;
            for (String contact : contacts) {
                meta.put(FN_CONTACT + idx, contact);
                idx++;
            }
        }
    }
    List<String> categories = inv.getCategories();
    if (categories != null) {
        int numCat = categories.size();
        if (numCat > 0) {
            meta.put(FN_NUM_CATEGORIES, numCat);
            int idx = 0;
            for (String cat : categories) {
                meta.put(FN_CATEGORY + idx, cat);
                idx++;
            }
        }
    }
    Geo geo = inv.getGeo();
    if (geo != null) {
        meta.put(FN_GEO, Util.encodeMetadata(geo));
    }
    String url = inv.getUrl();
    if (url != null && url.length() > 0)
        meta.put(FN_URL, url);
    if (!inv.mAlarms.isEmpty()) {
        meta.put(FN_NUM_ALARMS, inv.mAlarms.size());
        i = 0;
        for (Iterator<Alarm> iter = inv.mAlarms.iterator(); iter.hasNext(); i++) {
            Alarm alarm = iter.next();
            meta.put(FN_ALARM + i, alarm.encodeMetadata());
        }
    }
    if (inv.mXProps.size() > 0)
        Util.encodeXPropsAsMetadata(meta, inv.xpropsIterator());
    if (inv.mDontIndexMimeMessage)
        meta.put(FN_DONT_INDEX_MM, true);
    return meta;
}
Also used : Geo(com.zimbra.common.calendar.Geo) Metadata(com.zimbra.cs.mailbox.Metadata)

Example 3 with Geo

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

the class Invite method createFromCalendar.

private static void createFromCalendar(List<Invite> toAdd, Account account, String fragment, String method, TimeZoneMap tzmap, Iterator<ZComponent> compIter, boolean sentByMe, Mailbox mbx, int mailItemId, boolean continueOnError, InviteVisitor visitor) throws ServiceException {
    int compNum = 0;
    while (compIter.hasNext()) {
        ZComponent comp = compIter.next();
        Invite newInv = null;
        try {
            MailItem.Type type;
            ICalTok compTypeTok = comp.getTok();
            if (compTypeTok == null)
                continue;
            if (ICalTok.VTODO.equals(compTypeTok)) {
                type = MailItem.Type.TASK;
            } else {
                type = MailItem.Type.APPOINTMENT;
            }
            switch(compTypeTok) {
                case VEVENT:
                case VTODO:
                    boolean isEvent = ICalTok.VEVENT.equals(compTypeTok);
                    boolean isTodo = ICalTok.VTODO.equals(compTypeTok);
                    try {
                        newInv = new Invite(type, method, tzmap, false);
                        // set to true later if X-ZIMBRA-LOCAL-ONLY is present
                        newInv.setLocalOnly(false);
                        if (toAdd != null)
                            toAdd.add(newInv);
                        List<Object> addRecurs = new ArrayList<Object>();
                        List<Object> subRecurs = new ArrayList<Object>();
                        newInv.setComponentNum(compNum);
                        if (mbx != null)
                            newInv.setMailboxId(mbx.getId());
                        newInv.setMailItemId(mailItemId);
                        newInv.setSentByMe(sentByMe);
                        compNum++;
                        List<ZComponent> subcomponents = Lists.newArrayList(comp.getComponentIterator());
                        for (ZComponent subcomp : subcomponents) {
                            ICalTok subCompTypeTok = subcomp.getTok();
                            switch(subCompTypeTok) {
                                case VALARM:
                                    Alarm alarm = Alarm.parse(subcomp);
                                    if (alarm != null)
                                        newInv.addAlarm(alarm);
                                    break;
                                default:
                            }
                        }
                        boolean isTodoCompleted = false;
                        boolean sawIntendedFreeBusy = false;
                        List<ZProperty> properties = Lists.newArrayList(comp.getPropertyIterator());
                        for (ZProperty prop : properties) {
                            String propVal = prop.getValue();
                            ICalTok propToken = prop.getToken();
                            if (propToken == null) {
                                // parse errors later, so ignore them.
                                if (propVal == null || propVal.length() < 1)
                                    continue;
                                String name = prop.getName();
                                if (name.startsWith("X-") || name.startsWith("x-"))
                                    newInv.addXProp(prop);
                            } else if (propToken.equals(ICalTok.CATEGORIES)) {
                                List<String> categories = prop.getValueList();
                                if (categories != null && !categories.isEmpty()) {
                                    for (String cat : categories) {
                                        newInv.addCategory(cat);
                                    }
                                }
                            } else {
                                // parse errors later, so ignore them.
                                if (propVal == null || propVal.length() < 1)
                                    continue;
                                switch(propToken) {
                                    case ORGANIZER:
                                        newInv.setOrganizer(new ZOrganizer(prop));
                                        break;
                                    case ATTENDEE:
                                        newInv.addAttendee(new ZAttendee(prop));
                                        break;
                                    case DTSTAMP:
                                        ParsedDateTime dtstamp = ParsedDateTime.parse(prop, tzmap);
                                        newInv.setDtStamp(dtstamp.getUtcTime());
                                        break;
                                    case LAST_MODIFIED:
                                        ParsedDateTime lastModified = ParsedDateTime.parse(prop, tzmap);
                                        newInv.setLastModified(lastModified.getUtcTime());
                                        break;
                                    case RECURRENCE_ID:
                                        ParsedDateTime rid = ParsedDateTime.parse(prop, tzmap);
                                        if (DebugConfig.enableThisAndFuture) {
                                            newInv.setRecurId(new RecurId(rid, prop.paramVal(ICalTok.RANGE, null)));
                                        } else {
                                            newInv.setRecurId(new RecurId(rid, RecurId.RANGE_NONE));
                                        }
                                        break;
                                    case SEQUENCE:
                                        newInv.setSeqNo(prop.getIntValue());
                                        break;
                                    case DTSTART:
                                        ParsedDateTime dtstart = ParsedDateTime.parse(prop, tzmap);
                                        newInv.setDtStart(dtstart);
                                        if (!dtstart.hasTime())
                                            newInv.setIsAllDayEvent(true);
                                        break;
                                    case DTEND:
                                        if (isEvent) {
                                            ParsedDateTime dtend = ParsedDateTime.parse(prop, tzmap);
                                            newInv.setDtEnd(dtend);
                                            if (!dtend.hasTime())
                                                newInv.setIsAllDayEvent(true);
                                        }
                                        break;
                                    case DUE:
                                        if (isTodo) {
                                            ParsedDateTime due = ParsedDateTime.parse(prop, tzmap);
                                            // DUE is for VTODO what DTEND is for VEVENT.
                                            newInv.setDtEnd(due);
                                            if (!due.hasTime())
                                                newInv.setIsAllDayEvent(true);
                                        }
                                        break;
                                    case DURATION:
                                        ParsedDuration dur = ParsedDuration.parse(propVal);
                                        newInv.setDuration(dur);
                                        break;
                                    case LOCATION:
                                        newInv.setLocation(propVal);
                                        break;
                                    case SUMMARY:
                                        String summary = propVal;
                                        if (summary != null) {
                                            // Make sure SUMMARY is a single line.
                                            summary = summary.replaceAll("[\\\r\\\n]+", " ");
                                        }
                                        prop.setValue(summary);
                                        newInv.setName(summary);
                                        break;
                                    case DESCRIPTION:
                                        newInv.setDescription(propVal, newInv.mDescHtml);
                                        newInv.setFragment(Fragment.getFragment(propVal, true));
                                        break;
                                    case X_ALT_DESC:
                                        ZParameter fmttype = prop.getParameter(ICalTok.FMTTYPE);
                                        if (fmttype != null && MimeConstants.CT_TEXT_HTML.equalsIgnoreCase(fmttype.getValue())) {
                                            String html = propVal;
                                            newInv.setDescription(newInv.mDescription, html);
                                        } else {
                                            // Unknown format.  Just add as an x-prop.
                                            newInv.addXProp(prop);
                                        }
                                        break;
                                    case COMMENT:
                                        newInv.addComment(propVal);
                                        break;
                                    case UID:
                                        newInv.setUid(propVal);
                                        break;
                                    case RRULE:
                                        ZRecur recur = new ZRecur(propVal, tzmap);
                                        addRecurs.add(recur);
                                        newInv.setIsRecurrence(true);
                                        break;
                                    case RDATE:
                                        if (DebugConfig.enableRdate) {
                                            RdateExdate rdate = RdateExdate.parse(prop, tzmap);
                                            addRecurs.add(rdate);
                                            newInv.setIsRecurrence(true);
                                        }
                                        break;
                                    case EXRULE:
                                        ZRecur exrecur = new ZRecur(propVal, tzmap);
                                        subRecurs.add(exrecur);
                                        newInv.setIsRecurrence(true);
                                        break;
                                    case EXDATE:
                                        RdateExdate exdate = RdateExdate.parse(prop, tzmap);
                                        subRecurs.add(exdate);
                                        newInv.setIsRecurrence(true);
                                        break;
                                    case STATUS:
                                        String status = IcalXmlStrMap.sStatusMap.toXml(propVal);
                                        if (status != null) {
                                            if (IcalXmlStrMap.STATUS_IN_PROCESS.equals(status)) {
                                                String zstatus = prop.getParameterVal(ICalTok.X_ZIMBRA_STATUS, null);
                                                if (ICalTok.X_ZIMBRA_STATUS_WAITING.toString().equals(zstatus) || ICalTok.X_ZIMBRA_STATUS_DEFERRED.toString().equals(zstatus)) {
                                                    newInv.setStatus(IcalXmlStrMap.sStatusMap.toXml(zstatus));
                                                } else {
                                                    newInv.setStatus(status);
                                                }
                                            } else {
                                                newInv.setStatus(status);
                                                if (isTodo && IcalXmlStrMap.STATUS_COMPLETED.equals(status))
                                                    isTodoCompleted = true;
                                            }
                                        }
                                        break;
                                    case TRANSP:
                                        // TRANSP is examined only when intended F/B is not supplied.
                                        if (isEvent && !sawIntendedFreeBusy) {
                                            String transp = IcalXmlStrMap.sTranspMap.toXml(propVal);
                                            if (transp != null) {
                                                newInv.setTransparency(transp);
                                                // If opaque, don't set intended f/b because there are multiple possibilities.
                                                if (newInv.isTransparent())
                                                    newInv.setFreeBusy(IcalXmlStrMap.FBTYPE_FREE);
                                            }
                                        }
                                        break;
                                    case CLASS:
                                        String classProp = IcalXmlStrMap.sClassMap.toXml(propVal);
                                        if (classProp != null)
                                            newInv.setClassProp(classProp);
                                        break;
                                    case X_MICROSOFT_CDO_ALLDAYEVENT:
                                        if (isEvent) {
                                            if (prop.getBoolValue())
                                                newInv.setIsAllDayEvent(true);
                                        }
                                        break;
                                    case X_MICROSOFT_CDO_INTENDEDSTATUS:
                                        sawIntendedFreeBusy = true;
                                        if (isEvent) {
                                            String fb = IcalXmlStrMap.sOutlookFreeBusyMap.toXml(propVal);
                                            if (fb != null) {
                                                newInv.setFreeBusy(fb);
                                                // Intended F/B takes precedence over TRANSP.
                                                if (IcalXmlStrMap.FBTYPE_FREE.equals(fb))
                                                    newInv.setTransparency(IcalXmlStrMap.TRANSP_TRANSPARENT);
                                                else
                                                    newInv.setTransparency(IcalXmlStrMap.TRANSP_OPAQUE);
                                            }
                                        }
                                        break;
                                    case PRIORITY:
                                        String prio = propVal;
                                        if (prio != null)
                                            newInv.setPriority(prio);
                                        break;
                                    case PERCENT_COMPLETE:
                                        if (isTodo) {
                                            String pctComplete = propVal;
                                            if (pctComplete != null) {
                                                newInv.setPercentComplete(pctComplete);
                                                if (prop.getIntValue() == 100)
                                                    isTodoCompleted = true;
                                            }
                                        }
                                        break;
                                    case COMPLETED:
                                        if (isTodo) {
                                            ParsedDateTime completed = ParsedDateTime.parseUtcOnly(propVal);
                                            newInv.setCompleted(completed.getUtcTime());
                                            isTodoCompleted = true;
                                        }
                                        break;
                                    case CONTACT:
                                        newInv.addContact(propVal);
                                        break;
                                    case GEO:
                                        Geo geo = Geo.parse(prop);
                                        newInv.setGeo(geo);
                                        break;
                                    case URL:
                                        newInv.setUrl(propVal);
                                        break;
                                    case X_ZIMBRA_LOCAL_ONLY:
                                        if (prop.getBoolValue())
                                            newInv.setLocalOnly(true);
                                        break;
                                    case X_ZIMBRA_DISCARD_EXCEPTIONS:
                                        newInv.addXProp(prop);
                                        break;
                                    case X_ZIMBRA_CHANGES:
                                        newInv.addXProp(prop);
                                        break;
                                    case ATTACH:
                                        Attach attach = Attach.parse(prop);
                                        if (attach.getBinaryB64Data() != null) {
                                            newInv.addIcalendarAttach(attach);
                                        }
                                        break;
                                }
                            }
                        }
                        if (isTodoCompleted) {
                            // set the status to Completed.
                            newInv.setStatus(IcalXmlStrMap.STATUS_COMPLETED);
                            // set percent-complete to 100
                            newInv.setPercentComplete(Integer.toString(100));
                            if (// set COMPLETED property to now if not already set.
                            newInv.getCompleted() == 0)
                                newInv.setCompleted(System.currentTimeMillis());
                        }
                        newInv.setIsOrganizer(account);
                        newInv.validateDuration();
                        ParsedDuration duration = newInv.getDuration();
                        boolean durationCalculated = false;
                        if (duration == null) {
                            ParsedDateTime end = newInv.getEndTime();
                            if (end != null && newInv.getStartTime() != null) {
                                duration = end.difference(newInv.getStartTime());
                                durationCalculated = true;
                            }
                        }
                        if (!addRecurs.isEmpty() || !subRecurs.isEmpty()) {
                            // We have a recurrence.  Make sure DTSTART is not null.
                            ParsedDateTime st = newInv.getStartTime();
                            if (st == null) {
                                ParsedDateTime et = newInv.getEndTime();
                                if (et != null) {
                                    if (et.hasTime())
                                        st = et.add(ParsedDuration.NEGATIVE_ONE_SECOND);
                                    else
                                        st = et.add(ParsedDuration.NEGATIVE_ONE_DAY);
                                    newInv.setDtStart(st);
                                } else {
                                    // Both DTSTART and DTEND are unspecified.  Recurrence makes no sense!
                                    throw ServiceException.INVALID_REQUEST("recurrence used without DTSTART", null);
                                }
                            }
                            if (durationCalculated && newInv.getItemType() == MailItem.Type.TASK) {
                                if (newInv.getStartTime() != null && !newInv.getStartTime().hasTime()) {
                                    duration = ParsedDuration.ONE_DAY;
                                } else {
                                    duration = ParsedDuration.ONE_SECOND;
                                }
                            }
                        }
                        InviteInfo inviteInfo = new InviteInfo(newInv);
                        List<IRecurrence> addRules = new ArrayList<IRecurrence>();
                        if (addRecurs.size() > 0) {
                            for (Iterator<Object> iter = addRecurs.iterator(); iter.hasNext(); ) {
                                Object next = iter.next();
                                if (next instanceof ZRecur) {
                                    ZRecur cur = (ZRecur) next;
                                    addRules.add(new Recurrence.SimpleRepeatingRule(newInv.getStartTime(), duration, cur, inviteInfo));
                                } else if (next instanceof RdateExdate) {
                                    RdateExdate rdate = (RdateExdate) next;
                                    addRules.add(new Recurrence.SingleDates(rdate, duration, inviteInfo));
                                }
                            }
                        }
                        List<IRecurrence> subRules = new ArrayList<IRecurrence>();
                        if (subRecurs.size() > 0) {
                            for (Iterator<Object> iter = subRecurs.iterator(); iter.hasNext(); ) {
                                Object next = iter.next();
                                if (next instanceof ZRecur) {
                                    ZRecur cur = (ZRecur) iter.next();
                                    subRules.add(new Recurrence.SimpleRepeatingRule(newInv.getStartTime(), duration, cur, inviteInfo));
                                } else if (next instanceof RdateExdate) {
                                    RdateExdate exdate = (RdateExdate) next;
                                    subRules.add(new Recurrence.SingleDates(exdate, duration, inviteInfo));
                                }
                            }
                        }
                        if (newInv.hasRecurId()) {
                            if (addRules.size() > 0) {
                                newInv.setRecurrence(new Recurrence.ExceptionRule(newInv.getRecurId(), newInv.getStartTime(), duration, new InviteInfo(newInv), addRules, subRules));
                            }
                        } else {
                            if (addRules.size() > 0) {
                                // since exclusions can't affect DtStart, just ignore them if there are no add rules
                                newInv.setRecurrence(new Recurrence.RecurrenceRule(newInv.getStartTime(), duration, new InviteInfo(newInv), addRules, subRules));
                            }
                        }
                        String location = newInv.getLocation();
                        if (location == null)
                            newInv.setLocation("");
                        // Process callback.
                        if (visitor != null)
                            visitor.visit(newInv);
                    } catch (ParseException e) {
                        throw ServiceException.PARSE_ERROR("Unable to parse iCalendar data: " + e.getMessage(), e);
                    }
                    break;
            }
        } catch (ServiceException e) {
            if (!continueOnError)
                throw e;
            if (newInv != null)
                logIcsParseImportError(newInv, e);
            else
                ZimbraLog.calendar.warn("Skipping error during ics parse/import", e);
        } catch (RuntimeException e) {
            if (!continueOnError)
                throw e;
            if (newInv != null)
                logIcsParseImportError(newInv, e);
            else
                ZimbraLog.calendar.warn("Skipping error during ics parse/import", e);
        }
    }
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ArrayList(java.util.ArrayList) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZComponent(com.zimbra.common.calendar.ZCalendar.ZComponent) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Attach(com.zimbra.common.calendar.Attach) 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) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParseException(java.text.ParseException)

Example 4 with Geo

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

the class ZAppointmentHit method addInstances.

static void addInstances(Element e, List<ZSearchHit> appts, TimeZone timeZone, boolean isTask) throws ServiceException {
    String id = e.getAttribute(MailConstants.A_ID);
    String freeBusyActual = e.getAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, null);
    String transparency = e.getAttribute(MailConstants.A_APPT_TRANSPARENCY, null);
    String status = e.getAttribute(MailConstants.A_CAL_STATUS, null);
    String classProp = e.getAttribute(MailConstants.A_CAL_CLASS, null);
    String pstatus = e.getAttribute(MailConstants.A_CAL_PARTSTAT, null);
    boolean isAllDay = e.getAttributeBool(MailConstants.A_CAL_ALLDAY, false);
    boolean isDraft = e.getAttributeBool(MailConstants.A_CAL_DRAFT, false);
    boolean otherAtt = e.getAttributeBool(MailConstants.A_CAL_OTHER_ATTENDEES, false);
    boolean isAlarm = e.getAttributeBool(MailConstants.A_CAL_ALARM, false);
    boolean isRecurring = e.getAttributeBool(MailConstants.A_CAL_RECUR, false);
    String flags = e.getAttribute(MailConstants.A_FLAGS, null);
    String tags = e.getAttribute(MailConstants.A_TAGS, null);
    String name = e.getAttribute(MailConstants.A_NAME, null);
    String location = e.getAttribute(MailConstants.A_CAL_LOCATION, null);
    List<String> categories = null;
    Iterator<Element> catIter = e.elementIterator(MailConstants.E_CAL_CATEGORY);
    if (catIter.hasNext()) {
        categories = new ArrayList<String>();
        for (; catIter.hasNext(); ) {
            String cat = catIter.next().getTextTrim();
            categories.add(cat);
        }
    }
    Geo geo = null;
    Element geoElem = e.getOptionalElement(MailConstants.E_CAL_GEO);
    if (geoElem != null)
        geo = Geo.parse(geoElem);
    String inviteId = e.getAttribute(MailConstants.A_CAL_INV_ID, null);
    String inviteCompNumber = e.getAttribute(MailConstants.A_CAL_COMPONENT_NUM, null);
    boolean isOrganizer = e.getAttributeBool(MailConstants.A_CAL_ISORG, false);
    String priority = e.getAttribute(MailConstants.A_CAL_PRIORITY, null);
    String percentComplete = e.getAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, null);
    long dueDate = e.getAttributeLong(MailConstants.A_TASK_DUE_DATE, 0);
    long duration = e.getAttributeLong(MailConstants.A_CAL_NEW_DURATION, 0);
    long hitDate = e.getAttributeLong(MailConstants.A_DATE, 0);
    String sortField = e.getAttribute(MailConstants.A_SORT_FIELD, null);
    long size = (int) e.getAttributeLong(MailConstants.A_SIZE, 0);
    String convId = e.getAttribute(MailConstants.A_CONV_ID, null);
    String folderId = e.getAttribute(MailConstants.A_FOLDER, null);
    String fragment = e.getAttribute(MailConstants.E_FRAG, null);
    String uid = e.getAttribute(MailConstants.A_UID, null);
    long ms = e.getAttributeLong(MailConstants.A_MODIFIED_SEQUENCE, 0);
    long md = e.getAttributeLong(MailConstants.A_DATE, 0);
    long ss = e.getAttributeLong(MailConstants.A_REVISION, 0);
    List<Element> instances = e.listElements(MailConstants.E_INSTANCE);
    // if empty, add self as only instance
    boolean noInstances = instances.isEmpty();
    if (noInstances) {
        instances = new ArrayList<Element>();
        instances.add(e);
    }
    for (Element inst : instances) {
        ZAppointmentHit appt = isTask ? new ZTaskHit() : new ZAppointmentHit();
        appt.mTimeZoneOffset = e.getAttributeLong(MailConstants.A_CAL_TZ_OFFSET, 0);
        appt.mInstanceExpanded = !noInstances;
        appt.mFolderId = folderId;
        appt.mId = id;
        appt.mSize = size;
        appt.mSortField = sortField;
        appt.mConvId = convId;
        appt.mHitDate = hitDate;
        appt.mIsTask = isTask;
        appt.mDraft = inst.getAttributeBool(MailConstants.A_CAL_DRAFT, isDraft);
        appt.mIsAllDay = inst.getAttributeBool(MailConstants.A_CAL_ALLDAY, isAllDay);
        appt.mTimeZoneOffset = inst.getAttributeLong(MailConstants.A_CAL_TZ_OFFSET, appt.mTimeZoneOffset);
        appt.mStartTime = inst.getAttributeLong(MailConstants.A_CAL_START_TIME, 0);
        if (appt.mIsAllDay) {
            appt.mStartTime += appt.mTimeZoneOffset - timeZone.getOffset(appt.mStartTime);
        }
        appt.mIsException = inst.getAttributeBool(MailConstants.A_CAL_IS_EXCEPTION, false);
        appt.mRecurrenceIdZ = inst.getAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, null);
        appt.mFreeBusyActual = inst.getAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, freeBusyActual);
        appt.mTransparency = inst.getAttribute(MailConstants.A_APPT_TRANSPARENCY, transparency);
        appt.mStatus = inst.getAttribute(MailConstants.A_CAL_STATUS, status);
        appt.mClass = inst.getAttribute(MailConstants.A_CAL_CLASS, classProp);
        appt.mPartStatus = inst.getAttribute(MailConstants.A_CAL_PARTSTAT, pstatus);
        appt.mIsOtherAttendees = inst.getAttributeBool(MailConstants.A_CAL_OTHER_ATTENDEES, otherAtt);
        appt.mIsAlarm = inst.getAttributeBool(MailConstants.A_CAL_ALARM, isAlarm);
        appt.mIsRecurring = inst.getAttributeBool(MailConstants.A_CAL_RECUR, isRecurring);
        appt.mFlags = inst.getAttribute(MailConstants.A_FLAGS, flags);
        appt.mTags = inst.getAttribute(MailConstants.A_TAGS, tags);
        appt.mName = inst.getAttribute(MailConstants.A_NAME, name);
        appt.mLocation = inst.getAttribute(MailConstants.A_CAL_LOCATION, location);
        List<String> instCategories = null;
        Iterator<Element> instCatIter = inst.elementIterator(MailConstants.E_CAL_CATEGORY);
        if (instCatIter.hasNext()) {
            instCategories = new ArrayList<String>();
            for (; instCatIter.hasNext(); ) {
                String cat = instCatIter.next().getTextTrim();
                instCategories.add(cat);
            }
            appt.mCategories = instCategories;
        } else {
            appt.mCategories = categories;
        }
        Element instGeoElem = inst.getOptionalElement(MailConstants.E_CAL_GEO);
        if (instGeoElem != null)
            appt.mGeo = Geo.parse(instGeoElem);
        else
            appt.mGeo = geo;
        appt.mInviteId = inst.getAttribute(MailConstants.A_CAL_INV_ID, inviteId);
        appt.mSeriesInviteId = inviteId;
        appt.mInviteComponentNumber = inst.getAttribute(MailConstants.A_CAL_COMPONENT_NUM, inviteCompNumber);
        appt.mSeriesComponentNumber = inviteCompNumber;
        appt.mIsOrganizer = inst.getAttributeBool(MailConstants.A_CAL_ISORG, isOrganizer);
        appt.mPriority = inst.getAttribute(MailConstants.A_CAL_PRIORITY, priority);
        appt.mPercentComplete = inst.getAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, percentComplete);
        appt.mDueDate = inst.getAttributeLong(MailConstants.A_TASK_DUE_DATE, dueDate);
        appt.mDuration = inst.getAttributeLong(MailConstants.A_CAL_NEW_DURATION, duration);
        appt.mEndTime = appt.mStartTime + appt.mDuration;
        appt.mFragment = inst.getAttribute(MailConstants.E_FRAG, fragment);
        appt.mUid = inst.getAttribute(MailConstants.A_UID, uid);
        appt.mModifiedSeq = inst.getAttributeLong(MailConstants.A_MODIFIED_SEQUENCE, ms);
        appt.mModifiedDate = inst.getAttributeLong(MailConstants.A_DATE, md);
        appt.mSavedSeq = inst.getAttributeLong(MailConstants.A_REVISION, ss);
        appts.add(appt);
    }
}
Also used : Geo(com.zimbra.common.calendar.Geo) Element(com.zimbra.common.soap.Element)

Example 5 with Geo

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

the class GetCalendarItemSummaries method encodeCalendarItemInstances.

/**
     * Encodes a calendar item
     *
     * @param parent
     * @param elementName
     *         name of element to add (MailConstants .E_APPOINTMENT or MailConstants.E_TASK)
     * @param rangeStart
     *         start period to expand instances (or -1 for no start time constraint)
     * @param rangeEnd
     *         end period to expand instances (or -1 for no end time constraint)
     * @param newFormat
     *         temporary HACK - true: SearchRequest, false: GetAppointmentSummaries
     * @return
     */
static EncodeCalendarItemResult encodeCalendarItemInstances(ZimbraSoapContext lc, OperationContext octxt, CalendarItem calItem, Account acct, long rangeStart, long rangeEnd, boolean newFormat) throws ServiceException {
    EncodeCalendarItemResult toRet = new EncodeCalendarItemResult();
    ItemIdFormatter ifmt = new ItemIdFormatter(lc);
    Account authAccount = getAuthenticatedAccount(lc);
    boolean hidePrivate = !calItem.allowPrivateAccess(authAccount, lc.isUsingAdminPrivileges());
    try {
        boolean expandRanges;
        if (calItem instanceof Task) {
            expandRanges = true;
            if (rangeStart == -1 && rangeEnd == -1) {
                rangeStart = Long.MIN_VALUE;
                rangeEnd = Long.MAX_VALUE;
            }
        } else {
            expandRanges = (rangeStart != -1 && rangeEnd != -1 && rangeStart < rangeEnd);
        }
        boolean isAppointment = calItem instanceof Appointment;
        // Use the marshalling code in calendar summary cache for uniform output, when we can.
        if (isAppointment && expandRanges) {
            CalendarItemData calItemData = CalSummaryCache.reloadCalendarItemOverRange(calItem, rangeStart, rangeEnd);
            if (calItemData != null) {
                int numInstances = calItemData.getNumInstances();
                if (numInstances > 0) {
                    Element calItemElem = CacheToXML.encodeCalendarItemData(lc, ifmt, calItemData, !hidePrivate, !newFormat);
                    toRet.element = calItemElem;
                    toRet.numInstancesExpanded = numInstances;
                }
            }
            return toRet;
        }
        // But there are other cases (e.g. tasks, no time range) that require the legacy code below.
        // don't initialize until we find at least one valid instance
        Element calItemElem = null;
        Invite defaultInvite = calItem.getDefaultInviteOrNull();
        if (defaultInvite == null) {
            mLog.info("Could not load defaultinfo for calendar item with id=" + calItem.getId() + " SKIPPING");
            return toRet;
        }
        ParsedDuration defDuration = defaultInvite.getEffectiveDuration();
        // events and 1 second for non all-day.  (bug 28615)
        if (defDuration == null && !defaultInvite.isTodo()) {
            if (defaultInvite.isAllDayEvent()) {
                defDuration = ParsedDuration.ONE_DAY;
            } else {
                defDuration = ParsedDuration.ONE_SECOND;
            }
        }
        long defDurationMsecs = 0;
        if (defaultInvite.getStartTime() != null && defDuration != null) {
            ParsedDateTime s = defaultInvite.getStartTime();
            long et = s.add(defDuration).getUtcTime();
            defDurationMsecs = et - s.getUtcTime();
        }
        String defaultFba = null;
        if (calItem instanceof Appointment) {
            defaultFba = ((Appointment) calItem).getEffectiveFreeBusyActual(defaultInvite, null);
        }
        String defaultPtSt = calItem.getEffectivePartStat(defaultInvite, null);
        AlarmData alarmData = calItem.getAlarmData();
        // add all the instances:
        int numInRange = 0;
        if (expandRanges) {
            Collection<CalendarItem.Instance> instances = calItem.expandInstances(rangeStart, rangeEnd, true);
            long alarmTime = 0;
            long alarmInst = 0;
            if (alarmData != null) {
                alarmTime = alarmData.getNextAt();
                alarmInst = alarmData.getNextInstanceStart();
            }
            for (CalendarItem.Instance inst : instances) {
                try {
                    InviteInfo invId = inst.getInviteInfo();
                    Invite inv = calItem.getInvite(invId.getMsgId(), invId.getComponentId());
                    boolean showAll = !hidePrivate || inv.isPublic();
                    // figure out which fields are different from the default and put their data here...
                    ParsedDuration invDuration = inv.getEffectiveDuration();
                    long instStart = inst.getStart();
                    // For an instance whose alarm time is within the time range, we must
                    // include it even if its start time is after the range.
                    long startOrAlarm = instStart == alarmInst ? alarmTime : instStart;
                    // events and 1 second for non all-day.  (bug 28615)
                    if (invDuration == null) {
                        if (inv.isAllDayEvent())
                            invDuration = ParsedDuration.ONE_DAY;
                        else
                            invDuration = ParsedDuration.ONE_SECOND;
                    }
                    if (!inst.hasStart() || (startOrAlarm < rangeEnd && invDuration.addToTime(instStart) > rangeStart)) {
                        numInRange++;
                    } else {
                        continue;
                    }
                    if (calItemElem == null) {
                        calItemElem = lc.createElement(isAppointment ? MailConstants.E_APPOINTMENT : MailConstants.E_TASK);
                        if (showAll) {
                            // flags and tags
                            ToXML.recordItemTags(calItemElem, calItem, octxt);
                        }
                        // Organizer
                        if (inv.hasOrganizer()) {
                            ZOrganizer org = inv.getOrganizer();
                            org.toXml(calItemElem);
                        }
                        calItemElem.addAttribute("x_uid", calItem.getUid());
                        calItemElem.addAttribute(MailConstants.A_UID, calItem.getUid());
                    }
                    Element instElt = calItemElem.addElement(MailConstants.E_INSTANCE);
                    if (showAll) {
                        if (isAppointment && inv.isEvent()) {
                            String instFba = ((Appointment) calItem).getEffectiveFreeBusyActual(inv, inst);
                            if (instFba != null && (!instFba.equals(defaultFba) || inst.isException()))
                                instElt.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, instFba);
                        }
                        String instPtSt = calItem.getEffectivePartStat(inv, inst);
                        if (!defaultPtSt.equals(instPtSt) || inst.isException())
                            instElt.addAttribute(MailConstants.A_CAL_PARTSTAT, instPtSt);
                    }
                    if (inst.hasStart()) {
                        instElt.addAttribute(MailConstants.A_CAL_START_TIME, instStart);
                        if (inv.isAllDayEvent())
                            instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET, inst.getStartTzOffset());
                    }
                    if (inst.isException() && inv.hasRecurId()) {
                        RecurId rid = inv.getRecurId();
                        instElt.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, rid.getDtZ());
                    } else {
                        instElt.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, inst.getRecurIdZ());
                    }
                    if (inst.isException()) {
                        instElt.addAttribute(MailConstants.A_CAL_IS_EXCEPTION, true);
                        instElt.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(calItem, inst.getMailItemId()));
                        instElt.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, inst.getComponentNum());
                        if (showAll) {
                            // fragment has already been sanitized...
                            String frag = inv.getFragment();
                            if (frag != null && !frag.equals(""))
                                instElt.addAttribute(MailConstants.E_FRAG, frag, Element.Disposition.CONTENT);
                            if (inv.getPriority() != null)
                                instElt.addAttribute(MailConstants.A_CAL_PRIORITY, inv.getPriority());
                            if (inv.isEvent()) {
                                if (inv.getFreeBusy() != null)
                                    instElt.addAttribute(MailConstants.A_APPT_FREEBUSY, inv.getFreeBusy());
                                if (inv.getTransparency() != null)
                                    instElt.addAttribute(MailConstants.A_APPT_TRANSPARENCY, inv.getTransparency());
                            }
                            if (inv.isTodo()) {
                                if (inv.getPercentComplete() != null)
                                    instElt.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, inv.getPercentComplete());
                            }
                            if (inv.getName() != null)
                                instElt.addAttribute(MailConstants.A_NAME, inv.getName());
                            if (inv.getLocation() != null)
                                instElt.addAttribute(MailConstants.A_CAL_LOCATION, inv.getLocation());
                            List<String> categories = inv.getCategories();
                            if (categories != null) {
                                for (String cat : categories) {
                                    instElt.addElement(MailConstants.E_CAL_CATEGORY).setText(cat);
                                }
                            }
                            Geo geo = inv.getGeo();
                            if (geo != null)
                                geo.toXml(instElt);
                            if (inv.hasOtherAttendees())
                                instElt.addAttribute(MailConstants.A_CAL_OTHER_ATTENDEES, true);
                            if (inv.hasAlarm())
                                instElt.addAttribute(MailConstants.A_CAL_ALARM, true);
                        }
                        instElt.addAttribute(MailConstants.A_CAL_ISORG, inv.isOrganizer());
                        if (inv.isTodo()) {
                            if (inst.hasEnd()) {
                                instElt.addAttribute(MailConstants.A_TASK_DUE_DATE, inst.getEnd());
                                if (inv.isAllDayEvent())
                                    instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET_DUE, inst.getEndTzOffset());
                            }
                        } else {
                            if (inst.hasStart() && inst.hasEnd()) {
                                instElt.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, inst.getEnd() - inst.getStart());
                            }
                        }
                        if (inv.getStatus() != null)
                            instElt.addAttribute(MailConstants.A_CAL_STATUS, inv.getStatus());
                        if (inv.getClassProp() != null)
                            instElt.addAttribute(MailConstants.A_CAL_CLASS, inv.getClassProp());
                        if (inv.isAllDayEvent())
                            instElt.addAttribute(MailConstants.A_CAL_ALLDAY, true);
                        if (inv.isDraft())
                            instElt.addAttribute(MailConstants.A_CAL_DRAFT, true);
                        if (inv.isNeverSent())
                            instElt.addAttribute(MailConstants.A_CAL_NEVER_SENT, true);
                        if (inv.isRecurrence())
                            instElt.addAttribute(MailConstants.A_CAL_RECUR, true);
                    } else {
                        if (inv.isTodo()) {
                            if (inst.hasEnd()) {
                                instElt.addAttribute(MailConstants.A_TASK_DUE_DATE, inst.getEnd());
                                if (inv.isAllDayEvent())
                                    instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET_DUE, inst.getEndTzOffset());
                            }
                        } else {
                            // the default duration due to daylight savings time transitions.
                            if (inst.hasStart() && inst.hasEnd() && defDurationMsecs != inst.getEnd() - inst.getStart()) {
                                instElt.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, inst.getEnd() - inst.getStart());
                            }
                        }
                    }
                } catch (MailServiceException.NoSuchItemException e) {
                    mLog.info("Error could not get instance " + inst.getMailItemId() + "-" + inst.getComponentNum() + " for appt " + calItem.getId(), e);
                }
            }
        // iterate all the instances
        }
        if (!expandRanges || numInRange > 0) {
            // if we found any calItems at all, we have to encode the "Default" data here
            boolean showAll = !hidePrivate || defaultInvite.isPublic();
            if (calItemElem == null) {
                calItemElem = lc.createElement(isAppointment ? MailConstants.E_APPOINTMENT : MailConstants.E_TASK);
                calItemElem.addAttribute("x_uid", calItem.getUid());
                calItemElem.addAttribute(MailConstants.A_UID, calItem.getUid());
                if (showAll) {
                    // flags and tags
                    ToXML.recordItemTags(calItemElem, calItem, octxt);
                }
                // Organizer
                if (defaultInvite.hasOrganizer()) {
                    ZOrganizer org = defaultInvite.getOrganizer();
                    org.toXml(calItemElem);
                }
            }
            if (showAll) {
                if (alarmData != null)
                    ToXML.encodeAlarmData(calItemElem, calItem, alarmData);
                String defaultPriority = defaultInvite.getPriority();
                if (defaultPriority != null)
                    calItemElem.addAttribute(MailConstants.A_CAL_PRIORITY, defaultPriority);
                calItemElem.addAttribute(MailConstants.A_CAL_PARTSTAT, defaultPtSt);
                if (defaultInvite.isEvent()) {
                    calItemElem.addAttribute(MailConstants.A_APPT_FREEBUSY, defaultInvite.getFreeBusy());
                    calItemElem.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, defaultFba);
                    calItemElem.addAttribute(MailConstants.A_APPT_TRANSPARENCY, defaultInvite.getTransparency());
                }
                if (defaultInvite.isTodo()) {
                    String pctComplete = defaultInvite.getPercentComplete();
                    if (pctComplete != null)
                        calItemElem.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, pctComplete);
                }
                calItemElem.addAttribute(MailConstants.A_NAME, defaultInvite.getName());
                calItemElem.addAttribute(MailConstants.A_CAL_LOCATION, defaultInvite.getLocation());
                List<String> categories = defaultInvite.getCategories();
                if (categories != null) {
                    for (String cat : categories) {
                        calItemElem.addElement(MailConstants.E_CAL_CATEGORY).setText(cat);
                    }
                }
                Geo geo = defaultInvite.getGeo();
                if (geo != null)
                    geo.toXml(calItemElem);
                // fragment has already been sanitized...
                String fragment = defaultInvite.getFragment();
                if (!fragment.equals(""))
                    calItemElem.addAttribute(MailConstants.E_FRAG, fragment, Element.Disposition.CONTENT);
                if (defaultInvite.hasOtherAttendees()) {
                    calItemElem.addAttribute(MailConstants.A_CAL_OTHER_ATTENDEES, defaultInvite.hasOtherAttendees());
                }
                if (defaultInvite.hasAlarm()) {
                    calItemElem.addAttribute(MailConstants.A_CAL_ALARM, defaultInvite.hasAlarm());
                }
            }
            calItemElem.addAttribute(MailConstants.A_CAL_ISORG, defaultInvite.isOrganizer());
            calItemElem.addAttribute(MailConstants.A_ID, ifmt.formatItemId(calItem));
            calItemElem.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(calItem, defaultInvite.getMailItemId()));
            calItemElem.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, defaultInvite.getComponentNum());
            calItemElem.addAttribute(MailConstants.A_FOLDER, ifmt.formatItemId(new ItemId(calItem.getMailbox().getAccountId(), calItem.getFolderId())));
            calItemElem.addAttribute(MailConstants.A_CAL_STATUS, defaultInvite.getStatus());
            calItemElem.addAttribute(MailConstants.A_CAL_CLASS, defaultInvite.getClassProp());
            if (!defaultInvite.isTodo())
                calItemElem.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, defDurationMsecs);
            if (defaultInvite.isAllDayEvent())
                calItemElem.addAttribute(MailConstants.A_CAL_ALLDAY, defaultInvite.isAllDayEvent());
            if (defaultInvite.isDraft())
                calItemElem.addAttribute(MailConstants.A_CAL_DRAFT, defaultInvite.isDraft());
            if (defaultInvite.isNeverSent())
                calItemElem.addAttribute(MailConstants.A_CAL_NEVER_SENT, defaultInvite.isNeverSent());
            if (defaultInvite.isRecurrence())
                calItemElem.addAttribute(MailConstants.A_CAL_RECUR, defaultInvite.isRecurrence());
            if (calItem.hasExceptions()) {
                calItemElem.addAttribute(MailConstants.A_CAL_HAS_EXCEPTIONS, true);
            }
            toRet.element = calItemElem;
        }
        toRet.numInstancesExpanded = numInRange;
    } catch (MailServiceException.NoSuchItemException e) {
        mLog.info("Error could not get default invite for calendar item: " + calItem.getId(), e);
    } catch (RuntimeException e) {
        mLog.info("Caught Exception " + e + " while getting summary info for calendar item: " + calItem.getId(), e);
    }
    return toRet;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) Account(com.zimbra.cs.account.Account) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) Task(com.zimbra.cs.mailbox.Task) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Element(com.zimbra.common.soap.Element) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) CalendarItemData(com.zimbra.cs.mailbox.calendar.cache.CalendarItemData) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) Geo(com.zimbra.common.calendar.Geo) Invite(com.zimbra.cs.mailbox.calendar.Invite) AlarmData(com.zimbra.cs.mailbox.CalendarItem.AlarmData)

Aggregations

Geo (com.zimbra.common.calendar.Geo)8 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)5 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)5 Element (com.zimbra.common.soap.Element)5 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)4 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)4 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)3 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)3 ParseException (java.text.ParseException)3 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)2 ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)2 ServiceException (com.zimbra.common.service.ServiceException)2 Account (com.zimbra.cs.account.Account)2 Appointment (com.zimbra.cs.mailbox.Appointment)2 MailItem (com.zimbra.cs.mailbox.MailItem)2 Metadata (com.zimbra.cs.mailbox.Metadata)2 Alarm (com.zimbra.cs.mailbox.calendar.Alarm)2 Recurrence (com.zimbra.cs.mailbox.calendar.Recurrence)2 ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)2 ItemId (com.zimbra.cs.service.util.ItemId)2