use of com.zimbra.cs.mailbox.calendar.RdateExdate in project zm-mailbox by Zimbra.
the class CalendarUtils method parseRecur.
static Recurrence.IRecurrence parseRecur(Element recurElt, TimeZoneMap invTzMap, ParsedDateTime dtStart, ParsedDateTime dtEnd, ParsedDuration dur, RecurId recurId) throws ServiceException {
if (dur == null && dtStart != null && dtEnd != null)
dur = dtEnd.difference(dtStart);
ArrayList<IRecurrence> addRules = new ArrayList<IRecurrence>();
ArrayList<IRecurrence> subRules = new ArrayList<IRecurrence>();
for (Iterator iter = recurElt.elementIterator(); iter.hasNext(); ) {
Element e = (Element) iter.next();
boolean exclude = false;
if (e.getName().equals(MailConstants.E_CAL_EXCLUDE)) {
exclude = true;
} else {
if (!e.getName().equals(MailConstants.E_CAL_ADD)) {
continue;
}
}
for (Iterator intIter = e.elementIterator(); intIter.hasNext(); ) {
Element intElt = (Element) intIter.next();
if (intElt.getName().equals(MailConstants.E_CAL_DATES)) {
// handle RDATE or EXDATE
String tzid = intElt.getAttribute(MailConstants.A_CAL_TIMEZONE, null);
ICalTimeZone tz = tzid != null ? invTzMap.lookupAndAdd(tzid) : null;
RdateExdate rexdate = new RdateExdate(exclude ? ICalTok.EXDATE : ICalTok.RDATE, tz);
ICalTok valueType = null;
for (Iterator<Element> dtvalIter = intElt.elementIterator(MailConstants.E_CAL_DATE_VAL); dtvalIter.hasNext(); ) {
ICalTok dtvalValueType = null;
Element dtvalElem = dtvalIter.next();
Element dtvalStartElem = dtvalElem.getElement(MailConstants.E_CAL_START_TIME);
String dtvalStartDateStr = dtvalStartElem.getAttribute(MailConstants.A_CAL_DATETIME);
ParsedDateTime dtvalStart = parseDateTime(dtvalElem.getName(), dtvalStartDateStr, tzid, invTzMap);
Element dtvalEndElem = dtvalElem.getOptionalElement(MailConstants.E_CAL_END_TIME);
Element dtvalDurElem = dtvalElem.getOptionalElement(MailConstants.E_CAL_DURATION);
if (dtvalEndElem == null && dtvalDurElem == null) {
if (dtvalStart.hasTime())
dtvalValueType = ICalTok.DATE_TIME;
else
dtvalValueType = ICalTok.DATE;
rexdate.addValue(dtvalStart);
} else {
dtvalValueType = ICalTok.PERIOD;
if (dtvalEndElem != null) {
String dtvalEndDateStr = dtvalEndElem.getAttribute(MailConstants.A_CAL_DATETIME);
ParsedDateTime dtvalEnd = parseDateTime(dtvalElem.getName(), dtvalEndDateStr, tzid, invTzMap);
Period p = new Period(dtvalStart, dtvalEnd);
rexdate.addValue(p);
} else {
ParsedDuration d = ParsedDuration.parse(dtvalDurElem);
Period p = new Period(dtvalStart, d);
rexdate.addValue(p);
}
}
if (valueType == null) {
valueType = dtvalValueType;
rexdate.setValueType(valueType);
} else if (valueType != dtvalValueType)
throw ServiceException.INVALID_REQUEST("Cannot mix different value types in a single <" + intElt.getName() + "> element", null);
}
Recurrence.SingleDates sd = new Recurrence.SingleDates(rexdate, dur);
if (exclude)
subRules.add(sd);
else
addRules.add(sd);
} else if (intElt.getName().equals(MailConstants.E_CAL_RULE)) {
// handle RRULE or EXRULE
// Turn XML into iCal RECUR string, which will then be
// parsed by ical4j Recur object.
StringBuilder recurBuf = new StringBuilder(100);
String freq = IcalXmlStrMap.sFreqMap.toIcal(intElt.getAttribute(MailConstants.A_CAL_RULE_FREQ));
recurBuf.append("FREQ=").append(freq);
for (Iterator ruleIter = intElt.elementIterator(); ruleIter.hasNext(); ) {
Element ruleElt = (Element) ruleIter.next();
String ruleEltName = ruleElt.getName();
if (ruleEltName.equals(MailConstants.E_CAL_RULE_UNTIL)) {
recurBuf.append(";UNTIL=");
String d = ruleElt.getAttribute(MailConstants.A_CAL_DATETIME);
recurBuf.append(d);
// (RFC2445 Section 4.3.10 Recurrence Rule)
if (d.indexOf("T") >= 0)
if (d.indexOf("Z") < 0)
recurBuf.append('Z');
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_COUNT)) {
int num = (int) ruleElt.getAttributeLong(MailConstants.A_CAL_RULE_COUNT_NUM, -1);
if (num > 0) {
recurBuf.append(";COUNT=").append(num);
} else {
throw ServiceException.INVALID_REQUEST("Expected positive num attribute in <recur> <rule> <count>", null);
}
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_INTERVAL)) {
String ival = ruleElt.getAttribute(MailConstants.A_CAL_RULE_INTERVAL_IVAL);
recurBuf.append(";INTERVAL=").append(ival);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYSECOND)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYSECOND_SECLIST);
recurBuf.append(";BYSECOND=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYMINUTE)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYMINUTE_MINLIST);
recurBuf.append(";BYMINUTE=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYHOUR)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYHOUR_HRLIST);
recurBuf.append(";BYHOUR=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYDAY)) {
recurBuf.append(";BYDAY=");
int pos = 0;
for (Iterator bydayIter = ruleElt.elementIterator(MailConstants.E_CAL_RULE_BYDAY_WKDAY); bydayIter.hasNext(); pos++) {
Element wkdayElt = (Element) bydayIter.next();
if (pos > 0)
recurBuf.append(",");
String ordwk = wkdayElt.getAttribute(MailConstants.A_CAL_RULE_BYDAY_WKDAY_ORDWK, null);
if (ordwk != null)
recurBuf.append(ordwk);
String day = wkdayElt.getAttribute(MailConstants.A_CAL_RULE_DAY);
if (day == null || day.length() == 0)
throw ServiceException.INVALID_REQUEST("Missing " + MailConstants.A_CAL_RULE_DAY + " in <" + ruleEltName + ">", null);
recurBuf.append(day);
}
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYMONTHDAY)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYMONTHDAY_MODAYLIST);
recurBuf.append(";BYMONTHDAY=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYYEARDAY)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYYEARDAY_YRDAYLIST);
recurBuf.append(";BYYEARDAY=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYWEEKNO)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYWEEKNO_WKLIST);
recurBuf.append(";BYWEEKNO=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYMONTH)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYMONTH_MOLIST);
recurBuf.append(";BYMONTH=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_BYSETPOS)) {
String list = ruleElt.getAttribute(MailConstants.A_CAL_RULE_BYSETPOS_POSLIST);
recurBuf.append(";BYSETPOS=").append(list);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_WKST)) {
String day = ruleElt.getAttribute(MailConstants.A_CAL_RULE_DAY);
recurBuf.append(";WKST=").append(day);
} else if (ruleEltName.equals(MailConstants.E_CAL_RULE_XNAME)) {
String name = ruleElt.getAttribute(MailConstants.A_CAL_RULE_XNAME_NAME, null);
if (name != null) {
String value = ruleElt.getAttribute(MailConstants.A_CAL_RULE_XNAME_VALUE, "");
// TODO: Escape/unescape value according to
// "text" rule.
recurBuf.append(";").append(name).append("=").append(value);
}
}
}
try {
ZRecur recur = new ZRecur(recurBuf.toString(), invTzMap);
if (exclude) {
subRules.add(new Recurrence.SimpleRepeatingRule(dtStart, dur, recur, null));
} else {
addRules.add(new Recurrence.SimpleRepeatingRule(dtStart, dur, recur, null));
}
} catch (ServiceException ex) {
throw ServiceException.INVALID_REQUEST("Exception parsing <recur> <rule>", ex);
}
} else {
throw ServiceException.INVALID_REQUEST("Expected <date> or <rule> inside of " + e.getName() + ", got " + intElt.getName(), null);
}
}
// iterate inside <add> or <exclude>
}
if (recurId != null) {
return new Recurrence.ExceptionRule(recurId, dtStart, dur, null, addRules, subRules);
} else {
return new Recurrence.RecurrenceRule(dtStart, dur, null, addRules, subRules);
}
}
Aggregations