[Bedework-commit] calendarapi r308 - in trunk:
calCore/resources/hbms calFacade/src/org/bedework/calfacade/exc
calFacade/src/org/bedework/calfacade/svc/prefs
calsvc/src/org/bedework/calsvc calsvci/src/org/bedework/calsvci
svnadmin at bedework.org
svnadmin at bedework.org
Wed Jun 13 00:03:06 EDT 2007
Author: douglm
Date: 2007-06-13 00:03:01 -0400 (Wed, 13 Jun 2007)
New Revision: 308
Modified:
trunk/calCore/resources/hbms/Preferences.hbm.xml
trunk/calFacade/src/org/bedework/calfacade/exc/CalFacadeException.java
trunk/calFacade/src/org/bedework/calfacade/svc/prefs/BwPreferences.java
trunk/calsvc/src/org/bedework/calsvc/AutoScheduler.java
trunk/calsvc/src/org/bedework/calsvc/CalSvc.java
trunk/calsvc/src/org/bedework/calsvc/Scheduling.java
trunk/calsvci/src/org/bedework/calsvci/SchedulingI.java
Log:
Add preferences associated with auto responding to scheduling requests.
Fix up some of the auto processing for resources.
Make a start on handling system specific properties in the CalDAV server
Modified: trunk/calCore/resources/hbms/Preferences.hbm.xml
===================================================================
--- trunk/calCore/resources/hbms/Preferences.hbm.xml 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calCore/resources/hbms/Preferences.hbm.xml 2007-06-13 04:03:01 UTC (rev 308)
@@ -51,6 +51,7 @@
<property name="preferredView" column="preferred_view" type="string" />
<property name="preferredViewPeriod" column="preferred_view_period"
type="string" />
+ <property name="pageSize" column="bw_page_size" type="integer" />
<property name="workDays" column="workdays" type="string" />
<property name="workdayStart" column="workday_start" type="integer" />
<property name="workdayEnd" column="workday_end" type="integer" />
@@ -61,6 +62,18 @@
<property name="hour24" column="bw_hour24" type="true_false"
not-null="true" />
+ <property name="scheduleAutoRespond" column="bw_sched_auto_respond" type="true_false"
+ not-null="true" />
+
+ <property name="scheduleAutoCancelAction" column="scheduleAutoCancelAction"
+ type="integer" />
+
+ <property name="scheduleDoubleBook" column="bw_sched_double_book" type="true_false"
+ not-null="true" />
+
+ <property name="scheduleAutoProcessResponses" column="bw_sched_auto_process_responses"
+ type="integer" />
+
<set name="properties" table="bw_user_properties"
cascade="all-delete-orphan" >
<cache usage="read-write"/>
Modified: trunk/calFacade/src/org/bedework/calfacade/exc/CalFacadeException.java
===================================================================
--- trunk/calFacade/src/org/bedework/calfacade/exc/CalFacadeException.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calFacade/src/org/bedework/calfacade/exc/CalFacadeException.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -230,6 +230,10 @@
public static final String schedulingBadResponse =
"org.bedework.error.scheduling.badresponse";
+ /** Invalid scheduling action. */
+ public static final String schedulingBadAction =
+ "org.bedework.error.scheduling.badaction";
+
/** System error: Invalid freebusy granulator date limit - Must be DATETIME. */
public static final String schedulingBadGranulatorDt =
"org.bedework.error.scheduling.badgranulatordt";
Modified: trunk/calFacade/src/org/bedework/calfacade/svc/prefs/BwPreferences.java
===================================================================
--- trunk/calFacade/src/org/bedework/calfacade/svc/prefs/BwPreferences.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calFacade/src/org/bedework/calfacade/svc/prefs/BwPreferences.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -40,7 +40,7 @@
/** Account preferences for Bedework. These affect the user view of calendars.
*
- * @author Mike Douglass douglm at rpi.edu
+ * @author Mike Douglass douglm at rpi.edu
* @version 1.0
*/
public class BwPreferences extends BwOwnedDbentity {
@@ -116,6 +116,32 @@
private boolean hour24;
+ private boolean scheduleAutoRespond;
+
+ /** Do not auto process cancels */
+ public static int scheduleAutoCancelNoAction = 0;
+
+ /** Set status to cancelled */
+ public static int scheduleAutoCancelSetStatus = 1;
+
+ /** Delete the event */
+ public static int scheduleAutoCancelDelete = 2;
+
+ private int scheduleAutoCancelAction;
+
+ private boolean scheduleDoubleBook;
+
+ /** Do not auto process responses */
+ public static int scheduleAutoProcessResponsesNoAction = 0;
+
+ /** Only auto process accept responses */
+ public static int scheduleAutoProcessResponsesAccepts = 1;
+
+ /** Auto process all responses */
+ public static int scheduleAutoProcessResponsesAll = 2;
+
+ private int scheduleAutoProcessResponses;
+
private Collection<BwProperty> properties;
/** Constructor
@@ -348,6 +374,62 @@
/**
* @param val
*/
+ public void setScheduleAutoRespond(boolean val) {
+ scheduleAutoRespond = val;
+ }
+
+ /**
+ * @return bool
+ */
+ public boolean getScheduleAutoRespond() {
+ return scheduleAutoRespond;
+ }
+
+ /**
+ * @param val
+ */
+ public void setScheduleAutoCancelAction(int val) {
+ scheduleAutoCancelAction = val;
+ }
+
+ /**
+ * @return int
+ */
+ public int getScheduleAutoCancelAction() {
+ return scheduleAutoCancelAction;
+ }
+
+ /**
+ * @param val
+ */
+ public void setScheduleDoubleBook(boolean val) {
+ scheduleDoubleBook = val;
+ }
+
+ /**
+ * @return bool
+ */
+ public boolean getScheduleDoubleBook() {
+ return scheduleDoubleBook;
+ }
+
+ /**
+ * @param val
+ */
+ public void setScheduleAutoProcessResponses(int val) {
+ scheduleAutoProcessResponses = val;
+ }
+
+ /**
+ * @return int
+ */
+ public int getScheduleAutoProcessResponses() {
+ return scheduleAutoProcessResponses;
+ }
+
+ /**
+ * @param val
+ */
public void setProperties(Collection<BwProperty> val) {
properties = val;
}
@@ -359,6 +441,78 @@
return properties;
}
+ /**
+ * @return int
+ */
+ public int getNumProperties() {
+ Collection c = getProperties();
+ if (c == null) {
+ return 0;
+ }
+
+ return c.size();
+ }
+
+ /**
+ * @param val
+ */
+ public void addAttendee(BwProperty val) {
+ Collection<BwProperty> c = getProperties();
+ if (c == null) {
+ c = new TreeSet<BwProperty>();
+ setProperties(c);
+ }
+
+ if (!c.contains(val)) {
+ c.add(val);
+ }
+ }
+
+ /**
+ * @param val
+ * @return boolean
+ */
+ public boolean removeProperty(BwProperty val) {
+ Collection c = getProperties();
+ if (c == null) {
+ return false;
+ }
+
+ return c.remove(val);
+ }
+
+ /**
+ * @return BwProperty
+ */
+ public Collection<BwProperty> copyProperties() {
+ if (getNumProperties() == 0) {
+ return null;
+ }
+ TreeSet<BwProperty> ts = new TreeSet<BwProperty>();
+
+ for (BwProperty p: getProperties()) {
+ ts.add(p);
+ }
+
+ return ts;
+ }
+
+ /**
+ * @return BwProperty
+ */
+ public Collection<BwProperty> cloneProperties() {
+ if (getNumProperties() == 0) {
+ return null;
+ }
+ TreeSet<BwProperty> ts = new TreeSet<BwProperty>();
+
+ for (BwProperty p: getProperties()) {
+ ts.add((BwProperty)p.clone());
+ }
+
+ return ts;
+ }
+
/* ====================================================================
* Convenience methods
* ==================================================================== */
Modified: trunk/calsvc/src/org/bedework/calsvc/AutoScheduler.java
===================================================================
--- trunk/calsvc/src/org/bedework/calsvc/AutoScheduler.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calsvc/src/org/bedework/calsvc/AutoScheduler.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -25,22 +25,30 @@
*/
package org.bedework.calsvc;
+import org.bedework.calfacade.BwAttendee;
import org.bedework.calfacade.BwCalendar;
import org.bedework.calfacade.BwEvent;
+import org.bedework.calfacade.BwFreeBusy;
+import org.bedework.calfacade.BwFreeBusyComponent;
import org.bedework.calfacade.RecurringRetrievalMode;
import org.bedework.calfacade.ScheduleResult;
import org.bedework.calfacade.RecurringRetrievalMode.Rmode;
import org.bedework.calfacade.exc.CalFacadeException;
import org.bedework.calfacade.svc.EventInfo;
+import org.bedework.calfacade.svc.prefs.BwPreferences;
import org.bedework.calsvci.CalSvcFactoryDefault;
import org.bedework.calsvci.CalSvcI;
import org.bedework.calsvci.CalSvcIPars;
import org.bedework.calsvci.SchedulingI;
import org.bedework.icalendar.Icalendar;
+import net.fortuna.ical4j.model.Period;
+import net.fortuna.ical4j.model.parameter.PartStat;
+
import org.apache.log4j.Logger;
import java.io.Serializable;
+import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
@@ -132,6 +140,13 @@
return;
}
+ BwPreferences prefs = svci.getUserPrefs();
+
+ boolean scheduleAutoRespond = prefs.getScheduleAutoRespond();
+ int scheduleAutoCancelAction = prefs.getScheduleAutoCancelAction();
+ boolean scheduleDoubleBook = prefs.getScheduleDoubleBook();
+ int scheduleAutoProcessResponses = prefs.getScheduleAutoProcessResponses();
+
SchedulingI sched = svci.getScheduler();
ScheduleResult sr = null;
BwEvent ev = ei.getEvent();
@@ -143,18 +158,46 @@
}
if (method == Icalendar.methodTypeCancel) {
- svci.deleteEvent(ev, true);
- return;
+ if (scheduleAutoRespond &&
+ (scheduleAutoCancelAction != BwPreferences.scheduleAutoCancelNoAction)) {
+ sched.processCancel(ev, scheduleAutoCancelAction, null);
+ }
}
if (ev.getScheduleMethod() == Icalendar.methodTypeRequest) {
if (debug) {
trace("send response event " + ase.eventName);
}
+
+ String partStat = PartStat.ACCEPTED.getValue();
+
+ if (!scheduleDoubleBook) {
+ // See if there are any events booked during this time.
+ BwFreeBusy fb = svci.getFreeBusy(null, null,
+ svci.getUser(),
+ ev.getDtstart(), ev.getDtend(),
+ null, false);
+
+ Collection<BwFreeBusyComponent> times = fb.getTimes();
+
+ if ((times != null) && !times.isEmpty()) {
+ for (BwFreeBusyComponent fbc: times) {
+ if (fbc.getType() != BwFreeBusyComponent.typeFree) {
+ Collection<Period> periods = fbc.getPeriods();
+
+ if ((periods != null) && !periods.isEmpty()) {
+ partStat = PartStat.DECLINED.getValue();
+ break;
+ }
+ }
+ }
+ }
+ }
+
sr = sched.attendeeRespond(ev,
null, // delegate
"REPLY", // method
- "ACCEPTED", // partstat
+ partStat,
// Use preferred calendar
svci.getPreferredCalendar(), // evCal
null, // comment
@@ -162,7 +205,25 @@
}
if (ev.getScheduleMethod() == Icalendar.methodTypeReply) {
- sr = sched.processResponse(ev, null);
+ /* Reply back from attendee - update our copy
+ */
+ if (scheduleAutoProcessResponses != BwPreferences.scheduleAutoProcessResponsesNoAction) {
+ boolean process = true;
+
+ if (scheduleAutoProcessResponses == BwPreferences.scheduleAutoProcessResponsesAccepts) {
+ /* Should be exactly one attendee */
+ Collection<BwAttendee> atts = ev.getAttendees();
+ if ((atts != null) && (atts.size() == 1)) {
+ BwAttendee att = atts.iterator().next();
+
+ process = att.getPartstat() == PartStat.ACCEPTED.getValue();
+ }
+ }
+
+ if (process) {
+ sr = sched.processResponse(ev, null);
+ }
+ }
}
if (debug) {
Modified: trunk/calsvc/src/org/bedework/calsvc/CalSvc.java
===================================================================
--- trunk/calsvc/src/org/bedework/calsvc/CalSvc.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calsvc/src/org/bedework/calsvc/CalSvc.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -132,6 +132,7 @@
import edu.rpi.cct.uwcal.resources.Resources;
import edu.rpi.cmt.access.Ace;
import edu.rpi.cmt.access.AceWho;
+import edu.rpi.cmt.access.PrincipalInfo;
import edu.rpi.cmt.access.PrivilegeDefs;
import edu.rpi.cmt.access.Acl.CurrentAccess;
@@ -3054,6 +3055,12 @@
prefs.setPreferredViewPeriod("week");
prefs.setHour24(getSyspars().getDefaultUserHour24());
+ PrincipalInfo pi = getDirectories().getPrincipalInfo(user.getAccount());
+ if (pi != null) {
+ prefs.setScheduleAutoRespond(pi.whoType == Ace.whoTypeResource);
+ }
+
+ prefs.setScheduleAutoProcessResponses(BwPreferences.scheduleAutoProcessResponsesAccepts);
dbi.updatePreferences(prefs);
}
Modified: trunk/calsvc/src/org/bedework/calsvc/Scheduling.java
===================================================================
--- trunk/calsvc/src/org/bedework/calsvc/Scheduling.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calsvc/src/org/bedework/calsvc/Scheduling.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -45,6 +45,7 @@
import org.bedework.calfacade.exc.CalFacadeException;
import org.bedework.calfacade.svc.BwSubscription;
import org.bedework.calfacade.svc.EventInfo;
+import org.bedework.calfacade.svc.prefs.BwPreferences;
import org.bedework.calfacade.util.CalFacadeUtil;
import org.bedework.calfacade.util.Granulator;
import org.bedework.calfacade.util.Granulator.EventPeriod;
@@ -54,8 +55,6 @@
import org.bedework.icalendar.IcalTranslator;
import org.bedework.icalendar.Icalendar;
-import edu.rpi.cmt.access.Ace;
-import edu.rpi.cmt.access.PrincipalInfo;
import edu.rpi.cmt.access.PrivilegeDefs;
import net.fortuna.ical4j.model.Calendar;
@@ -357,13 +356,13 @@
}
/* Should be exactly one attendee */
- Collection atts = ev.getAttendees();
+ Collection<BwAttendee> atts = ev.getAttendees();
if ((atts == null) || (atts.size() != 1)) {
sr.errorCode = CalFacadeException.schedulingExpectOneAttendee;
return sr;
}
- BwAttendee att = (BwAttendee)atts.iterator().next();
+ BwAttendee att = atts.iterator().next();
BwCalendar inbox = ev.getCalendar();
if (inbox.getCalType() != BwCalendar.calTypeInbox) {
@@ -399,6 +398,7 @@
return forwardError;
}
*/
+
/* Look for any events with the same guid and for the time being update any
* in ordinary calendar collections. This is probably wrong.
*/
@@ -441,6 +441,67 @@
return sr;
}
+ public ScheduleResult processCancel(BwEvent ev,
+ int action,
+ BwCalendar eventCal) throws CalFacadeException {
+ ScheduleResult sr = new ScheduleResult();
+ BwCalendar inbox = ev.getCalendar();
+
+ if ((ev == null) || (ev.getScheduleMethod() != Icalendar.methodTypeCancel)) {
+ sr.errorCode = CalFacadeException.schedulingBadMethod;
+ return sr;
+ }
+
+ if (inbox.getCalType() != BwCalendar.calTypeInbox) {
+ sr.errorCode = CalFacadeException.schedulingBadSourceCalendar;
+ return sr;
+ }
+
+ if (ev.getOriginator() == null) {
+ sr.errorCode = CalFacadeException.schedulingNoOriginator;
+ return sr;
+ }
+
+ /* Look for any events with the same guid and for the time being update any
+ * in ordinary calendar collections. This is probably wrong.
+ */
+ RecurringRetrievalMode rrm =
+ new RecurringRetrievalMode(Rmode.overrides);
+
+ Collection<EventInfo> evs = svci.getEvent(null, eventCal, ev.getUid(),
+ ev.getRecurrenceId(), rrm);
+
+ if (evs.size() == 0) {
+ sr.errorCode = CalFacadeException.schedulingUnknownEvent;
+
+ /* I guess we delete event from inbox */
+ svci.deleteEvent(ev, true);
+ return sr;
+ }
+
+ for (EventInfo ei: evs) {
+ BwEvent calEv = ei.getEvent();
+
+ if (!ev.equals(calEv) && // Not the inbox event
+ (calEv.getCalendar().getCalType() == BwCalendar.calTypeCollection)) {
+ if (action == BwPreferences.scheduleAutoCancelDelete) {
+ svci.deleteEvent(calEv, true);
+ } else if (action == BwPreferences.scheduleAutoCancelSetStatus) {
+ calEv.setStatus(BwEvent.statusCancelled);
+ svci.updateEvent(calEv, null, null);
+ } else {
+ sr.errorCode = CalFacadeException.schedulingBadAction;
+ return sr;
+ }
+ }
+ }
+
+ /* Now delete processed event from inbox */
+ svci.deleteEvent(ev, true);
+
+ return sr;
+ }
+
/* (non-Javadoc)
* @see org.bedework.calsvci.SchedulingI#scheduleResponse(org.bedework.calfacade.BwEvent)
*/
@@ -819,11 +880,6 @@
null, false);
} else if (!ui.account.equals(svci.getUser().getAccount())) {
addToInbox(ui, event);
- if (!ui.autoProcess && (ui.account != null) &&
- (event.getScheduleMethod() == Icalendar.methodTypeReply)) {
- // For the moment always handle replies automatically
- ui.autoProcess = true;
- }
}
ui.status = ScheduleRecipientResult.scheduleOk;
@@ -840,10 +896,9 @@
trace("added recipient " + ui.recipient + " status = " + ui.status);
}
- if (!freeBusyRequest && ui.autoProcess) {
- if (autoSchedule != null) {
- autoSchedule.add(ui.account, ui.inboxEvent.getName(), null);
- }
+ if (!freeBusyRequest && (autoSchedule != null) &&
+ (ui.inboxEvent != null)) {
+ autoSchedule.add(ui.account, ui.inboxEvent.getName(), null);
}
}
@@ -857,8 +912,6 @@
/* Event we added to the inbox */
BwEvent inboxEvent;
-
- boolean autoProcess;
}
/* Return with deferred for external user.
@@ -886,10 +939,6 @@
}
ui.user = svci.findUser(ui.account, true);
- PrincipalInfo pi = svci.getDirectories().getPrincipalInfo(ui.account);
- if (pi != null) {
- ui.autoProcess = pi.whoType == Ace.whoTypeResource;
- }
ui.inbox = svci.getSpecialCalendar(ui.user,
BwCalendar.calTypeInbox,
Modified: trunk/calsvci/src/org/bedework/calsvci/SchedulingI.java
===================================================================
--- trunk/calsvci/src/org/bedework/calsvci/SchedulingI.java 2007-06-12 03:51:39 UTC (rev 307)
+++ trunk/calsvci/src/org/bedework/calsvci/SchedulingI.java 2007-06-13 04:03:01 UTC (rev 308)
@@ -91,6 +91,22 @@
public ScheduleResult processResponse(BwEvent ev,
BwCalendar eventCal) throws CalFacadeException;
+ /** The organizer has cancelled the meeting - or taken us (the attendee) off
+ * the list.
+ *
+ * <p>We will look for the event in the users calendar(s) and either remove it
+ * or set the status to cancelled.
+ *
+ * @param ev BwEvent object with method=CANCEL
+ * @param action Value from BwPreferences
+ * @param eventCal - if non-null where we have a copy of the meeting
+ * @return ScheduleResult
+ * @throws CalFacadeException
+ */
+ public ScheduleResult processCancel(BwEvent ev,
+ int action,
+ BwCalendar eventCal) throws CalFacadeException;
+
/** Respond to a scheduling request. The event object must have the organizer
* and a single attendee and possibly recipient set according to itip + caldav.
*
More information about the Bedework-commit
mailing list