Search in sources :

Example 1 with TimeZoneDefinition

use of com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition in project zm-mailbox by Zimbra.

the class DefaultTnefToICalendar method convert.

/* (non-Javadoc)
     * @see com.zimbra.cs.util.tnef.TnefToICalendar#convert(java.io.InputStream, net.fortuna.ical4j.data.ContentHandler)
     */
public boolean convert(MimeMessage mimeMsg, InputStream tnefInput, ContentHandler icalOutput) throws ServiceException {
    boolean conversionSuccessful = false;
    recurDef = null;
    TNEFInputStream tnefStream = null;
    SchedulingViewOfTnef schedView = null;
    Integer sequenceNum = 0;
    icalType = ICALENDAR_TYPE.VEVENT;
    try {
        tnefStream = new TNEFInputStream(tnefInput);
        schedView = new SchedulingViewOfTnef(tnefStream);
        String msgClass = schedView.getMessageClass();
        if (msgClass == null) {
            sLog.debug("Unable to determine Class of TNEF - cannot generate ICALENDER equivalent");
            // throw TNEFtoIcalendarServiceException.NON_CALENDARING_CLASS(msgClass);
            return false;
        }
        icalType = schedView.getIcalType();
        method = null;
        PartStat partstat = null;
        boolean replyWanted = schedView.getResponseRequested();
        Boolean isCounterProposal = schedView.isCounterProposal();
        if (msgClass != null) {
            // just in case.
            if (msgClass.startsWith("IPM.Microsoft Schedule.MtgReq")) {
                method = Method.REQUEST;
                partstat = PartStat.NEEDS_ACTION;
            } else if (msgClass.startsWith("IPM.Microsoft Schedule.MtgRespP")) {
                method = Method.REPLY;
                partstat = PartStat.ACCEPTED;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.Microsoft Schedule.MtgRespN")) {
                method = Method.REPLY;
                partstat = PartStat.DECLINED;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.Microsoft Schedule.MtgRespA")) {
                if ((isCounterProposal != null) && isCounterProposal) {
                    method = Method.COUNTER;
                } else {
                    method = Method.REPLY;
                }
                partstat = PartStat.TENTATIVE;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.Microsoft Schedule.MtgCncl")) {
                method = Method.CANCEL;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.TaskRequest.Accept")) {
                method = Method.REPLY;
                partstat = PartStat.ACCEPTED;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.TaskRequest.Decline")) {
                method = Method.REPLY;
                partstat = PartStat.DECLINED;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.TaskRequest.Update")) {
                method = Method.REPLY;
                // May be overridden?
                partstat = PartStat.IN_PROCESS;
                replyWanted = false;
            } else if (msgClass.startsWith("IPM.TaskRequest")) {
                method = Method.REQUEST;
                partstat = PartStat.NEEDS_ACTION;
                replyWanted = true;
            }
        }
        if (method == null) {
            sLog.debug("Unable to map class %s to ICALENDER", msgClass);
            return false;
        //                throw TNEFtoIcalendarServiceException.NON_CALENDARING_CLASS(msgClass);
        }
        if (icalType == ICALENDAR_TYPE.VTODO) {
            List<?> attaches = (List<?>) schedView.getAttachments();
            if (attaches == null) {
                sLog.debug("Unable to map class %s to ICALENDER - no attachments", msgClass);
                return false;
            }
            schedView = null;
            for (Object obj : attaches) {
                if (obj instanceof Attachment) {
                    Attachment currAttach = (Attachment) obj;
                    MAPIProps attachMPs = currAttach.getMAPIProps();
                    if (attachMPs != null) {
                        MAPIProp attachData = attachMPs.getProp(MAPIProp.PR_ATTACH_DATA_OBJ);
                        if (attachData != null) {
                            Object theVal = attachData.getValue();
                            if ((theVal != null) && (theVal instanceof TNEFInputStream)) {
                                TNEFInputStream tnefSubStream = (TNEFInputStream) theVal;
                                schedView = new SchedulingViewOfTnef(tnefSubStream);
                                break;
                            }
                        }
                    }
                }
            }
            if (schedView == null) {
                sLog.debug("Unable to map class %s to ICALENDER - no properties found for sub-msg", msgClass);
                return false;
            }
        }
        uid = schedView.getIcalUID();
        sequenceNum = schedView.getSequenceNumber();
        boolean reminderSet = schedView.getReminderSet();
        String location = schedView.getLocation();
        Boolean isAllDayEvent = schedView.isAllDayEvent();
        Integer importance = schedView.getMapiImportance();
        Clazz icalClass = schedView.getIcalClass();
        Integer ownerApptId = schedView.getOwnerAppointmentId();
        EnumSet<MeetingTypeFlag> meetingTypeFlags = schedView.getMeetingTypeFlags();
        BusyStatus busyStatus = schedView.getBusyStatus();
        BusyStatus intendedBusyStatus = schedView.getIntendedBusyStatus();
        // For some ICAL properties like TRANSP and STATUS, intendedBusyStatus
        // seems closer to what is intended than straight busyStatus
        BusyStatus bestBusyStatus = intendedBusyStatus;
        if (bestBusyStatus == null) {
            bestBusyStatus = busyStatus;
        }
        // An algorithm is used to choose the values for these
        // TimeZoneDefinitions  - they don't necessarily map to single
        // MAPI properties
        TimeZoneDefinition startTimeTZinfo = schedView.getStartDateTimezoneInfo();
        TimeZoneDefinition endTimeTZinfo = schedView.getEndDateTimezoneInfo();
        TimeZoneDefinition recurrenceTZinfo = schedView.getRecurrenceTimezoneInfo();
        recurDef = schedView.getRecurrenceDefinition(recurrenceTZinfo);
        DateTime icalStartDate = schedView.getStartTime();
        DateTime icalEndDate = schedView.getEndTime();
        DateTime icalDueDate = schedView.getDueDate();
        DateTime icalDateTaskCompleted = schedView.getDateTaskCompleted();
        DateTime icalCreateDate = MapiPropertyId.PidTagCreationTime.getDateTimeAsUTC(schedView);
        DateTime icalLastModDate = MapiPropertyId.PidTagLastModificationTime.getDateTimeAsUTC(schedView);
        DateTime recurrenceIdDateTime = schedView.getRecurrenceIdTime();
        DateTime attendeeCriticalChange = schedView.getAttendeeCriticalChange();
        DateTime ownerCriticalChange = schedView.getOwnerCriticalChange();
        int percentComplete = schedView.getPercentComplete();
        TaskStatus taskStatus = schedView.getTaskStatus();
        TaskMode taskMode = schedView.getTaskMode();
        String mileage = schedView.getMileage();
        String billingInfo = schedView.getBillingInfo();
        String companies = schedView.getCompanies();
        Integer actualEffort = schedView.getActualEffort();
        Integer estimatedEffort = schedView.getEstimatedEffort();
        List<String> categories = schedView.getCategories();
        String descriptionText = null;
        String summary = null;
        if (mimeMsg != null) {
            summary = mimeMsg.getSubject();
            PlainTextFinder finder = new PlainTextFinder();
            finder.accept(mimeMsg);
            descriptionText = finder.getPlainText();
        }
        // RTF might be useful as a basis for X-ALT-DESC if we can find a reliable
        // conversion to HTML
        // String rtfText = schedView.getRTF();
        icalOutput.startCalendar();
        // Results in a 2nd PRODID in iCalendar
        // IcalUtil.addProperty(icalOutput, Property.PRODID,
        //         "Zimbra-TNEF-iCalendar-Converter");
        IcalUtil.addProperty(icalOutput, method);
        if (recurDef != null) {
            String MsCalScale = recurDef.xMicrosoftCalscale();
            if ((MsCalScale == null) || (MsCalScale.equals(""))) {
                IcalUtil.addProperty(icalOutput, CalScale.GREGORIAN);
            } else {
                IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CALSCALE", MsCalScale);
            }
        } else {
            IcalUtil.addProperty(icalOutput, CalScale.GREGORIAN);
        }
        String startTZname = null;
        String endTZname = null;
        String recurTZname = null;
        if (startTimeTZinfo != null) {
            startTZname = startTimeTZinfo.getTimezoneName();
            startTimeTZinfo.addVtimezone(icalOutput);
        }
        if (endTimeTZinfo != null) {
            endTZname = endTimeTZinfo.getTimezoneName();
            if ((startTZname == null) || (!endTZname.equals(startTZname))) {
                endTimeTZinfo.addVtimezone(icalOutput);
            }
        }
        if (recurrenceTZinfo != null) {
            recurTZname = recurrenceTZinfo.getTimezoneName();
            boolean addName = true;
            if ((startTZname != null) && (recurTZname.equals(startTZname))) {
                addName = false;
            }
            if ((endTZname != null) && (recurTZname.equals(endTZname))) {
                addName = false;
            }
            if (addName) {
                recurrenceTZinfo.addVtimezone(icalOutput);
            }
        }
        if (uid == null) {
            sLog.debug("Unable to map class %s to ICALENDER - no suitable value found for UID", msgClass);
            return false;
        }
        icalOutput.startComponent(icalType.toString());
        IcalUtil.addProperty(icalOutput, Property.UID, uid);
        if ((attendeeCriticalChange != null) && (method.equals(Method.REPLY) || method.equals(Method.COUNTER))) {
            dtstamp = new DtStamp(attendeeCriticalChange);
        } else if (ownerCriticalChange != null) {
            dtstamp = new DtStamp(ownerCriticalChange);
        } else {
            DateTime stampTime = new DateTime("20000101T000000Z");
            dtstamp = new DtStamp(stampTime);
        }
        IcalUtil.addProperty(icalOutput, dtstamp);
        IcalUtil.addProperty(icalOutput, Property.CREATED, icalCreateDate, false);
        IcalUtil.addProperty(icalOutput, Property.LAST_MODIFIED, icalLastModDate, false);
        IcalUtil.addProperty(icalOutput, Property.SEQUENCE, sequenceNum, false);
        if ((summary == null) || (summary.length() == 0)) {
            // TNEF_to_iCalendar.pdf Spec requires SUMMARY for certain method types
            if (this.icalType == ICALENDAR_TYPE.VTODO) {
                if (method.equals(Method.REQUEST)) {
                    summary = new String("Task Request");
                } else if (method.equals(Method.REPLY)) {
                    summary = new String("Task Response");
                } else {
                    summary = new String("Task");
                }
            } else {
                if (method.equals(Method.REPLY)) {
                    summary = new String("Response");
                } else if (method.equals(Method.CANCEL)) {
                    summary = new String("Canceled");
                } else if (method.equals(Method.COUNTER)) {
                    summary = new String("Counter Proposal");
                }
            }
        }
        IcalUtil.addProperty(icalOutput, Property.SUMMARY, summary, false);
        IcalUtil.addProperty(icalOutput, Property.LOCATION, location, false);
        IcalUtil.addProperty(icalOutput, Property.DESCRIPTION, descriptionText, false);
        if (method.equals(Method.COUNTER)) {
            IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.DTSTART, schedView.getProposedStartTime(), startTimeTZinfo, isAllDayEvent);
            IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.DTEND, schedView.getProposedEndTime(), endTimeTZinfo, isAllDayEvent);
            IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, "X-MS-OLK-ORIGINALSTART", icalStartDate, startTimeTZinfo, isAllDayEvent);
            IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, "X-MS-OLK-ORIGINALEND", icalEndDate, endTimeTZinfo, isAllDayEvent);
        } else {
            if (this.icalType == ICALENDAR_TYPE.VTODO) {
                IcalUtil.addFloatingDateProperty(icalOutput, Property.DTSTART, icalStartDate);
                IcalUtil.addFloatingDateProperty(icalOutput, Property.DUE, icalDueDate);
                Status icalStatus = null;
                if (method.equals(Method.CANCEL)) {
                    icalStatus = Status.VTODO_CANCELLED;
                } else if (taskStatus != null) {
                    if (taskStatus.equals(TaskStatus.COMPLETE)) {
                        icalStatus = Status.VTODO_COMPLETED;
                    } else if (taskStatus.equals(TaskStatus.IN_PROGRESS)) {
                        icalStatus = Status.VTODO_IN_PROCESS;
                    }
                }
                IcalUtil.addProperty(icalOutput, icalStatus);
                if (percentComplete != 0) {
                    IcalUtil.addProperty(icalOutput, Property.PERCENT_COMPLETE, percentComplete, false);
                }
                // COMPLETED must be a UTC DATE-TIME according to rfc5545
                IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.COMPLETED, icalDateTaskCompleted, null, false);
            } else {
                IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.DTSTART, icalStartDate, startTimeTZinfo, isAllDayEvent);
                IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.DTEND, icalEndDate, endTimeTZinfo, isAllDayEvent);
            }
        }
        // just the original start date.
        if (recurrenceIdDateTime != null) {
            IcalUtil.addPropertyFromUtcTimeAndZone(icalOutput, Property.RECURRENCE_ID, recurrenceIdDateTime, startTimeTZinfo, isAllDayEvent);
        } else {
            // Outlook messages related to a specific instance still include info on
            // the full recurrence but we don't want to include that.
            addRecurrenceRelatedProps(icalOutput, recurDef, startTimeTZinfo, isAllDayEvent);
        }
        // VTODO REQUEST must have priority according to http://tools.ietf.org/html/rfc5546
        // No harm in always setting it
        Priority priority = Priority.MEDIUM;
        if (importance != null) {
            if (importance == 2) {
                priority = Priority.HIGH;
            } else if (importance == 1) {
                priority = Priority.MEDIUM;
            } else if (importance == 0) {
                priority = Priority.LOW;
            }
        }
        IcalUtil.addProperty(icalOutput, priority);
        IcalUtil.addProperty(icalOutput, icalClass);
        addStatusProperty(icalOutput, bestBusyStatus, meetingTypeFlags);
        addTranspProperty(icalOutput, bestBusyStatus);
        addAttendees(icalOutput, mimeMsg, partstat, replyWanted);
        // Not done as Zimbra doesn't currently support "RESOURCES".
        if (categories != null) {
            CategoryList cl = new CategoryList();
            for (String category : categories) {
                cl.add(category);
            }
            if (cl.size() > 0) {
                Categories myCategories = new Categories(cl);
                IcalUtil.addProperty(icalOutput, myCategories);
            }
        }
        if (taskStatus != null) {
            if (taskStatus.equals(TaskStatus.DEFERRED) || taskStatus.equals(TaskStatus.WAITING_ON_OTHER)) {
                IcalUtil.addProperty(icalOutput, "X-ZIMBRA-TASK-STATUS", taskStatus, false);
            }
        }
        if ((taskMode != null) && (!taskMode.equals(TaskMode.TASK_REQUEST))) {
            IcalUtil.addProperty(icalOutput, "X-ZIMBRA-TASK-MODE", taskMode, false);
        }
        IcalUtil.addProperty(icalOutput, "X-ZIMBRA-MILEAGE", mileage, false);
        IcalUtil.addProperty(icalOutput, "X-ZIMBRA-BILLING-INFO", billingInfo, false);
        IcalUtil.addProperty(icalOutput, "X-ZIMBRA-COMPANIES", companies, false);
        IcalUtil.addProperty(icalOutput, "X-ZIMBRA-ACTUAL-WORK-MINS", actualEffort, false);
        IcalUtil.addProperty(icalOutput, "X-ZIMBRA-TOTAL-WORK-MINS", estimatedEffort, false);
        if (this.icalType == ICALENDAR_TYPE.VEVENT) {
            IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-ALLDAYEVENT", isAllDayEvent ? "TRUE" : "FALSE");
            IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-BUSYSTATUS", busyStatus, false);
            if (method.equals(Method.REQUEST)) {
                IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-INTENDEDSTATUS", intendedBusyStatus, false);
            }
            IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-OWNERAPPTID", ownerApptId, false);
            IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-REPLYTIME", schedView.getAppointmentReplyTime(), false);
            IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE", ownerCriticalChange, false);
            Boolean disallowCounter = schedView.isDisallowCounter();
            if (disallowCounter != null) {
                IcalUtil.addProperty(icalOutput, "X-MICROSOFT-CDO-DISALLOW-COUNTER", disallowCounter ? "TRUE" : "FALSE");
            }
        }
        if (reminderSet) {
            addAlarmComponent(icalOutput, schedView.getReminderDelta());
        }
        icalOutput.endComponent(icalType.toString());
        if (recurrenceIdDateTime == null) {
            // If this message primarily relates to a specific instance,
            // exception information is superfluous
            addExceptions(icalOutput, recurDef, recurrenceTZinfo, sequenceNum, ownerApptId, summary, location, isAllDayEvent);
        }
        icalOutput.endCalendar();
        conversionSuccessful = true;
        sLog.info("Calendaring TNEF message mapped to ICALENDAR with UID=%s", uid);
    } catch (ParserException e) {
        sLog.debug("Unexpected ParserException thrown", e);
    } catch (URISyntaxException e) {
        sLog.debug("Unexpected URISyntaxException thrown", e);
    } catch (ParseException e) {
        sLog.debug("Unexpected ParseException thrown", e);
    } catch (MessagingException e) {
        sLog.debug("Unexpected MessagingException thrown", e);
    } catch (NegativeArraySizeException e) {
        sLog.debug("Problem decoding TNEF for ICALENDAR", e);
    } catch (IOException e) {
        sLog.debug("Unexpected IOException thrown", e);
    } catch (UnsupportedTnefCalendaringMsgException e) {
        sLog.debug("Unable to map this message to ICALENDAR", e);
    } catch (TNEFtoIcalendarServiceException e) {
        sLog.debug("Problem encountered mapping this message to ICALENDAR", e);
    } finally {
        try {
            if (tnefStream != null) {
                tnefStream.close();
            }
        } catch (IOException ioe) {
            sLog.debug("Problem encountered closing TNEF stream", ioe);
        }
    }
    return conversionSuccessful;
}
Also used : MAPIProps(net.freeutils.tnef.MAPIProps) TimeZoneDefinition(com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition) Attachment(net.freeutils.tnef.Attachment) BusyStatus(com.zimbra.cs.util.tnef.mapi.BusyStatus) URISyntaxException(java.net.URISyntaxException) TaskMode(com.zimbra.cs.util.tnef.mapi.TaskMode) MAPIProp(net.freeutils.tnef.MAPIProp) DateTime(net.fortuna.ical4j.model.DateTime) DtStamp(net.fortuna.ical4j.model.property.DtStamp) MeetingTypeFlag(com.zimbra.cs.util.tnef.mapi.MeetingTypeFlag) List(java.util.List) ParameterList(net.fortuna.ical4j.model.ParameterList) CategoryList(net.fortuna.ical4j.model.CategoryList) Clazz(net.fortuna.ical4j.model.property.Clazz) UnsupportedTnefCalendaringMsgException(com.zimbra.cs.util.tnef.TNEFtoIcalendarServiceException.UnsupportedTnefCalendaringMsgException) Status(net.fortuna.ical4j.model.property.Status) TaskStatus(com.zimbra.cs.util.tnef.mapi.TaskStatus) BusyStatus(com.zimbra.cs.util.tnef.mapi.BusyStatus) ParserException(net.fortuna.ical4j.data.ParserException) Categories(net.fortuna.ical4j.model.property.Categories) MessagingException(javax.mail.MessagingException) Priority(net.fortuna.ical4j.model.property.Priority) PartStat(net.fortuna.ical4j.model.parameter.PartStat) IOException(java.io.IOException) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) TaskStatus(com.zimbra.cs.util.tnef.mapi.TaskStatus) CategoryList(net.fortuna.ical4j.model.CategoryList) ParseException(java.text.ParseException)

