[Bedework-commit] r507 - in trunk/calendar3: calCore/src/org/bedework/calcore/hibernate calFacade/src/org/bedework/calfacade calFacade/src/org/bedework/calfacade/base calFacade/src/org/bedework/calfacade/ifs caldav/src/edu/rpi/cct/uwcal/caldav caldav/src/edu/rpi/cct/uwcal/caldav/calquery caldav/src/edu/rpi/cct/webdav/servlet/common caldavClientApi/src/org/bedework/caldav/client caldavClientApi/src/org/bedework/caldav/client/api calsvc/src/org/bedework/calsvc calsvci/src/org/bedework/calsvci freebusyServer/src/org/bedework/freebusyServer test/caldavTestData/eg test/caldavTestData/eg/content test/src/org/bedework/tests/caldav webclient/src/org/bedework/webclient

svnadmin at bedework.org svnadmin at bedework.org
Thu May 25 09:35:03 EDT 2006


Author: douglm
Date: 2006-05-25 09:34:51 -0400 (Thu, 25 May 2006)
New Revision: 507

Added:
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CalDavOptionsMethod.java
   trunk/calendar3/test/caldavTestData/eg/eg22.test
Modified:
   trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java
   trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Events.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/BwEvent.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/BwFreeBusyComponent.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeException.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeUtil.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/base/CalintfBase.java
   trunk/calendar3/calFacade/src/org/bedework/calfacade/ifs/Calintf.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWIntf.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWServlet.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBwNode.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavCalNode.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/MkcalendarMethod.java
   trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/calquery/FreeBusyQuery.java
   trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/OptionsMethod.java
   trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/PropPatchMethod.java
   trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/CalintfCaldavImpl.java
   trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/api/CaldavClientIo.java
   trunk/calendar3/calsvc/src/org/bedework/calsvc/CalSvc.java
   trunk/calendar3/calsvci/src/org/bedework/calsvci/CalSvcI.java
   trunk/calendar3/freebusyServer/src/org/bedework/freebusyServer/FreeBusyAggregator.java
   trunk/calendar3/test/caldavTestData/eg/content/eg02.xml
   trunk/calendar3/test/caldavTestData/eg/content/eg20.xml
   trunk/calendar3/test/caldavTestData/eg/eg12.test
   trunk/calendar3/test/caldavTestData/eg/eg16.test
   trunk/calendar3/test/caldavTestData/eg/eg17.test
   trunk/calendar3/test/src/org/bedework/tests/caldav/Req.java
   trunk/calendar3/test/src/org/bedework/tests/caldav/TestCalDav.java
   trunk/calendar3/webclient/src/org/bedework/webclient/BwFreeBusyAction.java
Log:
Mostly fixes to caldav for the calconnect interop.

Some restructuring to free/busy code and rearrangement of Calintf

Modified: trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java
===================================================================
--- trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -61,8 +61,12 @@
 import org.bedework.calfacade.BwCalendar;
 import org.bedework.calfacade.BwCategory;
 import org.bedework.calfacade.BwDateTime;
+import org.bedework.calfacade.BwDuration;
 import org.bedework.calfacade.BwEvent;
+import org.bedework.calfacade.BwFreeBusy;
+import org.bedework.calfacade.BwFreeBusyComponent;
 import org.bedework.calfacade.BwLocation;
+import org.bedework.calfacade.BwPrincipal;
 import org.bedework.calfacade.BwRWStats;
 import org.bedework.calfacade.BwSponsor;
 import org.bedework.calfacade.BwStats;
@@ -75,23 +79,30 @@
 import org.bedework.calfacade.CalFacadeAccessException;
 import org.bedework.calfacade.CalFacadeDefs;
 import org.bedework.calfacade.CalFacadeException;
+import org.bedework.calfacade.CalFacadeUtil;
 import org.bedework.calfacade.CoreEventInfo;
+import org.bedework.calfacade.CalFacadeUtil.EventPeriod;
+import org.bedework.calfacade.CalFacadeUtil.GetPeriodsPars;
 import org.bedework.calfacade.base.BwShareableDbentity;
+import org.bedework.calfacade.base.CalintfBase;
 import org.bedework.calfacade.filter.BwFilter;
 import org.bedework.calfacade.ifs.CalTimezones;
-import org.bedework.calfacade.ifs.Calintf;
 import org.bedework.calfacade.ifs.CalintfInfo;
 import org.bedework.calfacade.ifs.EventsI;
 import org.bedework.calfacade.ifs.Groups;
+import org.bedework.calfacade.svc.EventInfo;
 import org.bedework.icalendar.IcalTranslator;
 
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.TreeSet;
 
 import net.fortuna.ical4j.model.Calendar;
 import net.fortuna.ical4j.model.Component;
+import net.fortuna.ical4j.model.DateTime;
+import net.fortuna.ical4j.model.Period;
 import net.fortuna.ical4j.model.component.VTimeZone;
 
 import org.apache.log4j.Logger;
@@ -130,9 +141,7 @@
  *
  * @author Mike Douglass   douglm at rpi.edu
  */
-public class CalintfImpl implements Calintf, PrivilegeDefs {
-  private boolean debug;
-
+public class CalintfImpl extends CalintfBase implements PrivilegeDefs {
   private BwSystem syspars;
 
   private BwStats stats = new BwRWStats();
@@ -149,21 +158,6 @@
    */
   private AccessUtil access;
 
-  /** Ensure we don't open while open
-   */
-  private boolean isOpen;
-
-  /* * This is all the personal calendars modified while the current transaction
-   *  has been in progress. Just before commit we update the lastmod off all
-   *  the users on this list.
-   * /
-  private Vector personalModified;
-  */
-
-  /** User for whom we maintain this facade
-   */
-  private BwUser user;
-
   private EventsI events;
 
   private Calendars calendars;
@@ -174,12 +168,6 @@
 
   private EventProperties sponsors;
 
-  private int currentMode = CalintfUtil.guestMode;
-
-  /** Non-null if this is for synchronization. Identifies the client end.
-   */
-  private String synchId;
-
   /** Prevent updates.
    */
   //sprivate boolean readOnly;
@@ -212,11 +200,6 @@
     }
   }
 
-  private transient Logger log;
-
-  /** When we were created for debugging */
-  private Timestamp objTimestamp;
-
   /* ====================================================================
    *                   initialisation
    * ==================================================================== */
@@ -224,13 +207,16 @@
   /* (non-Javadoc)
    * @see org.bedework.calfacade.Calintf#init(org.bedework.calfacade.BwUser, java.lang.String, boolean, boolean, boolean, java.lang.String, boolean)
    */
