Search in sources :

Example 6 with ZParameter

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

the class Invite method newToVComponent.

public ZComponent newToVComponent(boolean useOutlookCompatAllDayEvents, boolean includePrivateData, boolean includeAttaches) throws ServiceException {
    boolean isRequestPublishCancel = ICalTok.REQUEST.equals(mMethod) || ICalTok.PUBLISH.equals(mMethod) || ICalTok.CANCEL.equals(mMethod);
    ICalTok compTok;
    if (type == MailItem.Type.TASK) {
        compTok = ICalTok.VTODO;
        useOutlookCompatAllDayEvents = false;
    } else {
        compTok = ICalTok.VEVENT;
    }
    ZComponent component = new ZComponent(compTok);
    component.addProperty(new ZProperty(ICalTok.UID, getUid()));
    IRecurrence recur = getRecurrence();
    if (recur != null) {
        for (Iterator iter = recur.addRulesIterator(); iter != null && iter.hasNext(); ) {
            IRecurrence cur = (IRecurrence) iter.next();
            switch(cur.getType()) {
                case Recurrence.TYPE_SINGLE_DATES:
                    if (DebugConfig.enableRdate) {
                        Recurrence.SingleDates sd = (Recurrence.SingleDates) cur;
                        RdateExdate rdate = sd.getRdateExdate();
                        rdate.addAsSeparateProperties(component);
                    }
                    break;
                case Recurrence.TYPE_REPEATING:
                    Recurrence.SimpleRepeatingRule srr = (Recurrence.SimpleRepeatingRule) cur;
                    component.addProperty(new ZProperty(ICalTok.RRULE, srr.getRule().toString()));
                    break;
            }
        }
        for (Iterator iter = recur.subRulesIterator(); iter != null && iter.hasNext(); ) {
            IRecurrence cur = (IRecurrence) iter.next();
            switch(cur.getType()) {
                case Recurrence.TYPE_SINGLE_DATES:
                    Recurrence.SingleDates sd = (Recurrence.SingleDates) cur;
                    RdateExdate exdate = sd.getRdateExdate();
                    exdate.addAsSeparateProperties(component);
                    break;
                case Recurrence.TYPE_REPEATING:
                    Recurrence.SimpleRepeatingRule srr = (Recurrence.SimpleRepeatingRule) cur;
                    component.addProperty(new ZProperty(ICalTok.EXRULE, srr.getRule().toString()));
                    break;
            }
        }
    }
    if (includePrivateData || isPublic()) {
        // SUMMARY (aka Name or Subject)
        String name = getName();
        if (name != null && name.length() > 0)
            component.addProperty(new ZProperty(ICalTok.SUMMARY, name));
        // DESCRIPTION and X-ALT-DESC;FMTTYPE=text/html
        String desc = getDescription();
        if (desc != null) {
            // Remove Outlook-style *~*~*~ header block.  Remove separator plus two newlines.
            int delim = desc.indexOf(HEADER_SEPARATOR);
            if (delim >= 0) {
                desc = desc.substring(delim + HEADER_SEPARATOR.length());
                desc = desc.replaceFirst("^\\r?\\n\\r?\\n", "");
            }
            if (desc.length() > 0)
                component.addProperty(new ZProperty(ICalTok.DESCRIPTION, desc));
        }
        String descHtml = getDescriptionHtml();
        if (descHtml != null && descHtml.length() > 0) {
            ZProperty altDesc = new ZProperty(ICalTok.X_ALT_DESC, descHtml);
            altDesc.addParameter(new ZParameter(ICalTok.FMTTYPE, MimeConstants.CT_TEXT_HTML));
            component.addProperty(altDesc);
        }
        // COMMENT
        List<String> comments = getComments();
        if (comments != null && !comments.isEmpty()) {
            for (String comment : comments) {
                component.addProperty(new ZProperty(ICalTok.COMMENT, comment));
            }
        }
        // LOCATION
        String location = getLocation();
        if (location != null && location.length() > 0)
            component.addProperty(new ZProperty(ICalTok.LOCATION, location.toString()));
        // ATTENDEES
        for (ZAttendee at : getAttendees()) {
            component.addProperty(at.toProperty());
        }
        // PRIORITY
        if (mPriority != null)
            component.addProperty(new ZProperty(ICalTok.PRIORITY, mPriority));
        // PERCENT-COMPLETE
        if (isTodo() && mPercentComplete != null)
            component.addProperty(new ZProperty(ICalTok.PERCENT_COMPLETE, mPercentComplete));
        // COMPLETED
        if (isTodo() && mCompleted != 0) {
            ParsedDateTime completed = ParsedDateTime.fromUTCTime(mCompleted);
            component.addProperty(completed.toProperty(ICalTok.COMPLETED, false));
        }
        // CATEGORIES
        List<String> categories = getCategories();
        if (categories != null && !categories.isEmpty()) {
            ZProperty catsProp = new ZProperty(ICalTok.CATEGORIES);
            catsProp.setValueList(categories);
            component.addProperty(catsProp);
        }
        // CONTACT
        List<String> contacts = getContacts();
        if (contacts != null && !contacts.isEmpty()) {
            for (String contact : contacts) {
                component.addProperty(new ZProperty(ICalTok.CONTACT, contact));
            }
        }
        // GEO
        if (mGeo != null)
            component.addProperty(mGeo.toZProperty());
        // VALARMs
        for (Alarm alarm : mAlarms) {
            ZComponent alarmComp = alarm.toZComponent();
            component.addComponent(alarmComp);
        }
        // x-prop
        for (ZProperty xprop : mXProps) {
            component.addProperty(xprop);
        }
        // ORGANIZER
        if (hasOrganizer()) {
            ZOrganizer organizer = getOrganizer();
            ZProperty orgProp = organizer.toProperty();
            component.addProperty(orgProp);
            // Hack for Outlook 2007 (bug 25777)
            if (organizer.hasSentBy() && !ICalTok.REPLY.equals(mMethod) && !ICalTok.COUNTER.equals(mMethod)) {
                String sentByParam = orgProp.paramVal(ICalTok.SENT_BY, null);
                if (sentByParam != null) {
                    ZProperty xMsOlkSender = new ZProperty("X-MS-OLK-SENDER");
                    xMsOlkSender.setValue(sentByParam);
                    component.addProperty(xMsOlkSender);
                }
            }
        }
    }
    // DTSTART
    ParsedDateTime dtstart = getStartTime();
    if (dtstart != null)
        component.addProperty(dtstart.toProperty(ICalTok.DTSTART, useOutlookCompatAllDayEvents));
    // DTEND or DUE
    ParsedDateTime dtend = getEndTime();
    if (dtend != null) {
        ICalTok prop = ICalTok.DTEND;
        if (isTodo())
            prop = ICalTok.DUE;
        component.addProperty(dtend.toProperty(prop, useOutlookCompatAllDayEvents));
    }
    // DURATION
    ParsedDuration dur = getDuration();
    if (dur != null)
        component.addProperty(new ZProperty(ICalTok.DURATION, dur.toString()));
    // STATUS
    String status = getStatus();
    String statusIcal = IcalXmlStrMap.sStatusMap.toIcal(status);
    if (IcalXmlStrMap.STATUS_ZCO_WAITING.equals(status) || IcalXmlStrMap.STATUS_ZCO_DEFERRED.equals(status)) {
        ZParameter param = new ZParameter(ICalTok.X_ZIMBRA_STATUS, statusIcal);
        ZProperty prop = new ZProperty(ICalTok.STATUS, ICalTok.IN_PROCESS.toString());
        prop.addParameter(param);
        component.addProperty(prop);
    } else {
        component.addProperty(new ZProperty(ICalTok.STATUS, statusIcal));
    }
    // CLASS
    component.addProperty(new ZProperty(ICalTok.CLASS, IcalXmlStrMap.sClassMap.toIcal(getClassProp())));
    if (isEvent()) {
        // allDay
        if (isAllDayEvent())
            component.addProperty(new ZProperty(ICalTok.X_MICROSOFT_CDO_ALLDAYEVENT, true));
        // Microsoft Outlook compatibility for free-busy status
        if (isRequestPublishCancel) {
            String outlookFreeBusy = IcalXmlStrMap.sOutlookFreeBusyMap.toIcal(getFreeBusy());
            component.addProperty(new ZProperty(ICalTok.X_MICROSOFT_CDO_INTENDEDSTATUS, outlookFreeBusy));
        }
        // TRANSPARENCY
        component.addProperty(new ZProperty(ICalTok.TRANSP, IcalXmlStrMap.sTranspMap.toIcal(getTransparency())));
    }
    // RECURRENCE-ID
    RecurId recurId = getRecurId();
    if (recurId != null)
        component.addProperty(recurId.toProperty(useOutlookCompatAllDayEvents));
    // LAST-MODIFIED
    long lastModified = getLastModified();
    if (lastModified != 0) {
        ParsedDateTime dtLastModified = ParsedDateTime.fromUTCTime(lastModified);
        component.addProperty(dtLastModified.toProperty(ICalTok.LAST_MODIFIED, false));
    }
    // DTSTAMP
    ParsedDateTime dtStamp = ParsedDateTime.fromUTCTime(getDTStamp());
    component.addProperty(dtStamp.toProperty(ICalTok.DTSTAMP, false));
    // SEQUENCE
    component.addProperty(new ZProperty(ICalTok.SEQUENCE, getSeqNo()));
    // URL
    String url = getUrl();
    if (url != null && url.length() > 0)
        component.addProperty(new ZProperty(ICalTok.URL, url));
    if (isLocalOnly())
        component.addProperty(new ZProperty(ICalTok.X_ZIMBRA_LOCAL_ONLY, true));
    if (includeAttaches) {
        addInlineATTACHes(component);
    }
    return component;
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZComponent(com.zimbra.common.calendar.ZCalendar.ZComponent) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) Iterator(java.util.Iterator) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 7 with ZParameter

