use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class RdatePropUpdater method applyUpdate.
public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
try {
BwEvent ev = ui.getEvent();
ChangeTableEntry cte = ui.getCte();
Set<BwDateTime> evDts = ev.getRdates();
DateDatetimePropertyType dt = (DateDatetimePropertyType) ui.getProp();
String dtUTC = XcalUtil.getUTC(dt, ui.getTzs());
if (ui.isRemove()) {
removeDt(dtUTC, evDts, cte);
return UpdateResult.getOkResult();
}
BwDateTime prdt = BwDateTime.makeBwDateTime(dt);
if (ui.isAdd()) {
addDt(prdt, evDts, cte);
return UpdateResult.getOkResult();
}
/* Changing rdate maybe just changing the parameters (UTC unchanged) or
* an actual value change. Second case is really a remove and add
*/
BwDateTime newdt = BwDateTime.makeBwDateTime((DateDatetimePropertyType) ui.getUpdprop());
if (prdt.getDate().equals(newdt.getDate())) {
// tzid or date only?
if (prdt.getTzid().equals(newdt.getTzid()) && (prdt.getDateType() == newdt.getDateType())) {
// Unchanged
return UpdateResult.getOkResult();
} else {
evDts.remove(prdt);
evDts.add(newdt);
cte.addChangedValue(newdt);
}
}
/* Do remove then add */
removeDt(prdt.getDate(), evDts, cte);
addDt(newdt, evDts, cte);
return UpdateResult.getOkResult();
} catch (WebdavException we) {
throw we;
} catch (Throwable t) {
throw new WebdavException(t);
}
}
use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class DateDatetimePropUpdater method makeDt.
protected UpdateResult makeDt(final BwDateTime evdt, final Holder<BwDateTime> resdt, final UpdateInfo ui) throws WebdavException {
try {
String tzid = evdt.getTzid();
String dtval = evdt.getDtval();
boolean dateOnly = evdt.getDateType();
BwDateTime newdt = null;
/* New or changed tzid? */
for (ParameterUpdater.UpdateInfo parui : ui.getParamUpdates()) {
if (parui.getParam() instanceof TzidParamType) {
if (parui.isRemove()) {
tzid = null;
break;
}
if (parui.isAdd()) {
if (tzid != null) {
return new UpdateResult(ui.getPropName().toString() + " already has tzid");
}
tzid = ((TzidParamType) parui.getParam()).getText();
break;
}
if (tzid == null) {
return new UpdateResult(ui.getPropName().toString() + " has no tzid to change");
}
tzid = ((TzidParamType) parui.getUpdparam()).getText();
break;
}
}
if (ui.getUpdprop() != null) {
// Has new value
DateDatetimePropertyType newdts = (DateDatetimePropertyType) ui.getUpdprop();
dateOnly = newdts.getDate() != null;
newdt = BwDateTime.makeBwDateTime(newdts, tzid);
}
if ((newdt == null) && (!Util.equalsString(tzid, evdt.getTzid()))) {
// Tzid changed
newdt = BwDateTime.makeBwDateTime(dateOnly, dtval, tzid);
}
if (newdt != null) {
// Validate
int res = newdt.validate();
if (res == BwDateTime.dtBadDtval) {
return new UpdateResult("Bad date value for " + ui.getPropName());
}
if (res == BwDateTime.dtBadTz) {
return new UpdateResult("Bad tzid for " + ui.getPropName());
}
}
resdt.value = newdt;
return UpdateResult.getOkResult();
} catch (CalFacadeException cfe) {
throw new WebdavException(cfe);
}
}
use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class DtEndDuePropUpdater method applyUpdate.
@Override
public UpdateResult applyUpdate(final UpdateInfo ui) throws WebdavException {
/* For start, end and duration we have to finish up at the end after all
* changes are made.
*/
try {
BwEvent ev = ui.getEvent();
DateDatetimePropertyType dt = (DateDatetimePropertyType) ui.getProp();
if (dt instanceof DuePropType) {
if (ev.getEntityType() != IcalDefs.entityTypeTodo) {
return new UpdateResult("DUE only valid for tasks");
}
} else {
if (ev.getEntityType() == IcalDefs.entityTypeTodo) {
return new UpdateResult("DUE required for tasks");
}
}
DatesState ds = (DatesState) ui.getState(DatesState.stateName);
if (ds == null) {
ds = new DatesState(ev);
ui.saveState(DatesState.stateName, ds);
}
ChangeTableEntry cte = ui.getCte();
if (ui.isRemove()) {
if (ev.getEndType() != StartEndComponent.endTypeDate) {
return new UpdateResult("Entity has no end date - cannot remove");
}
cte.setDeleted(ev.getDtend());
ds.end = null;
return UpdateResult.getOkResult();
}
if (ui.isAdd()) {
if (ev.getEndType() == StartEndComponent.endTypeDate) {
return new UpdateResult("Entity already has end date - cannot add");
}
ds.end = BwDateTime.makeBwDateTime(dt);
cte.setAdded(ds.end);
return UpdateResult.getOkResult();
}
/* Changing dtend - either value or parameters */
if (ev.getEndType() != StartEndComponent.endTypeDate) {
return new UpdateResult("Entity has no end date - cannot change");
}
Holder<BwDateTime> resdt = new Holder<BwDateTime>();
UpdateResult ur = makeDt(ev.getDtend(), resdt, ui);
if (!ur.getOk()) {
return ur;
}
if (resdt.value != null) {
cte.setChanged(ev.getDtend(), resdt.value);
ds.end = resdt.value;
}
return UpdateResult.getOkResult();
} catch (CalFacadeException cfe) {
throw new WebdavException(cfe);
}
}
use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class BwIndexEsImpl method reindexEvent.
private boolean reindexEvent(final ReindexResponse.Failure resp, final String indexName, final SearchHit sh, final EventInfo ei, final BulkProcessor bulkProcessor) {
try {
/* If it's not recurring or a stand-alone instance index it */
final BwEvent ev = ei.getEvent();
if ((uidsMap != null) && (ev.getLocationUid() == null)) {
final String locuid = uidsMap.get(ev.getUid());
if (locuid != null) {
uidsSet++;
ev.setLocationUid(locuid);
}
}
if (!restoreEvProps(resp, ei)) {
return false;
}
if (!ev.testRecurring() && (ev.getRecurrenceId() == null)) {
final EsDocInfo doc = makeDoc(resp, ei, ItemKind.master, ev.getDtstart(), ev.getDtend(), // ev.getRecurrenceId(),
null, null);
if (doc == null) {
return false;
}
final IndexRequest request = new IndexRequest(indexName, sh.type(), doc.getId());
request.source(doc.getSource());
bulkProcessor.add(request);
return true;
}
if (ev.getRecurrenceId() != null) {
errorReturn(resp, "Not implemented - index of single override");
return false;
}
if (!addOverrides(resp, idxpars.getUserIndexName(), ei)) {
return false;
}
final int maxYears;
final int maxInstances;
final DateLimits dl = new DateLimits();
if (ev.getPublick()) {
maxYears = unauthpars.getMaxYears();
maxInstances = unauthpars.getMaxInstances();
} else {
maxYears = authpars.getMaxYears();
maxInstances = authpars.getMaxInstances();
}
final RecurPeriods rp = RecurUtil.getPeriods(ev, maxYears, maxInstances);
if (rp.instances.isEmpty()) {
errorReturn(resp, "No instances for an alleged recurring event.");
return false;
}
final String stzid = ev.getDtstart().getTzid();
int instanceCt = maxInstances;
final boolean dateOnly = ev.getDtstart().getDateType();
/* First build a table of overrides so we can skip these later
*/
final Map<String, String> overrides = new HashMap<>();
if (!Util.isEmpty(ei.getOverrides())) {
for (final EventInfo oei : ei.getOverrides()) {
final BwEvent ov = oei.getEvent();
overrides.put(ov.getRecurrenceId(), ov.getRecurrenceId());
final String dtstart;
if (ov.getDtstart().getDateType()) {
dtstart = ov.getRecurrenceId().substring(0, 8);
} else {
dtstart = ov.getRecurrenceId();
}
final BwDateTime rstart = BwDateTime.makeBwDateTime(ov.getDtstart().getDateType(), dtstart, stzid);
final BwDateTime rend = rstart.addDuration(BwDuration.makeDuration(ov.getDuration()));
final EsDocInfo doc = makeDoc(resp, oei, ItemKind.override, rstart, rend, ov.getRecurrenceId(), dl);
if (doc == null) {
return false;
}
final IndexRequest request = new IndexRequest(indexName, sh.type(), doc.getId());
request.source(doc.getSource());
bulkProcessor.add(request);
instanceCt--;
}
}
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);
if (overrides.get(rstart.getDate()) != null) {
// Overrides indexed separately - skip this instance.
continue;
}
final String recurrenceId = rstart.getDate();
dtval = p.getEnd().toString();
if (dateOnly) {
dtval = dtval.substring(0, 8);
}
final BwDateTime rend = BwDateTime.makeBwDateTime(dateOnly, dtval, stzid);
final EsDocInfo doc = makeDoc(resp, ei, entity, rstart, rend, recurrenceId, dl);
if (doc == null) {
return false;
}
final IndexRequest request = new IndexRequest(indexName, sh.type(), doc.getId());
request.source(doc.getSource());
bulkProcessor.add(request);
instanceCt--;
if (instanceCt == 0) {
// That's all you're getting from me
break;
}
}
// </editor-fold>
// <editor-fold desc="Emit the master event with a date range covering the entire period.">
final BwDateTime dtstart = BwDateTime.makeBwDateTime(dateOnly, dl.minStart, stzid);
final BwDateTime dtend = BwDateTime.makeBwDateTime(dateOnly, dl.maxEnd, stzid);
final EsDocInfo doc = makeDoc(resp, ei, ItemKind.master, dtstart, dtend, null, null);
if (doc == null) {
return false;
}
final IndexRequest request = new IndexRequest(indexName, sh.type(), doc.getId());
request.source(doc.getSource());
bulkProcessor.add(request);
// </editor-fold>
return true;
} catch (final Throwable t) {
errorReturn(resp, t);
return false;
}
}
use of org.bedework.calfacade.BwDateTime in project bw-calendar-engine by Bedework.
the class CoreEvents method updateRecurrences.
/* XXX This is a bit brute force but it will do for the moment. We have to
* turn a set of rules into a set of changes. If we'd preserved the rules
* prior to this I guess we could figure out the differences without querying
* the db.
*
* For the moment create a whole set of instances and then query the db to see if
* they match.
*/
@SuppressWarnings("unchecked")
private void updateRecurrences(final EventInfo ei, final UpdateEventResult uc, final Collection<BwEventProxy> overrides, final boolean shared) throws CalFacadeException {
final BwEvent val = ei.getEvent();
final ChangeTable changes = val.getChangeset(currentPrincipal());
if (!changes.isEmpty()) {
if (!changes.recurrenceChanged()) {
return;
}
if (!changes.recurrenceRulesChanged()) {
// We can handle exdate and rdate changes.
ChangeTableEntry ent = changes.getEntry(PropertyInfoIndex.EXDATE);
if (ent.getAddedValues() != null) {
// exdates added - remove the instances.
removeInstances(val, uc, overrides, ent.getAddedValues(), shared);
}
if (ent.getRemovedValues() != null) {
// exdates removed - add the instances.
addInstances(val, uc, overrides, ent.getRemovedValues(), shared);
}
ent = changes.getEntry(PropertyInfoIndex.RDATE);
if (ent.getAddedValues() != null) {
// rdates added - add the instances.
addInstances(val, uc, overrides, ent.getAddedValues(), shared);
}
if (ent.getRemovedValues() != null) {
// rdates removed - remove the instances.
removeInstances(val, uc, overrides, ent.getRemovedValues(), shared);
}
return;
}
}
final Map<String, BwRecurrenceInstance> updated = new HashMap<>();
/* 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.
// XXX Mark the master as non-recurring to stop it disappearing
val.setRecurring(false);
// throwException(CalFacadeException.noRecurrenceInstances);
}
final String stzid = val.getDtstart().getTzid();
/* try {
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();
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);
dtval = p.getEnd().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);
updated.put(ri.getRecurrenceId(), ri);
maxInstances--;
if (maxInstances == 0) {
// That's all you're getting from me
break;
}
}
final List<BwRecurrenceInstance> current = dao.getInstances(val);
for (final BwRecurrenceInstance ri : current) {
final BwRecurrenceInstance updri = updated.get(ri.getRecurrenceId());
if (updri == null) {
// Not in the new instance set - delete from db
ei.removeOverride(ri.getRecurrenceId());
dao.delete(ri);
uc.addDeleted(ri);
notifyInstanceChange(SysEvent.SysCode.ENTITY_DELETED, val, shared, ri.getRecurrenceId());
continue;
}
/* Found instance with same recurrence id. Is the start and end the same
*/
if (!ri.getDtstart().equals(updri.getDtstart()) || !ri.getDtend().equals(updri.getDtend())) {
ri.setDtstart(updri.getDtstart());
ri.setDtend(updri.getDtend());
dao.update(ri);
uc.addUpdated(ri);
notifyInstanceChange(SysEvent.SysCode.ENTITY_UPDATED, val, shared, ri.getRecurrenceId());
}
// Remove the entry - we've processed it.
updated.remove(ri.getRecurrenceId());
}
for (final BwRecurrenceInstance ri : updated.values()) {
dao.save(ri);
uc.addAdded(ri);
notifyInstanceChange(SysEvent.SysCode.ENTITY_ADDED, val, shared, ri.getRecurrenceId());
}
}
Aggregations