use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Calendars method getCategorySet.
@Override
public Set<BwCategory> getCategorySet(final String href) throws CalFacadeException {
/* The set of categories referenced by the alias and its parents */
final Collection<BwCalendar> cols;
cols = decomposeVirtualPath(href);
if (Util.isEmpty(cols)) {
if (debug) {
debug("No collections for vpath " + href);
}
return null;
}
/* For each entry in the returned list add any category to the set.
*
* For the last alias entry in the list work up to the root adding any
* categories in.
*/
BwCalendar curCol = null;
final Set<BwCategory> cats = new TreeSet<>();
for (final BwCalendar col : cols) {
int numCats = 0;
final Set<BwCategory> colCats = col.getCategories();
if (!Util.isEmpty(colCats)) {
cats.addAll(colCats);
numCats = colCats.size();
}
if (debug) {
debug("For col " + col.getPath() + " found " + numCats);
}
if (col.getAlias()) {
curCol = col;
}
}
while (curCol != null) {
try {
curCol = get(curCol.getColPath());
if (curCol != null) {
if (!Util.isEmpty(curCol.getCategories())) {
cats.addAll(curCol.getCategories());
}
}
} catch (final CalFacadeAccessException cfae) {
// We'll assume that's OK. We'll get that for /user at least.
break;
}
}
return cats;
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Calendars method delete.
boolean delete(final BwCalendar val, final boolean emptyIt, final boolean reallyDelete, final boolean sendSchedulingMessage, final boolean unsubscribe) throws CalFacadeException {
if (!emptyIt) {
/* Only allow delete if not in use
*/
if (!getCal().isEmpty(val)) {
throw new CalFacadeException(CalFacadeException.collectionNotEmpty);
}
}
final BwPreferences prefs = getSvc().getPrefsHandler().get(getSvc().getUsersHandler().getPrincipal(val.getOwnerHref()));
if (val.getPath().equals(prefs.getDefaultCalendarPath())) {
throw new CalFacadeException(CalFacadeException.cannotDeleteDefaultCalendar);
}
/* Remove any sharing */
if (val.getCanAlias()) {
getSvc().getSharingHandler().delete(val);
}
if (unsubscribe) {
getSvc().getSharingHandler().unsubscribe(val);
}
getSvc().getSynch().unsubscribe(val, true);
/* Remove from preferences */
((Preferences) getSvc().getPrefsHandler()).updateAdminPrefs(true, val, null, null, null);
/* If it' an alias we just delete it - otherwise we might need to empty it.
*/
if (!val.getInternalAlias() && emptyIt) {
if (val.getCalendarCollection()) {
final Events events = ((Events) getSvc().getEventsHandler());
for (final EventInfo ei : events.getSynchEvents(val.getPath(), null)) {
events.delete(ei, false, sendSchedulingMessage, true);
}
}
/* Remove resources */
final ResourcesI resI = getSvc().getResourcesHandler();
final Collection<BwResource> rs = resI.getAll(val.getPath());
if (!Util.isEmpty(rs)) {
for (final BwResource r : rs) {
resI.delete(Util.buildPath(false, r.getColPath(), "/", r.getName()));
}
}
for (final BwCalendar cal : getChildren(val)) {
if (!delete(cal, true, true, sendSchedulingMessage, true)) {
// Somebody else at it
getSvc().rollbackTransaction();
throw new CalFacadeException(CalFacadeException.collectionNotFound, cal.getPath());
}
}
}
val.getProperties().clear();
/* Attempt to tombstone it
*/
return getSvc().getCal().deleteCalendar(val, reallyDelete);
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Events method copyMoveNamed.
@Override
public CopyMoveStatus copyMoveNamed(final EventInfo fromEi, final BwCalendar to, String name, final boolean copy, final boolean overwrite, final boolean newGuidOK) throws CalFacadeException {
BwEvent ev = fromEi.getEvent();
String fromPath = ev.getColPath();
boolean sameCal = fromPath.equals(to.getPath());
if (name == null) {
name = ev.getName();
}
if (sameCal && name.equals(ev.getName())) {
// No-op
return CopyMoveStatus.noop;
}
try {
// Get the target
final EventInfo destEi = get(to.getPath(), name);
if (destEi != null) {
if (!overwrite) {
return CopyMoveStatus.destinationExists;
}
if (!destEi.getEvent().getUid().equals(ev.getUid())) {
// Not allowed to change uid.
return CopyMoveStatus.changedUid;
}
// deleteEvent(destEi.getEvent(), true);
}
if (!copy) {
if (!sameCal) {
/* Not sure why I was doing a delete+add
delete(from, false, false); // Delete unreffed
if (destEi != null) {
delete(destEi.getEvent(), false, false); // Delete unreffed
}
add(to, newEi, true);
*/
BwCalendar from = getCols().get(fromPath);
getCal().moveEvent(ev, from, to);
getCal().touchCalendar(from);
} else {
// Just changing name
ev.setName(name);
}
ev.updateStag(getCurrentTimestamp());
update(fromEi, false, null);
} else {
// Copying the event.
BwEvent newEvent = (BwEvent) ev.clone();
newEvent.setName(name);
// WebDAV ACL say's new event must not carry over access
newEvent.setAccess(null);
EventInfo newEi = new EventInfo(newEvent);
if (fromEi.getOverrideProxies() != null) {
for (BwEventProxy proxy : fromEi.getOverrideProxies()) {
newEi.addOverride(new EventInfo(proxy.clone(newEvent, newEvent)));
}
}
if (sameCal && newGuidOK) {
// Assign a new guid
newEvent.setUid(null);
assignGuid(newEvent);
}
if (destEi != null) {
delete(destEi, false);
}
newEvent.setColPath(to.getPath());
newEvent.updateStag(getCurrentTimestamp());
add(newEi, true, false, false, true);
}
if (destEi != null) {
return CopyMoveStatus.ok;
}
return CopyMoveStatus.created;
} catch (CalFacadeException cfe) {
if (cfe.getMessage().equals(CalFacadeException.duplicateGuid)) {
return CopyMoveStatus.duplicateUid;
}
throw cfe;
}
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Events method validate.
private BwCalendar validate(final BwEvent ev, final boolean adding, final boolean schedulingInbox, final boolean autoCreateCollection) throws CalFacadeException {
if (ev.getColPath() == null) {
throw new CalFacadeException(CalFacadeException.noEventCalendar);
}
if (ev.getNoStart() == null) {
throw new CalFacadeException(CalFacadeException.missingEventProperty, "noStart");
}
if (ev.getDtstart() == null) {
throw new CalFacadeException(CalFacadeException.missingEventProperty, "dtstart");
}
if (ev.getDtend() == null) {
throw new CalFacadeException(CalFacadeException.missingEventProperty, "dtend");
}
if (ev.getDuration() == null) {
throw new CalFacadeException(CalFacadeException.missingEventProperty, "duration");
}
if (ev.getRecurring() == null) {
throw new CalFacadeException(CalFacadeException.missingEventProperty, "recurring");
}
setScheduleState(ev, adding, schedulingInbox);
BwCalendar col = getCols().get(ev.getColPath());
if (col == null) {
if (!autoCreateCollection) {
throw new CalFacadeException(CalFacadeException.collectionNotFound);
}
// TODO - need a configurable default display name
// TODO - this all needs a rework
final String entityType = IcalDefs.entityTypeIcalNames[ev.getEntityType()];
final int calType;
switch(entityType) {
case Component.VEVENT:
calType = BwCalendar.calTypeCalendarCollection;
break;
case Component.VTODO:
calType = BwCalendar.calTypeTasks;
break;
case Component.VPOLL:
calType = BwCalendar.calTypePoll;
break;
default:
return null;
}
final GetSpecialCalendarResult gscr = getCal().getSpecialCalendar(getPrincipal(), calType, true, PrivilegeDefs.privAny);
col = gscr.cal;
}
Preferences prefs = null;
if (getPars().getPublicAdmin() && !getPars().getService()) {
prefs = (Preferences) getSvc().getPrefsHandler();
prefs.updateAdminPrefs(false, col, ev.getCategories(), ev.getLocation(), ev.getContact());
}
return col;
}
use of org.bedework.calfacade.BwCalendar in project bw-calendar-engine by Bedework.
the class Events method update.
@Override
public UpdateResult update(final EventInfo ei, final boolean noInvites, final String fromAttUri, final boolean alwaysWrite) throws CalFacadeException {
try {
final BwEvent event = ei.getEvent();
final UpdateResult updResult = ei.getUpdResult();
updateEntities(updResult, event);
final BwCalendar cal = validate(event, false, false, false);
adjustEntities(ei);
final RealiasResult raResp = reAlias(event);
if (raResp.getStatus() != ok) {
throw new CalFacadeException(CalFacadeException.badRequest, "Status: " + raResp.getStatus() + " message: " + raResp.getMessage());
}
boolean organizerSchedulingObject = false;
boolean attendeeSchedulingObject = false;
if (cal.getCollectionInfo().scheduling) {
organizerSchedulingObject = event.getOrganizerSchedulingObject();
attendeeSchedulingObject = event.getAttendeeSchedulingObject();
}
boolean schedulingObject = organizerSchedulingObject || attendeeSchedulingObject;
if (event.getSignificantChange() && schedulingObject) {
event.updateStag(getCurrentTimestamp());
}
boolean changed = alwaysWrite || checkChanges(ei, organizerSchedulingObject, attendeeSchedulingObject) || ei.getOverridesChanged();
boolean sequenceChange = ei.getUpdResult().sequenceChange;
/* TODO - this is wrong.
At the very least we should only reschedule the override that changed.
However adding an override looks like a change for all the fields
copied in. There should only be a change if the value is different
*/
boolean doReschedule = ei.getUpdResult().doReschedule;
if (ei.getNumOverrides() > 0) {
for (final EventInfo oei : ei.getOverrides()) {
setScheduleState(oei.getEvent(), false, false);
if (cal.getCollectionInfo().scheduling && oei.getEvent().getAttendeeSchedulingObject()) {
schedulingObject = true;
attendeeSchedulingObject = true;
// Shouldn't need to check organizer - it's set in the master even
// if suppressed.
}
if (checkChanges(oei, organizerSchedulingObject, attendeeSchedulingObject)) {
changed = true;
if (oei.getUpdResult().sequenceChange) {
sequenceChange = true;
}
}
if (schedulingObject) {
oei.getEvent().updateStag(getCurrentTimestamp());
}
doReschedule = doReschedule || oei.getUpdResult().doReschedule;
}
}
if (!changed) {
if (debug) {
trace("No changes to event: returning");
}
return ei.getUpdResult();
}
event.setDtstamps(getCurrentTimestamp());
if (organizerSchedulingObject && sequenceChange) {
event.setSequence(event.getSequence() + 1);
}
final UpdateEventResult uer = getCal().updateEvent(ei);
updResult.addedInstances = uer.added;
updResult.updatedInstances = uer.updated;
updResult.deletedInstances = uer.deleted;
updResult.fromAttUri = fromAttUri;
if (!noInvites && schedulingObject) {
if (organizerSchedulingObject) {
// Set RSVP on all attendees with PARTSTAT = NEEDS_ACTION
for (final BwAttendee att : event.getAttendees()) {
if (att.getPartstat().equals(IcalDefs.partstatValNeedsAction)) {
att.setRsvp(true);
}
}
}
boolean sendit = organizerSchedulingObject || updResult.reply;
if (!sendit) {
if (!Util.isEmpty(ei.getOverrides())) {
for (final EventInfo oei : ei.getOverrides()) {
if (oei.getUpdResult().reply) {
sendit = true;
break;
}
}
}
}
if (sendit) {
final SchedulingIntf sched = (SchedulingIntf) getSvc().getScheduler();
sched.implicitSchedule(ei, false);
/* We assume we don't need to update again to set attendee status
* Trying to do an update results in duplicate key errors.
*
* If it turns out the scgedule status is not getting persisted in the
* calendar entry then we need to find a way to set just that value in
* already persisted entity.
*/
}
}
return updResult;
} catch (final Throwable t) {
getSvc().rollbackTransaction();
if (t instanceof CalFacadeException) {
throw (CalFacadeException) t;
}
throw new CalFacadeException(t);
}
}
Aggregations