use of net.fortuna.ical4j.model.WeekDayList in project zm-mailbox by Zimbra.
the class RecurrenceDefinition method icalRecurrenceProperty.
/**
* @param isAllDay
* @param isFloating
* @return The main recurrence property as ICAL - typically an RRULE but
* could theoretically be an X-MICROSOFT-RRULE
* @throws ServiceException
*/
public Property icalRecurrenceProperty(boolean isAllDay, boolean isFloating) throws ServiceException {
RRule theRule = null;
if (this.calScale.isSolarCalendar() == false) {
throw TNEFtoIcalendarServiceException.NON_SOLAR_CALENDAR();
}
// iCal4j Recur is a bit basic when it come to building things
// up from components, for instance, there currently isn't a way
// to set any BYDAY= value other than in the constructor from a String
StringBuffer recurrenceRule = new StringBuffer("FREQ=");
// According to RFC, only absolutely NEED WKST of have a
// weekly recurrence with interval greater than 1 OR using
// BYWEEKNO - however, does no harm to always include it.
String weekStartDay = firstDayOfWeek.toString();
boolean hasBYDAY = false;
boolean isYearly = false;
int interval = 1;
switch(patternType) {
case DAY:
recurrenceRule.append(Recur.DAILY);
interval = Long.valueOf(period).intValue() / 1440;
break;
case WEEK:
recurrenceRule.append(Recur.WEEKLY);
interval = Long.valueOf(period).intValue();
hasBYDAY = true;
break;
case MONTH:
interval = Long.valueOf(period).intValue();
if ((interval % 12) == 0) {
isYearly = true;
recurrenceRule.append(Recur.YEARLY);
interval = (interval / 12);
} else {
recurrenceRule.append(Recur.MONTHLY);
}
if (dayOfMonth != 0) {
recurrenceRule.append(";BYMONTHDAY=");
if (dayOfMonth == 31) {
recurrenceRule.append("-1");
} else {
recurrenceRule.append(dayOfMonth);
}
}
if (isYearly) {
java.util.TimeZone javaTZ = null;
if (tzDef != null) {
javaTZ = tzDef.getTimeZone();
} else {
javaTZ = TimeZone.getTimeZone(TimeZones.UTC_ID);
}
Date bymonthDate = IcalUtil.localMinsSince1601toDate(firstDateTime, tzDef);
Calendar bymonthCal = new GregorianCalendar(javaTZ);
bymonthCal.setTimeInMillis(bymonthDate.getTime());
String MONTH_ONLY_PATTERN = "MM";
DateFormat monthOnlyFormat = new SimpleDateFormat(MONTH_ONLY_PATTERN);
monthOnlyFormat.setCalendar(bymonthCal);
recurrenceRule.append(";BYMONTH=");
recurrenceRule.append(monthOnlyFormat.format(bymonthDate));
}
break;
case MONTH_NTH:
interval = Long.valueOf(period).intValue();
if ((interval % 12) == 0) {
isYearly = true;
recurrenceRule.append(Recur.YEARLY);
interval = (interval / 12);
} else {
recurrenceRule.append(Recur.MONTHLY);
}
hasBYDAY = true;
recurrenceRule.append(";BYSETPOS=");
if (weekDayOccurrenceNumber == 5) {
recurrenceRule.append(-1);
} else {
recurrenceRule.append(weekDayOccurrenceNumber);
}
if (isYearly) {
java.util.TimeZone javaTZ = null;
if (tzDef != null) {
javaTZ = tzDef.getTimeZone();
} else {
javaTZ = TimeZone.getTimeZone(TimeZones.UTC_ID);
}
Date bymonthDate = IcalUtil.localMinsSince1601toDate(firstDateTime, tzDef);
Calendar bymonthCal = new GregorianCalendar(javaTZ);
bymonthCal.setTimeInMillis(bymonthDate.getTime());
String MONTH_ONLY_PATTERN = "MM";
DateFormat monthOnlyFormat = new SimpleDateFormat(MONTH_ONLY_PATTERN);
monthOnlyFormat.setCalendar(bymonthCal);
recurrenceRule.append(";BYMONTH=");
recurrenceRule.append(monthOnlyFormat.format(bymonthDate));
}
break;
case MONTH_END:
case HJ_MONTH:
case HJ_MONTH_END:
case HJ_MONTH_NTH:
throw TNEFtoIcalendarServiceException.UNSUPPORTED_RECURRENCE_TYPE(patternType.name());
default:
throw TNEFtoIcalendarServiceException.UNSUPPORTED_RECURRENCE_TYPE(patternType.name());
}
if (recurrenceRule.length() > 5) /* length of "FREQ=" */
{
if (endType.equals(EndType.END_AFTER_N_OCCURRENCES)) {
recurrenceRule.append(";COUNT=");
recurrenceRule.append(occurrenceCount);
} else if (endType.equals(EndType.END_BY_DATE)) {
// MS-OXCICAL :
// set to (EndDate + startTimeOffset), converted from the
// time zone specified by PidLidTimeZoneStruct to the UTC time zone
// From RFC 5545 :
// The UNTIL rule part defines a DATE or DATE-TIME value that bounds
// the recurrence rule in an inclusive manner. If the value
// specified by UNTIL is synchronized with the specified recurrence,
// this DATE or DATE-TIME becomes the last instance of the
// recurrence. The value of the UNTIL rule part MUST have the same
// value type as the "DTSTART" property. Furthermore, if the
// "DTSTART" property is specified as a date with local time, then
// the UNTIL rule part MUST also be specified as a date with local
// time [Gren - i.e. when DTSTART is a floating time].
// If the "DTSTART" property is specified as a date with UTC
// time or a date with local time and time zone reference, then the
// UNTIL rule part MUST be specified as a date with UTC time.
long minsSince1601 = this.endMinsSince1601 + this.startTimeOffset;
DateTime untilDateTime = IcalUtil.localMinsSince1601toDate(minsSince1601, tzDef);
recurrenceRule.append(";UNTIL=");
java.util.TimeZone untilTZ = null;
if (this.tzDef != null) {
untilTZ = this.tzDef.getTimeZone();
}
if (isFloating) {
// Use localtime.
recurrenceRule.append(IcalUtil.iCalDateTimeValue(untilDateTime, untilTZ, isAllDay));
} else {
if (isAllDay) {
recurrenceRule.append(IcalUtil.iCalDateTimeValue(untilDateTime, untilTZ, isAllDay));
} else {
// MUST be UTC time
recurrenceRule.append(IcalUtil.icalUtcTime(minsSince1601, tzDef));
}
}
}
if (hasBYDAY) {
WeekDayList weekDayList = new WeekDayList();
dayOfWeekMask = getDayOfWeekMask();
for (DayOfWeek dow : dayOfWeekMask) {
weekDayList.add(dow.iCal4JWeekDay());
}
if (!weekDayList.isEmpty()) {
recurrenceRule.append(";BYDAY=");
recurrenceRule.append(weekDayList);
}
}
if (interval != 1) {
recurrenceRule.append(";INTERVAL=");
recurrenceRule.append(interval);
}
if (weekStartDay != null) {
recurrenceRule.append(";WKST=");
recurrenceRule.append(weekStartDay);
}
Recur recur;
try {
recur = new Recur(recurrenceRule.toString());
} catch (ParseException ex) {
throw TNEFtoIcalendarServiceException.RRULE_PARSING_PROBLEM(ex);
}
theRule = new RRule(recur);
}
return theRule;
}
Aggregations