Example 2 with TimeZoneDefinition

use of com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition in project zm-mailbox by Zimbra.

the class TnefTimeZone method getTimeZone.

/**
     * Ref: [MS-OXOCAL] - v20100729
     * Returns a time zone from the given index;
     * The default TimeZone ID is "tnefTimeZone"
     * @param index
     * @return
     * @throws IOException 
     */
public static TimeZone getTimeZone(int index, boolean observeDaylightSaving, String tzId) throws IOException {
    if (index < 0 || index > 59)
        return null;
    // UTC offset in minutes
    int bias = 0;
    // offset in minutes from bias during standard time.; has a value of 0 in most cases
    int standardBias = 0;
    // offset in minutes from bias during daylight saving time.
    int daylightBias = 0;
    SYSTEMTIME StandardDate = null;
    SYSTEMTIME DaylightDate = null;
    // 1 - January, 12 - December
    int startMonth = 0;
    // 0 - Sunday, 6 - Saturday
    int startDayOfWeek = 0;
    // day of the week within the month, 5 = last occurrence of that day
    int startDay = 0;
    int startHour = 0;
    int endMonth = 0;
    int endDayOfWeek = 0;
    int endDay = 0;
    int endHour = 0;
    // get the UTC+12 standard offset in minutes from MS_OXOCAL_STANDARD_OFFSET table!!
    int utcPlus12offset = MS_OXOCAL_STANDARD_OFFSET[index][0];
    int indexToDaytimeSavingDatesTable = MS_OXOCAL_STANDARD_OFFSET[index][1];
    if (utcPlus12offset > 12 * 60)
        bias = (utcPlus12offset - 12 * 60) * -1;
    else if (utcPlus12offset < 12 * 60)
        bias = (12 * 60 - utcPlus12offset);
    if (indexToDaytimeSavingDatesTable == -1 || !observeDaylightSaving) {
        int utcOffsetInMilliseconds = bias * 60 * 1000;
        return getNoDaylightSavingTimeZoneFromUtcOffset(utcOffsetInMilliseconds);
    }
    // handle the daylight saving case here...
    // HACK!!
    // HACK!!
    // TZRule.getStandardUtcOffset() always multiply the offset by -1;
    // Hence, we are multiplying by -1 in reverse order.
    bias = bias * -1;
    // If daylight saving time is observed, during the daylight time period, 
    // an additional -60 offset is added to the standard offset.
    daylightBias = -60;
    startMonth = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][1][0];
    startDayOfWeek = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][1][1];
    startDay = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][1][2];
    startHour = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][1][3];
    endMonth = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][0][0];
    endDayOfWeek = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][0][1];
    endDay = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][0][2];
    endHour = MS_OXOCAL_STAN_DST_DATES[indexToDaytimeSavingDatesTable][0][3];
    StandardDate = new SYSTEMTIME(endMonth, endDayOfWeek, endDay, endHour);
    DaylightDate = new SYSTEMTIME(startMonth, startDayOfWeek, startDay, startHour);
    if (sLog.isDebugEnabled()) {
        StringBuilder debugInfo = new StringBuilder();
        debugInfo.append(bias * -1 + " " + "{" + endMonth + "," + endDayOfWeek + "," + endDay + "," + endHour + "} " + "{" + startMonth + "," + startDayOfWeek + "," + startDay + "," + startHour + "}");
        sLog.debug(debugInfo);
    }
    String timeZoneId;
    if (tzId == null || tzId.length() == 0)
        timeZoneId = DEFAULT_TNEF_TIMEZONE_ID;
    else
        timeZoneId = tzId;
    TimeZoneDefinition timeZoneDefinition = new TimeZoneDefinition(timeZoneId, bias, standardBias, daylightBias, StandardDate, DaylightDate);
    return timeZoneDefinition.getTimeZone();
}
Also used : TimeZoneDefinition(com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition) SYSTEMTIME(com.zimbra.cs.util.tnef.mapi.SYSTEMTIME)

