use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class RecurUtil method getRange.
/**
* Returns range of dates for this recurring event possibly bounded by
* the supplied maximum end date.
*
* @param ev the recurring event
* @param maxYears Provide an upper limit
* @return the range for this event
* @throws CalFacadeException
*/
@SuppressWarnings("unchecked")
public static RecurRange getRange(final BwEvent ev, final int maxYears) throws CalFacadeException {
PropertyList evprops = new PropertyList();
VEventUtil.doRecurring(ev, evprops);
RecurRange rr = new RecurRange();
DtStart start = ev.getDtstart().makeDtStart();
DtEnd end = ev.getDtend().makeDtEnd();
Duration duration = new Duration(null, ev.getDuration());
// boolean durSpecified = ev.getEndType() == BwEvent.endTypeDuration;
rr.rangeStart = start.getDate();
for (Object o : evprops) {
if (o instanceof RDate) {
RDate rd = (RDate) o;
for (Object o1 : rd.getDates()) {
Date d = (Date) o1;
if (d.before(rr.rangeStart)) {
rr.rangeStart = d;
}
}
}
}
/* Limit date according to system settings
*/
Dur dur = new Dur(maxYears * 365, 0, 0, 0);
Date maxRangeEnd = new Date(dur.getTime(rr.rangeStart));
if (ev.getParent() != null) {
BwDateTime pend = ev.getParent().getDtend();
if (pend != null) {
Date dt = pend.makeDate();
if (dt.before(maxRangeEnd)) {
maxRangeEnd = dt;
}
}
}
rr.rangeEnd = getLatestRecurrenceDate(evprops, start, end, duration, maxRangeEnd);
if ((rr.rangeEnd == null) || (rr.rangeEnd.after(maxRangeEnd))) {
rr.rangeEnd = maxRangeEnd;
}
return rr;
}
use of org.bedework.calfacade.BwDateTime 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 org.bedework.calfacade.BwDateTime 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 org.bedework.calfacade.BwDateTime 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 org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class Events method getInstances.
@Override
public InstancesResponse getInstances(final GetInstancesRequest req) {
final InstancesResponse resp = new InstancesResponse();
resp.setId(req.getId());
if (!req.validate(resp)) {
return resp;
}
// Use a BwEvent to build the instance set
final BwEvent ev = new BwEventObj();
try {
final BwDateTime st = req.getStartDt();
ev.setDtstart(st);
ev.setDtend(req.getEndDt());
ev.addRrule(req.getRrule());
if (!Util.isEmpty(req.getExdates())) {
for (final String dt : req.getExdates()) {
ev.addExdate(BwDateTime.makeBwDateTime(st.getDateType(), dt, st.getTzid()));
}
}
if (!Util.isEmpty(req.getRdates())) {
for (final String dt : req.getRdates()) {
ev.addRdate(BwDateTime.makeBwDateTime(st.getDateType(), dt, st.getTzid()));
}
}
final RecurPeriods rp = RecurUtil.getPeriods(ev, getAuthpars().getMaxYears(), getAuthpars().getMaxInstances(), req.getBegin(), req.getEnd());
resp.setInstances(rp.instances);
return resp;
} catch (final Throwable t) {
return Response.error(resp, t);
}
}
Aggregations