-  public boolean init(String authenticatedUser,
+  public boolean init(String url,
+                      String authenticatedUser,
                       String user,
                       boolean publicAdmin,
                       Groups groups,
                       String synchId,
                       boolean debug) throws CalFacadeException {
-    this.debug = debug;
+    super.init(url, authenticatedUser, user, publicAdmin,
+               groups, synchId, debug);
+
     boolean userCreated = false;
 
     BwUser authUser;
@@ -238,11 +224,6 @@
     try {
       access = new AccessUtil(debug);
 
-      objTimestamp = new Timestamp(System.currentTimeMillis());
-
-      this.synchId = synchId;
-      log = Logger.getLogger(getClass());
-
       if ((synchId != null) && publicAdmin) {
         throw new CalFacadeException("synch only valid for non admin");
       }
@@ -326,6 +307,15 @@
     return userCreated;
   }
 
+  public void logon(BwUser val) throws CalFacadeException {
+    checkOpen();
+    Timestamp now = new Timestamp(System.currentTimeMillis());
+
+    val.setLogon(now);
+    val.setLastAccess(now);
+    sess.update(val);
+  }
+
   public void setSuperUser(boolean val) {
     access.setSuperUser(val);
   }
@@ -420,32 +410,13 @@
     return info;
   }
 
-  public boolean getDebug() throws CalFacadeException {
-    return debug;
-  }
-
-  public void setUser(String val) throws CalFacadeException {
-    refreshEvents();
-
-    user = getUser(val);
-    if (this.user == null) {
-      throw new CalFacadeException("User " + val + " does not exist.");
-    }
-
-    logon(user);
-
-    if (debug) {
-      log.debug("User " + val + " set in calintf");
-    }
-  }
-
   /* ====================================================================
    *                   Misc methods
    * ==================================================================== */
 
   public void flushAll() throws CalFacadeException {
     if (debug) {
-      log.debug("flushAll for " + objTimestamp);
+      debug("flushAll for " + objTimestamp);
     }
     if (sess == null) {
       return;
@@ -471,12 +442,12 @@
 
     if (sess == null) {
       if (debug) {
-        log.debug("New hibernate session for " + objTimestamp);
+        debug("New hibernate session for " + objTimestamp);
       }
-      sess = new HibSession(sessFactory, log);
+      sess = new HibSession(sessFactory, getLogger());
     } else {
       if (debug) {
-        log.debug("Reconnect hibernate session for " + objTimestamp);
+        debug("Reconnect hibernate session for " + objTimestamp);
       }
       sess.reconnect();
     }
@@ -491,13 +462,13 @@
   public synchronized void close() throws CalFacadeException {
     if (!isOpen) {
       if (debug) {
-        log.debug("Close for " + objTimestamp + " closed session");
+        debug("Close for " + objTimestamp + " closed session");
       }
       return;
     }
 
     if (debug) {
-      log.debug("Close for " + objTimestamp);
+      debug("Close for " + objTimestamp);
     }
 
     try {
@@ -525,7 +496,7 @@
     checkOpen();
 //    sess.close();
     if (debug) {
-      log.debug("Begin transaction for " + objTimestamp);
+      debug("Begin transaction for " + objTimestamp);
     }
     sess.beginTransaction();
   }
@@ -534,7 +505,7 @@
     checkOpen();
 
     if (debug) {
-      log.debug("End transaction for " + objTimestamp);
+      debug("End transaction for " + objTimestamp);
     }
 
     /* Update the lastmods for any changed users
@@ -604,10 +575,6 @@
    *                   Users
    * ==================================================================== */
 
-  public BwUser getUser() throws CalFacadeException {
-    return user;
-  }
-
   public BwUser getUser(int id) throws CalFacadeException {
     checkOpen();
     StringBuffer q = new StringBuffer();
@@ -655,10 +622,6 @@
     sess.save(user);
   }
 
-  public void updateUser() throws CalFacadeException {
-    updateUser(getUser());
-  }
-
   public void updateUser(BwUser user) throws CalFacadeException {
     checkOpen();
     sess.update(user);
@@ -682,15 +645,6 @@
     throw new CalFacadeException("Unimplemented");
   }*/
 
-  private void logon(BwUser val) throws CalFacadeException {
-    checkOpen();
-    Timestamp now = new Timestamp(System.currentTimeMillis());
-
-    val.setLogon(now);
-    val.setLastAccess(now);
-    sess.update(val);
-  }
-
   /* ====================================================================
    *                   Access
    * ==================================================================== */
@@ -1081,6 +1035,204 @@
   }
 
   /* ====================================================================
+   *                   Free busy
+   * ==================================================================== */
+
+  public BwFreeBusy getFreeBusy(BwCalendar cal, BwPrincipal who,
+                                BwDateTime start, BwDateTime end,
+                                BwDuration granularity,
+                                boolean returnAll,
+                                boolean ignoreTransparency)
+          throws CalFacadeException {
+    if (!(who instanceof BwUser)) {
+      throw new CalFacadeException("Unsupported: non user principal for free-busy");
+    }
+
+    Collection events = getFreeBusyEntities(cal, start, end, ignoreTransparency);
+    BwFreeBusy fb = new BwFreeBusy(who, start, end);
+
+    try {
+      if (granularity != null) {
+        // chunked.
+        GetPeriodsPars gpp = new GetPeriodsPars();
+
+        gpp.events = events;
+        gpp.startDt = start;
+        gpp.dur = granularity;
+        gpp.tzcache = getTimezones();
+
+        BwFreeBusyComponent fbc = null;
+
+        if (!returnAll) {
+          // One component
+          fbc = new BwFreeBusyComponent();
+          fb.addTime(fbc);
+        }
+
+        int limit = 10000; // XXX do this better
+
+        /* endDt is null first time through, then represents end of last
+         * segment.
+         */
+        while ((gpp.endDt == null) || (gpp.endDt.before(end))) {
+          //if (debug) {
+          //  trace("gpp.startDt=" + gpp.startDt + " end=" + end);
+          //}
+          if (limit < 0) {
+            throw new CalFacadeException("org.bedework.svci.limit.exceeded");
+          }
+          limit--;
+
+          Collection periodEvents = CalFacadeUtil.getPeriodsEvents(gpp);
+
+          if (returnAll) {
+            fbc = new BwFreeBusyComponent();
+            fb.addTime(fbc);
+
+            DateTime psdt = new DateTime(gpp.startDt.getDtval());
+            DateTime pedt = new DateTime(gpp.endDt.getDtval());
+
+            psdt.setUtc(true);
+            pedt.setUtc(true);
+            fbc.addPeriod(new Period(psdt, pedt));
+            if (periodEvents.size() == 0) {
+              fbc.setType(BwFreeBusyComponent.typeFree);
+            }
+          } else if (periodEvents.size() != 0) {
+            /* Some events fall in the period. Add an entry.
+             * We eliminated cancelled events earler. Now we should set the
+             * free/busy type based on the events status.
+             */
+
+            DateTime psdt = new DateTime(gpp.startDt.getDtval());
+            DateTime pedt = new DateTime(gpp.endDt.getDtval());
+
+            psdt.setUtc(true);
+            pedt.setUtc(true);
+
+            if (fbc == null) {
+              fbc = new BwFreeBusyComponent();
+              fb.addTime(fbc);
+            }
+
+            fbc.addPeriod(new Period(psdt, pedt));
+          }
+        }
+
+        return fb;
+      }
+
+      Iterator it = events.iterator();
+
+      TreeSet eventPeriods = new TreeSet();
+
+      while (it.hasNext()) {
+        EventInfo ei = (EventInfo)it.next();
+        BwEvent ev = ei.getEvent();
+
+        if (BwEvent.statusCancelled.equals(ev.getStatus())) {
+          // Ignore this one.
+          continue;
+        }
+
+        // Ignore if times were specified and this event is outside the times
+
+        BwDateTime estart = ev.getDtstart();
+        BwDateTime eend = ev.getDtend();
+
+        /* Don't report out of the requested period */
+
+        String dstart;
+        String dend;
+
+        if (estart.before(start)) {
+          dstart = start.getDtval();
+        } else {
+          dstart = estart.getDtval();
+        }
+
+        if (eend.after(end)) {
+          dend = end.getDtval();
+        } else {
+          dend = eend.getDtval();
+        }
+
+        DateTime psdt = new DateTime(dstart);
+        DateTime pedt = new DateTime(dend);
+
+        psdt.setUtc(true);
+        pedt.setUtc(true);
+
+        int type = BwFreeBusyComponent.typeBusy;
+
+        if (BwEvent.statusTentative.equals(ev.getStatus())) {
+          type = BwFreeBusyComponent.typeBusyTentative;
+       }
+
+        eventPeriods.add(new EventPeriod(psdt, pedt, type));
+      }
+
+      /* iterate through the sorted periods combining them where they are
+       adjacent or overlap */
+
+      Period p = null;
+
+      /* For the moment just build a single BwFreeBusyComponent
+       */
+      BwFreeBusyComponent fbc = null;
+      int lastType = 0;
+
+      it = eventPeriods.iterator();
+      while (it.hasNext()) {
+        EventPeriod ep = (EventPeriod)it.next();
+
+        if (debug) {
+          trace(ep.toString());
+        }
+
+        if (p == null) {
+          p = new Period(ep.getStart(), ep.getEnd());
+          lastType = ep.getType();
+        } else if ((lastType != ep.getType()) || ep.getStart().after(p.getEnd())) {
+          // Non adjacent periods
+          if (fbc == null) {
+            fbc = new BwFreeBusyComponent();
+            fbc.setType(lastType);
+            fb.addTime(fbc);
+          }
+          fbc.addPeriod(p);
+
+          if (lastType != ep.getType()) {
+            fbc = null;
+          }
+
+          p = new Period(ep.getStart(), ep.getEnd());
+          lastType = ep.getType();
+        } else if (ep.getEnd().after(p.getEnd())) {
+          // Extend the current period
+          p = new Period(p.getStart(), ep.getEnd());
+        } // else it falls within the existing period
+      }
+
+      if (p != null) {
+        if ((fbc == null) || (lastType != fbc.getType())) {
+          fbc = new BwFreeBusyComponent();
+          fbc.setType(lastType);
+          fb.addTime(fbc);
+        }
+        fbc.addPeriod(p);
+      }
+    } catch (Throwable t) {
+      if (debug) {
+        error(t);
+      }
+      throw new CalFacadeException(t);
+    }
+
+    return fb;
+  }
+
+  /* ====================================================================
    *                   Events
    * ==================================================================== */
 
@@ -1341,24 +1493,38 @@
    *                   Private methods
    * ==================================================================== */
 
-  private void checkOpen() throws CalFacadeException {
-    if (!isOpen) {
-      throw new CalFacadeException("Calintf call when closed");
-    }
-  }
+  private Collection getFreeBusyEntities(BwCalendar cal,
+                                         BwDateTime start, BwDateTime end,
+                                         boolean ignoreTransparency)
+          throws CalFacadeException {
+    Collection evs = getEvents(cal, null, start, end,
+                               CalFacadeDefs.retrieveRecurExpanded, true,
+                               true);
 
-  /* Get a logger for messages
-   */
-  private Logger getLogger() {
-    if (log == null) {
-      log = Logger.getLogger(this.getClass());
+    // Filter out transparent and cancelled events
+    Iterator evit = evs.iterator();
+
+    Collection events = new TreeSet();
+
+    while (evit.hasNext()) {
+      EventInfo ei = (EventInfo)evit.next();
+      BwEvent ev = ei.getEvent();
+
+      if (!ignoreTransparency &&
+          BwEvent.transparencyTransparent.equals(ev.getTransparency())) {
+        // Ignore this one.
+        continue;
+      }
+
+      if (BwEvent.statusCancelled.equals(ev.getStatus())) {
+        // Ignore this one.
+        continue;
+      }
+
+      events.add(ei);
     }
 
-    return log;
+    return events;
   }
-
-  private void trace(String msg) {
-    getLogger().debug(msg);
-  }
 }
 

Modified: trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Events.java
===================================================================
--- trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Events.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Events.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -1091,6 +1091,9 @@
       if (calendar.getCalendarCollection()) {
         // Single leaf calendar - always include
         sess.setEntity("calendar", calendar);
+        if (debug) {
+          trace("------------Using calendar " + calendar.getPath());
+        }
       } else {
         // Non leaf - add entities
         setCalendarEntities(calendar, new CalTerm(), allCalendars);
@@ -1105,6 +1108,9 @@
       if (allCalendars || (calendar.getCalType() == BwCalendar.calTypeCollection)) {
         // leaf calendar
         getSess().setEntity("calendar" + calTerm.i, calendar);
+        if (debug) {
+          trace("------------Using calendar " + calendar.getPath());
+        }
         calTerm.i++;
       }
     } else {

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/BwEvent.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/BwEvent.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/BwEvent.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -184,6 +184,16 @@
   private char endType = endTypeDate;
 
   private String link;
+
+  /** Rfc value for a confirmed meeting */
+  public static final String statusConfirmed = "CONFIRMED";
+
+  /** Rfc value for a cancelled meeting */
+  public static final String statusCancelled = "CANCELLED";
+
+  /** Rfc value for a tentative meeting */
+  public static final String statusTentative = "TENTATIVE";
+
   private String status;
   private String cost;
 
@@ -984,6 +994,7 @@
     res.setEndType(getEndType());
     res.setGuid(getGuid());
     res.setTransparency(getTransparency());
+    res.setStatus(getStatus());
 
     return res;
   }

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/BwFreeBusyComponent.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/BwFreeBusyComponent.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/BwFreeBusyComponent.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -78,7 +78,7 @@
   /** tentative busy time */
   public static final int typeBusyTentative = 3;
 
-  private int type;
+  private int type = typeBusy;
 
   /** Collection of Period
    */

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeException.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeException.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeException.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -61,23 +61,23 @@
   /* Property names used as message value. These should be used to
    * retrieve a localized message and can also be used to identify the
    * cause of the exception.
-   * 
+   *
    * Every CalFacadeException should have one of these as the getMessage()
    * value.
    */
-  
+
   /* ****************** Admin groups ****************************** */
-  
+
   /** The admin group already exists */
   public static final String duplicateAdminGroup =
       "org.bedework.exception.duplicateadmingroup";
-  
+
   /** The admin group is already on the path to the root (makes a loop) */
   public static final String alreadyOnAdminGroupPath =
       "org.bedework.exception.alreadyonadmingrouppath";
 
   /* ****************** Calendars ****************************** */
-  
+
   /** Couldn't find calendar */
   public static final String calendarNotFound =
       "org.bedework.exception.calendarnotfound";
@@ -99,7 +99,7 @@
       "org.bedework.exception.cannotdeletecalendarroot";
 
   /* ****************** Subscriptions ****************************** */
-  
+
   /** Somebody tried to create a duplicate subscription */
   public static final String duplicateSubscription =
       "org.bedework.exception.duplicatesubscription";
@@ -108,22 +108,28 @@
   public static final String endAndDuration =
       "org.bedework.exception.ical.endandduration";
 
+  /* ****************** Users ****************************** */
+
+  /** No such account */
+  public static final String noSuchAccount =
+      "org.bedework.exception.nosuchaccount";
+
   /* ****************** Events ****************************** */
-  
+
   /** The guid for this event already exists */
   public static final String duplicateGuid =
       "org.bedework.exception.duplicateguid";
 
   /* ****************** Timezones ****************************** */
-  
+
   /** Error reading timezones */
   public static final String timezonesReadError =
       "org.bedework.error.timezones.readerror";
-  
+
   /** Unknown timezones */
   public static final String unknownTimezone =
       "org.bedework.error.unknown.timezone";
-  
+
   /** Bad date */
   public static final String badDate =
       "org.bedework.error.bad.date";
@@ -133,7 +139,7 @@
   /** */
   public static final String illegalObjectClass =
       "org.bedework.exception.illegalobjectclass";
-  
+
   private String extra;
 
   /** Constructor

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeUtil.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeUtil.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/CalFacadeUtil.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -56,6 +56,7 @@
 import org.bedework.calfacade.ifs.CalTimezones;
 import org.bedework.calfacade.svc.EventInfo;
 
+import net.fortuna.ical4j.model.DateTime;
 import net.fortuna.ical4j.model.Parameter;
 import net.fortuna.ical4j.model.ParameterList;
 import net.fortuna.ical4j.model.Property;
@@ -670,14 +671,11 @@
     //  debugMsg("Did UTC stuff in " + (System.currentTimeMillis() - millis));
     //}
 
+    EntityRange er = new EntityRange();
     Iterator it = pars.events.iterator();
     while (it.hasNext()) {
-      EventInfo ei = (EventInfo)it.next();
-      BwEvent ev = ei.getEvent();
+      er.setEntity(it.next());
 
-      String evStart = ev.getDtstart().getDate();
-      String evEnd = ev.getDtend().getDate();
-
       /* Event is within range if:
          1.   (((evStart <= :start) and (evEnd > :start)) or
          2.    ((evStart >= :start) and (evStart < :end)) or
@@ -687,15 +685,15 @@
          3.    ((evEnd > :start) and (evEnd < :end)))
       */
 
-      int evstSt = evStart.compareTo(start);
-      int evendSt = evEnd.compareTo(start);
+      int evstSt = er.start.compareTo(start);
+      int evendSt = er.end.compareTo(start);
 
       //debugMsg("                   event " + evStart + " to " + evEnd);
 
       if (((evstSt <= 0) && (evendSt > 0)) ||
-          ((evstSt >= 0) && (evStart.compareTo(end) < 0)) ||
+          ((evstSt >= 0) && (er.start.compareTo(end) < 0)) ||
           //((evendSt > 0) && (evEnd.compareTo(end) <= 0))) {
-          ((evendSt > 0) && (evEnd.compareTo(end) < 0))) {
+          ((evendSt > 0) && (er.end.compareTo(end) < 0))) {
         // Passed the tests.
         /*
         if (debug) {
@@ -703,7 +701,7 @@
                    " with dates " + evStart + "-" + evEnd +
                    ": " + ev.getSummary());
         }*/
-        al.add(ei);
+        al.add(er.entity);
       }
     }
 
@@ -730,5 +728,124 @@
 
     return "0" + String.valueOf(val);
   }
+
+  private static class EntityRange {
+    Object entity;
+
+    String start;
+    String end;
+
+    void setEntity(Object o) throws CalFacadeException {
+      entity = o;
+
+      if (o instanceof EventInfo) {
+        EventInfo ei = (EventInfo)o;
+        BwEvent ev = ei.getEvent();
+
+        start = ev.getDtstart().getDate();
+        start = ev.getDtend().getDate();
+
+        return;
+      }
+
+      if (o instanceof EventPeriod) {
+        EventPeriod ep = (EventPeriod)o;
+
+        start = String.valueOf(ep.getStart());
+        start = String.valueOf(ep.getEnd());
+
+        return;
+      }
+
+      start = null;
+      end = null;
+    }
+  }
+
+  /**
+   *
+   */
+  public static class EventPeriod implements Comparable {
+    private DateTime start;
+    private DateTime end;
+    private int type;  // from BwFreeBusyComponent
+
+    /** Constructor
+     *
+     * @param start
+     * @param end
+     * @param type
+     */
+    public EventPeriod(DateTime start, DateTime end, int type) {
+      this.start = start;
+      this.end = end;
+      this.type = type;
+    }
+
+    /**
+     * @return DateTime
+     */
+    public DateTime getStart() {
+      return start;
+    }
+
+    /**
+     * @return DateTime
+     */
+    public DateTime getEnd() {
+      return end;
+    }
+
+    /**
+     * @return int
+     */
+    public int getType() {
+      return type;
+    }
+
+    public int compareTo(Object o) {
+      if (!(o instanceof EventPeriod)) {
+        return -1;
+      }
+
+      EventPeriod that = (EventPeriod)o;
+
+      /* Sort by type first */
+      if (type < that.type) {
+        return -1;
+      }
+
+      if (type > that.type) {
+        return 1;
+      }
+
+      int res = start.compareTo(that.start);
+      if (res != 0) {
+        return res;
+      }
+
+      return end.compareTo(that.end);
+    }
+
+    public boolean equals(Object o) {
+      return compareTo(o) == 0;
+    }
+
+    public int hashCode() {
+      return 7 * (type + 1) * (start.hashCode() + 1) * (end.hashCode() + 1);
+    }
+
+    public String toString() {
+      StringBuffer sb = new StringBuffer("EventPeriod{start=");
+
+      sb.append(start);
+      sb.append(", end=");
+      sb.append(end);
+      sb.append(", type=");
+      sb.append(type);
+      sb.append("}");
+
+      return sb.toString();
+    }
+  }
 }
-

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/base/CalintfBase.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/base/CalintfBase.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/base/CalintfBase.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -54,36 +54,48 @@
 package org.bedework.calfacade.base;
 
 
-import org.bedework.calfacade.BwAlarm;
-import org.bedework.calfacade.BwCalendar;
-import org.bedework.calfacade.BwCategory;
-import org.bedework.calfacade.BwDateTime;
-import org.bedework.calfacade.BwEvent;
-import org.bedework.calfacade.BwLocation;
-import org.bedework.calfacade.BwSponsor;
-import org.bedework.calfacade.BwStats;
-import org.bedework.calfacade.BwSynchInfo;
-import org.bedework.calfacade.BwSynchState;
-import org.bedework.calfacade.BwSystem;
+//import org.bedework.calfacade.BwAlarm;
+//import org.bedework.calfacade.BwCalendar;
+//import org.bedework.calfacade.BwCategory;
+//import org.bedework.calfacade.BwDateTime;
+//import org.bedework.calfacade.BwDuration;
+//import org.bedework.calfacade.BwEvent;
+//import org.bedework.calfacade.BwFreeBusy;
+//import org.bedework.calfacade.BwFreeBusyComponent;
+//import org.bedework.calfacade.BwLocation;
+//import org.bedework.calfacade.BwPrincipal;
+//import org.bedework.calfacade.BwSponsor;
+//import org.bedework.calfacade.BwStats;
+//import org.bedework.calfacade.BwSynchInfo;
+//import org.bedework.calfacade.BwSynchState;
+//import org.bedework.calfacade.BwSystem;
 import org.bedework.calfacade.BwUser;
 import org.bedework.calfacade.CalFacadeAccessException;
-import org.bedework.calfacade.CalFacadeUnimplementedException;
+//import org.bedework.calfacade.CalFacadeDefs;
+//import org.bedework.calfacade.CalFacadeUnimplementedException;
 import org.bedework.calfacade.CalFacadeException;
+//import org.bedework.calfacade.CalFacadeUtil;
 import org.bedework.calfacade.CalintfDefs;
-import org.bedework.calfacade.CoreEventInfo;
-import org.bedework.calfacade.filter.BwFilter;
-import org.bedework.calfacade.ifs.CalTimezones;
+//import org.bedework.calfacade.CoreEventInfo;
+//import org.bedework.calfacade.CalFacadeUtil.EventPeriod;
+//import org.bedework.calfacade.CalFacadeUtil.GetPeriodsPars;
+//import org.bedework.calfacade.filter.BwFilter;
+//import org.bedework.calfacade.ifs.CalTimezones;
 import org.bedework.calfacade.ifs.Calintf;
-import org.bedework.calfacade.ifs.CalintfInfo;
+//import org.bedework.calfacade.ifs.CalintfInfo;
 import org.bedework.calfacade.ifs.Groups;
+//import org.bedework.calfacade.svc.EventInfo;
 
-import edu.rpi.cct.uwcal.access.Acl.CurrentAccess;
+//import edu.rpi.cct.uwcal.access.Acl.CurrentAccess;
 
 import java.sql.Timestamp;
-import java.util.Collection;
-import java.util.TreeSet;
+//import java.util.Collection;
+//import java.util.Iterator;
+//import java.util.TreeSet;
 
-import net.fortuna.ical4j.model.component.VTimeZone;
+//import net.fortuna.ical4j.model.DateTime;
+//import net.fortuna.ical4j.model.Period;
+//import net.fortuna.ical4j.model.component.VTimeZone;
 
 import org.apache.log4j.Logger;
 
@@ -91,7 +103,9 @@
 *
 * @author Mike Douglass   douglm at rpi.edu
 */
-public class CalintfBase implements Calintf {
+public abstract class CalintfBase implements Calintf {
+  protected String url;
+
   protected boolean debug;
 
   /** When we were created for debugging */
@@ -109,7 +123,7 @@
 
   /** Ensure we don't open while open
    */
-  private boolean isOpen;
+  protected boolean isOpen;
 
   /** Ignore owner for superuser
    */
@@ -124,12 +138,14 @@
   /* (non-Javadoc)
    * @see org.bedework.calfacade.Calintf#init(org.bedework.calfacade.BwUser, java.lang.String, boolean, boolean, boolean, java.lang.String, boolean)
    */
-  public boolean init(String authenticatedUser,
+  public boolean init(String url,
+                      String authenticatedUser,
                       String user,
                       boolean publicAdmin,
                       Groups groups,
                       String synchId,
                       boolean debug) throws CalFacadeException {
+    this.url = url;
     this.debug = debug;
     boolean userCreated = false;
 
@@ -152,6 +168,11 @@
     return userCreated;
   }
 
+  public boolean getDebug() throws CalFacadeException {
+    return debug;
+  }
+
+  /*
   public void setSuperUser(boolean val) {
   }
 
@@ -159,11 +180,6 @@
     return false;
   }
 
-  /** Get the current stats
-   *
-   * @return BwStats object
-   * @throws CalFacadeException if not admin
-   */
   public BwStats getStats() throws CalFacadeException {
     return null;
   }
@@ -189,11 +205,6 @@
   public void updateSyspars(BwSystem val) throws CalFacadeException {
   }
 
-  /** Get the timezones cache object
-   *
-   * @return CalTimezones object
-   * @throws CalFacadeException if not admin
-   */
   public CalTimezones getTimezones() throws CalFacadeException {
     return null;
   }
@@ -205,17 +216,14 @@
         false      // handlesCategories
       );
   }
+  */
 
-  public boolean getDebug() throws CalFacadeException {
-    return debug;
-  }
-
   public void setUser(String val) throws CalFacadeException {
     refreshEvents();
 
     user = getUser(val);
     if (this.user == null) {
-      throw new CalFacadeException("User " + val + " does not exist.");
+      throw new CalFacadeException(CalFacadeException.noSuchAccount, val);
     }
 
     logon(user);
@@ -229,11 +237,13 @@
    *                   Misc methods
    * ==================================================================== */
 
+  /*
   public void flushAll() throws CalFacadeException {
     if (debug) {
       log.debug("flushAll for " + objTimestamp);
     }
   }
+  */
 
   /** Default implementation fails if already open and sets the open flag
    * otherwise.
@@ -268,6 +278,7 @@
     isOpen = false;
   }
 
+  /*
   public void beginTransaction() throws CalFacadeException {
     checkOpen();
   }
@@ -283,6 +294,7 @@
   public Object getDbSession() throws CalFacadeException {
     return null;
   }
+  */
 
   /* ====================================================================
    *                   General data methods
@@ -292,13 +304,12 @@
   public void refresh() throws CalFacadeException {
     checkOpen();
     sess.flush();
-  }*/
+  }
 
   public void refreshEvents() throws CalFacadeException {
     checkOpen();
   }
 
-  /*
   public void lockRead(Object val) throws CalFacadeException {
     checkOpen();
     sess.lockRead(val);
@@ -314,6 +325,7 @@
    *                   Global parameters
    * ==================================================================== */
 
+  /*
   public long getPublicLastmod() throws CalFacadeException {
     checkOpen();
     return 0; // for the moment
@@ -322,6 +334,7 @@
   public String getSysid() throws CalFacadeException {
     return "";
   }
+  */
 
   /* ====================================================================
    *                   Users
@@ -335,6 +348,7 @@
     updateUser(getUser());
   }
 
+  /*
   public void updateUser(BwUser user) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
@@ -351,7 +365,6 @@
     throw new CalFacadeUnimplementedException();
   }
 
-
   public BwUser getUser(String account) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
@@ -366,11 +379,13 @@
     checkOpen();
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Access
    * ==================================================================== */
 
+  /*
   public void changeAccess(BwShareableDbentity ent,
                            Collection aces) throws CalFacadeException {
     checkOpen();
@@ -381,11 +396,13 @@
                                    boolean returnResult) throws CalFacadeException {
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Timezones
    * ==================================================================== */
 
+  /*
   public void saveTimeZone(String tzid, VTimeZone vtz) throws CalFacadeException {
     throw new CalFacadeUnimplementedException();
   }
@@ -406,11 +423,13 @@
   public void clearPublicTimezones() throws CalFacadeException {
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Calendars and search
    * ==================================================================== */
 
+  /*
   public BwCalendar getPublicCalendars() throws CalFacadeException {
     throw new CalFacadeUnimplementedException();
   }
@@ -504,11 +523,13 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Filters and search
    * ==================================================================== */
 
+  /*
   public void setSearch(String val) throws CalFacadeException {
     checkOpen();
   }
@@ -519,7 +540,7 @@
     return null;
   }
 
-  /*
+  / *
   public BwFilter getFilter(String name) throws CalFacadeException {
     checkOpen();
     if (currentMode != CalintfUtil.guestMode) {
@@ -546,7 +567,7 @@
     sess.setInt("id", id);
 
     return (BwFilter)sess.getUnique();
-  } */
+  }
 
   public void addFilter(BwFilter val) throws CalFacadeException {
     checkOpen();
@@ -557,11 +578,13 @@
     checkOpen();
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Categories
    * ==================================================================== */
 
+  /*
   public Collection getCategories(BwUser owner, BwUser creator)
         throws CalFacadeException {
     checkOpen();
@@ -604,11 +627,13 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Locations
    * ==================================================================== */
 
+  /*
   public Collection getLocations(BwUser owner, BwUser creator)
         throws CalFacadeException {
     checkOpen();
@@ -651,11 +676,13 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Sponsors
    * ==================================================================== */
 
+  /*
   public Collection getSponsors(BwUser owner, BwUser creator)
         throws CalFacadeException {
     checkOpen();
@@ -698,11 +725,13 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Events
    * ==================================================================== */
 
+  /*
   public CoreEventInfo getEvent(int id) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
@@ -745,6 +774,7 @@
   public Collection getDeletedProxies(BwCalendar cal) throws CalFacadeException {
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                       Caldav support
@@ -752,16 +782,19 @@
    * names clients might assign to events.
    * ==================================================================== */
 
+  /*
   public Collection getEventsByName(BwCalendar cal, String val)
           throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Synchronization
    * ==================================================================== */
 
+  /*
   public BwSynchInfo getSynchInfo() throws CalFacadeException {
     checkOpen();
 
@@ -839,11 +872,13 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                       Alarms
    * ==================================================================== */
 
+  /*
   public Collection getAlarms(BwEvent event, BwUser user) throws CalFacadeException {
     checkOpen();
 
@@ -873,6 +908,7 @@
 
     throw new CalFacadeUnimplementedException();
   }
+  */
 
   /* ====================================================================
    *                   Protected methods
@@ -893,7 +929,7 @@
    */
   protected Logger getLogger() {
     if (log == null) {
-      log = Logger.getLogger(this.getClass());
+      log = Logger.getLogger(getClass());
     }
 
     return log;
@@ -903,10 +939,18 @@
     getLogger().error(msg);
   }
 
+  protected void error(Throwable t) {
+    getLogger().error(this, t);
+  }
+
   protected void trace(String msg) {
     getLogger().debug(msg);
   }
 
+  protected void debug(String msg) {
+    getLogger().debug(msg);
+  }
+
   /* Ensure the current user is not a guest.
    */
   protected void requireNotGuest() throws CalFacadeException {

Modified: trunk/calendar3/calFacade/src/org/bedework/calfacade/ifs/Calintf.java
===================================================================
--- trunk/calendar3/calFacade/src/org/bedework/calfacade/ifs/Calintf.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calFacade/src/org/bedework/calfacade/ifs/Calintf.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -54,9 +54,14 @@
 package org.bedework.calfacade.ifs;
 
 import org.bedework.calfacade.BwAlarm;
+import org.bedework.calfacade.BwCalendar;
 import org.bedework.calfacade.BwCategory;
+import org.bedework.calfacade.BwDateTime;
+import org.bedework.calfacade.BwDuration;
 import org.bedework.calfacade.BwEvent;
+import org.bedework.calfacade.BwFreeBusy;
 import org.bedework.calfacade.BwLocation;
+import org.bedework.calfacade.BwPrincipal;
 import org.bedework.calfacade.BwSponsor;
 import org.bedework.calfacade.BwStats;
 import org.bedework.calfacade.BwSynchInfo;
@@ -94,6 +99,7 @@
 public interface Calintf extends CalendarsI, EventsI {
   /** Must be called to initialise the new object.
    *
+   * @param url         String url to which we are connecting
    * @param authenticatedUser    String authenticated user of the application
    *                             or null for guest
    * @param user        String user we are acting as. If null we use authUser
@@ -105,13 +111,21 @@
    * @return boolean    true if the authUser was added to the db
    * @throws CalFacadeException
    */
-  public boolean init(String authenticatedUser,
+  public boolean init(String url,
+                      String authenticatedUser,
                       String user,
                       boolean publicAdmin,
                       Groups groups,
                       String synchId,
                       boolean debug) throws CalFacadeException;
 
+  /** Can be called after init to flag the arrival of a user.
+   *
+   * @param val       true for a super user
+   * @throws CalFacadeException
+   */
+  public void logon(BwUser val) throws CalFacadeException;
+
   /** Called after init to flag this user as a super user.
    *
    * @param val       true for a super user
@@ -693,6 +707,29 @@
   public Collection getSponsorRefs(BwSponsor val) throws CalFacadeException;
 
   /* ====================================================================
+   *                   Free busy
+   * ==================================================================== */
+
+  /**
+   * @param cal
+   * @param who
+   * @param start
+   * @param end
+   * @param granularity
+   * @param returnAll
+   * @param ignoreTransparency
+   * @return  BwFreeBusy object representing the calendar (or principals)
+   *          free/busy
+   * @throws CalFacadeException
+   */
+  public BwFreeBusy getFreeBusy(BwCalendar cal, BwPrincipal who,
+                                BwDateTime start, BwDateTime end,
+                                BwDuration granularity,
+                                boolean returnAll,
+                                boolean ignoreTransparency)
+          throws CalFacadeException;
+
+  /* ====================================================================
    *                   Synchronization
    * ==================================================================== */
 

Added: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CalDavOptionsMethod.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CalDavOptionsMethod.java	                        (rev 0)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CalDavOptionsMethod.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -0,0 +1,70 @@
+/*
+ Copyright (c) 2000-2005 University of Washington.  All rights reserved.
+
+ Redistribution and use of this distribution in source and binary forms,
+ with or without modification, are permitted provided that:
+
+   The above copyright notice and this permission notice appear in
+   all copies and supporting documentation;
+
+   The name, identifiers, and trademarks of the University of Washington
+   are not used in advertising or publicity without the express prior
+   written permission of the University of Washington;
+
+   Recipients acknowledge that this distribution is made available as a
+   research courtesy, "as is", potentially with defects, without
+   any obligation on the part of the University of Washington to
+   provide support, services, or repair;
+
+   THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR
+   IMPLIED, WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION
+   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+   PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF
+   WASHINGTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+   DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+   PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT (INCLUDING
+   NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
+   THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/* **********************************************************************
+    Copyright 2005 Rensselaer Polytechnic Institute. All worldwide rights reserved.
+
+    Redistribution and use of this distribution in source and binary forms,
+    with or without modification, are permitted provided that:
+       The above copyright notice and this permission notice appear in all
+        copies and supporting documentation;
+
+        The name, identifiers, and trademarks of Rensselaer Polytechnic
+        Institute are not used in advertising or publicity without the
+        express prior written permission of Rensselaer Polytechnic Institute;
+
+    DISCLAIMER: The software is distributed" AS IS" without any express or
+    implied warranty, including but not limited to, any implied warranties
+    of merchantability or fitness for a particular purpose or any warrant)'
+    of non-infringement of any current or pending patent rights. The authors
+    of the software make no representations about the suitability of this
+    software for any particular purpose. The entire risk as to the quality
+    and performance of the software is with the user. Should the software
+    prove defective, the user assumes the cost of all necessary servicing,
+    repair or correction. In particular, neither Rensselaer Polytechnic
+    Institute, nor the authors of the software are liable for any indirect,
+    special, consequential, or incidental damages related to the software,
+    to the maximum extent the law permits.
+*/
+package edu.rpi.cct.uwcal.caldav;
+
+import edu.rpi.cct.webdav.servlet.common.OptionsMethod;
+import edu.rpi.cct.webdav.servlet.shared.WebdavException;
+
+import javax.servlet.http.HttpServletResponse;
+
+/** Add our own dav header
+ *
+ * @author Mike Douglass   douglm at rpi.edu
+ *
+ */
+public class CalDavOptionsMethod extends OptionsMethod {
+  protected void addDavHeader(HttpServletResponse resp) throws WebdavException {
+    resp.addHeader("DAV", "1, 2, 3, access-control, calendar-access");
+  }
+}

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWIntf.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWIntf.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWIntf.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -1037,13 +1037,63 @@
 
     try {
       /* Deal with webdav properties */
-      if (!ns.equals(CaldavDefs.caldavNamespace)) {
+      if ((!ns.equals(CaldavDefs.caldavNamespace) &&
+          !ns.equals(CaldavDefs.icalNamespace))) {
         // Not ours
         super.generatePropValue(node, pr);
         return;
       }
 
-      if (tag.equals(CaldavTags.calendarDescription)) {
+      // XXX Change this to have node class generate???
+      if (tag.equals(ICalTags.summary)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.dtstart)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.dtend)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.duration)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.transp)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.due)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.status)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.uid)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.sequence)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.hasRecurrence)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.hasAlarm)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(ICalTags.hasAttachment)) {
+        openPropstat();
+        xml.property(tag, pr.getPval());
+        closePropstat();
+      } else if (tag.equals(CaldavTags.calendarDescription)) {
         if ((cal != null) && (cal.getDescription() != null)) {
           // XXX lang
           openPropstat();
@@ -1394,6 +1444,10 @@
         return null;
       }
 
+      if (uri.endsWith("/")) {
+        uri = uri.substring(0, uri.length() - 1);
+      }
+
       String[] ss = uri.split("/");
       int pathLength = ss.length - 1;  // First element is empty string
       String namePart = null;

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWServlet.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWServlet.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWServlet.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -106,6 +106,7 @@
 
     // Replace methods
     methods.put("MKCALENDAR", new MkcalendarMethod());
+    methods.put("OPTIONS", new CalDavOptionsMethod());
     methods.put("REPORT", new ReportMethod());
   }
 

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBwNode.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBwNode.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBwNode.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -62,8 +62,8 @@
 
 import java.io.StringReader;
 import java.io.Reader;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Vector;
 
 /** Class to represent a caldav node.
  *
@@ -132,7 +132,7 @@
    * @throws WebdavIntfException
    */
   public Collection getProperties(String ns) throws WebdavIntfException {
-    return new Vector();
+    return new ArrayList();
   }
 
   /** Returns an InputStream for the content.

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavCalNode.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavCalNode.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavCalNode.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -155,7 +155,7 @@
     try {
       VFreeBusy vfreeBusy = VFreeUtil.toVFreeBusy(fb);
       if (vfreeBusy != null) {
-        ical = new Calendar();
+        ical = IcalTranslator.newIcal();
         ical.getComponents().add(vfreeBusy);
         vfreeBusyString = ical.toString();
         contentLen = vfreeBusyString.length();

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/MkcalendarMethod.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/MkcalendarMethod.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/MkcalendarMethod.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -57,10 +57,8 @@
 import org.bedework.davdefs.CaldavTags;
 
 import edu.rpi.cct.webdav.servlet.common.PropPatchMethod;
-import edu.rpi.cct.webdav.servlet.common.Property;
 import edu.rpi.cct.webdav.servlet.shared.WebdavBadRequest;
 import edu.rpi.cct.webdav.servlet.shared.WebdavException;
-import edu.rpi.cct.webdav.servlet.shared.WebdavNsIntf;
 import edu.rpi.cct.webdav.servlet.shared.WebdavNsNode;
 
 import java.util.Collection;
@@ -113,8 +111,6 @@
   protected void processDoc(HttpServletRequest req,
                             Document doc) throws WebdavException {
     try {
-      WebdavNsIntf intf = getNsIntf();
-
       Element root = doc.getDocumentElement();
 
       if (!nodeMatches(root, CaldavTags.mkcalendar)) {
@@ -133,7 +129,11 @@
 
         Iterator pit = sr.iterator();
         while (pit.hasNext()) {
-          Property prop = (Property)pit.next();
+          Element prop = (Element)pit.next();
+
+          if (nodeMatches(prop, CaldavTags.calendarDescription)) {
+            // Some way to set description
+          }
         }
       }
     } catch (WebdavException wde) {

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/calquery/FreeBusyQuery.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/calquery/FreeBusyQuery.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/calquery/FreeBusyQuery.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -136,7 +136,12 @@
       if (user == null) {
         throw WebdavIntfException.unauthorized();
       }
-      BwFreeBusy fb = svci.getFreeBusy(cal, user,
+
+      if (svci.isUserRoot(cal)) {
+        cal = null;
+      }
+
+      BwFreeBusy fb = svci.getFreeBusy(null, cal, user,
                                        timeRange.getStart(), timeRange.getEnd(),
                                        null, false);
 

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/OptionsMethod.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/OptionsMethod.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/OptionsMethod.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -51,7 +51,6 @@
     special, consequential, or incidental damages related to the software,
     to the maximum extent the law permits.
 */
