Search in sources :

Example 1 with Attach

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

the class Invite method addInlineATTACHes.

protected ZComponent addInlineATTACHes(ZComponent comp) {
    MimeMessage mimeMsg = null;
    try {
        mimeMsg = getMimeMessage();
    } catch (ServiceException e1) {
        return comp;
    }
    if (mimeMsg == null) {
        return comp;
    }
    try {
        List<MPartInfo> parts = Mime.getParts(mimeMsg, MimeConstants.P_CHARSET_UTF8);
        if (parts != null && !parts.isEmpty()) {
            for (MPartInfo body : parts.get(0).getChildren()) {
                if (body.isMultipart()) {
                    continue;
                }
                MimePart mp = body.getMimePart();
                String ctype = StringUtil.stripControlCharacters(body.getContentType());
                if (MimeConstants.CT_TEXT_CALENDAR.equalsIgnoreCase(ctype)) {
                    // Otherwise it's just an attachment that happens to be a .ics file.
                    try {
                        ContentType ct = new ContentType(body.getMimePart().getContentType());
                        if (ct.getParameter("method") != null) {
                            continue;
                        }
                    } catch (MessagingException e) {
                    }
                }
                String contentType = StringUtil.stripControlCharacters(body.getContentType());
                String fileName = Mime.getFilename(mp);
                try (InputStream in = mp.getInputStream()) {
                    byte[] rawBytes = IOUtils.toByteArray(in);
                    Attach attachment = Attach.fromUnencodedAndContentType(rawBytes, contentType);
                    if (!Strings.isNullOrEmpty(fileName)) {
                        attachment.setFileName(fileName);
                    }
                    comp.addProperty(attachment.toZProperty());
                }
            }
        }
    } catch (MessagingException | IOException e) {
        ZimbraLog.calendar.warn("Problem adding inline ATTACHes", e);
    }
    return comp;
}
Also used : ContentType(javax.mail.internet.ContentType) MessagingException(javax.mail.MessagingException) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Attach(com.zimbra.common.calendar.Attach) IOException(java.io.IOException) MPartInfo(com.zimbra.cs.mime.MPartInfo) ServiceException(com.zimbra.common.service.ServiceException) MimeMessage(javax.mail.internet.MimeMessage) MimePart(javax.mail.internet.MimePart)

Example 2 with Attach

use of com.zimbra.common.calendar.Attach 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 3 with Attach

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

the class Alarm method parse.

/**
     * Create an Alarm from SOAP.  Return value may be null.
     * @param alarmElem
     * @return
     * @throws ServiceException
     */
