use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.
the class AttendeeSchedulingHandler method attendeeRespond.
@Override
public ScheduleResult attendeeRespond(final EventInfo ei, final int method) throws CalFacadeException {
ScheduleResult sr = new ScheduleResult();
final BwEvent ev = ei.getEvent();
check: {
/* Check that the current user is actually the only attendee of the event.
* Note we may have a suppressed master and/or multiple overrides
*/
BwAttendee att = null;
if (!ev.getSuppressed()) {
att = findUserAttendee(ev);
if (att == null) {
sr.errorCode = CalFacadeException.schedulingNotAttendee;
break check;
}
}
if (ei.getNumOverrides() > 0) {
for (final EventInfo oei : ei.getOverrides()) {
att = findUserAttendee(oei.getEvent());
if (att == null) {
sr.errorCode = CalFacadeException.schedulingNotAttendee;
break check;
}
}
}
if (ev.getOriginator() == null) {
sr.errorCode = CalFacadeException.schedulingNoOriginator;
break check;
}
// EventInfo outEi = makeReplyEventInfo(ei, getUser().getPrincipalRef());
final EventInfo outEi = copyEventInfo(ei, getPrincipal());
final BwEvent outEv = outEi.getEvent();
if (!Util.isEmpty(outEv.getRecipients())) {
outEv.getRecipients().clear();
}
if (!Util.isEmpty(outEv.getAttendees())) {
outEv.getAttendees().clear();
}
// XXX we should get a comment from non db field in event
// if (comment != null) {
// // Just add for the moment
// outEv.addComment(null, comment);
// }
outEv.addRecipient(outEv.getOrganizer().getOrganizerUri());
outEv.setOriginator(att.getAttendeeUri());
outEv.updateDtstamp();
outEv.getOrganizer().setDtstamp(outEv.getDtstamp());
String delegate = att.getDelegatedTo();
if (delegate != null) {
/* RFC 2446 4.2.5 - Delegating an event
*
* When delegating an event request to another "Calendar User", the
* "Delegator" must both update the "Organizer" with a "REPLY" and send
* a request to the "Delegate". There is currently no protocol
* limitation to delegation depth. It is possible for the original
* delegate to delegate the meeting to someone else, and so on. When a
* request is delegated from one CUA to another there are a number of
* responsibilities required of the "Delegator". The "Delegator" MUST:
*
* . Send a "REPLY" to the "Organizer" with the following updates:
* . The "Delegator's" "ATTENDEE" property "partstat" parameter set
* to "delegated" and the "delegated-to" parameter is set to the
* address of the "Delegate"
* . Add an additional "ATTENDEE" property for the "Delegate" with
* the "delegated-from" property parameter set to the "Delegator"
* . Indicate whether they want to continue to receive updates when
* the "Organizer" sends out updated versions of the event.
* Setting the "rsvp" property parameter to "TRUE" will cause the
* updates to be sent, setting it to "FALSE" causes no further
* updates to be sent. Note that in either case, if the "Delegate"
* declines the invitation the "Delegator" will be notified.
* . The "Delegator" MUST also send a copy of the original "REQUEST"
* method to the "Delegate".
*/
// outEv is the reply
outEv.setScheduleMethod(ScheduleMethods.methodTypeReply);
// Additional attendee
BwAttendee delAtt = new BwAttendee();
delAtt.setAttendeeUri(delegate);
delAtt.setDelegatedFrom(att.getAttendeeUri());
delAtt.setPartstat(IcalDefs.partstatValNeedsAction);
delAtt.setRsvp(true);
delAtt.setRole(att.getRole());
outEv.addAttendee(delAtt);
// ei is 'original "REQUEST"'. */
EventInfo delegateEi = copyEventInfo(ei, getPrincipal());
BwEvent delegateEv = delegateEi.getEvent();
delegateEv.addRecipient(delegate);
// Not in RFC
delegateEv.addAttendee((BwAttendee) delAtt.clone());
delegateEv.setScheduleMethod(ScheduleMethods.methodTypeRequest);
att.setPartstat(IcalDefs.partstatValDelegated);
att.setRsvp(false);
att.setDelegatedTo(delegate);
// XXX Not sure if this is correct
schedule(delegateEi, null, null, false);
} else if (method == ScheduleMethods.methodTypeReply) {
// Only attendee should be us
ei.setOnlyAttendee(outEi, att.getAttendeeUri());
if (ev.getEntityType() == IcalDefs.entityTypeVpoll) {
setPollResponse(outEi, ei, att.getAttendeeUri());
}
outEv.setScheduleMethod(ScheduleMethods.methodTypeReply);
} else if (method == ScheduleMethods.methodTypeCounter) {
// Only attendee should be us
ei.setOnlyAttendee(outEi, att.getAttendeeUri());
/* Not sure how much we can change - at least times of the meeting.
*/
outEv.setScheduleMethod(ScheduleMethods.methodTypeCounter);
} else {
throw new RuntimeException("Never get here");
}
outEv.addRequestStatus(new BwRequestStatus(IcalDefs.requestStatusSuccess.getCode(), IcalDefs.requestStatusSuccess.getDescription()));
sr = scheduleResponse(outEi);
outEv.setScheduleState(BwEvent.scheduleStateProcessed);
ev.getOrganizer().setScheduleStatus(IcalDefs.deliveryStatusDelivered);
}
return sr;
}
use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.
the class EntityProcessor method process.
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void process() throws CalFacadeException {
try {
try (BwSvc bw = getBw()) {
final CalSvcI svci = bw.getSvci();
final BwIndexer indexer = svci.getIndexer(principal, indexRootPath);
for (final String name : entityNames) {
try {
if (debug) {
debug("Indexing collection " + path + " entity " + name);
}
status.stats.inc(IndexedType.events);
final EventInfo ent = svci.getEventsHandler().get(path, name);
if (ent == null) {
status.stats.inc(IndexedType.unreachableEntities);
continue;
}
indexer.indexEntity(ent);
} catch (final Throwable t) {
Logger.getLogger(this.getClass()).error(this, t);
errors++;
if (errors > maxErrors) {
error("Too many errors (" + errors + "): terminating");
break;
}
}
}
}
} catch (final Throwable t) {
Logger.getLogger(this.getClass()).error(t);
}
}
use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.
the class InScheduler method processEntityQueuedEvent.
private ProcessMessageResult processEntityQueuedEvent(final EntityQueuedEvent msg) {
/* These are events that are placed in the inbox.
*/
EventInfo ei = null;
try (final CalSvcI svci = getSvci(msg.getOwnerHref())) {
if (debug) {
trace("InSchedule inbox entry for principal " + msg.getOwnerHref());
}
ei = getInboxEvent(svci, msg.getName());
if (ei == null) {
// Event deleted from inbox.
if (debug) {
trace("InSchedule event deleted from inbox");
}
return ProcessMessageResult.NO_ACTION;
}
final BwEvent ev = ei.getEvent();
final int method = ev.getScheduleMethod();
if (debug) {
trace("InSchedule event for " + msg.getOwnerHref() + " " + msg.getName() + " with method " + ScheduleMethods.methods[method] + "\n" + ev);
if (ev.getSuppressed()) {
for (final EventInfo oei : ei.getOverrides()) {
trace("Override: " + oei.getEvent());
}
}
}
InProcessor proc = null;
switch(method) {
case Icalendar.methodTypeCancel:
proc = new InCancel(svci);
break;
case Icalendar.methodTypeRequest:
case Icalendar.methodTypePollStatus:
proc = new InRequest(svci);
break;
case Icalendar.methodTypeReply:
proc = new InReply(svci);
break;
case Icalendar.methodTypeRefresh:
proc = new InRefresh(svci);
break;
default:
warn("InSchedule: unhandled method for " + ev.getOwnerHref() + " " + method);
}
if (proc == null) {
deleteEvent(ei, false, false);
return ProcessMessageResult.PROCESSED;
}
final ProcessResult pr = proc.process(ei);
if (debug) {
trace("InSchedule " + pr.sr);
}
if (!pr.noInboxChange) {
proc.pendingToInbox(ei, ev.getOwnerHref(), pr.attendeeAccepting, pr.removeInboxEntry);
}
deleteEvent(ei, false, false);
return ProcessMessageResult.PROCESSED;
} catch (final CalFacadeForbidden cff) {
if (debug) {
trace("Forbidden exception" + cff);
}
if (ei != null) {
try {
deleteEvent(ei, false, false);
} catch (final Throwable ignored) {
}
}
return ProcessMessageResult.FAILED_NORETRIES;
} catch (final CalFacadeStaleStateException csse) {
if (debug) {
trace("Stale state exception");
}
rollback(getSvc());
return ProcessMessageResult.STALE_STATE;
} catch (final Throwable t) {
rollback(getSvc());
error(t);
}
return ProcessMessageResult.FAILED;
}
use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.
the class InScheduler method getInboxEvent.
private EventInfo getInboxEvent(final CalSvcI svci, final String eventName) throws CalFacadeException {
final BwCalendar inbox = svci.getCalendarsHandler().getSpecial(BwCalendar.calTypePendingInbox, false);
if (inbox == null) {
return null;
}
final EventInfo ei = svci.getEventsHandler().get(inbox.getPath(), eventName);
if (ei == null) {
if (debug) {
trace("autoSchedule: no event with name " + eventName);
}
return null;
}
if (debug) {
final boolean recur = ei.getEvent().getRecurring();
int numOverrides = 0;
if (recur && (ei.getOverrides() != null)) {
numOverrides = ei.getOverrides().size();
}
if (recur) {
trace("autoSchedule: retrieved recurring event with name " + eventName + " and " + numOverrides + " overrides");
} else {
trace("autoSchedule: retrieved non-recurring event with name " + eventName);
}
}
return ei;
}
use of org.bedework.calfacade.svc.EventInfo in project bw-calendar-engine by Bedework.
the class OutScheduler method processOutBox.
/* Process pending messages in outbox.
*
*/
private ProcessMessageResult processOutBox() throws CalFacadeException {
IcalTranslator trans = new IcalTranslator(getSvc().getIcalCallback());
Collection<EventInfo> eis = getOutboxEvents();
if (eis == null) {
return ProcessMessageResult.NO_ACTION;
}
class DedupKey implements Comparable<DedupKey> {
private String uid;
private String rid;
DedupKey(final String uid, final String rid) {
this.uid = uid;
this.rid = rid;
}
public int compareTo(final DedupKey that) {
int res = uid.compareTo(that.uid);
if (res != 0) {
return res;
}
if ((rid == null) && (that.rid == null)) {
return 0;
}
if ((rid != null) && (that.rid != null)) {
return rid.compareTo(that.rid);
}
if (rid != null) {
return 1;
}
return -1;
}
@Override
public int hashCode() {
int h = uid.hashCode();
if (rid != null) {
h *= rid.hashCode();
}
return h;
}
@Override
public boolean equals(final Object o) {
return compareTo((DedupKey) o) == 0;
}
}
Map<DedupKey, EventInfo> deduped = new HashMap<DedupKey, EventInfo>();
int discarded = 0;
for (EventInfo ei : eis) {
BwEvent ev = ei.getEvent();
DedupKey evKey = new DedupKey(ev.getUid(), ev.getRecurrenceId());
EventInfo mapei = deduped.get(evKey);
if (mapei == null) {
deduped.put(evKey, ei);
continue;
}
// Decide which to discard
discarded++;
BwEvent mapev = mapei.getEvent();
if (mapev.getSequence() > ev.getSequence()) {
continue;
}
if (mapev.getSequence() < ev.getSequence()) {
// Replace
deduped.put(evKey, ei);
continue;
}
// sequence is equal -- try for dtstamp.
int cmp = mapev.getDtstamp().compareTo(ev.getDtstamp());
if (cmp >= 0) {
continue;
}
deduped.put(evKey, ei);
}
if (debug) {
trace("Outbox process discarded " + discarded);
}
boolean allOk = true;
for (EventInfo ei : deduped.values()) {
BwEvent ev = ei.getEvent();
Calendar cal = trans.toIcal(ei, ev.getScheduleMethod());
Collection<String> recipients = new ArrayList<String>();
for (String r : ev.getRecipients()) {
if (r.toLowerCase().startsWith("mailto:")) {
recipients.add(r.substring(7));
} else {
recipients.add(r);
}
}
String orig = ev.getOriginator();
if (orig.toLowerCase().startsWith("mailto:")) {
orig = orig.substring(7);
}
try {
if (getSvc().getMailer().mailEntity(cal, orig, recipients, ev.getSummary())) {
/* Save sent messages somewhere - keep in outbox?
ev.setScheduleState(BwEvent.scheduleStateExternalDone);
updateEvent(ev, ei.getOverrideProxies(), null);
*/
getSvc().getEventsHandler().delete(ei, false);
}
} catch (CalFacadeException cfe) {
// Should count the exceptions and discard after a number of retries.
error(cfe);
allOk = false;
}
}
if (allOk) {
return ProcessMessageResult.PROCESSED;
}
return ProcessMessageResult.FAILED;
}
Aggregations