-
 package edu.rpi.cct.webdav.servlet.common;
 
 import edu.rpi.cct.webdav.servlet.shared.WebdavException;
@@ -90,11 +89,7 @@
         return;
       }
 
-      if (getNsIntf().getAccessControl()) {
-        resp.addHeader("DAV", "1, 2, access-control");
-      } else {
-        resp.addHeader("DAV", "1, 2");
-      }
+      addDavHeader(resp);
 
       // Lisa say's we need this
       resp.addHeader("MS-Author-Via", "DAV");
@@ -118,5 +113,13 @@
       throw new WebdavException(t);
     }
   }
+
+  protected void addDavHeader(HttpServletResponse resp) throws WebdavException {
+    if (getNsIntf().getAccessControl()) {
+      resp.addHeader("DAV", "1, 2, 3, access-control");
+    } else {
+      resp.addHeader("DAV", "1, 2, 3");
+    }
+  }
 }
 

Modified: trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/PropPatchMethod.java
===================================================================
--- trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/PropPatchMethod.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldav/src/edu/rpi/cct/webdav/servlet/common/PropPatchMethod.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -155,18 +155,18 @@
     for (int i = 0; i < props.length; i++) {
       Element prop = props[i];
 
-      String ns = prop.getNamespaceURI();
-      String nm = prop.getLocalName();
       String value = getElementContent(prop);
 
       if (remove && (value != null)) {
         throw new WebdavBadRequest();
       }
 
-      plist.add(new Property(ns, nm, value));
+      plist.add(prop);
 
       if (debug) {
-        trace("reqtype: " + nm + " ns: " + ns + " value: " + value);
+        trace("reqtype: " + prop.getLocalName() +
+              " ns: " + prop.getNamespaceURI() +
+              " value: " + value);
       }
     }
   }

