use of com.zimbra.common.calendar.ParsedDateTime 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;
}
use of com.zimbra.common.calendar.ParsedDateTime 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);
}
}
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class Recurrence method main.
public static void main(String[] args) throws Exception {
ICalTimeZone pacific = new ICalTimeZone("America/Los_Angeles", -28800000, "16010101T020000", "FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU", "PST", -25200000, "16010101T020000", "FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU", "PDT");
TimeZoneMap tzmap = new TimeZoneMap(pacific);
String str = "TZID=\"" + pacific.getID() + "\":20090105T120000";
ParsedDateTime dtStart = ParsedDateTime.parse(str, tzmap);
ParsedDuration duration = ParsedDuration.parse("PT1H");
List<IRecurrence> addRules = new ArrayList<IRecurrence>();
List<IRecurrence> subRules = new ArrayList<IRecurrence>();
// weekly from 2009/01/05, for 52 weeks
ZRecur rule = new ZRecur("FREQ=WEEKLY;INTERVAL=1", tzmap);
addRules.add(new SimpleRepeatingRule(dtStart, duration, rule, null));
// add a couple of RDATES: 2009/01/06, 2009/01/07
RdateExdate rdate = new RdateExdate(ICalTok.RDATE, pacific);
str = "TZID=\"" + pacific.getID() + "\":20090106T120000";
ParsedDateTime rd1 = ParsedDateTime.parse(str, tzmap);
rdate.addValue(rd1);
str = "TZID=\"" + pacific.getID() + "\":20090107T120000";
ParsedDateTime rd2 = ParsedDateTime.parse(str, tzmap);
rdate.addValue(rd2);
addRules.add(new SingleDates(rdate, duration));
// modify instance on 2009/02/16 to start at 1pm instead of noon, for 2 hours
str = "TZID=\"" + pacific.getID() + "\":20090216T120000";
ParsedDateTime ridDtModify1 = ParsedDateTime.parse(str, tzmap);
RecurId ridModify1 = new RecurId(ridDtModify1, RecurId.RANGE_NONE);
str = "TZID=\"" + pacific.getID() + "\":20090216T130000";
ParsedDateTime dtStartModify1 = ParsedDateTime.parse(str, tzmap);
ParsedDuration durModify1 = ParsedDuration.parse("PT2H");
ExceptionRule modify1 = new ExceptionRule(ridModify1, dtStartModify1, durModify1, null);
// cancel instance on 2009/01/19
str = "TZID=\"" + pacific.getID() + "\":20090119T120000";
ParsedDateTime dtCancel1 = ParsedDateTime.parse(str, tzmap);
RecurId ridCancel1 = new RecurId(dtCancel1, RecurId.RANGE_NONE);
CancellationRule cancel1 = new CancellationRule(ridCancel1);
// EXDATE on 2009/02/09
RdateExdate exdate = new RdateExdate(ICalTok.EXDATE, pacific);
str = "TZID=\"" + pacific.getID() + "\":20090209T120000";
ParsedDateTime ex1 = ParsedDateTime.parse(str, tzmap);
exdate.addValue(ex1);
SingleDates exdateRule = new SingleDates(exdate, duration);
subRules.add(exdateRule);
RecurrenceRule recurrence = new RecurrenceRule(dtStart, duration, null, addRules, subRules);
recurrence.addException(modify1);
recurrence.addException(cancel1);
// Get all instances between 2009/01/01 and 2010/01/01.
Calendar startCal = new GregorianCalendar(pacific);
startCal.clear();
startCal.set(2009, Calendar.JANUARY, 1, 0, 0, 0);
Calendar endCal = (Calendar) startCal.clone();
endCal.add(Calendar.YEAR, 1);
// List<Instance> instances = recurrence.expandInstances(-1, startCal.getTimeInMillis(), endCal.getTimeInMillis());
List<Instance> instances = recurrence.expandInstances(-1, startCal.getTimeInMillis(), Long.MAX_VALUE);
for (Instance inst : instances) {
System.out.println(inst);
}
System.out.println("Got " + instances.size() + " instances");
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class RdateExdate method encodeMetadata.
public Metadata encodeMetadata() {
Metadata meta = new Metadata();
meta.put(FN_IS_RDATE, isRDATE());
if (mTimeZone != null)
meta.put(FN_TZID, mTimeZone.getID());
String vt = VT_DATE_TIME;
if (!ICalTok.DATE_TIME.equals(mValueType)) {
vt = ICalTok.DATE.equals(mValueType) ? VT_DATE : VT_PERIOD;
}
meta.put(FN_VALUE_TYPE, vt);
meta.put(FN_NUM_VALUES, mValues.size());
int i = 0;
for (Object val : mValues) {
if (val instanceof ParsedDateTime) {
ParsedDateTime dt = (ParsedDateTime) val;
meta.put(FN_VALUE + i, dt.getDateTimePartString(false));
} else if (val instanceof Period) {
Period p = (Period) val;
meta.put(FN_VALUE + i, p.encodeMetadata());
}
i++;
}
return meta;
}
use of com.zimbra.common.calendar.ParsedDateTime 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;
}
Aggregations