Example 3 with TimeZoneDefinition

use of com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition in project zm-mailbox by Zimbra.

the class SchedulingViewOfTnef method getTimeZoneStructInfo.

/**
     * PidLidTimeZoneStruct Specifies time zone information for a recurring meeting.
     *
     * @param tzName
     * @return
     * @throws IOException
     */
private TimeZoneDefinition getTimeZoneStructInfo(String tzName) throws IOException {
    RawInputStream tzRis = MapiPropertyId.PidLidTimeZoneStruct.getRawInputStreamValue(this);
    if (tzRis == null) {
        return null;
    }
    TimeZoneDefinition tzDef = new TimeZoneDefinition(tzRis, tzName);
    if (tzDef == null) {
        if (sLog.isDebugEnabled()) {
            sLog.debug("Failed to load TimeZoneDefinition from PidLidTimeZoneStruct and " + tzName);
        }
    }
    return tzDef;
}
Also used : RawInputStream(net.freeutils.tnef.RawInputStream) TimeZoneDefinition(com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition)

Example 4 with TimeZoneDefinition

use of com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition in project zm-mailbox by Zimbra.

the class SchedulingViewOfTnef method initTZinfo.

/**
     * Initialise timezone related fields.
     * Replies from Outlook 2007 related to a recurrence or an instance
     * of a recurrence had :
     *     PidLidTimeZoneDescription,PidLidTimeZoneStruct,
     *     PidLidAppointmentTimeZoneDefinitionStartDisplay and
     *     PidLidAppointmentTimeZoneDefinitionEndDisplay present but NOT
     *     PidLidAppointmentTimeZoneDefinitionRecur
     * further, the StartDisplay/EndDisplay properties were appropriate to the
     * Outlook client replying and were NOT related to the originally sent ICAL.
     *
     * The Outlook originated TimeZone names associated with
     * StartDisplay/EndDisplay/Recur props seem "nicer" than the names
     * used in PidLidTimeZoneDescription - so, tend to prefer those.
     *
     * @throws IOException
     */