use of com.zimbra.common.calendar.ZCalendar.ZParameter 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 8 with ZParameter

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

the class Util method decodeXPropsFromMetadata.

public static List<ZProperty> decodeXPropsFromMetadata(Metadata meta) throws ServiceException {
    int xpropCount = (int) meta.getLong(FN_NUM_XPROPS_OR_XPARAMS, 0);
    if (xpropCount > 0) {
        List<ZProperty> list = new ArrayList<ZProperty>(xpropCount);
        for (int propNum = 0; propNum < xpropCount; propNum++) {
            Metadata propMeta = meta.getMap(FN_XPROP_OR_XPARAM + propNum, true);
            if (propMeta == null)
                continue;
            String propName = propMeta.get(FN_NAME, null);
            if (propName == null)
                continue;
            // Never persist the transport-only special x-prop X-ZIMBRA-CHANGES.
            if (propName.equalsIgnoreCase(ICalTok.X_ZIMBRA_CHANGES.toString()))
                continue;
            ZProperty xprop = new ZProperty(propName);
            String propValue = propMeta.get(FN_VALUE, null);
            if (propValue != null)
                xprop.setValue(propValue);
            List<ZParameter> xparams = decodeXParamsFromMetadata(propMeta);
            if (xparams != null) {
                for (ZParameter xparam : xparams) {
                    xprop.addParameter(xparam);
                }
            }
            list.add(xprop);
        }
        return list;
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) Metadata(com.zimbra.cs.mailbox.Metadata) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter)