public static Alarm parse(Element alarmElem) throws ServiceException {
    Action action = Action.DISPLAY;
    TriggerType triggerType = TriggerType.RELATIVE;
    TriggerRelated triggerRelated = null;
    ParsedDuration triggerRelative = null;
    ParsedDateTime triggerAbsolute = null;
    ParsedDuration repeatDuration = null;
    int repeatCount = 0;
    String description = null;
    String summary = null;
    Attach attach = null;
    List<ZAttendee> attendees = null;
    String val;
    val = alarmElem.getAttribute(MailConstants.A_CAL_ALARM_ACTION);
    action = Action.lookup(val);
    if (action == null)
        throw ServiceException.INVALID_REQUEST("Invalid " + MailConstants.A_CAL_ALARM_ACTION + " value " + val, null);
    if (!actionAllowed(action))
        return null;
    Element triggerElem = alarmElem.getElement(MailConstants.E_CAL_ALARM_TRIGGER);
    Element triggerRelativeElem = triggerElem.getOptionalElement(MailConstants.E_CAL_ALARM_RELATIVE);
    if (triggerRelativeElem != null) {
        triggerType = TriggerType.RELATIVE;
        String related = triggerRelativeElem.getAttribute(MailConstants.A_CAL_ALARM_RELATED, null);
        if (related != null) {
            triggerRelated = TriggerRelated.lookup(related);
            if (triggerRelated == null)
                throw ServiceException.INVALID_REQUEST("Invalid " + MailConstants.A_CAL_ALARM_RELATED + " value " + val, null);
        }
        triggerRelative = ParsedDuration.parse(triggerRelativeElem);
    } else {
        triggerType = TriggerType.ABSOLUTE;
        Element triggerAbsoluteElem = triggerElem.getOptionalElement(MailConstants.E_CAL_ALARM_ABSOLUTE);
        if (triggerAbsoluteElem == null)
            throw ServiceException.INVALID_REQUEST("<" + MailConstants.E_CAL_ALARM_TRIGGER + "> must have either <" + MailConstants.E_CAL_ALARM_RELATIVE + "> or <" + MailConstants.E_CAL_ALARM_ABSOLUTE + "> child element", null);
        String datetime = triggerAbsoluteElem.getAttribute(MailConstants.A_DATE);
        try {
            triggerAbsolute = ParsedDateTime.parseUtcOnly(datetime);
        } catch (ParseException e) {
            throw ServiceException.INVALID_REQUEST("Invalid absolute trigger value " + val, e);
        }
    }
    Element repeatElem = alarmElem.getOptionalElement(MailConstants.E_CAL_ALARM_REPEAT);
    if (repeatElem != null) {
        repeatDuration = ParsedDuration.parse(repeatElem);
        repeatCount = (int) repeatElem.getAttributeLong(MailConstants.A_CAL_ALARM_COUNT, 0);
    }
    Element descElem = alarmElem.getOptionalElement(MailConstants.E_CAL_ALARM_DESCRIPTION);
    if (descElem != null) {
        description = descElem.getText();
    }
    Element summaryElem = alarmElem.getOptionalElement(MailConstants.E_CAL_ALARM_SUMMARY);
    if (summaryElem != null) {
        summary = summaryElem.getText();
    }
    Element attachElem = alarmElem.getOptionalElement(MailConstants.E_CAL_ATTACH);
    if (attachElem != null)
        attach = Attach.parse(attachElem);
    Iterator<Element> attendeesIter = alarmElem.elementIterator(MailConstants.E_CAL_ATTENDEE);
    while (attendeesIter.hasNext()) {
        ZAttendee at = ZAttendee.parse(attendeesIter.next());
        if (attendees == null)
            attendees = new ArrayList<ZAttendee>();
        attendees.add(at);
    }
    Alarm alarm = new Alarm(action, triggerType, triggerRelated, triggerRelative, triggerAbsolute, repeatDuration, repeatCount, description, summary, attach, attendees, CalendarUtils.parseXProps(alarmElem));
    return alarm;
}
Also used : ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Attach(com.zimbra.common.calendar.Attach) CalendarAttach(com.zimbra.soap.mail.type.CalendarAttach) Element(com.zimbra.common.soap.Element) ArrayList(java.util.ArrayList) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException)

Example 4 with Attach

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

the class Alarm method parse.

/**
     * Create an Alarm from ZComponent.  Return value may be null.
     * @param comp
     * @return
     * @throws ServiceException
     */