private void initTZinfo() {
    if (tzinfoInitialized) {
        return;
    }
    try {
        RawInputStream tzRis;
        MapiPropertyId mpi;
        mpi = MapiPropertyId.PidLidAppointmentTimeZoneDefinitionStartDisplay;
        tzRis = mpi.getRawInputStreamValue(this);
        if (tzRis != null) {
            startTimeTZinfo = new TimeZoneDefinition(mpi, tzRis);
        }
        mpi = MapiPropertyId.PidLidAppointmentTimeZoneDefinitionEndDisplay;
        tzRis = mpi.getRawInputStreamValue(this);
        if (tzRis != null) {
            endTimeTZinfo = new TimeZoneDefinition(mpi, tzRis);
        }
        mpi = MapiPropertyId.PidLidAppointmentTimeZoneDefinitionRecur;
        tzRis = mpi.getRawInputStreamValue(this);
        if (tzRis != null) {
            recurrenceTZinfo = new TimeZoneDefinition(mpi, tzRis);
        }
        String tzDesc = this.getTimeZoneDescription();
        if (null != tzDesc) {
            TimeZoneDefinition tzStructInfo = this.getTimeZoneStructInfo(tzDesc);
            if (tzStructInfo != null) {
                // We know we have a recurrence related TZ definition.  Make
                // sure we have the most appropriate/nice definition for that.
                TZRule tzsRule = tzStructInfo.getEffectiveRule();
                if (recurrenceTZinfo == null) {
                    if ((startTimeTZinfo != null) && (tzsRule.equivalentRule(startTimeTZinfo.getEffectiveRule()))) {
                        recurrenceTZinfo = startTimeTZinfo;
                        sLog.debug("Using %s for TZ info", "PidLidAppointmentTimeZoneDefinitionStart");
                    } else if ((endTimeTZinfo != null) && (tzsRule.equivalentRule(endTimeTZinfo.getEffectiveRule()))) {
                        recurrenceTZinfo = endTimeTZinfo;
                        sLog.debug("Using %s for TZ info", "PidLidAppointmentTimeZoneDefinitionEnd");
                    } else {
                        recurrenceTZinfo = tzStructInfo;
                        sLog.debug("Using %s for TZ info", "PidLidTimeZoneStruct");
                    }
                } else if (!tzsRule.equivalentRule(recurrenceTZinfo.getEffectiveRule())) {
                    recurrenceTZinfo = tzStructInfo;
                    sLog.debug("Using %s for TZ info", "PidLidAppointmentTimeZoneDefinitionRecur");
                }
            }
        }
    } catch (IOException e) {
        sLog.debug("Problem encountered initialising timezone information", e);
    }
    if (recurrenceTZinfo != null) {
        // For recurrences, we want just one TZ for consistency
        if (endTimeTZinfo == null) {
            endTimeTZinfo = recurrenceTZinfo;
        } else if (recurrenceTZinfo.getEffectiveRule().equivalentRule(endTimeTZinfo.getEffectiveRule())) {
            endTimeTZinfo = recurrenceTZinfo;
        } else if (startTimeTZinfo != null) {
            // for cancel/request, even when related to an exception.
            if (startTimeTZinfo.getEffectiveRule().equivalentRule(endTimeTZinfo.getEffectiveRule())) {
                endTimeTZinfo = recurrenceTZinfo;
            }
        }
        startTimeTZinfo = recurrenceTZinfo;
    }
    if (endTimeTZinfo == null) {
        endTimeTZinfo = startTimeTZinfo;
    } else if (startTimeTZinfo == null) {
        startTimeTZinfo = endTimeTZinfo;
    } else if (startTimeTZinfo.getEffectiveRule().equivalentRule(endTimeTZinfo.getEffectiveRule())) {
        endTimeTZinfo = startTimeTZinfo;
    }
}
Also used : TZRule(com.zimbra.cs.util.tnef.mapi.TZRule) RawInputStream(net.freeutils.tnef.RawInputStream) TimeZoneDefinition(com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition) IOException(java.io.IOException) MapiPropertyId(com.zimbra.cs.util.tnef.mapi.MapiPropertyId)

