use of org.bedework.calfacade.BwEventProxy in project bw-calendar-engine by Bedework.
the class Events method postProcess.
private EventInfo postProcess(final CoreEventInfo cei) throws CalFacadeException {
if (cei == null) {
return null;
}
// trace("ev: " + ev);
/* If the event is an event reference (an alias) implant it in an event
* proxy and return that object.
*/
BwEvent ev = cei.getEvent();
if (ev instanceof BwEventAnnotation) {
ev = new BwEventProxy((BwEventAnnotation) ev);
}
final Set<EventInfo> overrides = new TreeSet<EventInfo>();
if (cei.getOverrides() != null) {
for (final CoreEventInfo ocei : cei.getOverrides()) {
final BwEventProxy op = (BwEventProxy) ocei.getEvent();
overrides.add(new EventInfo(op));
}
}
final EventInfo ei = new EventInfo(ev, overrides);
/* Reconstruct if any contained items. */
if (cei.getNumContainedItems() > 0) {
for (CoreEventInfo ccei : cei.getContainedItems()) {
BwEvent cv = ccei.getEvent();
ei.addContainedItem(new EventInfo(cv));
}
}
ei.setCurrentAccess(cei.getCurrentAccess());
return ei;
}
use of org.bedework.calfacade.BwEventProxy in project bw-calendar-engine by Bedework.
the class Events method add.
@Override
public UpdateResult add(final EventInfo ei, final boolean noInvites, final boolean schedulingInbox, final boolean autoCreateCollection, final boolean rollbackOnError) throws CalFacadeException {
try {
if (getPrincipalInfo().getSubscriptionsOnly()) {
throw new CalFacadeForbidden("User has read only access");
}
final UpdateResult updResult = ei.getUpdResult();
updResult.adding = true;
updResult.hasChanged = true;
final BwEvent event = ei.getEvent();
adjustEntities(ei);
final BwPreferences prefs = getSvc().getPrefsHandler().get();
if (prefs != null) {
final Collection<BwCategory> cats = getSvc().getCategoriesHandler().get(prefs.getDefaultCategoryUids());
for (final BwCategory cat : cats) {
event.addCategory(cat);
}
}
final RealiasResult raResp = reAlias(event);
if (raResp.getStatus() != ok) {
throw new CalFacadeException(CalFacadeException.badRequest, "Status: " + raResp.getStatus() + " message: " + raResp.getMessage());
}
// Or just validate?
assignGuid(event);
updateEntities(updResult, event);
BwCalendar cal = validate(event, true, schedulingInbox, autoCreateCollection);
BwEventProxy proxy = null;
BwEvent override = null;
if (event instanceof BwEventProxy) {
proxy = (BwEventProxy) event;
override = proxy.getRef();
setupSharableEntity(override, getPrincipal().getPrincipalRef());
} else {
setupSharableEntity(event, getPrincipal().getPrincipalRef());
if (ei.getNumContainedItems() > 0) {
for (final EventInfo aei : ei.getContainedItems()) {
final BwEvent av = aei.getEvent();
av.setParent(event);
setupSharableEntity(av, getPrincipal().getPrincipalRef());
}
}
}
final BwCalendar undereffedCal = cal;
if (cal.getInternalAlias()) {
/* Resolve the alias and put the event in it's proper place */
// XXX This is probably OK for non-public admin
final boolean setCats = getSvc().getPars().getPublicAdmin();
if (!setCats) {
cal = getCols().resolveAlias(cal, true, false);
} else {
while (true) {
final Set<BwCategory> cats = cal.getCategories();
for (final BwCategory cat : cats) {
event.addCategory(cat);
}
if (!cal.getInternalAlias()) {
break;
}
cal = getCols().resolveAlias(cal, false, false);
}
}
event.setColPath(cal.getPath());
}
if (!cal.getCalendarCollection()) {
throw new CalFacadeAccessException();
}
if (!event.getPublick() && Util.isEmpty(event.getAlarms())) {
setDefaultAlarms(ei, undereffedCal);
}
boolean schedulingObject = false;
if (cal.getCollectionInfo().scheduling && (event.getOrganizerSchedulingObject() || event.getAttendeeSchedulingObject())) {
schedulingObject = true;
}
final Integer maxAttendees = getSvc().getAuthProperties().getMaxAttendeesPerInstance();
if ((maxAttendees != null) && !Util.isEmpty(event.getAttendees()) && (event.getAttendees().size() > maxAttendees)) {
throw new CalFacadeException(CalFacadeException.schedulingTooManyAttendees);
}
event.setDtstamps(getCurrentTimestamp());
if (schedulingObject) {
event.updateStag(getCurrentTimestamp());
}
/* All Overrides go in same calendar and have same name */
final Collection<BwEventProxy> overrides = ei.getOverrideProxies();
if (overrides != null) {
for (final BwEventProxy ovei : overrides) {
setScheduleState(ovei, true, schedulingInbox);
if ((maxAttendees != null) && !Util.isEmpty(ovei.getAttendees()) && (ovei.getAttendees().size() > maxAttendees)) {
throw new CalFacadeException(CalFacadeException.schedulingTooManyAttendees);
}
ovei.setDtstamps(getCurrentTimestamp());
if (cal.getCollectionInfo().scheduling && (ovei.getOrganizerSchedulingObject() || ovei.getAttendeeSchedulingObject())) {
schedulingObject = true;
}
if (schedulingObject) {
ovei.updateStag(getCurrentTimestamp());
}
final BwEventAnnotation ann = ovei.getRef();
ann.setColPath(event.getColPath());
ann.setName(event.getName());
}
}
if (event.getOrganizerSchedulingObject()) {
// Set RSVP on all attendees with PARTSTAT = NEEDS_ACTION
for (final BwAttendee att : event.getAttendees()) {
if (att.getPartstat() == IcalDefs.partstatValNeedsAction) {
att.setRsvp(true);
}
}
}
UpdateEventResult uer = getCal().addEvent(ei, schedulingInbox, rollbackOnError);
if (ei.getNumContainedItems() > 0) {
for (final EventInfo oei : ei.getContainedItems()) {
oei.getEvent().setName(event.getName());
final UpdateEventResult auer = getCal().addEvent(oei, schedulingInbox, rollbackOnError);
if (auer.errorCode != null) {
// ?
}
}
}
updResult.failedOverrides = uer.failedOverrides;
if (!noInvites) {
if (event.getAttendeeSchedulingObject()) {
// Attendee replying?
updResult.reply = true;
}
if (cal.getCollectionInfo().scheduling && schedulingObject) {
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) {
if (debug) {
error(t);
}
getSvc().rollbackTransaction();
if (t instanceof CalFacadeException) {
throw (CalFacadeException) t;
}
throw new CalFacadeException(t);
}
}
use of org.bedework.calfacade.BwEventProxy in project bw-calendar-engine by Bedework.
the class Events method setScheduleState.
/* Flag this as an attendee scheduling object or an organizer scheduling object
*/
private void setScheduleState(final BwEvent ev, final boolean adding, final boolean schedulingInbox) throws CalFacadeException {
ev.setOrganizerSchedulingObject(false);
ev.setAttendeeSchedulingObject(false);
if ((ev.getEntityType() != IcalDefs.entityTypeEvent) && (ev.getEntityType() != IcalDefs.entityTypeTodo) && (ev.getEntityType() != IcalDefs.entityTypeVpoll)) {
// Not a possible scheduling entity
return;
}
final BwOrganizer org = ev.getOrganizer();
final Set<BwAttendee> atts = ev.getAttendees();
if (Util.isEmpty(atts) || (org == null)) {
return;
}
final String curPrincipal = getSvc().getPrincipal().getPrincipalRef();
final Directories dirs = getSvc().getDirectories();
AccessPrincipal evPrincipal = dirs.caladdrToPrincipal(org.getOrganizerUri());
if ((evPrincipal != null) && (evPrincipal.getPrincipalRef().equals(curPrincipal))) {
ev.setOrganizerSchedulingObject(true);
/* If we are expanding groups do so here */
final ChangeTable chg = ev.getChangeset(getPrincipalHref());
final Set<BwAttendee> groups = new TreeSet<>();
if (!schedulingInbox) {
final ChangeTableEntry cte = chg.getEntry(PropertyInfoIndex.ATTENDEE);
checkAttendees: for (final BwAttendee att : atts) {
if (CuType.GROUP.getValue().equals(att.getCuType())) {
groups.add(att);
}
final AccessPrincipal attPrincipal = getSvc().getDirectories().caladdrToPrincipal(att.getAttendeeUri());
if ((attPrincipal != null) && (attPrincipal.getPrincipalRef().equals(curPrincipal))) {
// It's us
continue;
}
if (att.getPartstat().equals(IcalDefs.partstatValNeedsAction)) {
continue;
}
if (adding) {
// Can't add an event with attendees set to accepted
att.setPartstat(IcalDefs.partstatValNeedsAction);
continue;
}
// Not adding event. Did we add attendee?
if ((cte != null) && !Util.isEmpty(cte.getAddedValues())) {
for (final Object o : cte.getAddedValues()) {
final BwAttendee chgAtt = (BwAttendee) o;
if (chgAtt.getCn().equals(att.getCn())) {
att.setPartstat(IcalDefs.partstatValNeedsAction);
continue checkAttendees;
}
}
}
}
}
try {
/* If this is a vpoll we need the vvoters as we are going to
have to remove the group vvoter entry and clone it for the
attendees we add.
I think this will work for any poll mode - if not we may
have to rethink this approach.
*/
Map<String, VVoter> voters = null;
final boolean vpoll;
if (ev.getEntityType() == IcalDefs.entityTypeVpoll) {
voters = IcalUtil.parseVpollVvoters(ev);
// We'll add them all back
ev.clearVvoters();
vpoll = true;
} else {
vpoll = false;
}
for (final BwAttendee att : groups) {
/* If the group is in one of our domains we can try to expand it.
* We should leave it if it's an external id.
*/
final Holder<Boolean> trunc = new Holder<>();
final List<BwPrincipalInfo> groupPis = dirs.find(att.getAttendeeUri(), att.getCuType(), // expand
true, trunc);
if ((groupPis == null) || (groupPis.size() != 1)) {
continue;
}
final BwPrincipalInfo pi = groupPis.get(0);
if (pi.getMembers() == null) {
continue;
}
VVoter groupVvoter = null;
Voter groupVoter = null;
PropertyList pl = null;
if (vpoll) {
groupVvoter = voters.get(att.getAttendeeUri());
if (groupVvoter == null) {
if (debug) {
warn("No vvoter found for " + att.getAttendeeUri());
}
continue;
}
voters.remove(att.getAttendeeUri());
groupVoter = groupVvoter.getVoter();
pl = groupVvoter.getProperties();
}
// Remove the group
ev.removeAttendee(att);
chg.changed(PropertyInfoIndex.ATTENDEE, att, null);
for (final BwPrincipalInfo mbrPi : pi.getMembers()) {
if (mbrPi.getCaladruri() == null) {
continue;
}
final BwAttendee mbrAtt = new BwAttendee();
mbrAtt.setType(att.getType());
mbrAtt.setAttendeeUri(mbrPi.getCaladruri());
mbrAtt.setCn(mbrPi.getEmail());
mbrAtt.setCuType(mbrPi.getKind());
mbrAtt.setMember(att.getAttendeeUri());
ev.addAttendee(mbrAtt);
chg.addValue(PropertyInfoIndex.ATTENDEE, mbrAtt);
if (vpoll) {
pl.remove(groupVoter);
groupVoter = IcalUtil.setVoter(mbrAtt);
pl.add(groupVoter);
ev.addVvoter(groupVvoter.toString());
}
}
}
if (vpoll) {
// Add back any remaining vvoters
for (VVoter vv : voters.values()) {
ev.addVvoter(vv.toString());
}
}
} catch (final CalFacadeException cfe) {
throw cfe;
} catch (final Throwable t) {
throw new CalFacadeException(t);
}
if (ev instanceof BwEventProxy) {
// Only add x-property to master
return;
}
if (CalFacadeDefs.jasigSchedulingAssistant.equals(getPars().getClientId())) {
ev.addXproperty(new BwXproperty(BwXproperty.bedeworkSchedAssist, null, "true"));
}
return;
}
for (final BwAttendee att : atts) {
/* See if at least one attendee is us */
evPrincipal = getSvc().getDirectories().caladdrToPrincipal(att.getAttendeeUri());
if ((evPrincipal != null) && (evPrincipal.getPrincipalRef().equals(curPrincipal))) {
ev.setAttendeeSchedulingObject(true);
break;
}
}
}
use of org.bedework.calfacade.BwEventProxy in project bw-calendar-engine by Bedework.
the class Events method makeInstance.
private EventInfo makeInstance(final EventInfo ei, final String recurrenceId) throws CalFacadeException {
final BwEvent ev = ei.getEvent();
if (!ev.getRecurring()) {
return ei;
}
if (!Util.isEmpty(ei.getOverrides())) {
for (final EventInfo oei : ei.getOverrides()) {
if (oei.getEvent().getRecurrenceId().equals(recurrenceId)) {
oei.setRetrievedEvent(ei);
oei.setCurrentAccess(ei.getCurrentAccess());
return oei;
}
}
}
/* Not in the overrides - generate an instance */
final BwDateTime rstart;
final boolean dateOnly = ev.getDtstart().getDateType();
if (dateOnly) {
rstart = BwDateTime.makeBwDateTime(true, recurrenceId.substring(0, 8), null);
} else {
final String stzid = ev.getDtstart().getTzid();
DateTime dt = null;
try {
dt = new DateTime(recurrenceId);
} catch (final ParseException pe) {
throw new CalFacadeException(pe);
}
final DtStart ds = ev.getDtstart().makeDtStart();
dt.setTimeZone(ds.getTimeZone());
rstart = BwDateTime.makeBwDateTime(dt);
}
final BwDateTime rend = rstart.addDuration(BwDuration.makeDuration(ev.getDuration()));
final BwEventAnnotation ann = new BwEventAnnotation();
ann.setDtstart(rstart);
ann.setDtend(rend);
ann.setRecurrenceId(recurrenceId);
ann.setOwnerHref(ev.getOwnerHref());
// Call it an override
ann.setOverride(true);
ann.setTombstoned(false);
ann.setName(ev.getName());
ann.setUid(ev.getUid());
ann.setTarget(ev);
ann.setMaster(ev);
BwEvent proxy = new BwEventProxy(ann);
EventInfo oei = new EventInfo(proxy);
oei.setCurrentAccess(ei.getCurrentAccess());
oei.setRetrievedEvent(ei);
return oei;
}
use of org.bedework.calfacade.BwEventProxy in project bw-calendar-engine by Bedework.
the class RestoreImpl method restoreEvent.
@Override
public void restoreEvent(final EventInfo ei) throws Throwable {
try {
startTransaction();
final UpdateEventResult uer = getCal().addEvent(ei, // scheduling
false, false);
if (!uer.addedUpdated) {
throw new CalFacadeException(uer.errorCode);
}
if (uer.failedOverrides != null) {
error("Following overrides failed for event ");
error(ei.getEvent().toString());
for (final BwEventProxy proxy : uer.failedOverrides) {
error(proxy.toString());
}
}
} finally {
endTransaction();
}
}
Aggregations