use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class RecurUtil method getPeriods.
/**
* Returns a list of instances for this recurring event possibly bounded by
* the supplied maximum end date.
*
* <p>This is mostly a copy of VEvent.getConsumedTime()
*
* @param ev the recurring event
* @param maxYears Provide an upper limit
* @param maxInstances to limit
* @param startRange null or set earliest
* @param endRange null or set latest
* @return a list of periods for this event
* @throws CalFacadeException on error
*/
public static RecurPeriods getPeriods(final BwEvent ev, final int maxYears, final int maxInstances, final String startRange, final String endRange) throws CalFacadeException {
final PropertyList evprops = new PropertyList();
VEventUtil.doRecurring(ev, evprops);
final RecurPeriods rp = new RecurPeriods();
// DtStart vstart = (DtStart)IcalUtil.getProperty(comp, Property.DTSTART);
/* BwDateTime evstart = ev.getDtstart();
String tzid = evstart.getTzid();
DtStart start = new DtStart();
if (tzid != null) {
start.setTimeZone(timezones.getTimeZone(tzid));
}
try {
start.setValue(evstart.getDtval());
} catch (Throwable t) {
throw new CalFacadeException(t);
}*/
final DtStart start = ev.getDtstart().makeDtStart();
if (startRange != null) {
try {
rp.rangeStart = new DateTime(startRange);
} catch (final Throwable t) {
throw new CalFacadeException(t);
}
} else {
// boolean durSpecified = ev.getEndType() == BwEvent.endTypeDuration;
rp.rangeStart = start.getDate();
for (final Object o : evprops) {
if (o instanceof RDate) {
final RDate rd = (RDate) o;
for (final Object o1 : rd.getDates()) {
final Date d = (Date) o1;
if (d.before(rp.rangeStart)) {
rp.rangeStart = d;
}
}
}
}
}
/* Limit date according to system settings
*/
final Dur dur = new Dur(maxYears * 365, 0, 0, 0);
Date maxRangeEnd = new Date(dur.getTime(rp.rangeStart));
if (ev.getParent() != null) {
final BwDateTime pend = ev.getParent().getDtend();
if (pend != null) {
final Date dt = pend.makeDate();
if (dt.before(maxRangeEnd)) {
maxRangeEnd = dt;
}
}
}
final DtEnd end = ev.getDtend().makeDtEnd();
if (endRange != null) {
try {
rp.rangeEnd = new DateTime(endRange);
} catch (final Throwable t) {
throw new CalFacadeException(t);
}
} else {
final Duration duration = new Duration(null, ev.getDuration());
rp.rangeEnd = getLatestRecurrenceDate(evprops, start, end, duration, maxRangeEnd);
if ((rp.rangeEnd == null) || (rp.rangeEnd.after(maxRangeEnd))) {
rp.rangeEnd = maxRangeEnd;
}
}
Period rangePeriod = new Period(new DateTime(rp.rangeStart), new DateTime(rp.rangeEnd));
VEvent vev = new VEvent();
PropertyList vevprops = vev.getProperties();
vevprops.addAll(evprops);
if (!ev.getSuppressed()) {
// Allow inclusion of master start/end
vevprops.add(start);
vevprops.add(end);
} else {
// Move start/end outside of our period
Dur evdur = new Dur(ev.getDuration());
// Ensure at least a day
Dur setback = evdur.add(new Dur(1, 0, 0, 0));
boolean dateOnly = ev.getDtstart().getDateType();
Date adjustedEnd;
if (dateOnly) {
adjustedEnd = new Date(rp.rangeStart);
} else {
adjustedEnd = new DateTime(rp.rangeStart);
}
adjustedEnd.setTime(setback.negate().getTime(rp.rangeStart).getTime());
vevprops.add(new DtEnd(adjustedEnd));
// End now before range - make start evdur before that
Date adjustedStart;
if (dateOnly) {
adjustedStart = new Date(adjustedEnd);
} else {
adjustedStart = new DateTime(adjustedEnd);
}
adjustedStart.setTime(evdur.negate().getTime(adjustedEnd).getTime());
vevprops.add(new DtStart(adjustedStart));
}
PeriodList pl = vev.calculateRecurrenceSet(rangePeriod);
/*
PeriodList periods = new PeriodList();
if (ev.getDtstart().isUTC()) {
periods.setUtc(true);
} else if (start.getDate() instanceof DateTime) {
periods.setTimeZone(((DateTime)start.getDate()).getTimeZone());
} else {
try {
periods.setTimeZone(Timezones.getDefaultTz());
} catch (Throwable t) {
throw new CalFacadeException(t);
}
}
rp.instances = periods;
// if no start date return empty list..
if (start == null) {
return rp;
}
// if an explicit event duration is not specified, derive a value for recurring
// periods from the end date..
Dur rDuration;
Dur adjustDuration;
if (duration == null) {
if (end == null) {
rDuration = new Dur(0);
adjustDuration = new Dur(0, 0, 0, 1); // 1 second fudge
} else {
rDuration = new Dur(start.getDate(), end.getDate());
adjustDuration = rDuration;
}
} else {
rDuration = duration.getDuration();
adjustDuration = rDuration;
}
// adjust range start back by duration to allow for recurrences that
// start before the range but finish inside..
// FIXME: See bug #1325558..
Date adjustedRangeStart = new DateTime(rp.rangeStart);
adjustedRangeStart.setTime(adjustDuration.negate().getTime(rp.rangeStart).getTime());
// recurrence dates..
PropertyList rDates = evprops.getProperties(Property.RDATE);
for (Iterator i = rDates.iterator(); i.hasNext();) {
RDate rdate = (RDate) i.next();
if (Value.PERIOD.equals(rdate.getParameter(Parameter.VALUE))) {
/* These fully define the period * /
for (Iterator j = rdate.getPeriods().iterator(); j.hasNext();) {
Period period = (Period) j.next();
if (period.getStart().before(rp.rangeEnd) &&
period.getEnd().after(rp.rangeStart)) {
periods.add(period);
}
}
} else {
// Create a period based on rdate and duration
DateList startDates = rdate.getDates();
for (int j = 0; j < startDates.size(); j++) {
Date startDate = (Date) startDates.get(j);
periods.add(new Period(new DateTime(startDate), rDuration));
}
}
}
Value startVal = (Value)start.getParameter(Parameter.VALUE);
if (startVal == null) {
startVal = Value.DATE_TIME;
}
// recurrence rules..
PropertyList rRules = evprops.getProperties(Property.RRULE);
for (Iterator i = rRules.iterator(); i.hasNext();) {
RRule rrule = (RRule) i.next();
Recur recur = rrule.getRecur();
// Limit nummber of instances.
DateList startDates = recur.getDates(start.getDate(),
adjustedRangeStart,
rp.rangeEnd,
startVal,
maxInstances);
// DateList startDates = rrule.getRecur().getDates(start.getDate(), rangeStart, rangeEnd, (Value) start.getParameters().getParameter(Parameter.VALUE));
for (int j = 0; j < startDates.size(); j++) {
Date startDate = (Date) startDates.get(j);
periods.add(new Period(new DateTime(startDate), rDuration));
}
}
// add initial instance if intersection with the specified period.
if (!ev.getSuppressed()) {
Period startPeriod = null;
if (!durSpecified) {
startPeriod = new Period(new DateTime(start.getDate()),
new DateTime(end.getDate()));
} else {
startPeriod = new Period(new DateTime(start.getDate()),
duration.getDuration());
}
if (rangePeriod.intersects(startPeriod)) {
periods.add(startPeriod);
}
}
// exception dates..
PropertyList exDates = evprops.getProperties(Property.EXDATE);
for (Iterator i = exDates.iterator(); i.hasNext();) {
ExDate exDate = (ExDate) i.next();
for (Iterator j = periods.iterator(); j.hasNext();) {
Period period = (Period) j.next();
DateList dl = exDate.getDates();
// for DATE-TIME instances check for DATE-based exclusions also..
if (dl.contains(period.getStart())) {
j.remove();
} else if (dl.contains(new Date(period.getStart()))) {
j.remove();
}
}
}
// exception rules..
// FIXME: exception rules should be consistent with exception dates (i.e. not use periods?)..
PropertyList exRules = evprops.getProperties(Property.EXRULE);
PeriodList exPeriods = new PeriodList();
for (Iterator i = exRules.iterator(); i.hasNext();) {
ExRule exrule = (ExRule) i.next();
// DateList startDates = exrule.getRecur().getDates(start.getDate(), adjustedRangeStart, rangeEnd, (Value) start.getParameters().getParameter(Parameter.VALUE));
DateList startDates = exrule.getRecur().getDates(start.getDate(),
rp.rangeStart,
rp.rangeEnd,
startVal);
for (Iterator j = startDates.iterator(); j.hasNext();) {
Date startDate = (Date) j.next();
exPeriods.add(new Period(new DateTime(startDate), rDuration));
}
}
// apply exceptions..
if (!exPeriods.isEmpty()) {
periods = periods.subtract(exPeriods);
}
// if periods already specified through recurrence, return..
// ..also normalise before returning.
// if (!periods.isEmpty()) {
// periods = periods.normalise();
// }
*
*/
if (pl.size() <= maxInstances) {
rp.instances = pl;
} else {
rp.instances = new TreeSet<Period>();
for (Object o : pl) {
rp.instances.add((Period) o);
if (rp.instances.size() == maxInstances) {
break;
}
}
}
return rp;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class RecurUtil method getLastDate.
/* Return the highest possible start date from this recurrence or null
* if no count or until date specified
*/
private static Date getLastDate(final Recur r, Date start, final Date maxRangeEnd) {
Date seed = start;
Date until = r.getUntil();
if (until != null) {
return until;
}
int count = r.getCount();
if (count < 1) {
return null;
}
Dur days100 = new Dur(100, 0, 0, 0);
int counted = 0;
while ((counted < count) && (start.before(maxRangeEnd))) {
Date end = new DateTime(days100.getTime(start));
DateList dl = r.getDates(seed, start, end, Value.DATE_TIME);
int sz = dl.size();
counted += sz;
if (sz != 0) {
until = (Date) dl.get(sz - 1);
}
start = end;
}
return until;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class VEventUtil method makeDlp.
private static void makeDlp(final BwEvent val, final boolean exdt, final Collection<BwDateTime> dts, final PropertyList pl) throws Throwable {
if ((dts == null) || (dts.isEmpty())) {
return;
}
TimeZone tz = null;
if (!val.getForceUTC()) {
BwDateTime dtstart = val.getDtstart();
if ((dtstart != null) && !dtstart.isUTC()) {
DtStart ds = dtstart.makeDtStart();
tz = ds.getTimeZone();
}
}
/* Generate as one date per property - matches up to other vendors better */
for (BwDateTime dt : dts) {
DateList dl = null;
/* Always use the UTC values */
boolean dateType = false;
if (dt.getDateType()) {
dl = new DateList(Value.DATE);
dl.setUtc(true);
dateType = true;
dl.add(new Date(dt.getDtval()));
} else {
dl = new DateList(Value.DATE_TIME);
if (tz == null) {
dl.setUtc(true);
DateTime dtm = new DateTime(dt.getDate());
dtm.setUtc(true);
dl.add(dtm);
} else {
dl.setTimeZone(tz);
DateTime dtm = new DateTime(dt.getDate());
dtm.setTimeZone(tz);
dl.add(dtm);
}
}
DateListProperty dlp;
if (exdt) {
dlp = new ExDate(dl);
} else {
dlp = new RDate(dl);
}
if (tz != null) {
dlp.setTimeZone(tz);
}
if (dateType) {
dlp.getParameters().add(Value.DATE);
}
pl.add(dlp);
}
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class VEventUtil method makeZonedDt.
private static Date makeZonedDt(final BwEvent val, final String dtval) throws Throwable {
BwDateTime dtstart = val.getDtstart();
Date dt = new DateTime(dtval);
if (dtstart.getDateType()) {
// RECUR - fix all day recurrences sometime
if (dtval.length() > 8) {
// Try to fix up bad all day recurrence ids. - assume a local timezone
((DateTime) dt).setTimeZone(null);
return new Date(dt.toString().substring(0, 8));
}
return dt;
}
if (val.getForceUTC()) {
return dt;
}
if ((dtstart != null) && !dtstart.isUTC()) {
DtStart ds = dtstart.makeDtStart();
((DateTime) dt).setTimeZone(ds.getTimeZone());
}
return dt;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class VFreeUtil method toVFreeBusy.
/**
* Make a VFreeBusy object from a BwFreeBusy.
*/
/**
* @param val
* @return VFreeBusy
* @throws CalFacadeException
*/
public static VFreeBusy toVFreeBusy(final BwEvent val) throws CalFacadeException {
try {
VFreeBusy vfb = new VFreeBusy(IcalUtil.makeDateTime(val.getDtstart()), IcalUtil.makeDateTime(val.getDtend()));
PropertyList pl = vfb.getProperties();
Property prop;
/* ------------------- Attendees -------------------- */
if (val.getNumAttendees() > 0) {
for (BwAttendee att : val.getAttendees()) {
pl.add(setAttendee(att));
}
}
if (val.getNumComments() > 0) {
for (BwString str : val.getComments()) {
// LANG
pl.add(new Comment(str.getValue()));
}
}
if (val.getDtstamp() != null) {
DtStamp dts = (DtStamp) pl.getProperty(Property.DTSTAMP);
if (dts == null) {
prop = new DtStamp(new DateTime(val.getDtstamp()));
// if (pars.includeDateTimeProperty) {
// prop.getParameters().add(Value.DATE_TIME);
// }
pl.add(prop);
} else {
dts.setDateTime(new DateTime(val.getDtstamp()));
}
}
/* ------------------- freebusy -------------------- */
Collection<BwFreeBusyComponent> times = val.getFreeBusyPeriods();
if (times != null) {
for (BwFreeBusyComponent fbc : times) {
FreeBusy fb = new FreeBusy();
int type = fbc.getType();
if (type == BwFreeBusyComponent.typeBusy) {
addParameter(fb, FbType.BUSY);
} else if (type == BwFreeBusyComponent.typeFree) {
addParameter(fb, FbType.FREE);
} else if (type == BwFreeBusyComponent.typeBusyUnavailable) {
addParameter(fb, FbType.BUSY_UNAVAILABLE);
} else if (type == BwFreeBusyComponent.typeBusyTentative) {
addParameter(fb, FbType.BUSY_TENTATIVE);
} else {
throw new CalFacadeException("Bad free-busy type " + type);
}
PeriodList pdl = fb.getPeriods();
for (Period p : fbc.getPeriods()) {
// XXX inverse.ca plugin cannot handle durations.
Period np = new Period(p.getStart(), p.getEnd());
pdl.add(np);
}
pl.add(fb);
}
}
/* ------------------- Organizer -------------------- */
BwOrganizer org = val.getOrganizer();
if (org != null) {
pl.add(setOrganizer(org));
}
if (val.getUid() != null) {
pl.add(new Uid(val.getUid()));
}
return vfb;
} catch (CalFacadeException cfe) {
throw cfe;
} catch (Throwable t) {
throw new CalFacadeException(t);
}
}
Aggregations