Aggregations

TimeZoneDefinition (com.zimbra.cs.util.tnef.mapi.TimeZoneDefinition)4 IOException (java.io.IOException)2 RawInputStream (net.freeutils.tnef.RawInputStream)2 UnsupportedTnefCalendaringMsgException (com.zimbra.cs.util.tnef.TNEFtoIcalendarServiceException.UnsupportedTnefCalendaringMsgException)1 BusyStatus (com.zimbra.cs.util.tnef.mapi.BusyStatus)1 MapiPropertyId (com.zimbra.cs.util.tnef.mapi.MapiPropertyId)1 MeetingTypeFlag (com.zimbra.cs.util.tnef.mapi.MeetingTypeFlag)1 SYSTEMTIME (com.zimbra.cs.util.tnef.mapi.SYSTEMTIME)1 TZRule (com.zimbra.cs.util.tnef.mapi.TZRule)1 TaskMode (com.zimbra.cs.util.tnef.mapi.TaskMode)1 TaskStatus (com.zimbra.cs.util.tnef.mapi.TaskStatus)1 URISyntaxException (java.net.URISyntaxException)1 ParseException (java.text.ParseException)1 List (java.util.List)1 MessagingException (javax.mail.MessagingException)1 ParserException (net.fortuna.ical4j.data.ParserException)1 CategoryList (net.fortuna.ical4j.model.CategoryList)1 DateTime (net.fortuna.ical4j.model.DateTime)1 ParameterList (net.fortuna.ical4j.model.ParameterList)1 PartStat (net.fortuna.ical4j.model.parameter.PartStat)1