Modified: trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/CalintfCaldavImpl.java
===================================================================
--- trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/CalintfCaldavImpl.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/CalintfCaldavImpl.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -58,10 +58,14 @@
 import org.bedework.calfacade.BwCalendar;
 import org.bedework.calfacade.BwCategory;
 import org.bedework.calfacade.BwDateTime;
+import org.bedework.calfacade.BwDuration;
 import org.bedework.calfacade.BwEvent;
+import org.bedework.calfacade.BwFreeBusy;
 import org.bedework.calfacade.BwLocation;
+import org.bedework.calfacade.BwPrincipal;
 import org.bedework.calfacade.BwSponsor;
 import org.bedework.calfacade.BwStats;
+import org.bedework.calfacade.BwSystem;
 import org.bedework.calfacade.CoreEventInfo;
 //import org.bedework.calfacade.BwSynchData;
 import org.bedework.calfacade.BwSynchInfo;
@@ -109,13 +113,14 @@
   /* (non-Javadoc)
    * @see org.bedework.calfacade.Calintf#init(org.bedework.calfacade.BwUser, java.lang.String, boolean, boolean, boolean, java.lang.String, boolean)
    */
-  public boolean init(String authenticatedUser,
+  public boolean init(String url,
+                      String authenticatedUser,
                       String user,
                       boolean publicAdmin,
                       Groups groups,
                       String synchId,
                       boolean debug) throws CalFacadeException {
-    boolean userAdded = super.init(authenticatedUser, user, publicAdmin,
+    boolean userAdded = super.init(url, authenticatedUser, user, publicAdmin,
                                    groups, synchId, debug);
 
     if (httpManager == null) {
@@ -129,20 +134,43 @@
     return userAdded;
   }
 
-  /** Get the current stats
-   *
-   * @return BwStats object
-   * @throws CalFacadeException if not admin
-   */
+  public void logon(BwUser val) throws CalFacadeException {
+    checkOpen();
+    throw new CalFacadeUnimplementedException();
+  }
+
+  public void setSuperUser(boolean val) {
+  }
+
+  public boolean getSuperUser() {
+    return false;
+  }
+
   public BwStats getStats() throws CalFacadeException {
     return null;
   }
 
-  /** Get the timezones cache object
-   *
-   * @return CalTimezones object
-   * @throws CalFacadeException if not admin
-   */
+  public void setDbStatsEnabled(boolean enable) throws CalFacadeException {
+  }
+
+  public boolean getDbStatsEnabled() throws CalFacadeException {
+    return false;
+  }
+
+  public void dumpDbStats() throws CalFacadeException {
+  }
+
+  public Collection getDbStats() throws CalFacadeException {
+    return null;
+  }
+
+  public BwSystem getSyspars() throws CalFacadeException {
+    return null;
+  }
+
+  public void updateSyspars(BwSystem val) throws CalFacadeException {
+  }
+
   public CalTimezones getTimezones() throws CalFacadeException {
     return null;
   }
@@ -151,10 +179,6 @@
     return info;
   }
 
-  public boolean getDebug() throws CalFacadeException {
-    return debug;
-  }
-
   public void setUser(String val) throws CalFacadeException {
     refreshEvents();
 
@@ -180,14 +204,6 @@
     }
   }
 
-  public synchronized void open() throws CalFacadeException {
-    super.open();
-  }
-
-  public synchronized void close() throws CalFacadeException {
-    super.close();
-  }
-
   public void beginTransaction() throws CalFacadeException {
     checkOpen();
   }
@@ -208,28 +224,10 @@
    *                   General data methods
    * ==================================================================== */
 
-  /*
-  public void refresh() throws CalFacadeException {
-    checkOpen();
-    sess.flush();
-  }*/
-
   public void refreshEvents() throws CalFacadeException {
     checkOpen();
   }
 
-  /*
-  public void lockRead(Object val) throws CalFacadeException {
-    checkOpen();
-    sess.lockRead(val);
-  }
-
-  public void lockMod(Object val) throws CalFacadeException {
-    checkOpen();
-    sess.lockUpdate(val);
-  }
-  */
-
   /* ====================================================================
    *                   Global parameters
    * ==================================================================== */
@@ -247,44 +245,29 @@
    *                   Users
    * ==================================================================== */
 
-  public BwUser getUser() throws CalFacadeException {
-    return user;
-  }
-
-  public BwUser getUser(int id) throws CalFacadeException {
+  public void updateUser(BwUser user) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
   }
 
+  public void addUser(BwUser user) throws CalFacadeException {
+    checkOpen();
 
-  public BwUser getUser(String user) throws CalFacadeException {
-    checkOpen();
     throw new CalFacadeUnimplementedException();
   }
 
-  public void addUser(BwUser user) throws CalFacadeException {
+  public BwUser getUser(int id) throws CalFacadeException {
     checkOpen();
-
     throw new CalFacadeUnimplementedException();
   }
 
-  public void updateUser() throws CalFacadeException {
-    updateUser(getUser());
-  }
-
-  public void updateUser(BwUser user) throws CalFacadeException {
+  public BwUser getUser(String user) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
   }
 
-  /*
-  public void deleteUser(BwUser user) throws CalFacadeException {
+  public Collection getInstanceOwners() throws CalFacadeException {
     checkOpen();
-    throw new CalFacadeException("Unimplemented");
-  }*/
-
-  private void logon(BwUser val) throws CalFacadeException {
-    checkOpen();
     throw new CalFacadeUnimplementedException();
   }
 
@@ -347,6 +330,11 @@
     throw new CalFacadeUnimplementedException();
   }
 
+  public BwCalendar getCalendars(BwUser user,
+                                 int desiredAccess) throws CalFacadeException {
+    throw new CalFacadeUnimplementedException();
+  }
+
   public Collection getCalendarCollections() throws CalFacadeException {
     checkOpen();
 
@@ -388,6 +376,12 @@
     throw new CalFacadeUnimplementedException();
   }
 
+  public BwCalendar getSpecialCalendar(BwUser user,
+                                       int calType,
+                                       boolean create) throws CalFacadeException {
+    throw new CalFacadeUnimplementedException();
+  }
+
   public void addCalendar(BwCalendar val, String parentPath) throws CalFacadeException {
     checkOpen();
 
@@ -399,6 +393,12 @@
     throw new CalFacadeUnimplementedException();
   }
 
+  public void changeAccess(BwCalendar cal,
+                           Collection aces) throws CalFacadeException {
+    checkOpen();
+    throw new CalFacadeUnimplementedException();
+  }
+
   public boolean deleteCalendar(BwCalendar val) throws CalFacadeException {
     checkOpen();
     throw new CalFacadeUnimplementedException();
@@ -576,6 +576,19 @@
   }
 
   /* ====================================================================
+   *                   Free busy
+   * ==================================================================== */
+
+  public BwFreeBusy getFreeBusy(BwCalendar cal, BwPrincipal who,
+                                BwDateTime start, BwDateTime end,
+                                BwDuration granularity,
+                                boolean returnAll,
+                                boolean ignoreTransparency)
+          throws CalFacadeException {
+    throw new CalFacadeUnimplementedException();
+  }
+
+  /* ====================================================================
    *                   Events
    * ==================================================================== */
 
@@ -614,6 +627,14 @@
     throw new CalFacadeUnimplementedException();
   }
 
+  public Collection getDeletedProxies() throws CalFacadeException {
+    throw new CalFacadeUnimplementedException();
+  }
+
+  public Collection getDeletedProxies(BwCalendar cal) throws CalFacadeException {
+    throw new CalFacadeUnimplementedException();
+  }
+
   /* ====================================================================
    *                       Caldav support
    * Caldav as it stands at the moment requires that we save the arbitary
@@ -741,5 +762,9 @@
 
     throw new CalFacadeUnimplementedException();
   }
+
+  /* ====================================================================
+   *                   Free busy
+   * ==================================================================== */
 }
 

