use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class CalintfImpl method getFreeBusy.
/* ====================================================================
* Free busy
* ==================================================================== */
@Override
public BwEvent getFreeBusy(final Collection<BwCalendar> cals, final BwPrincipal who, final BwDateTime start, final BwDateTime end, final boolean returnAll, final boolean ignoreTransparency) throws CalFacadeException {
if (who.getKind() != WhoDefs.whoTypeUser) {
throw new CalFacadeException("Unsupported: non user principal for free-busy");
}
final Collection<CoreEventInfo> events = getFreeBusyEntities(cals, start, end, ignoreTransparency);
final BwEvent fb = new BwEventObj();
fb.setEntityType(IcalDefs.entityTypeFreeAndBusy);
fb.setOwnerHref(who.getPrincipalRef());
fb.setDtstart(start);
fb.setDtend(end);
try {
final TreeSet<EventPeriod> eventPeriods = new TreeSet<>();
for (final CoreEventInfo ei : events) {
final BwEvent ev = ei.getEvent();
// Ignore if times were specified and this event is outside the times
final BwDateTime estart = ev.getDtstart();
final BwDateTime eend = ev.getDtend();
/* Don't report out of the requested period */
final String dstart;
final String dend;
if (estart.before(start)) {
dstart = start.getDtval();
} else {
dstart = estart.getDtval();
}
if (eend.after(end)) {
dend = end.getDtval();
} else {
dend = eend.getDtval();
}
final DateTime psdt = new DateTime(dstart);
final DateTime pedt = new DateTime(dend);
psdt.setUtc(true);
pedt.setUtc(true);
int type = BwFreeBusyComponent.typeBusy;
if (BwEvent.statusTentative.equals(ev.getStatus())) {
type = BwFreeBusyComponent.typeBusyTentative;
}
eventPeriods.add(new EventPeriod(psdt, pedt, type));
}
/* iterate through the sorted periods combining them where they are
adjacent or overlap */
Period p = null;
/* For the moment just build a single BwFreeBusyComponent
*/
BwFreeBusyComponent fbc = null;
int lastType = 0;
for (final EventPeriod ep : eventPeriods) {
if (debug) {
debug(ep.toString());
}
if (p == null) {
p = new Period(ep.getStart(), ep.getEnd());
lastType = ep.getType();
} else if ((lastType != ep.getType()) || ep.getStart().after(p.getEnd())) {
// Non adjacent periods
if (fbc == null) {
fbc = new BwFreeBusyComponent();
fbc.setType(lastType);
fb.addFreeBusyPeriod(fbc);
}
fbc.addPeriod(p.getStart(), p.getEnd());
if (lastType != ep.getType()) {
fbc = null;
}
p = new Period(ep.getStart(), ep.getEnd());
lastType = ep.getType();
} else if (ep.getEnd().after(p.getEnd())) {
// Extend the current period
p = new Period(p.getStart(), ep.getEnd());
}
// else it falls within the existing period
}
if (p != null) {
if ((fbc == null) || (lastType != fbc.getType())) {
fbc = new BwFreeBusyComponent();
fbc.setType(lastType);
fb.addFreeBusyPeriod(fbc);
}
fbc.addPeriod(p.getStart(), p.getEnd());
}
} catch (final Throwable t) {
if (debug) {
error(t);
}
throw new CalFacadeException(t);
}
return fb;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class Filters method drReplace.
private void drReplace(final boolean floatingTest, final TimeRange tr) throws CalFacadeException {
String startVal = null;
String endVal = null;
DateTime start = tr.getStart();
DateTime end = tr.getEnd();
if (floatingTest) {
if (start != null) {
startVal = tr.getStartExpanded().toString();
}
if (end != null) {
endVal = tr.getEndExpanded().toString();
}
} else {
if (start != null) {
startVal = start.toString();
}
if (end != null) {
endVal = end.toString();
}
}
if (start == null) {
sess.setString(parPrefix + qi, endVal);
qi++;
return;
}
if (end == null) {
sess.setString(parPrefix + qi, startVal);
qi++;
return;
}
sess.setString(parPrefix + qi, endVal);
qi++;
sess.setString(parPrefix + qi, startVal);
qi++;
sess.setString(parPrefix + qi, startVal);
qi++;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class CoreEvents method addEvent.
@Override
public UpdateEventResult addEvent(final EventInfo ei, final boolean scheduling, final boolean rollbackOnError) throws CalFacadeException {
final BwEvent val = ei.getEvent();
final Collection<BwEventProxy> overrides = ei.getOverrideProxies();
final long startTime = System.currentTimeMillis();
RecuridTable recurids = null;
final UpdateEventResult uer = new UpdateEventResult();
uer.addedUpdated = true;
final BwCalendar cal = getEntityCollection(val.getColPath(), privBind, scheduling, false);
/* Indicate if we want sharing notifications of changes */
final boolean shared = cal.getPublick() || cal.getShared();
final CollectionInfo collInf = cal.getCollectionInfo();
if (!Util.isEmpty(overrides)) {
if (!val.testRecurring()) {
throwException(CalFacadeException.overridesForNonRecurring);
}
recurids = new RecuridTable(overrides);
}
if (val.getUid() == null) {
throwException(CalFacadeException.noEventGuid);
}
if (val.getName() == null) {
throwException(CalFacadeException.noEventName);
}
/* The guid must not exist in the same calendar. We assign a guid if
* one wasn't assigned already. However, the event may have come with a guid
* (caldav, import, etc) so we need to check here.
*
* It also ensures our guid allocation is working OK
*/
if (collInf.uniqueKey) {
String name = calendarGuidExists(val, false, true);
if (name == null) {
name = calendarGuidExists(val, true, true);
}
if (name != null) {
throwException(CalFacadeException.duplicateGuid, name);
}
}
/* Similarly for event names which must be unique within a collection.
* Note that a duplicate name is essentially overwriting an event with a
* new uid - also disallowed.
*/
if ((val.getEntityType() != IcalDefs.entityTypeAvailable) && (calendarNameExists(val, false, true) || calendarNameExists(val, true, true))) {
throwException(CalFacadeException.duplicateName, val.getName());
}
setupDependentEntities(val);
/* Remove any tombstoned event in the collection with same uid */
deleteTombstoned(val.getColPath(), val.getUid());
/* If it's a recurring event see what we can do to optimize searching
* and retrieval
*/
if ((val instanceof BwEventAnnotation) || !val.getRecurring()) {
dao.save(val);
if (!getForRestore()) {
notify(SysEvent.SysCode.ENTITY_ADDED, val, shared);
}
stat(StatsEvent.createTime, startTime);
indexEntity(ei);
return uer;
}
/* Get all the times for this event. - this could be a problem. Need to
limit the number. Should we do this in chunks, stepping through the
whole period?
*/
final RecurPeriods rp = RecurUtil.getPeriods(val, getAuthprops().getMaxYears(), getAuthprops().getMaxInstances());
if (rp.instances.isEmpty()) {
// No instances for an alleged recurring event.
if (rollbackOnError) {
throwException(CalFacadeException.noRecurrenceInstances, val.getUid());
}
uer.addedUpdated = false;
uer.errorCode = CalFacadeException.noRecurrenceInstances;
stat(StatsEvent.createTime, startTime);
indexEntity(ei);
return uer;
}
/* We can save the master at this point */
dao.save(val);
final String stzid = val.getDtstart().getTzid();
final TimeZone stz = null;
/* try {
if (stzid != null) {
stz = Timezones.getTz(stzid);
}
val.setLatestDate(Timezones.getUtc(rp.rangeEnd.toString(),
stzid));
} catch (Throwable t) {
throwException(new CalFacadeException(t));
} */
int maxInstances = getAuthprops().getMaxInstances();
final boolean dateOnly = val.getDtstart().getDateType();
/* There appears to be a bug in ical4j in which the first instance gets
* duplicated. Rather than change that code and run the risk of breaking
* all recurrences I'll just look for that duplicate.
*/
String firstRecurrenceId = null;
for (final Period p : rp.instances) {
String dtval = p.getStart().toString();
if (dateOnly) {
dtval = dtval.substring(0, 8);
}
final BwDateTime rstart = BwDateTime.makeBwDateTime(dateOnly, dtval, stzid);
final DateTime edt = p.getEnd();
if (!dateOnly && (stz != null)) {
edt.setTimeZone(stz);
}
dtval = edt.toString();
if (dateOnly) {
dtval = dtval.substring(0, 8);
}
final BwDateTime rend = BwDateTime.makeBwDateTime(dateOnly, dtval, stzid);
final BwRecurrenceInstance ri = new BwRecurrenceInstance();
ri.setDtstart(rstart);
ri.setDtend(rend);
ri.setRecurrenceId(ri.getDtstart().getDate());
ri.setMaster(val);
if (firstRecurrenceId == null) {
firstRecurrenceId = ri.getRecurrenceId();
} else if (firstRecurrenceId.equals(ri.getRecurrenceId())) {
// Skip it
if (debug) {
debugMsg("Skipping duplicate recurid " + firstRecurrenceId);
}
continue;
}
if (recurids != null) {
/* See if we have a recurrence */
final String rid = ri.getRecurrenceId();
final BwEventProxy ov = recurids.get(rid);
if (ov != null) {
if (debug) {
debugMsg("Add override with recurid " + rid);
}
setupDependentEntities(ov);
addOverride(ov, ri);
recurids.remove(rid);
}
}
dao.save(ri);
maxInstances--;
if (maxInstances == 0) {
// That's all you're getting from me
break;
}
}
if ((recurids != null) && (recurids.size() != 0)) {
/* We removed all the valid overrides - we are left with those
* with recurrence ids that don't match.
*/
if (rollbackOnError) {
throwException(CalFacadeException.invalidOverride);
}
uer.failedOverrides = recurids.values();
}
if (!getForRestore()) {
notify(SysEvent.SysCode.ENTITY_ADDED, val, shared);
}
indexEntity(ei);
stat(StatsEvent.createTime, startTime);
return uer;
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class BwDateTime method makeDateTime.
/**
* Make a new date time value based on the dtStart value + the duration.
*
* @param dtStart
* @param dateOnly
* @param dur
* @return BwDateTime
* @throws CalFacadeException
*/
public static BwDateTime makeDateTime(final DateProperty dtStart, final boolean dateOnly, final Dur dur) throws CalFacadeException {
DtEnd dtEnd;
java.util.Date endDt = dur.getTime(dtStart.getDate());
Parameter tzid = getIcalParameter(dtStart, "TZID");
if (dateOnly) {
// dtEnd = new DtEnd(new Date(endDt));
ParameterList parl = new ParameterList();
parl.add(Value.DATE);
dtEnd = new DtEnd(parl, new Date(endDt));
// addIcalParameter(dtEnd, Value.DATE);
// if (tzid != null) {
// addIcalParameter(dtEnd, tzid);
// }
} else {
DateTime d = new DateTime(endDt);
if (tzid != null) {
DateTime sd = (DateTime) dtStart.getDate();
d.setTimeZone(sd.getTimeZone());
}
// dtEnd = new DtEnd(d, dtStart.isUtc());
dtEnd = new DtEnd(d);
if (tzid != null) {
addIcalParameter(dtEnd, tzid);
} else if (dtStart.isUtc()) {
dtEnd.setUtc(true);
}
}
return makeBwDateTime(dtEnd);
}
use of net.fortuna.ical4j.model.DateTime in project bw-calendar-engine by Bedework.
the class BwEvent method getTimeZoneIds.
/**
* Return all timezone ids this event uses. This is used when an event is
* added by another user to ensure that the target user has a copy of user
* specific timezones.
*
* @return Set of timezone ids.
* @throws CalFacadeException
*/
@NoProxy
@NoDump
public Set<String> getTimeZoneIds() throws CalFacadeException {
Set<String> ids = new TreeSet<String>();
BwDateTime dt = getDtstart();
if ((dt != null) && (dt.getTzid() != null)) {
ids.add(dt.getTzid());
}
dt = getDtend();
if ((dt != null) && (dt.getTzid() != null)) {
ids.add(dt.getTzid());
}
Set<BwDateTime> dts = getRdates();
if (dts != null) {
for (BwDateTime rdt : dts) {
if (rdt.getTzid() != null) {
ids.add(rdt.getTzid());
}
}
}
dts = getExdates();
if (dts != null) {
for (BwDateTime rdt : dts) {
if (rdt.getTzid() != null) {
ids.add(rdt.getTzid());
}
}
}
List<BwFreeBusyComponent> fbcs = getFreeBusyPeriods();
if (fbcs != null) {
for (BwFreeBusyComponent fbc : fbcs) {
for (Period p : fbc.getPeriods()) {
DateTime fdt = p.getStart();
if (fdt.getTimeZone() != null) {
ids.add(fdt.getTimeZone().getID());
}
fdt = p.getEnd();
if (fdt.getTimeZone() != null) {
ids.add(fdt.getTimeZone().getID());
}
}
}
}
return ids;
}
Aggregations