Search in sources :

Example 36 with BwDateTime

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;
}
Also used : Dur(net.fortuna.ical4j.model.Dur) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) RDate(net.fortuna.ical4j.model.property.RDate) BwDateTime(org.bedework.calfacade.BwDateTime) Duration(net.fortuna.ical4j.model.property.Duration) BwDuration(org.bedework.calfacade.BwDuration) RDate(net.fortuna.ical4j.model.property.RDate) Date(net.fortuna.ical4j.model.Date) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Example 37 with BwDateTime

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;
}
Also used : Dur(net.fortuna.ical4j.model.Dur) VEvent(net.fortuna.ical4j.model.component.VEvent) RDate(net.fortuna.ical4j.model.property.RDate) BwDateTime(org.bedework.calfacade.BwDateTime) Period(net.fortuna.ical4j.model.Period) PeriodList(net.fortuna.ical4j.model.PeriodList) Duration(net.fortuna.ical4j.model.property.Duration) BwDuration(org.bedework.calfacade.BwDuration) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime) CalFacadeException(org.bedework.calfacade.exc.CalFacadeException) RDate(net.fortuna.ical4j.model.property.RDate) Date(net.fortuna.ical4j.model.Date) PropertyList(net.fortuna.ical4j.model.PropertyList) DtStart(net.fortuna.ical4j.model.property.DtStart) DtEnd(net.fortuna.ical4j.model.property.DtEnd)

Example 38 with BwDateTime

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);
    }
}
Also used : TimeZone(net.fortuna.ical4j.model.TimeZone) DtStart(net.fortuna.ical4j.model.property.DtStart) RDate(net.fortuna.ical4j.model.property.RDate) BwDateTime(org.bedework.calfacade.BwDateTime) DateListProperty(net.fortuna.ical4j.model.property.DateListProperty) ExDate(net.fortuna.ical4j.model.property.ExDate) DateList(net.fortuna.ical4j.model.DateList) Date(net.fortuna.ical4j.model.Date) RDate(net.fortuna.ical4j.model.property.RDate) ExDate(net.fortuna.ical4j.model.property.ExDate) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime)

Example 39 with BwDateTime

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;
}
Also used : DtStart(net.fortuna.ical4j.model.property.DtStart) BwDateTime(org.bedework.calfacade.BwDateTime) Date(net.fortuna.ical4j.model.Date) RDate(net.fortuna.ical4j.model.property.RDate) ExDate(net.fortuna.ical4j.model.property.ExDate) DateTime(net.fortuna.ical4j.model.DateTime) BwDateTime(org.bedework.calfacade.BwDateTime)

Example 40 with BwDateTime

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);
    }
}
Also used : BwDateTime(org.bedework.calfacade.BwDateTime) BwEvent(org.bedework.calfacade.BwEvent) InstancesResponse(org.bedework.calfacade.responses.InstancesResponse) RecurPeriods(org.bedework.icalendar.RecurUtil.RecurPeriods) BwEventObj(org.bedework.calfacade.BwEventObj)

Aggregations

BwDateTime (org.bedework.calfacade.BwDateTime)45 BwEvent (org.bedework.calfacade.BwEvent)23 CalFacadeException (org.bedework.calfacade.exc.CalFacadeException)20 Period (net.fortuna.ical4j.model.Period)11 DateTime (net.fortuna.ical4j.model.DateTime)9 DtStart (net.fortuna.ical4j.model.property.DtStart)8 BwEventProxy (org.bedework.calfacade.BwEventProxy)8 BwRecurrenceInstance (org.bedework.calfacade.BwRecurrenceInstance)8 EventInfo (org.bedework.calfacade.svc.EventInfo)8 Date (net.fortuna.ical4j.model.Date)7 BwEventAnnotation (org.bedework.calfacade.BwEventAnnotation)7 BwString (org.bedework.calfacade.BwString)7 WebdavException (org.bedework.webdav.servlet.shared.WebdavException)7 Dur (net.fortuna.ical4j.model.Dur)6 CoreEventInfo (org.bedework.calcorei.CoreEventInfo)6 ChangeTableEntry (org.bedework.calfacade.util.ChangeTableEntry)6 RecurPeriods (org.bedework.icalendar.RecurUtil.RecurPeriods)6 TreeSet (java.util.TreeSet)5 ChangeTable (org.bedework.calfacade.util.ChangeTable)5 DateDatetimePropertyType (ietf.params.xml.ns.icalendar_2.DateDatetimePropertyType)4