public static Alarm parse(ZComponent comp) throws ServiceException {
    Action action = Action.DISPLAY;
    TriggerType triggerType = TriggerType.RELATIVE;
    TriggerRelated triggerRelated = null;
    ParsedDuration triggerRelative = null;
    ParsedDateTime triggerAbsolute = null;
    ParsedDuration repeatDuration = null;
    int repeatCount = 0;
    String description = null;
    String summary = null;
    Attach attach = null;
    List<ZAttendee> attendees = null;
    List<ZProperty> xprops = new ArrayList<ZProperty>();
    Iterator<ZProperty> propIter = comp.getPropertyIterator();
    while (propIter.hasNext()) {
        ZProperty prop = propIter.next();
        ICalTok tok = prop.getToken();
        String val = prop.getValue();
        if (tok == null) {
            String name = prop.getName();
            if (name.startsWith("X-") || name.startsWith("x-")) {
                xprops.add(prop);
            }
            continue;
        }
        switch(tok) {
            case ACTION:
                if (val != null) {
                    action = Action.lookup(val);
                    if (action == null)
                        throw ServiceException.INVALID_REQUEST("Invalid ACTION value " + val, null);
                    if (!actionAllowed(action))
                        return null;
                }
                break;
            case TRIGGER:
                ZParameter valueType = prop.getParameter(ICalTok.VALUE);
                if (valueType != null) {
                    String vt = valueType.getValue();
                    if (ICalTok.DATE_TIME.toString().equals(vt))
                        triggerType = TriggerType.ABSOLUTE;
                }
                if (TriggerType.RELATIVE.equals(triggerType)) {
                    ZParameter related = prop.getParameter(ICalTok.RELATED);
                    if (related != null) {
                        String rel = related.getValue();
                        if (rel != null) {
                            triggerRelated = TriggerRelated.lookup(rel);
                            if (triggerRelated == null)
                                throw ServiceException.INVALID_REQUEST("Invalid RELATED value " + rel, null);
                        }
                    }
                    triggerRelative = ParsedDuration.parse(val);
                } else {
                    try {
                        if (val != null)
                            triggerAbsolute = ParsedDateTime.parseUtcOnly(val);
                    } catch (ParseException e) {
                        throw ServiceException.INVALID_REQUEST("Invalid TRIGGER value " + val, e);
                    }
                }
                break;
            case DURATION:
                if (val != null)
                    repeatDuration = ParsedDuration.parse(val);
                break;
            case REPEAT:
                if (val != null) {
                    try {
                        repeatCount = Integer.parseInt(val);
                    } catch (NumberFormatException e) {
                        throw ServiceException.INVALID_REQUEST("Invalid REPEAT value " + val, e);
                    }
                }
                break;
            case DESCRIPTION:
                description = val;
                break;
            case SUMMARY:
                summary = val;
                break;
            case ATTACH:
                attach = Attach.parse(prop);
                break;
            case ATTENDEE:
                ZAttendee attendee = new ZAttendee(prop);
                if (attendees == null)
                    attendees = new ArrayList<ZAttendee>();
                attendees.add(attendee);
                break;
        }
    }
    Alarm alarm = new Alarm(action, triggerType, triggerRelated, triggerRelative, triggerAbsolute, repeatDuration, repeatCount, description, summary, attach, attendees, xprops);
    return alarm;
}
Also used : ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Attach(com.zimbra.common.calendar.Attach) CalendarAttach(com.zimbra.soap.mail.type.CalendarAttach) ArrayList(java.util.ArrayList) ZParameter(com.zimbra.common.calendar.ZCalendar.ZParameter) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException)

Example 5 with Attach

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

the class CalendarMailSender method createCalendarMessage.