Modified: trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/api/CaldavClientIo.java
===================================================================
--- trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/api/CaldavClientIo.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/caldavClientApi/src/org/bedework/caldav/client/api/CaldavClientIo.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -56,6 +56,7 @@
 
 import org.bedework.calfacade.CalFacadeException;
 import org.bedework.http.client.caldav.CaldavClient;
+import org.bedework.http.client.DepthHttpMethod;
 import org.bedework.http.client.HttpManager;
 
 import java.io.InputStream;
@@ -134,6 +135,7 @@
    * @param method
    * @param url
    * @param hdrs
+   * @param depth
    * @param contentType
    * @param contentLen
    * @param content
@@ -141,9 +143,11 @@
    * @throws Throwable
    */
   public int sendRequest(String method, String url,
-                         Header[] hdrs, String contentType, int contentLen,
+                         Header[] hdrs, int depth,
+                         String contentType, int contentLen,
                          byte[] content) throws Throwable {
-    return sendRequest(method, url, null, null, hdrs, contentType, contentLen, content);
+    return sendRequest(method, url, null, null, hdrs, depth,
+                       contentType, contentLen, content);
   }
 
   /** Send an authenticated request to the server
@@ -153,6 +157,7 @@
    * @param user
    * @param pw
    * @param hdrs
+   * @param depth
    * @param contentType
    * @param contentLen
    * @param content
@@ -160,7 +165,8 @@
    * @throws Throwable
    */
   public int sendRequest(String method, String url, String user, String pw,
-                         Header[] hdrs, String contentType, int contentLen,
+                         Header[] hdrs, int depth,
+                         String contentType, int contentLen,
                          byte[] content) throws Throwable {
     int sz = 0;
     if (content != null) {
@@ -175,6 +181,10 @@
 
     HttpMethod meth = client.getMethod();
 
+    if (meth instanceof DepthHttpMethod) {
+      ((DepthHttpMethod)meth).setDepth(depth);
+    }
+
     if (user != null) {
       String upw = user + ":" + pw;
 

Modified: trunk/calendar3/calsvc/src/org/bedework/calsvc/CalSvc.java
===================================================================
--- trunk/calendar3/calsvc/src/org/bedework/calsvc/CalSvc.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calsvc/src/org/bedework/calsvc/CalSvc.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -729,6 +729,18 @@
     return 1; //doesn't exist
   }
 
+  public boolean isUserRoot(BwCalendar cal) throws CalFacadeException {
+    if (cal == null) {
+      return false;
+    }
+
+    String[] ss = cal.getPath().split("/");
+    int pathLength = ss.length - 1;  // First element is empty string
+
+    return (pathLength == 2) &&
+           (ss[1].equals(getSyspars().getUserCalendarRoot()));
+  }
+
   /* ====================================================================
    *                   Views
    * ==================================================================== */
@@ -1021,7 +1033,8 @@
    *                   Free busy
    * ==================================================================== */
 
-  public BwFreeBusy getFreeBusy(BwCalendar cal, BwPrincipal who,
+  public BwFreeBusy getFreeBusy(Collection subs,
+                                BwCalendar cal, BwPrincipal who,
                                 BwDateTime start, BwDateTime end,
                                 BwDuration granularity,
                                 boolean returnAll)
@@ -1031,21 +1044,10 @@
     }
 
     BwUser u = (BwUser)who;
-    Collection subs;
 
-    /* See if the calendar is a user root. */
-
-    if (cal != null) {
-      String[] ss = cal.getPath().split("/");
-      int pathLength = ss.length - 1;  // First element is empty string
-
-      if ((pathLength == 2) &&
-          (ss[1].equals(getSyspars().getUserCalendarRoot()))) {
-        cal = null;
-      }
-    }
-
-    if (cal != null) {
+    if (subs != null) {
+      // Use these
+    } else if (cal != null) {
       getCal().checkAccess(cal, PrivilegeDefs.privReadFreeBusy, false);
 
       BwSubscription sub = BwSubscription.makeSubscription(cal);
@@ -1095,6 +1097,11 @@
           continue;
         }
 
+        if (BwEvent.statusCancelled.equals(ev.getStatus())) {
+          // Ignore this one.
+          continue;
+        }
+
         events.add(ei);
       }
     }
@@ -1147,13 +1154,22 @@
               fbc.setType(BwFreeBusyComponent.typeFree);
             }
           } else if (periodEvents.size() != 0) {
-            // Some events fall in the period. Add an entry.
+            /* Some events fall in the period. Add an entry.
+             * We eliminated cancelled events earler. Now we should set the
+             * free/busy type based on the events status.
+             */
 
             DateTime psdt = new DateTime(gpp.startDt.getDtval());
             DateTime pedt = new DateTime(gpp.endDt.getDtval());
 
             psdt.setUtc(true);
             pedt.setUtc(true);
+
+            if (fbc == null) {
+              fbc = new BwFreeBusyComponent();
+              fb.addTime(fbc);
+            }
+
             fbc.addPeriod(new Period(psdt, pedt));
           }
         }
