use of org.bedework.calfacade.BwRequestStatus in project bw-calendar-engine by Bedework.
the class BwEventUtil method toEvent.
/**
* We are going to try to construct a BwEvent object from a VEvent. This
* may represent a new event or an update to a pre-existing event. In any
* case, the VEvent probably has insufficient information to completely
* reconstitute the event object so we'll get the uid first and retrieve
* the event if it exists.
*
* <p>To put it another way we're doing a diff then update.
*
* <p>If it doesn't exist, we'll first fill in the appropriate fields,
* (non-public, creator, created etc) then for both cases update the
* remaining fields from the VEvent.
*
* <p>Recurring events present some challenges. If there is no recurrence
* id the vevent represents the master entity which defines the recurrence
* rules. If a recurrence id is present then the vevent represents a
* recurrence instance override and we should not attempt to retrieve the
* actual object but the referenced instance.
*
* <p>Also, note that we sorted the components first so we get the master
* before any instances.
*
* <p>If DTSTART, RRULE, EXRULE have changed (also RDATE, EXDATE?) then any
* existing overrides are unusable. We should delete all overrides and replace
* with new ones.
*
* <p>For an update we have to keep track of which fields were present in
* the vevent and set all absent fields to null in the BwEvent.
*
* @param cb IcalCallback object
* @param cal Needed so we can retrieve the event.
* @param ical Icalendar we are converting. We check its events for
* overrides.
* @param val VEvent object
* @param diff True if we should assume we are updating existing events.
* @param mergeAttendees True if we should only update our own attendee.
* @return EventInfo object representing new entry or updated entry
* @throws CalFacadeException
*/
public static EventInfo toEvent(final IcalCallback cb, final BwCalendar cal, final Icalendar ical, final Component val, final boolean diff, final boolean mergeAttendees) throws CalFacadeException {
if (val == null) {
return null;
}
String currentPrincipal = null;
final BwPrincipal principal = cb.getPrincipal();
if (principal != null) {
currentPrincipal = principal.getPrincipalRef();
}
final boolean debug = getLog().isDebugEnabled();
@SuppressWarnings("unchecked") final Holder<Boolean> hasXparams = new Holder<Boolean>(Boolean.FALSE);
final int methodType = ical.getMethodType();
String attUri = null;
if (mergeAttendees) {
// We'll need this later.
attUri = cb.getCaladdr(cb.getPrincipal().getPrincipalRef());
}
final String colPath;
if (cal == null) {
colPath = null;
} else {
colPath = cal.getPath();
}
try {
final PropertyList pl = val.getProperties();
boolean vpoll = false;
if (pl == null) {
// Empty component
return null;
}
final int entityType;
if (val instanceof VEvent) {
entityType = IcalDefs.entityTypeEvent;
} else if (val instanceof VToDo) {
entityType = IcalDefs.entityTypeTodo;
} else if (val instanceof VJournal) {
entityType = IcalDefs.entityTypeJournal;
} else if (val instanceof VFreeBusy) {
entityType = IcalDefs.entityTypeFreeAndBusy;
} else if (val instanceof VAvailability) {
entityType = IcalDefs.entityTypeVavailability;
} else if (val instanceof Available) {
entityType = IcalDefs.entityTypeAvailable;
} else if (val instanceof VPoll) {
entityType = IcalDefs.entityTypeVpoll;
vpoll = true;
} else {
throw new CalFacadeException("org.bedework.invalid.component.type", val.getName());
}
Property prop;
// Get the guid from the component
String guid = null;
prop = pl.getProperty(Property.UID);
if (prop != null) {
testXparams(prop, hasXparams);
guid = prop.getValue();
}
if (guid == null) {
/* XXX A guid is required - but are there devices out there without a
* guid - and if so how do we handle it?
*/
throw new CalFacadeException(CalFacadeException.noGuid);
}
/* See if we have a recurrence id */
BwDateTime ridObj = null;
String rid = null;
prop = pl.getProperty(Property.RECURRENCE_ID);
if (prop != null) {
testXparams(prop, hasXparams);
ridObj = BwDateTime.makeBwDateTime((DateProperty) prop);
if (ridObj.getRange() != null) {
/* XXX What do I do with it? */
warn("TRANS-TO_EVENT: Got a recurrence id range");
}
rid = ridObj.getDate();
}
EventInfo masterEI = null;
EventInfo evinfo = null;
BwEvent ev = null;
/* If we have a recurrence id see if we already have the master (we should
* get a master + all its overrides).
*
* If so find the override and use the annnotation or if no override,
* make one.
*
* If no override retrieve the event, add it to our table and then locate the
* annotation.
*
* If there is no annotation, create one.
*
* It's possible we have been sent 'detached' instances of a recurring
* event. This may happen if we are invited to one or more instances of a
* meeting. In this case we try to retrieve the master and if it doesn't
* exist we manufacture one. We consider such an instance an update to
* that instance only and leave the others alone.
*/
/* We need this in a couple of places */
final DtStart dtStart = (DtStart) pl.getProperty(Property.DTSTART);
/* If this is a recurrence instance see if we can find the master
*/
if (rid != null) {
// See if we have a new master event. If so create a proxy to this event.
masterEI = findMaster(guid, ical.getComponents());
if (masterEI != null) {
evinfo = masterEI.findOverride(rid);
}
}
if (diff && (evinfo == null) && (cal != null) && (cal.getCalType() != BwCalendar.calTypeInbox) && (cal.getCalType() != BwCalendar.calTypePendingInbox) && (cal.getCalType() != BwCalendar.calTypeOutbox)) {
if (debug) {
debugMsg("TRANS-TO_EVENT: try to fetch event with guid=" + guid);
}
final Collection<EventInfo> eis = cb.getEvent(colPath, guid);
if (Util.isEmpty(eis)) {
// do nothing
} else if (eis.size() > 1) {
// DORECUR - wrong again
throw new CalFacadeException("More than one event returned for guid.");
} else {
evinfo = eis.iterator().next();
}
if (debug) {
if (evinfo != null) {
debugMsg("TRANS-TO_EVENT: fetched event with guid");
} else {
debugMsg("TRANS-TO_EVENT: did not find event with guid");
}
}
if (evinfo != null) {
if (rid != null) {
// We just retrieved it's master
masterEI = evinfo;
masterEI.setInstanceOnly(true);
evinfo = masterEI.findOverride(rid);
ical.addComponent(masterEI);
} else if (methodType == ScheduleMethods.methodTypeCancel) {
// This should never have an rid for cancel of entire event.
evinfo.setInstanceOnly(evinfo.getEvent().getSuppressed());
} else {
// Presumably sent an update for the entire event. No longer suppressed master
evinfo.getEvent().setSuppressed(false);
}
} else if (rid != null) {
/* Manufacture a master for the instance */
masterEI = makeNewEvent(cb, entityType, guid, colPath);
final BwEvent e = masterEI.getEvent();
// XXX This seems bogus
final DtStart mdtStart;
final String bogusDate = "19980118";
final String bogusTime = "T230000";
final Parameter par = dtStart.getParameter("VALUE");
final boolean isDateType = (par != null) && (par.equals(Value.DATE));
if (isDateType) {
mdtStart = new DtStart(new Date(bogusDate));
} else if (dtStart.isUtc()) {
mdtStart = new DtStart(bogusDate + bogusTime + "Z");
} else if (dtStart.getTimeZone() == null) {
mdtStart = new DtStart(bogusDate + bogusTime);
} else {
mdtStart = new DtStart(bogusDate + bogusTime + "Z", dtStart.getTimeZone());
}
setDates(cb.getPrincipal().getPrincipalRef(), masterEI, mdtStart, null, null);
e.setRecurring(true);
// e.addRdate(ridObj);
e.setSuppressed(true);
ical.addComponent(masterEI);
evinfo = masterEI.findOverride(rid);
masterEI.setInstanceOnly(rid != null);
}
}
if (evinfo == null) {
evinfo = makeNewEvent(cb, entityType, guid, colPath);
} else if (evinfo.getEvent().getEntityType() != entityType) {
throw new CalFacadeException("org.bedework.mismatched.entity.type", val.toString());
}
final ChangeTable chg = evinfo.getChangeset(cb.getPrincipal().getPrincipalRef());
if (rid != null) {
final String evrid = evinfo.getEvent().getRecurrenceId();
if ((evrid == null) || (!evrid.equals(rid))) {
warn("Mismatched rid ev=" + evrid + " expected " + rid);
// XXX spurious???
chg.changed(PropertyInfoIndex.RECURRENCE_ID, evrid, rid);
}
if (masterEI.getEvent().getSuppressed()) {
masterEI.getEvent().addRdate(ridObj);
}
}
ev = evinfo.getEvent();
ev.setScheduleMethod(methodType);
DtEnd dtEnd = null;
if (entityType == IcalDefs.entityTypeTodo) {
final Due due = (Due) pl.getProperty(Property.DUE);
if (due != null) {
dtEnd = new DtEnd(due.getParameters(), due.getValue());
}
} else {
dtEnd = (DtEnd) pl.getProperty(Property.DTEND);
}
final Duration duration = (Duration) pl.getProperty(Property.DURATION);
setDates(cb.getPrincipal().getPrincipalRef(), evinfo, dtStart, dtEnd, duration);
for (final Object aPl : pl) {
prop = (Property) aPl;
testXparams(prop, hasXparams);
// debugMsg("ical prop " + prop.getClass().getName());
String pval = prop.getValue();
if ((pval != null) && (pval.length() == 0)) {
pval = null;
}
final PropertyInfoIndex pi;
if (prop instanceof XProperty) {
pi = PropertyInfoIndex.XPROP;
} else {
pi = PropertyInfoIndex.fromName(prop.getName());
}
if (pi == null) {
debugMsg("Unknown property with name " + prop.getName() + " class " + prop.getClass() + " and value " + pval);
continue;
}
chg.present(pi);
switch(pi) {
case ACCEPT_RESPONSE:
/* ------------------- Accept Response -------------------- */
String sval = ((AcceptResponse) prop).getValue();
if (chg.changed(pi, ev.getPollAcceptResponse(), sval)) {
ev.setPollAcceptResponse(sval);
}
break;
case ATTACH:
/* ------------------- Attachment -------------------- */
chg.addValue(pi, getAttachment((Attach) prop));
break;
case ATTENDEE:
if (methodType == ScheduleMethods.methodTypePublish) {
if (cb.getStrictness() == IcalCallback.conformanceStrict) {
throw new CalFacadeException(CalFacadeException.attendeesInPublish);
}
if (cb.getStrictness() == IcalCallback.conformanceWarn) {
// warn("Had attendees for PUBLISH");
}
}
Attendee attPr = (Attendee) prop;
if (evinfo.getNewEvent() || !mergeAttendees) {
chg.addValue(pi, getAttendee(cb, attPr));
} else {
final String pUri = cb.getCaladdr(attPr.getValue());
if (pUri.equals(attUri)) {
/* Only update for our own attendee
* We're doing a PUT and this must be the attendee updating their
* partstat. We don't allow them to change other attendees
* whatever the PUT content says.
*/
chg.addValue(pi, getAttendee(cb, attPr));
} else {
// Use the value we currently have
boolean found = false;
for (final BwAttendee att : ev.getAttendees()) {
if (pUri.equals(att.getAttendeeUri())) {
chg.addValue(pi, att.clone());
found = true;
break;
}
}
if (!found) {
// An added attendee
final BwAttendee att = getAttendee(cb, attPr);
att.setPartstat(IcalDefs.partstatValNeedsAction);
chg.addValue(pi, att);
}
}
}
break;
case BUSYTYPE:
int ibt = BwEvent.fromBusyTypeString(pval);
if (chg.changed(pi, ev.getBusyType(), ibt)) {
ev.setBusyType(ibt);
}
break;
case CATEGORIES:
/* ------------------- Categories -------------------- */
Categories cats = (Categories) prop;
TextList cl = cats.getCategories();
String lang = getLang(cats);
if (cl != null) {
/* Got some categories */
Iterator cit = cl.iterator();
while (cit.hasNext()) {
String wd = (String) cit.next();
if (wd == null) {
continue;
}
BwString key = new BwString(lang, wd);
BwCategory cat = cb.findCategory(key);
if (cat == null) {
cat = BwCategory.makeCategory();
cat.setWord(key);
cb.addCategory(cat);
}
chg.addValue(pi, cat);
}
}
break;
case CLASS:
if (chg.changed(pi, ev.getClassification(), pval)) {
ev.setClassification(pval);
}
break;
case COMMENT:
/* ------------------- Comment -------------------- */
chg.addValue(pi, new BwString(null, pval));
break;
case COMPLETED:
if (chg.changed(pi, ev.getCompleted(), pval)) {
ev.setCompleted(pval);
}
break;
case CONTACT:
/* ------------------- Contact -------------------- */
String altrep = getAltRepPar(prop);
lang = getLang(prop);
String uid = getUidPar(prop);
BwString nm = new BwString(lang, pval);
BwContact contact = null;
if (uid != null) {
contact = cb.getContact(uid);
}
if (contact == null) {
contact = cb.findContact(nm);
}
if (contact == null) {
contact = BwContact.makeContact();
contact.setCn(nm);
contact.setLink(altrep);
cb.addContact(contact);
} else {
contact.setCn(nm);
contact.setLink(altrep);
}
chg.addValue(pi, contact);
break;
case CREATED:
if (chg.changed(pi, ev.getCreated(), pval)) {
ev.setCreated(pval);
}
break;
case DESCRIPTION:
if (chg.changed(pi, ev.getDescription(), pval)) {
ev.setDescription(pval);
}
break;
case DTEND:
break;
case DTSTAMP:
/* ------------------- DtStamp -------------------- */
ev.setDtstamp(pval);
break;
case DTSTART:
break;
case DURATION:
break;
case EXDATE:
/* ------------------- ExDate -------------------- */
chg.addValues(pi, makeDateTimes((DateListProperty) prop));
break;
case EXRULE:
/* ------------------- ExRule -------------------- */
chg.addValue(pi, pval);
break;
case FREEBUSY:
/* ------------------- freebusy -------------------- */
FreeBusy fbusy = (FreeBusy) prop;
PeriodList perpl = fbusy.getPeriods();
Parameter par = getParameter(fbusy, "FBTYPE");
int fbtype;
if (par == null) {
fbtype = BwFreeBusyComponent.typeBusy;
} else if (par.equals(FbType.BUSY)) {
fbtype = BwFreeBusyComponent.typeBusy;
} else if (par.equals(FbType.BUSY_TENTATIVE)) {
fbtype = BwFreeBusyComponent.typeBusyTentative;
} else if (par.equals(FbType.BUSY_UNAVAILABLE)) {
fbtype = BwFreeBusyComponent.typeBusyUnavailable;
} else if (par.equals(FbType.FREE)) {
fbtype = BwFreeBusyComponent.typeFree;
} else {
if (debug) {
debugMsg("Unsupported parameter " + par.getName());
}
throw new IcalMalformedException("parameter " + par.getName());
}
BwFreeBusyComponent fbc = new BwFreeBusyComponent();
fbc.setType(fbtype);
Iterator perit = perpl.iterator();
while (perit.hasNext()) {
Period per = (Period) perit.next();
fbc.addPeriod(per);
}
ev.addFreeBusyPeriod(fbc);
break;
case GEO:
/* ------------------- Geo -------------------- */
Geo g = (Geo) prop;
BwGeo geo = new BwGeo(g.getLatitude(), g.getLongitude());
if (chg.changed(pi, ev.getGeo(), geo)) {
ev.setGeo(geo);
}
break;
case LAST_MODIFIED:
if (chg.changed(pi, ev.getLastmod(), pval)) {
ev.setLastmod(pval);
}
break;
case LOCATION:
/* ------------------- Location -------------------- */
BwLocation loc = null;
// String uid = getUidPar(prop);
/* At the moment Mozilla lightning is broken and this leads to all
* sorts of problems.
if (uid != null) {
loc = cb.getLocation(uid);
}
*/
lang = getLang(prop);
BwString addr = null;
if (pval != null) {
if (loc == null) {
addr = new BwString(lang, pval);
loc = cb.findLocation(addr);
}
if (loc == null) {
loc = BwLocation.makeLocation();
loc.setAddress(addr);
cb.addLocation(loc);
}
}
BwLocation evloc = ev.getLocation();
if (chg.changed(pi, evloc, loc)) {
// CHGTBL - this only shows that it's a different location object
ev.setLocation(loc);
} else if ((loc != null) && (evloc != null)) {
// See if the value is changed
String evval = evloc.getAddress().getValue();
String inval = loc.getAddress().getValue();
if (!evval.equals(inval)) {
chg.changed(pi, evval, inval);
evloc.getAddress().setValue(inval);
}
}
break;
case ORGANIZER:
/* ------------------- Organizer -------------------- */
final BwOrganizer org = getOrganizer(cb, (Organizer) prop);
final BwOrganizer evorg = ev.getOrganizer();
final BwOrganizer evorgCopy;
if (evorg == null) {
evorgCopy = null;
} else {
evorgCopy = (BwOrganizer) evorg.clone();
}
if (chg.changed(pi, evorgCopy, org)) {
if (evorg == null) {
ev.setOrganizer(org);
} else {
evorg.update(org);
}
}
break;
case PERCENT_COMPLETE:
/* ------------------- PercentComplete -------------------- */
Integer ival = ((PercentComplete) prop).getPercentage();
if (chg.changed(pi, ev.getPercentComplete(), ival)) {
ev.setPercentComplete(ival);
}
break;
case POLL_MODE:
/* ------------------- Poll mode -------------------- */
sval = ((PollMode) prop).getValue();
if (chg.changed(pi, ev.getPollMode(), sval)) {
ev.setPollMode(sval);
}
break;
case POLL_PROPERTIES:
/* ------------------- Poll properties ---------------- */
sval = ((PollProperties) prop).getValue();
if (chg.changed(pi, ev.getPollProperties(), sval)) {
ev.setPollProperties(sval);
}
break;
case POLL_WINNER:
/* ------------------- Poll winner -------------------- */
ival = ((PollWinner) prop).getPollwinner();
if (chg.changed(pi, ev.getPollWinner(), ival)) {
ev.setPollWinner(ival);
}
break;
case PRIORITY:
/* ------------------- Priority -------------------- */
ival = ((Priority) prop).getLevel();
if (chg.changed(pi, ev.getPriority(), ival)) {
ev.setPriority(ival);
}
break;
case RDATE:
/* ------------------- RDate -------------------- */
chg.addValues(pi, makeDateTimes((DateListProperty) prop));
break;
case RECURRENCE_ID:
break;
case RELATED_TO:
/* ------------------- RelatedTo -------------------- */
final RelatedTo irelto = (RelatedTo) prop;
final BwRelatedTo relto = new BwRelatedTo();
final String parval = IcalUtil.getParameterVal(irelto, "RELTYPE");
if (parval != null) {
relto.setRelType(parval);
}
relto.setValue(irelto.getValue());
if (chg.changed(pi, ev.getRelatedTo(), relto)) {
ev.setRelatedTo(relto);
}
break;
case REQUEST_STATUS:
/* ------------------- RequestStatus -------------------- */
final BwRequestStatus rs = BwRequestStatus.fromRequestStatus((RequestStatus) prop);
chg.addValue(pi, rs);
break;
case RESOURCES:
/* ------------------- Resources -------------------- */
final TextList rl = ((Resources) prop).getResources();
if (rl != null) {
/* Got some resources */
lang = getLang(prop);
Iterator rit = rl.iterator();
while (rit.hasNext()) {
BwString rsrc = new BwString(lang, (String) rit.next());
chg.addValue(pi, rsrc);
}
}
break;
case RRULE:
/* ------------------- RRule -------------------- */
chg.addValue(pi, pval);
break;
case SEQUENCE:
/* ------------------- Sequence -------------------- */
int seq = ((Sequence) prop).getSequenceNo();
if (seq != ev.getSequence()) {
chg.changed(pi, ev.getSequence(), seq);
ev.setSequence(seq);
}
break;
case STATUS:
if (chg.changed(pi, ev.getStatus(), pval)) {
ev.setStatus(pval);
}
break;
case SUMMARY:
if (chg.changed(pi, ev.getSummary(), pval)) {
ev.setSummary(pval);
}
break;
case TRANSP:
if (chg.changed(pi, ev.getPeruserTransparency(cb.getPrincipal().getPrincipalRef()), pval)) {
BwXproperty pu = ev.setPeruserTransparency(cb.getPrincipal().getPrincipalRef(), pval);
if (pu != null) {
chg.addValue(PropertyInfoIndex.XPROP, pu);
}
}
break;
case UID:
break;
case URL:
if (chg.changed(pi, ev.getLink(), pval)) {
ev.setLink(pval);
}
break;
case XPROP:
/* ------------------------- x-property --------------------------- */
final String name = prop.getName();
if (name.equalsIgnoreCase(BwXproperty.bedeworkCost)) {
if (chg.changed(PropertyInfoIndex.COST, ev.getCost(), pval)) {
ev.setCost(pval);
}
break;
}
if (name.equalsIgnoreCase(BwXproperty.xBedeworkCategories)) {
if (checkCategory(cb, chg, ev, null, pval)) {
break;
}
}
if (name.equalsIgnoreCase(BwXproperty.xBedeworkLocation)) {
if (checkLocation(cb, chg, ev, prop)) {
break;
}
}
if (name.equalsIgnoreCase(BwXproperty.xBedeworkContact)) {
if (checkContact(cb, chg, ev, null, pval)) {
break;
}
}
/* See if this is an x-category that can be
converted to a real category
*/
final XProperty xp = (XProperty) prop;
chg.addValue(PropertyInfoIndex.XPROP, new BwXproperty(name, xp.getParameters().toString(), pval));
break;
default:
if (debug) {
debugMsg("Unsupported property with index " + pi + "; class " + prop.getClass() + " and value " + pval);
}
}
}
if (val instanceof VAvailability) {
processAvailable(cb, cal, ical, (VAvailability) val, evinfo);
} else if (!(val instanceof Available)) {
VAlarmUtil.processComponentAlarms(cb, val, ev, currentPrincipal, chg);
if (val instanceof VPoll) {
processVvoters((VPoll) val, evinfo, cb, chg, mergeAttendees);
processCandidates((VPoll) val, evinfo, chg);
}
}
/* Fix up timestamps. */
if (ev.getCreated() == null) {
if (ev.getLastmod() != null) {
ev.setCreated(ev.getLastmod());
chg.changed(PropertyInfoIndex.CREATED, null, ev.getCreated());
} else {
ev.updateDtstamp();
chg.changed(PropertyInfoIndex.CREATED, null, ev.getCreated());
chg.changed(PropertyInfoIndex.LAST_MODIFIED, null, ev.getLastmod());
}
}
if (ev.getLastmod() == null) {
// created cannot be null now
ev.setLastmod(ev.getCreated());
chg.changed(PropertyInfoIndex.LAST_MODIFIED, null, ev.getLastmod());
}
processTimezones(ev, ical, chg);
/* Remove any recipients and originator
*/
if (ev.getRecipients() != null) {
ev.getRecipients().clear();
}
ev.setOriginator(null);
if (hasXparams.value) {
/* Save a text copy of the entire event as an x-property */
Component valCopy = val.copy();
/* Remove potentially large values */
prop = valCopy.getProperty(Property.DESCRIPTION);
if (prop != null) {
prop.setValue(null);
}
prop = valCopy.getProperty(Property.ATTACH);
// Don't store the entire attachment - we just need the parameters.
if (prop != null) {
Value v = (Value) prop.getParameter(Parameter.VALUE);
if (v != null) {
prop.setValue(String.valueOf(prop.getValue().hashCode()));
}
}
chg.addValue(PropertyInfoIndex.XPROP, new BwXproperty(BwXproperty.bedeworkIcal, null, valCopy.toString()));
}
chg.processChanges(ev, true);
ev.setRecurring(new Boolean(ev.isRecurringEntity()));
if (debug) {
debugMsg(chg.toString());
debugMsg(ev.toString());
}
if (masterEI != null) {
// Just return null as this event is on its override list
return null;
}
return evinfo;
} catch (CalFacadeException cfe) {
if (debug) {
cfe.printStackTrace();
}
throw cfe;
} catch (Throwable t) {
if (debug) {
t.printStackTrace();
}
throw new CalFacadeException(t);
}
}
use of org.bedework.calfacade.BwRequestStatus in project bw-calendar-engine by Bedework.
the class ImplicitSchedulingHandler method sendReply.
/* (non-Javadoc)
* @see org.bedework.calsvci.SchedulingI#sendReply(org.bedework.calfacade.svc.EventInfo, int, java.lang.String)
*/
@Override
public ScheduleResult sendReply(final EventInfo ei, final int partstat, final String comment) throws CalFacadeException {
ScheduleResult sr = new ScheduleResult();
BwEvent ev = ei.getEvent();
if (!ev.getAttendeeSchedulingObject()) {
sr.errorCode = CalFacadeException.schedulingBadMethod;
return sr;
}
BwAttendee att = findUserAttendee(ev);
if (att == null) {
sr.errorCode = CalFacadeException.schedulingNotAttendee;
return sr;
}
att = (BwAttendee) att.clone();
att.setPartstat(IcalDefs.partstats[partstat]);
att.setRsvp(partstat == IcalDefs.partstatNeedsAction);
BwEvent outEv = new BwEventObj();
EventInfo outEi = new EventInfo(outEv);
outEv.setScheduleMethod(ScheduleMethods.methodTypeReply);
outEv.addRequestStatus(new BwRequestStatus(IcalDefs.requestStatusSuccess.getCode(), IcalDefs.requestStatusSuccess.getDescription()));
outEv.addRecipient(ev.getOrganizer().getOrganizerUri());
outEv.setOriginator(att.getAttendeeUri());
outEv.updateDtstamp();
outEv.setOrganizer((BwOrganizer) ev.getOrganizer().clone());
outEv.getOrganizer().setDtstamp(outEv.getDtstamp());
outEv.addAttendee(att);
outEv.setUid(ev.getUid());
outEv.setRecurrenceId(ev.getRecurrenceId());
outEv.setDtstart(ev.getDtstart());
outEv.setDtend(ev.getDtend());
outEv.setDuration(ev.getDuration());
outEv.setNoStart(ev.getNoStart());
outEv.setSummary(ev.getSummary());
outEv.setRecurring(false);
if (comment != null) {
outEv.addComment(new BwString(null, comment));
}
sr = scheduleResponse(outEi);
outEv.setScheduleState(BwEvent.scheduleStateProcessed);
return sr;
}
use of org.bedework.calfacade.BwRequestStatus 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.BwRequestStatus in project bw-calendar-engine by Bedework.
the class SchedAttendeeUpdate method attendeeRespond.
private ScheduleResult attendeeRespond(final EventInfo ei, final int method) throws CalFacadeException {
ScheduleResult sr = new ScheduleResult();
final BwEvent ev = ei.getEvent();
final SchedulingIntf sched = (SchedulingIntf) getSvc().getScheduler();
final String attUri = getSvc().getDirectories().principalToCaladdr(getSvc().getPrincipal());
check: {
/* Check that the current user is actually an attendee of the event.
* Note we may have a suppressed master and/or multiple overrides
*/
BwAttendee att = null;
if (!ev.getSuppressed()) {
att = ev.findAttendee(attUri);
if (att == null) {
sr.errorCode = CalFacadeException.schedulingNotAttendee;
break check;
}
}
if (ei.getNumOverrides() > 0) {
for (final EventInfo oei : ei.getOverrides()) {
att = oei.getEvent().findAttendee(attUri);
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 = sched.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());
final 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(Icalendar.methodTypeReply);
// Additional attendee
final 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"'. */
final EventInfo delegateEi = sched.copyEventInfo(ei, getPrincipal());
final BwEvent delegateEv = delegateEi.getEvent();
delegateEv.addRecipient(delegate);
// Not in RFC
delegateEv.addAttendee((BwAttendee) delAtt.clone());
delegateEv.setScheduleMethod(Icalendar.methodTypeRequest);
att.setPartstat(IcalDefs.partstatValDelegated);
att.setRsvp(false);
att.setDelegatedTo(delegate);
// XXX Not sure if this is correct
sched.schedule(delegateEi, null, null, false);
} else if (method == Icalendar.methodTypeReply) {
// Only attendee should be us
ei.setOnlyAttendee(outEi, att.getAttendeeUri());
outEv.setScheduleMethod(Icalendar.methodTypeReply);
} else if (method == Icalendar.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(Icalendar.methodTypeCounter);
} else {
throw new RuntimeException("Never get here");
}
outEv.addRequestStatus(new BwRequestStatus(IcalDefs.requestStatusSuccess.getCode(), IcalDefs.requestStatusSuccess.getDescription()));
sr = sched.scheduleResponse(outEi);
outEv.setScheduleState(BwEvent.scheduleStateProcessed);
ev.getOrganizer().setScheduleStatus(IcalDefs.deliveryStatusDelivered);
}
return sr;
}
Aggregations