Example 9 with ZParameter

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

the class RdateExdate method parse.

public static RdateExdate parse(ZProperty prop, TimeZoneMap tzmap) throws ServiceException {
    ICalTok propName = prop.getToken();
    ZParameter valueParam = prop.getParameter(ICalTok.VALUE);
    ICalTok valueType = ICalTok.DATE_TIME;
    if (valueParam != null) {
        String typeStr = valueParam.getValue();
        if (typeStr != null) {
            valueType = ICalTok.lookup(typeStr);
            if (valueType == null)
                throw ServiceException.INVALID_REQUEST("Invalid " + propName.toString() + " value type " + typeStr, null);
        }
    }
    String tzid = prop.getParameterVal(ICalTok.TZID, null);
    ICalTimeZone tz = null;
    if (tzid != null)
        tz = tzmap.lookupAndAdd(tzid);
    RdateExdate rexdate = new RdateExdate(propName, valueType, tz);
    String csv = prop.getValue();
    if (csv == null || csv.length() == 0)
        throw ServiceException.INVALID_REQUEST("Empty value not allowed for " + propName.toString() + " property", null);
    for (String value : csv.split(",")) {
        try {
            switch(valueType) {
                case DATE_TIME:
                case DATE:
                    ParsedDateTime dt = ParsedDateTime.parse(value, tzmap, tz, tzmap.getLocalTimeZone());
                    rexdate.addValue(dt);
                    break;
                case PERIOD:
                    Period p = Period.parse(value, tz, tzmap);
                    rexdate.addValue(p);
                    break;
            }
        } catch (ParseException e) {
            throw ServiceException.INVALID_REQUEST("Unable to parse " + propName.toString() + " value \"" + value + "\"", e);
        }
    }
    return rexdate;
}
Also used : ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok)

Example 10 with ZParameter

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

the class RdateExdate method addAsSeparateProperties.

// bug 59333: Hack for Apple iCal.  It doesn't like comma-separate values in a single EXDATE property.
// Output each value as its own EXDATE property.
void addAsSeparateProperties(ZComponent comp) {
    if (isRDATE() && !DebugConfig.enableRdate) {
        return;
    }
    ZParameter tzid = mTimeZone != null ? new ZParameter(ICalTok.TZID, mTimeZone.getID()) : null;
    ZParameter valType = !ICalTok.DATE_TIME.equals(mValueType) ? new ZParameter(ICalTok.VALUE, mValueType.toString()) : null;
    for (Object value : mValues) {
        ZProperty prop = new ZProperty(mPropertyName);
        if (tzid != null) {
            prop.addParameter(tzid);
        }
        if (valType != null) {
            prop.addParameter(valType);
        }
        if (value instanceof ParsedDateTime) {
            ParsedDateTime t = (ParsedDateTime) value;
            prop.setValue(t.getDateTimePartString(false));
        } else if (value instanceof Period) {
            prop.setValue(value.toString());
        }
        comp.addProperty(prop);
    }
}
Also used : ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter)

Aggregations

ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)28 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)20 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)8 ArrayList (java.util.ArrayList)8 ICalTok (com.zimbra.common.calendar.ZCalendar.ICalTok)7 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)7 ParseException (java.text.ParseException)5 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)4 Metadata (com.zimbra.cs.mailbox.Metadata)4 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)3 Element (com.zimbra.common.soap.Element)3 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)3 Attach (com.zimbra.common.calendar.Attach)2 Geo (com.zimbra.common.calendar.Geo)2 ServiceException (com.zimbra.common.service.ServiceException)2 Account (com.zimbra.cs.account.Account)2 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)2 MailItem (com.zimbra.cs.mailbox.MailItem)2 Mailbox (com.zimbra.cs.mailbox.Mailbox)2 Invite (com.zimbra.cs.mailbox.calendar.Invite)2