@@ -1169,6 +1185,11 @@
         EventInfo ei = (EventInfo)it.next();
         BwEvent ev = ei.getEvent();
 
+        if (BwEvent.statusCancelled.equals(ev.getStatus())) {
+          // Ignore this one.
+          continue;
+        }
+
         // Ignore if times were specified and this event is outside the times
 
         BwDateTime estart = ev.getDtstart();
@@ -1197,7 +1218,13 @@
         psdt.setUtc(true);
         pedt.setUtc(true);
 
-        eventPeriods.add(new EventPeriod(psdt, pedt));
+        int type = BwFreeBusyComponent.typeBusy;
+
+        if (BwEvent.statusTentative.equals(ev.getStatus())) {
+          type = BwFreeBusyComponent.typeBusyTentative;
+       }
+
+        eventPeriods.add(new EventPeriod(psdt, pedt, type));
       }
 
       /* iterate through the sorted periods combining them where they are
@@ -1208,20 +1235,34 @@
       /* For the moment just build a single BwFreeBusyComponent
        */
       BwFreeBusyComponent fbc = null;
+      int lastType = 0;
 
       it = eventPeriods.iterator();
       while (it.hasNext()) {
         EventPeriod ep = (EventPeriod)it.next();
 
+        if (debug) {
+          trace(ep.toString());
+        }
+
         if (p == null) {
           p = new Period(ep.start, ep.end);
-        } else if (ep.start.after(p.getEnd())) {
+          lastType = ep.type;
+        } else if ((lastType != ep.type) || ep.start.after(p.getEnd())) {
           // Non adjacent periods
           if (fbc == null) {
             fbc = new BwFreeBusyComponent();
+            fbc.setType(lastType);
+            fb.addTime(fbc);
           }
           fbc.addPeriod(p);
+
+          if (lastType != ep.type) {
+            fbc = null;
+          }
+
           p = new Period(ep.start, ep.end);
+          lastType = ep.type;
         } else if (ep.end.after(p.getEnd())) {
           // Extend the current period
           p = new Period(p.getStart(), ep.end);
@@ -1229,16 +1270,17 @@
       }
 
       if (p != null) {
-        if (fbc == null) {
+        if ((fbc == null) || (lastType != fbc.getType())) {
           fbc = new BwFreeBusyComponent();
+          fbc.setType(lastType);
+          fb.addTime(fbc);
         }
         fbc.addPeriod(p);
       }
-
-      if (fbc != null) {
-        fb.addTime(fbc);
+    } catch (Throwable t) {
+      if (debug) {
+        error(t);
       }
-    } catch (Throwable t) {
       throw new CalFacadeException(t);
     }
 
@@ -1248,10 +1290,12 @@
   private static class EventPeriod implements Comparable {
     DateTime start;
     DateTime end;
+    int type;  // from BwFreeBusyComponent
 
-    EventPeriod(DateTime start, DateTime end) {
+    EventPeriod(DateTime start, DateTime end, int type) {
       this.start = start;
       this.end = end;
+      this.type = type;
     }
 
     public int compareTo(Object o) {
@@ -1261,6 +1305,15 @@
 
       EventPeriod that = (EventPeriod)o;
 
+      /* Sort by type first */
+      if (type < that.type) {
+        return -1;
+      }
+
+      if (type > that.type) {
+        return 1;
+      }
+
       int res = start.compareTo(that.start);
       if (res != 0) {
         return res;
@@ -1268,6 +1321,27 @@
 
       return end.compareTo(that.end);
     }
+
+    public boolean equals(Object o) {
+      return compareTo(o) == 0;
+    }
+
+    public int hashCode() {
+      return 7 * (type + 1) * (start.hashCode() + 1) * (end.hashCode() + 1);
+    }
+
+    public String toString() {
+      StringBuffer sb = new StringBuffer("EventPeriod{start=");
+
+      sb.append(start);
+      sb.append(", end=");
+      sb.append(end);
+      sb.append(", type=");
+      sb.append(type);
+      sb.append("}");
+
+      return sb.toString();
+    }
   }
 
   /* ====================================================================
@@ -1920,9 +1994,9 @@
     if (sub != null) {
       // Explicitly selected calendar - via a subscription.
 
-      return postProcess(getCal().getEvents(sub.getCalendar(), filter, startDate,
-                                            endDate, recurRetrieval,
-                                            freeBusy, true),
+      return postProcess(getCal(sub).getEvents(sub.getCalendar(), filter,
+                                               startDate, endDate,
+                                               recurRetrieval, freeBusy, true),
                          sub);
     }
 
@@ -2211,6 +2285,15 @@
                                      true, false);
   }*/
 
+  /* This will get a calintf based on the subscription uri.
+   */
+  Calintf getCal(BwSubscription sub) throws CalFacadeException {
+    return getCal();
+  }
+
+  /* Currently this gets a local calintf only. Later we need to use a par to
+   * get calintf from a table.
+   */
   Calintf getCal() throws CalFacadeException {
     if (cali != null) {
       return cali;
@@ -2226,7 +2309,8 @@
       cali.open(); // Just for the user interactions
       cali.beginTransaction();
 
-      boolean userCreated = cali.init(pars.getAuthUser(),
+      boolean userCreated = cali.init(null,
+                                      pars.getAuthUser(),
                                       pars.getUser(),
                                       pars.getPublicAdmin(),
                                       getGroups(),
@@ -2548,5 +2632,9 @@
   private void trace(String msg) {
     getLogger().debug(msg);
   }
+
+  private void error(Throwable t) {
+    getLogger().error(this, t);
+  }
 }
 

Modified: trunk/calendar3/calsvci/src/org/bedework/calsvci/CalSvcI.java
===================================================================
--- trunk/calendar3/calsvci/src/org/bedework/calsvci/CalSvcI.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/calsvci/src/org/bedework/calsvci/CalSvcI.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -611,6 +611,14 @@
    */
   public abstract int deleteCalendar(BwCalendar val) throws CalFacadeException;
 
+  /** Return true if cal != null and it represents a (local) user root
+   *
+   * @param cal
+   * @return boolean
+   * @throws CalFacadeException
+   */
+  public abstract boolean isUserRoot(BwCalendar cal) throws CalFacadeException;
+
   /* ====================================================================
    *                   Views
    * ==================================================================== */
@@ -811,9 +819,12 @@
    * into granularity sized chunks which will only be reported if one or more
    * events fall in the segment.
    *
-   * @param cal    Calendar to provide free-busy for. Null or the user root
+   * @param subs   If non-null use these as the subscriptions.
+   * @param cal    Calendar to provide free-busy for. Null for the user root
    *               for default collection (as specified by user).
-   * @param who
+   *               Used for local access to a given calendar via e.g. caldav
+   * @param who    If sub and cal are null get the info for this user, otherwise
+   *               this si used as the free/busy result owner
    * @param start
    * @param end
    * @param granularity BwDuration object defining how to divide free/busy
@@ -824,7 +835,8 @@
    * @return BwFreeBusy
    * @throws CalFacadeException
    */
-  public abstract BwFreeBusy getFreeBusy(BwCalendar cal, BwPrincipal who,
+  public abstract BwFreeBusy getFreeBusy(Collection subs,
+                                         BwCalendar cal, BwPrincipal who,
                                          BwDateTime start, BwDateTime end,
                                          BwDuration granularity,
                                          boolean returnAll)

Modified: trunk/calendar3/freebusyServer/src/org/bedework/freebusyServer/FreeBusyAggregator.java
===================================================================
--- trunk/calendar3/freebusyServer/src/org/bedework/freebusyServer/FreeBusyAggregator.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/freebusyServer/src/org/bedework/freebusyServer/FreeBusyAggregator.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -133,8 +133,8 @@
 //                               CalFacadeUtil.isoDateTimeUTC(start) + "\"");
 //    req.addContentLine("                end=\"" +
 //                               CalFacadeUtil.isoDateTimeUTC(end) + "\"/>");
-    req.addContentLine("  <C:time-range start=\"20060521T131358Z\"");
-    req.addContentLine("                end=\"20060528T131358Z\"/>");
+    req.addContentLine("  <C:time-range start=\"20060601T131358Z\"");
+    req.addContentLine("                end=\"20060631T131358Z\"/>");
     req.addContentLine("</C:free-busy-query>");
 
     return req;
@@ -157,14 +157,22 @@
                          "localhost", 8080, false,
                          "/ucaldav/user/johnsa"));
                          */
-
+    /*
     addUser(new UserInfo("testuser02", "bedework", "testuser02",
                          "www.bedework.org", 80, false,
                          "/ucaldav/user/testuser02"));
-    addUser(new UserInfo("testuser03", "bedework", "testuser03",
+                         */
+    addUser(new UserInfo("douglm", "bedework", "douglm",
+                         "localhost", 8080, false,
+                         "/ucaldav/user/douglm"));
+/*
+    addUser(new UserInfo("testuser02", "bedework", "testuser02",
                          "www.bedework.org", 80, false,
-                         "/ucaldav/user/testuser03"));
-
+                         "/ucaldav/user/testuser02"));
+    addUser(new UserInfo("testuser08", "bedework", "testuser08",
+                         "www.bedework.org", 80, false,
+                         "/ucaldav/user/testuser08"));
+*/
     getSvci(); //
   }
 
@@ -184,11 +192,13 @@
 
       if (r.getAuth()) {
         resp.responseCode = cio.sendRequest(r.getMethod(), r.getUrl(),
-                                            r.getUser(), r.getPw(), r.getHeaders(),
+                                            r.getUser(), r.getPw(),
+                                            r.getHeaders(), 0,
                                             r.getContentType(),
                                             r.getContentLength(), r.getContentBytes());
       } else {
-        resp.responseCode = cio.sendRequest(r.getMethod(), r.getUrl(), r.getHeaders(),
+        resp.responseCode = cio.sendRequest(r.getMethod(), r.getUrl(),
+                                            r.getHeaders(), 0,
                                             r.getContentType(), r.getContentLength(),
                                             r.getContentBytes());
       }

Modified: trunk/calendar3/test/caldavTestData/eg/content/eg02.xml
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/content/eg02.xml	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/caldavTestData/eg/content/eg02.xml	2006-05-25 13:34:51 UTC (rev 507)
@@ -29,8 +29,8 @@
   <C:filter> <!-- a comment -->
     <C:comp-filter name="VCALENDAR">
       <C:comp-filter name="VEVENT">
-        <C:time-range start="20050402T000000Z"
-                      end="20050602T235959Z"/>
+        <C:time-range start="20060601T000000Z"
+                      end="20060630T235959Z"/>
       </C:comp-filter>
     </C:comp-filter>
   </C:filter>

Modified: trunk/calendar3/test/caldavTestData/eg/content/eg20.xml
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/content/eg20.xml	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/caldavTestData/eg/content/eg20.xml	2006-05-25 13:34:51 UTC (rev 507)
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
-  <C:time-range start="@NOW@"
-                  end="@NEXTWEEK@"/>
+  <C:time-range start="20060601T131358Z"
+                  end="20060701T131358Z"/>
+<!--  <C:time-range start="@NOW@"
+                  end="@NEXTWEEK@"/> -->
 </C:free-busy-query>
 

Modified: trunk/calendar3/test/caldavTestData/eg/eg12.test
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/eg12.test	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/caldavTestData/eg/eg12.test	2006-05-25 13:34:51 UTC (rev 507)
@@ -13,7 +13,7 @@
 CONTENT:
 <?xml version="1.0" encoding="utf-8" ?>
 <C:free-busy-query xmlns:C="urn:ietf:params:xml:ns:caldav">
-  <C:time-range start="20050701T000000Z"
-                  end="20050731T240000Z"/>
+  <C:time-range start="20060401T000000Z"
+                  end="20060731T240000Z"/>
 </C:free-busy-query>
 

Modified: trunk/calendar3/test/caldavTestData/eg/eg16.test
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/eg16.test	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/caldavTestData/eg/eg16.test	2006-05-25 13:34:51 UTC (rev 507)
@@ -4,5 +4,5 @@
 
 AUTH: true
 
-URL: newcol
+URL: RPI_TEST
 

Modified: trunk/calendar3/test/caldavTestData/eg/eg17.test
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/eg17.test	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/caldavTestData/eg/eg17.test	2006-05-25 13:34:51 UTC (rev 507)
@@ -4,5 +4,5 @@
 
 AUTH: true
 
-URL: newcol/newcalendar
+URL: RPI_TEST/RPI_TEST/
 

Added: trunk/calendar3/test/caldavTestData/eg/eg22.test
===================================================================
--- trunk/calendar3/test/caldavTestData/eg/eg22.test	                        (rev 0)
+++ trunk/calendar3/test/caldavTestData/eg/eg22.test	2006-05-25 13:34:51 UTC (rev 507)
@@ -0,0 +1,10 @@
+DESCRIPTION: propfind on user
+
+METHOD: PROPFIND
+
+DEPTH: 2
+
+AUTH: true
+
+URL: calendar
+

Modified: trunk/calendar3/test/src/org/bedework/tests/caldav/Req.java
===================================================================
--- trunk/calendar3/test/src/org/bedework/tests/caldav/Req.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/src/org/bedework/tests/caldav/Req.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -73,6 +73,7 @@
   String pw;
   String description;
   Header[] hdrs;
+  int depth;
   String contentType;
   String[] content;
   boolean auth;
@@ -88,6 +89,7 @@
   static final String descHdr = "DESCRIPTION: ";
   static final String exprespHdr = "EXPECT-RESPONSE: ";
   static final String methHdr = "METHOD: ";
+  static final String depthHdr = "DEPTH: ";
   static final String authHdr = "AUTH: ";
   static final String urlHdr = "URL: ";
   static final String hdrHdr = "HEADER: ";
@@ -140,6 +142,11 @@
                 METHOD
            */
           method = ln.substring(methHdr.length());
+        } else if (ln.startsWith(depthHdr)) {
+          /*
+                DEPTH
+           */
+          depth = Integer.valueOf(ln.substring(depthHdr.length())).intValue();
         } else if (ln.startsWith(authHdr)) {
           /*
                 AUTH
@@ -261,6 +268,13 @@
   }
 
   /**
+   * @return int
+   */
+  public int getDepth() {
+    return depth;
+  }
+
+  /**
    * @return String
    */
   public String getContentType() {

Modified: trunk/calendar3/test/src/org/bedework/tests/caldav/TestCalDav.java
===================================================================
--- trunk/calendar3/test/src/org/bedework/tests/caldav/TestCalDav.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/test/src/org/bedework/tests/caldav/TestCalDav.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -364,10 +364,12 @@
       int respCode;
       if (r.getAuth()) {
         respCode = cio.sendRequest(r.getMethod(), r.getPrefixedUrl(),
-                                   user, pw, r.getHdrs(), r.getContentType(),
+                                   user, pw, r.getHdrs(), r.getDepth(),
+                                   r.getContentType(),
                                    r.getContentLength(), r.getContentBytes());
       } else {
-        respCode = cio.sendRequest(r.getMethod(), r.getPrefixedUrl(), r.getHdrs(),
+        respCode = cio.sendRequest(r.getMethod(), r.getPrefixedUrl(),
+                                   r.getHdrs(), r.getDepth(),
                                    r.getContentType(), r.getContentLength(),
                                    r.getContentBytes());
       }

Modified: trunk/calendar3/webclient/src/org/bedework/webclient/BwFreeBusyAction.java
===================================================================
--- trunk/calendar3/webclient/src/org/bedework/webclient/BwFreeBusyAction.java	2006-05-20 00:58:29 UTC (rev 506)
+++ trunk/calendar3/webclient/src/org/bedework/webclient/BwFreeBusyAction.java	2006-05-25 13:34:51 UTC (rev 507)
@@ -77,7 +77,7 @@
  * Action to fetch free busy information
  * <p>Request parameters - all optional:<ul>
  *      <li>  userid:   whose free busy we want - default to current user</li>.
- *      <li>  calendar: name of the calendar - default to subscriptions
+ *      <li>  subname:  name of the subscription - default to subscriptions
  *                      specified by user</li>.
  *      <li>  start:    start of period - default to beginning of this week</li>.
  *      <li>  end:      end of period - default to end of this week</li>.
@@ -202,7 +202,7 @@
       }
 
       try {
-        BwFreeBusy fb = svci.getFreeBusy(null, user,
+        BwFreeBusy fb = svci.getFreeBusy(null, null, user,
                                          CalFacadeUtil.getDateTime(sdt, false, false, tzs),
                                          CalFacadeUtil.getDateTime(edt, false, false, tzs),
                                          dur, true);



More information about the Bedework-commit mailing list