public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal, List<Attach> attaches, boolean replyToSender) throws ServiceException {
    if (desc == null)
        desc = "";
    try {
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
        MimeMultipart mpAlternatives = new ZMimeMultipart("alternative");
        if (attaches != null && !attaches.isEmpty()) {
            MimeMultipart mpMixed = new ZMimeMultipart("mixed");
            mm.setContent(mpMixed);
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mpAlternatives);
            mpMixed.addBodyPart(mbpWrapper);
            for (Attach attach : attaches) {
                byte[] rawData = attach.getDecodedData();
                if (rawData == null) {
                    continue;
                }
                ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT, true);
                String ctypeAsString = attach.getContentType();
                if (ctypeAsString == null) {
                    ctypeAsString = MimeConstants.CT_APPLICATION_OCTET_STREAM;
                }
                ContentType ctype = new ContentType(ctypeAsString);
                if (attach.getFileName() != null) {
                    ctype.setParameter("name", attach.getFileName());
                    cdisp.setParameter("filename", attach.getFileName());
                }
                MimeBodyPart mbp2 = new ZMimeBodyPart();
                ByteArrayDataSource bads = new ByteArrayDataSource(rawData, ctypeAsString);
                mbp2.setDataHandler(new DataHandler(bads));
                mbp2.setHeader("Content-Type", ctype.toString());
                mbp2.setHeader("Content-Disposition", cdisp.toString());
                mbp2.setHeader("Content-Transfer-Encoding", "base64");
                mpMixed.addBodyPart(mbp2);
            }
        } else {
            mm.setContent(mpAlternatives);
        }
        // Add the text as DESCRIPTION property in the iCalendar part.
        // MS Entourage for Mac wants this.  It ignores text/plain and
        // text/html MIME parts.
        cal.addDescription(desc, null);
        // ///////
        // TEXT part (add me first!)
        MimeBodyPart textPart = new ZMimeBodyPart();
        textPart.setText(desc, MimeConstants.P_CHARSET_UTF8);
        mpAlternatives.addBodyPart(textPart);
        // HTML part is needed to keep Outlook happy as it doesn't know
        // how to deal with a message with only text/plain but no HTML.
        MimeBodyPart htmlPart = new ZMimeBodyPart();
        if (descHtml != null) {
            ContentType ct = new ContentType(MimeConstants.CT_TEXT_HTML);
            ct.setParameter(MimeConstants.P_CHARSET, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setText(descHtml, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setHeader("Content-Type", ct.toString());
        } else {
            htmlPart.setDataHandler(new DataHandler(new HtmlPartDataSource(desc)));
        }
        mpAlternatives.addBodyPart(htmlPart);
        // ///////
        // CALENDAR part
        MimeBodyPart icalPart = makeICalIntoMimePart(cal);
        mpAlternatives.addBodyPart(icalPart);
        // MESSAGE HEADERS
        if (subject != null) {
            mm.setSubject(subject, MimeConstants.P_CHARSET_UTF8);
        }
        if (toAddrs != null) {
            Address[] addrs = new Address[toAddrs.size()];
            toAddrs.toArray(addrs);
            mm.addRecipients(javax.mail.Message.RecipientType.TO, addrs);
        }
        if (fromAddr != null)
            mm.setFrom(fromAddr);
        if (senderAddr != null) {
            mm.setSender(senderAddr);
            if (replyToSender) {
                mm.setReplyTo(new Address[] { senderAddr });
            }
        }
        mm.setSentDate(new Date());
        mm.saveChanges();
        return mm;
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("Messaging Exception while building MimeMessage from invite", e);
    }
}
Also used : ContentType(javax.mail.internet.ContentType) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attach(com.zimbra.common.calendar.Attach) DataHandler(javax.activation.DataHandler) Date(java.util.Date) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Aggregations

Attach (com.zimbra.common.calendar.Attach)6 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)4 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)4 ParseException (java.text.ParseException)4 ArrayList (java.util.ArrayList)4 ServiceException (com.zimbra.common.service.ServiceException)3 CalendarAttach (com.zimbra.soap.mail.type.CalendarAttach)3 ICalTok (com.zimbra.common.calendar.ZCalendar.ICalTok)2 ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)2 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)2 MessagingException (javax.mail.MessagingException)2 ContentType (javax.mail.internet.ContentType)2 MimeMessage (javax.mail.internet.MimeMessage)2 ImmutableList (com.google.common.collect.ImmutableList)1 Geo (com.zimbra.common.calendar.Geo)1 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)1 ContentDisposition (com.zimbra.common.mime.ContentDisposition)1 JavaMailInternetAddress (com.zimbra.common.mime.shim.JavaMailInternetAddress)1 Element (com.zimbra.common.soap.Element)1 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)1