Changeset 207

Show
Ignore:
Timestamp:
02/25/06 17:51:32
Author:
douglm
Message:

Changes caused by use of calendar id in uris.

This round of changes were caused by the need to make the guid unique only
within the context of a calendar collection. This requires that the calendar
id be part of the event key.

Some reorganizarion of the calcore code also took place.

In addition, adding a public event to the personal calendar now seems to work.

All of the url for fetching single events need to change. There are about 8 of
them in the public default stylesheet.

The changes were relatively simple:

Change all occurrences of

subid={$subscriptionId}&

to

subid={$subscriptionId}&calid={$calendarId}&

In 2-3 places you need to define calendarId. Look for occurences of

<xsl:variable name="subscriptionId" select="subscription/id"/>

and immediately following add

<xsl:variable name="calendarId" select="calendar/id"/>

A further change is to look for the addEventRef.do url and change the text

eventId={$id}

to

subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}
that is, make it the same form as the others. (I found 2 of these)

These changes will also be required in the user client stylesheet.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/calendar3/calCore/resources/hbms/Event.hbm.xml

    r200 r207  
    210210  ]]></query> 
    211211 
    212   <!-- Use this to see if a guid exists. The count should be zero or one --> 
     212  <!-- Use this to see if a guid exists. --> 
    213213  <query name="getGuidCount"><![CDATA[ 
    214214    select count(*) from org.bedework.calfacade.BwEventObj as ev 
    215215      where ev.guid = :guid 
    216216  ]]></query> 
     217 
     218  <!-- Use this to see if a guid exists in a calendar. The count should be zero or one --> 
     219  <query name="getGuidCountCalendar"><![CDATA[ 
     220    select count(*) from org.bedework.calfacade.BwEventObj as ev 
     221      where ev.calendar=:cal and ev.guid = :guid 
     222  ]]></query> 
    217223</hibernate-mapping> 
    218224 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Calendars.java

    r164 r207  
    7979   * @throws CalFacadeException 
    8080   */ 
    81   public Calendars(Calintf cal, AccessUtil access, BwUser user, boolean debug) 
     81  public Calendars(Calintf cal, AccessUtil access, BwUser user,  
     82                   int currentMode, boolean ignoreCreator, boolean debug) 
    8283                  throws CalFacadeException { 
    83     super(cal, access, user, debug); 
     84    super(cal, access, user, currentMode, ignoreCreator, debug); 
    8485 
    8586    publicCalendarRootPath = "/" + getSyspars().getPublicCalendarRoot(); 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfHelper.java

    r99 r207  
    7979  protected BwUser user; 
    8080 
     81  protected int currentMode = CalintfUtil.guestMode; 
     82   
     83  protected boolean ignoreCreator; 
     84 
    8185  private transient Logger log; 
    8286 
     
    8993   */ 
    9094  public CalintfHelper(Calintf cal, AccessUtil access, 
    91                    BwUser user, boolean debug) { 
     95                       BwUser user, int currentMode, boolean ignoreCreator,  
     96                       boolean debug) { 
    9297    this.cal = cal; 
    9398    this.access = access; 
    9499    this.user = user; 
     100    this.currentMode = currentMode; 
     101    this.ignoreCreator = ignoreCreator; 
    95102    this.debug = debug; 
    96103  } 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/CalintfImpl.java

    r191 r207  
    311311    access.setAuthUser(authUser); 
    312312 
    313     events = new Events(this, access, this.user, debug); 
    314  
    315     calendars = new Calendars(this, access, this.user, debug); 
    316  
    317     categories = new EventProperties(this, access, this.user, 
     313    events = new Events(this, access, this.user, currentMode,  
     314                        ignoreCreator, debug); 
     315 
     316    calendars = new Calendars(this, access, this.user, currentMode,  
     317                              ignoreCreator, debug); 
     318 
     319    categories = new EventProperties(this, access, this.user, currentMode,  
     320                                     ignoreCreator,  
    318321                                     "word", BwCategory.class.getName(), 
    319322                                     "getCategoryRefs", 
    320323                                     -1, debug); 
    321     locations = new EventProperties(this, access, this.user, 
     324    locations = new EventProperties(this, access, this.user, currentMode,  
     325                                    ignoreCreator,  
    322326                                    "address", BwLocation.class.getName(), 
    323                                     "getLocationRefs", 
     327                                    "getLocationRefs", 
    324328                                     CalFacadeDefs.maxReservedLocationId, debug); 
    325     sponsors = new EventProperties(this, access, this.user, 
     329    sponsors = new EventProperties(this, access, this.user, currentMode,  
     330                                   ignoreCreator,  
    326331                                   "name", BwSponsor.class.getName(), 
    327332                                   "getSponsorRefs", 
     
    928933    checkOpen(); 
    929934 
    930     return (BwCategory)categories.get(id, currentMode, ignoreCreator); 
     935    return (BwCategory)categories.get(id); 
    931936  } 
    932937 
     
    977982    checkOpen(); 
    978983 
    979     return (BwLocation)locations.get(id, currentMode, ignoreCreator); 
     984    return (BwLocation)locations.get(id); 
    980985  } 
    981986 
     
    10261031    checkOpen(); 
    10271032 
    1028     return (BwSponsor)sponsors.get(id, currentMode, ignoreCreator); 
     1033    return (BwSponsor)sponsors.get(id); 
    10291034  } 
    10301035 
     
    10701075          throws CalFacadeException { 
    10711076    return events.getEvents(calendar, filter, 
    1072                             startDate, endDate, recurRetrieval, 
    1073                             currentMode, ignoreCreator); 
     1077                            startDate, endDate, recurRetrieval); 
    10741078  } 
    10751079 
     
    10791083  } 
    10801084 
    1081  public Collection getEvent(String guid, String rid, 
    1082                            Integer seqnum, 
     1085 public Collection getEvent(BwCalendar calendar, String guid, String rid, 
    10831086                           int recurRetrieval) throws CalFacadeException { 
    10841087    checkOpen(); 
    1085     return events.getEvent(guid, rid, seqnum, recurRetrieval); 
     1088    return events.getEvent(calendar, guid, rid, recurRetrieval); 
    10861089  } 
    10871090 
     
    11051108    checkOpen(); 
    11061109 
    1107     if (currentMode == CalintfUtil.guestMode) { 
    1108       return false; 
    1109     } 
    1110  
    1111     if (val.getPublick() != (currentMode == CalintfUtil.publicAdminMode)) { 
    1112       return false; 
    1113     } 
    1114  
    1115     return user.equals(val.getCreator()); 
    1116   } 
    1117  
    1118   /* ==================================================================== 
    1119    *                       Caldav support 
    1120    * Caldav as it stands at the moment requires that we save the arbitary 
    1121    * names clients might assign to events. 
    1122    * ==================================================================== */ 
     1110    return events.editable(val); 
     1111  } 
    11231112 
    11241113  public Collection getEventsByName(BwCalendar cal, String val) 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/EventProperties.java

    r99 r207  
    9696   */ 
    9797  public EventProperties(Calintf cal, AccessUtil access, BwUser user, 
     98                         int currentMode, boolean ignoreCreator, 
    9899                         String keyFieldName, 
    99100                         String className, 
    100101                         String refQuery, 
    101                          int minId, 
     102                         int minId,  
    102103                         boolean debug) { 
    103     super(cal, access, user, debug); 
     104    super(cal, access, user, currentMode, ignoreCreator, debug); 
    104105 
    105106    this.keyFieldName = keyFieldName; 
     
    177178   * 
    178179   * @param id            int id of the entity 
    179    * @param currentMode   mode we are in (guest etc) 
    180    * @param ignoreCreator true if we ignore creator 
    181180   * @return BwEventProperty object representing the entity in question 
    182181   *                     null if it doesn't exist. 
    183182   * @throws CalFacadeException 
    184183   */ 
    185   public BwEventProperty get(int id, 
    186                              int currentMode, 
    187                              boolean ignoreCreator) throws CalFacadeException { 
     184  public BwEventProperty get(int id) throws CalFacadeException { 
    188185    HibSession sess = getSess(); 
    189186 
  • trunk/calendar3/calCore/src/org/bedework/calcore/hibernate/Events.java

    r200 r207  
    6868import org.bedework.calfacade.ifs.CalTimezones; 
    6969import org.bedework.calfacade.ifs.Calintf; 
    70 import org.bedework.calfacade.ifs.Calintf.DelEventResult
     70import org.bedework.calfacade.ifs.EventsI
    7171import org.bedework.calfacade.CalFacadeException; 
    7272import org.bedework.icalendar.VEventUtil; 
     
    9595 * @author Mike Douglass   douglm@rpi.edu 
    9696 */ 
    97 public class Events extends CalintfHelper
     97public class Events extends CalintfHelper implements EventsI
    9898  private transient UUIDHexGenerator uuidGen; 
    9999 
     
    105105   * @param debug 
    106106   */ 
    107   public Events(Calintf cal, AccessUtil access, BwUser user, boolean debug) { 
    108     super(cal, access, user, debug); 
    109   } 
    110  
    111   /** Return one or more events using the guid and optionally a sequence number 
    112    * and recurrence-id as a key. 
    113    * 
    114    * <p>For non-recurring events, one and only one event should be returned 
    115    * for any given guid. 
    116    * 
    117    * <p>For recurring events, the guid defines the 'master' event defining 
    118    * the rules together with any exceptions. 
    119    * 
    120    * <p>The sequence number and the recurrence id define a particular instance 
    121    * of a recurrence. 
    122    * 
    123    * <p>To specify the master entry provide a null recurrenceId or use the 
    124    * recurRetrieval parameter. 
    125    * 
    126    * <p>If a recurrence id is given and recurRetrieval=retrieveRecurMaster the 
    127    * associated master event will be returned rather than the instance or any 
    128    * override. 
    129    * 
    130    * @param   guid      String guid for the event 
    131    * @param   rid       String recurrence id, null for non-recurring, null valued for 
    132    *                    master or non-null-valued for particular occurrence. 
    133    * @param   seqnum    Integer sequence nbr 
    134    * @param recurRetrieval Takes value defined in CalFacadeDefs. 
    135    * @return  Collection   objects representing event - possibly with overrides. 
    136    * @throws CalFacadeException 
    137    */ 
    138   public Collection getEvent(String guid, String rid, 
    139                              Integer seqnum, 
     107  public Events(Calintf cal, AccessUtil access, BwUser user,  
     108                int currentMode, boolean ignoreCreator, boolean debug) { 
     109    super(cal, access, user, currentMode, ignoreCreator, debug); 
     110  } 
     111 
     112  public Collection getEvent(BwCalendar calendar, String guid, String rid, 
    140113                             int recurRetrieval) throws CalFacadeException { 
    141114    BwEvent ev = null; 
     
    146119    if (rid == null) { 
    147120      // First look in the events table for the master. 
    148       eventQuery(BwEventObj.class, guid, rid, seqnum, true); 
     121      eventQuery(BwEventObj.class, calendar, guid, rid, true); 
    149122 
    150123      /* There should be one only */ 
     
    160133      if (!user.equals(ev.getOwner())) { 
    161134        // XXX that check prevents annotation by owner - is that OK? 
    162         eventQuery(BwEventAnnotation.class, guid, rid, seqnum, true); 
     135        eventQuery(BwEventAnnotation.class, calendar, guid, rid, true); 
    163136        BwEventAnnotation ann = (BwEventAnnotation)postGetEvent((BwEvent)sess.getUnique(), 
    164137                                                            privRead, noAccessReturnsNull); 
     
    208181      */ 
    209182      if (recurRetrieval == CalFacadeDefs.retrieveRecurOverrides) { 
    210         eventQuery(BwEventAnnotation.class, guid, rid, seqnum, false); 
     183        eventQuery(BwEventAnnotation.class, calendar, guid, rid, false); 
    211184 
    212185        Collection ovs = sess.getList(); 
     
    239212      sb.append(" where rec.master=:master "); 
    240213 
    241       if (seqnum != null) { 
    242         sb.append(" and rec.master.sequence=:seq "); 
    243       } 
    244  
    245214      sess.createQuery(sb.toString()); 
    246215 
    247216      sess.setEntity("master", master); 
    248  
    249       if (seqnum != null) { 
    250         sess.setInt("seq", seqnum.intValue()); 
    251       } 
    252217 
    253218      Collection instances = sess.getList(); 
     
    266231    /* Rid is non-null - look first for an override then for the instance. 
    267232     */ 
    268     eventQuery(BwEventAnnotation.class, guid, rid, seqnum, false); 
     233    eventQuery(BwEventAnnotation.class, calendar, guid, rid, false); 
    269234    BwEventAnnotation override = (BwEventAnnotation)sess.getUnique(); 
    270235 
     
    282247      sb.append(" where rec.master.guid=:guid "); 
    283248 
    284       if (seqnum != null) { 
    285         sb.append(" and rec.master.sequence=:seq "); 
    286       } 
    287  
    288249      sb.append(" and rec.recurrenceId=:rid "); 
    289250 
     
    291252 
    292253      sess.setString("guid", guid); 
    293  
    294       if (seqnum != null) { 
    295         sess.setInt("seq", seqnum.intValue()); 
    296       } 
    297254 
    298255      sess.setString("rid", rid); 
     
    314271  } 
    315272 
    316   /** Return a single event 
    317    * 
    318    * @param   id          int id of the event 
    319    * @return  EventVO   value object representing event. 
    320    * @throws CalFacadeException 
    321    */ 
    322273  public BwEvent getEvent(int id) throws CalFacadeException { 
    323274    HibSession sess = getSess(); 
     
    335286  } 
    336287 
    337   /** Add an event to the database. 
    338    * 
    339    * @param val   BwEvent object to be added 
    340    * @param overrides 
    341    * @throws CalFacadeException 
    342    */ 
    343   public void addEvent(BwEvent val, Collection overrides) throws CalFacadeException { 
     288  public void addEvent(BwEvent val,  
     289                       Collection overrides) throws CalFacadeException { 
    344290    RecuridTable recurids = null; 
    345291    HibSession sess = getSess(); 
     
    361307     * It also ensures our guid allocation is working OK 
    362308     */ 
    363     sess.namedQuery("getGuidCount"); 
     309    sess.namedQuery("getGuidCountCalendar"); 
     310    sess.setEntity("cal", val.getCalendar()); 
    364311    sess.setString("guid", val.getGuid()); 
    365312 
     
    461408  } 
    462409 
    463   /* Called when adding an event with overrides 
    464    */ 
    465   private void addOverride(BwEventProxy proxy, 
    466                            BwRecurrenceInstance inst) throws CalFacadeException { 
    467     BwEventAnnotation override = proxy.getRef(); 
    468     override.setOwner(user); 
    469  
    470     getSess().saveOrUpdate(override); 
    471     inst.setOverride(override); 
    472   } 
    473  
    474   /** Replace an event with the same id in the database. 
    475    * 
    476    * @param val   EventVO object to be replaced 
    477    * @throws CalFacadeException 
    478    */ 
    479410  public void updateEvent(BwEvent val) throws CalFacadeException { 
    480411    HibSession sess = getSess(); 
     
    555486 
    556487    proxy.setRefChanged(false); 
     488  } 
     489 
     490  public DelEventResult deleteEvent(BwEvent val) throws CalFacadeException { 
     491    HibSession sess = getSess(); 
     492    DelEventResult der = new DelEventResult(false, 0); 
     493 
     494    der.alarmsDeleted = deleteAlarms(val); 
     495 
     496    StringBuffer sb = new StringBuffer(); 
     497 
     498    /* SEG:   delete from recurrences recur where */ 
     499    sb.append("delete from "); 
     500    sb.append(BwRecurrenceInstance.class.getName()); 
     501    sb.append(" where master=:master"); 
     502 
     503    sess.createQuery(sb.toString()); 
     504    sess.setEntity("master", val); 
     505    sess.executeUpdate(); 
     506 
     507    /* XXX Cascades don't seem to do the job here - we have to explicitly delete the 
     508       annotations. 
     509 
     510       In any case, this won't work if we have a shared event and there are 
     511       annotations to the annotation. We need a field which identifies all 
     512       annotations related to the master i.e. not just a target field but a 
     513       master field. 
     514     */ 
     515    sb = new StringBuffer(); 
     516 
     517    sb.append("from "); 
     518    sb.append(BwEventAnnotation.class.getName()); 
     519    sb.append(" where target=:target"); 
     520 
     521    sess.createQuery(sb.toString()); 
     522    sess.setEntity("target", val); 
     523 
     524    Collection anns = sess.getList(); 
     525    Iterator it = anns.iterator(); 
     526 
     527    while (it.hasNext()) { 
     528      BwEventAnnotation ann = (BwEventAnnotation)it.next(); 
     529 
     530      ann.getAttendees().clear(); 
     531 
     532      sess.delete(ann); 
     533    } 
     534 
     535    sess.delete(val); 
     536 
     537    /* This event was really deleted so we need to set any synch states to 
     538     * indicate this is the case. 
     539     */ 
     540    cal.setSynchState(val, BwSynchState.DELETED); 
     541 
     542    der.eventDeleted = true; 
     543 
     544    return der; 
     545  } 
     546 
     547  public Collection getEvents(BwCalendar calendar, BwFilter filter, 
     548                              BwDateTime startDate, BwDateTime endDate, 
     549                              int recurRetrieval) 
     550          throws CalFacadeException { 
     551    HibSession sess = getSess(); 
     552    StringBuffer sb = new StringBuffer(); 
     553 
     554    if (debug) { 
     555      trace("getEvents for start=" + startDate + " end=" + endDate); 
     556    } 
     557 
     558    /* Name of the event in the query */ 
     559    final String qevName = "ev"; 
     560 
     561    Filters flt = new Filters(filter, sb, qevName, debug); 
     562 
     563    /* SEG:   from Events ev where */ 
     564    sb.append("from "); 
     565    sb.append(BwEvent.class.getName()); 
     566    sb.append(" "); 
     567    sb.append(qevName); 
     568    sb.append(" where "); 
     569 
     570    /* SEG:   (<date-ranges>) and  */ 
     571    if (appendDateTerms(sb, qevName + ".dtstart.date", 
     572                        qevName + ".dtend.date", 
     573                        startDate, endDate)) { 
     574      sb.append(" and "); 
     575    } 
     576 
     577    /* Don't retrieve any master records - I guess we might have a choice 
     578       to retrieve any with the dates in the given range 
     579     */ 
     580    sb.append(qevName); 
     581    sb.append(".recurring = false and "); 
     582 
     583    /* SEG   (    */ 
     584    sb.append(" ("); 
     585 
     586    boolean setUser = doCalendarClause(sb, qevName, calendar, 
     587                                       currentMode, ignoreCreator); 
     588 
     589    sb.append(") "); 
     590 
     591    flt.addWhereFilters(); 
     592 
     593    sb.append(" order by "); 
     594    sb.append(qevName); 
     595    sb.append(".dtstart.dtval"); 
     596 
     597    //if (debug) { 
     598    //  trace(sb.toString()); 
     599    //} 
     600 
     601    sess.createQuery(sb.toString()); 
     602 
     603    /* XXX Limit result set size - pagination allows something like: 
     604       query.setFirstResult(0); 
     605       query.setMaxResults(10); 
     606       */ 
     607 
     608    if (startDate != null) { 
     609      sess.setString("fromDate", startDate.getDate()); 
     610    } 
     611 
     612    if (endDate != null) { 
     613      sess.setString("toDate", endDate.getDate()); 
     614    } 
     615 
     616    doCalendarEntities(setUser, calendar); 
     617 
     618    flt.parPass(sess); 
     619 
     620    if (debug) { 
     621      trace(sess.getQueryString()); 
     622    } 
     623 
     624    Collection es = sess.getList(); 
     625 
     626    if (debug) { 
     627      trace("Found " + es.size() + " events"); 
     628    } 
     629 
     630    es = postGetEvents(es, privRead, noAccessReturnsNull); 
     631 
     632    /** Run the events we got through the filters 
     633     */ 
     634    es = flt.postExec(es); 
     635 
     636    Collection rs = getLimitedRecurrences(calendar, filter, startDate, endDate, 
     637                                          currentMode, ignoreCreator, 
     638                                          recurRetrieval); 
     639    if (rs != null) { 
     640      es.addAll(rs); 
     641    } 
     642 
     643    return es; 
     644  } 
     645 
     646  public boolean editable(BwEvent val) throws CalFacadeException { 
     647    if (currentMode == CalintfUtil.guestMode) { 
     648      return false; 
     649    } 
     650 
     651    if (val.getPublick() != (currentMode == CalintfUtil.publicAdminMode)) { 
     652      return false; 
     653    } 
     654 
     655    return user.equals(val.getCreator()); 
     656  } 
     657 
     658  public Collection getEventsByName(BwCalendar cal, String val) 
     659          throws CalFacadeException { 
     660    HibSession sess = getSess(); 
     661    sess.namedQuery("eventsByName"); 
     662    sess.setString("name", val); 
     663    sess.setEntity("cal", cal); 
     664 
     665    Collection evs = sess.getList(); 
     666 
     667    return postGetEvents(evs, privRead, noAccessReturnsNull); 
     668  } 
     669 
     670  /* ==================================================================== 
     671   *                   Private methods 
     672   * ==================================================================== */ 
     673 
     674  /** Assign a guid to an event. A noop if this event already has a guid. 
     675   * 
     676   * @param val      BwEvent object 
     677   * @throws CalFacadeException 
     678   */ 
     679  private void assignGuid(BwEvent val) throws CalFacadeException { 
     680    if (val == null) { 
     681      return; 
     682    } 
     683 
     684    String guidPrefix = "CAL-" + (String)getUuidGen().generate(null, null); 
     685 
     686    if (val.getName() == null) { 
     687      val.setName(guidPrefix + ".ics"); 
     688    } 
     689 
     690    if (val.getGuid() != null) { 
     691      return; 
     692    } 
     693 
     694    String guid = guidPrefix + cal.getSysid(); 
     695 
     696    val.setGuid(guid); 
     697  } 
     698 
     699  /* Called when adding an event with overrides 
     700   */ 
     701  private void addOverride(BwEventProxy proxy, 
     702                           BwRecurrenceInstance inst) throws CalFacadeException { 
     703    BwEventAnnotation override = proxy.getRef(); 
     704    override.setOwner(user); 
     705 
     706    getSess().saveOrUpdate(override); 
     707    inst.setOverride(override); 
    557708  } 
    558709 
     
    649800  } 
    650801 
    651   /** Delete an event 
    652    * 
    653    * @param val                BwEvent object to be deleted 
    654    * @return DelEventResult    result. 
    655    * @exception CalFacadeException If there's a database access problem 
    656    */ 
    657   public DelEventResult deleteEvent(BwEvent val) throws CalFacadeException { 
    658     HibSession sess = getSess(); 
    659     DelEventResult der = new DelEventResult(false, 0); 
    660  
    661     der.alarmsDeleted = deleteAlarms(val); 
    662  
    663     StringBuffer sb = new StringBuffer(); 
    664  
    665     /* SEG:   delete from recurrences recur where */ 
    666     sb.append("delete from "); 
    667     sb.append(BwRecurrenceInstance.class.getName()); 
    668     sb.append(" where master=:master"); 
    669  
    670     sess.createQuery(sb.toString()); 
    671     sess.setEntity("master", val); 
    672     sess.executeUpdate(); 
    673  
    674     /* XXX Cascades don't seem to do the job here - we have to explicitly delete the 
    675        annotations. 
    676  
    677        In any case, this won't work if we have a shared event and there are 
    678        annotations to the annotation. We need a field which identifies all 
    679        annotations related to the master i.e. not just a target field but a 
    680        master field. 
    681      */ 
    682     sb = new StringBuffer(); 
    683  
    684     sb.append("from "); 
    685     sb.append(BwEventAnnotation.class.getName()); 
    686     sb.append(" where target=:target"); 
    687  
    688     sess.createQuery(sb.toString()); 
    689     sess.setEntity("target", val); 
    690  
    691     Collection anns = sess.getList(); 
    692     Iterator it = anns.iterator(); 
    693  
    694     while (it.hasNext()) { 
    695       BwEventAnnotation ann = (BwEventAnnotation)it.next(); 
    696  
    697       ann.getAttendees().clear(); 
    698  
    699       sess.delete(ann); 
    700     } 
    701  
    702     sess.delete(val); 
    703  
    704     /* This event was really deleted so we need to set any synch states to 
    705      * indicate this is the case. 
    706      */ 
    707     cal.setSynchState(val, BwSynchState.DELETED); 
    708  
    709     der.eventDeleted = true; 
    710  
    711     return der; 
    712   } 
    713  
    714   /** Assign a guid to an event. A noop if this event already has a guid. 
    715    * 
    716    * @param val      EventVO object 
    717    * @throws CalFacadeException 
    718    */ 
    719   public void assignGuid(BwEvent val) throws CalFacadeException { 
    720     if (val == null) { 
    721       return; 
    722     } 
    723  
    724     String guidPrefix = "CAL-" + (String)getUuidGen().generate(null, null); 
    725  
    726     if (val.getName() == null) { 
    727       val.setName(guidPrefix + ".ics"); 
    728     } 
    729  
    730     if (val.getGuid() != null) { 
    731       return; 
    732     } 
    733  
    734     String guid = guidPrefix + cal.getSysid(); 
    735  
    736     val.setGuid(guid); 
    737   } 
    738  
    739   /** Return the events within the given date range. If this is not a public 
    740    * admin view we apply any filters. 
    741    * 
    742    * <p>This should really be a UNION query but hibernate doesn't currently 
    743    * support these. However, most queries are for a single days events, 
    744    * repeated to obtain a week or month, and returns a small number of objects. 
    745    * 
    746    * <p>Appropriately enabled caching should reduce db interactions to an 
    747    * acceptable level. 
    748    * 
    749    * <p>We try to build something like the following: 
    750    * 
    751    * from EventVO where 
    752    *     [ ( <in-date-range> ) and ]       if date(s) given 
    753    * 
    754    *   one of: 
    755    *  A: for personal 
    756    *    ( ( public = false and creator = user) or 
    757    *      [ and <not-in-blocked-events> ] 
    758    * 
    759    * B: for guest 
    760    *    ( public = true ) 
    761    * 
    762    * C: for public admin 
    763    *    ( public = true and creator = user) 
    764    * 
    765    * followed by 
    766    *    [ and <filter-expr> ] 
    767    * 
    768    * <filter-expr> 
    769    * 1. Not null but inexpressable - post process 
    770    * 
    771    * 2. Not null but (partially) expressible 
    772    *    Add sql but possibly post-process 
    773    *     e.g.  A and B and C 
    774    *     if any of A, B, C are expressible add to query 
    775    * 
    776    * 3. null - add nothing 
    777    * 
    778    * <p>All parameters may be null implying all events for this object. 
    779    * Start or end or both may be null.<ul> 
    780    * <li>startDate=null,endDate=null means all</li> 
    781    * <li>startDate=null means all less than endDate</li> 
    782    * <li>endDate=null means all including and after startDate</li> 
    783    * 
    784    * @param calendar     BwCalendar object restricting search or null. 
    785    * @param filter       BwFilter object restricting search or null. 
    786    * @param startDate    DateTimeVO start - may be null 
    787    * @param endDate      DateTimeVO end - may be null. 
    788    * @param recurRetrieval Takes value defined in.CalFacadeDefs 
    789    * @param currentMode 
    790    * @param ignoreCreator 
    791    * @return Collection  populated event value objects 
    792    * @throws CalFacadeException 
    793    */ 
    794   public Collection getEvents(BwCalendar calendar, BwFilter filter, 
    795                               BwDateTime startDate, BwDateTime endDate, 
    796                               int recurRetrieval, 
    797                               int currentMode, boolean ignoreCreator) 
    798           throws CalFacadeException { 
    799     HibSession sess = getSess(); 
    800     StringBuffer sb = new StringBuffer(); 
    801  
    802     if (debug) { 
    803       trace("getEvents for start=" + startDate + " end=" + endDate); 
    804     } 
    805  
    806     /* Name of the event in the query */ 
    807     final String qevName = "ev"; 
    808  
    809     Filters flt = new Filters(filter, sb, qevName, debug); 
    810  
    811     /* SEG:   from Events ev where */ 
    812     sb.append("from "); 
    813     sb.append(BwEvent.class.getName()); 
    814     sb.append(" "); 
    815     sb.append(qevName); 
    816     sb.append(" where "); 
    817  
    818     /* SEG:   (<date-ranges>) and  */ 
    819     if (appendDateTerms(sb, qevName + ".dtstart.date", 
    820                         qevName + ".dtend.date", 
    821                         startDate, endDate)) { 
    822       sb.append(" and "); 
    823     } 
    824  
    825     /* Don't retrieve any master records - I guess we might have a choice 
    826        to retrieve any with the dates in the given range 
    827      */ 
    828     sb.append(qevName); 
    829     sb.append(".recurring = false and "); 
    830  
    831     /* SEG   (    */ 
    832     sb.append(" ("); 
    833  
    834     boolean setUser = doCalendarClause(sb, qevName, calendar, 
    835                                        currentMode, ignoreCreator); 
    836  
    837     sb.append(") "); 
    838  
    839     flt.addWhereFilters(); 
    840  
    841     sb.append(" order by "); 
    842     sb.append(qevName); 
    843     sb.append(".dtstart.dtval"); 
    844  
    845     //if (debug) { 
    846     //  trace(sb.toString()); 
    847     //} 
    848  
    849     sess.createQuery(sb.toString()); 
    850  
    851     /* XXX Limit result set size - pagination allows something like: 
    852        query.setFirstResult(0); 
    853        query.setMaxResults(10); 
    854        */ 
    855  
    856     if (startDate != null) { 
    857       sess.setString("fromDate", startDate.getDate()); 
    858     } 
    859  
    860     if (endDate != null) { 
    861       sess.setString("toDate", endDate.getDate()); 
    862     } 
    863  
    864     doCalendarEntities(setUser, calendar); 
    865  
    866     flt.parPass(sess); 
    867  
    868     if (debug) { 
    869       trace(sess.getQueryString()); 
    870     } 
    871  
    872     Collection es = sess.getList(); 
    873  
    874     if (debug) { 
    875       trace("Found " + es.size() + " events"); 
    876     } 
    877  
    878     es = postGetEvents(es, privRead, noAccessReturnsNull); 
    879  
    880     /** Run the events we got through the filters 
    881      */ 
    882     es = flt.postExec(es); 
    883  
    884     Collection rs = getLimitedRecurrences(calendar, filter, startDate, endDate, 
    885                                           currentMode, ignoreCreator, 
    886                                           recurRetrieval); 
    887     if (rs != null) { 
    888       es.addAll(rs); 
    889     } 
    890  
    891     return es; 
    892   } 
    893  
    894   /** Get events given the calendar and String name. Return null for not 
    895    * found. For non-recurring there should be only one event. Otherwise we 
    896    * return the master event and overrides. 
    897    * 
    898    * @param cal        BwCalendar object 
    899    * @param val        String possible name 
    900    * @return Collection of BwEvent or null 
    901    * @throws CalFacadeException 
    902    */ 
    903   public Collection getEventsByName(BwCalendar cal, String val) 
    904           throws CalFacadeException { 
    905     HibSession sess = getSess(); 
    906     sess.namedQuery("eventsByName"); 
    907     sess.setString("name", val); 
    908     sess.setEntity("cal", cal); 
    909  
    910     Collection evs = sess.getList(); 
    911  
    912     return postGetEvents(evs, privRead, noAccessReturnsNull); 
    913   } 
    914  
    915   /* ==================================================================== 
    916    *                   Private methods 
    917    * ==================================================================== */ 
    918  
    919   private void eventQuery(Class cl, String guid, String rid, Integer seqnum, 
     802  private void eventQuery(Class cl, BwCalendar calendar, String guid, String rid,  
    920803                          boolean masterOnly) throws CalFacadeException { 
    921804    HibSession sess = getSess(); 
     
    926809    sb.append(cl.getName()); 
    927810    sb.append(" ev "); 
    928     sb.append(" where ev.guid=:guid "); 
    929  
    930     if (seqnum != null) { 
    931       sb.append(" and ev.sequence=:seq "); 
    932     } 
     811    sb.append(" where ev.calendar=:cal "); 
     812    sb.append(" and ev.guid=:guid "); 
    933813 
    934814    if (masterOnly) { 
     
    940820    sess.createQuery(sb.toString()); 
    941821 
     822    sess.setEntity("cal", calendar); 
    942823    sess.setString("guid", guid); 
    943  
    944     if (seqnum != null) { 
    945       sess.setInt("seq", seqnum.intValue()); 
    946     } 
    947824 
    948825    if (! masterOnly && (rid != null)) { 
  • trunk/calendar3/calFacade/src/org/bedework/calfacade/base/CalintfBase.java

    r191 r207  
    694694  } 
    695695 
    696   public Collection getEvent(String guid, String rid, 
    697                              Integer seqnum, 
     696  public Collection getEvent(BwCalendar calendar, String guid, String rid, 
    698697                             int recurRetrieval) throws CalFacadeException { 
    699698    checkOpen(); 
  • trunk/calendar3/calFacade/src/org/bedework/calfacade/ifs/Calintf.java

    r191 r207  
    5555 
    5656import org.bedework.calfacade.BwAlarm; 
    57 import org.bedework.calfacade.BwCalendar; 
    5857import org.bedework.calfacade.BwCategory; 
    59 import org.bedework.calfacade.BwDateTime; 
    6058import org.bedework.calfacade.BwEvent; 
    6159import org.bedework.calfacade.BwLocation; 
     
    9189 * @author Mike Douglass   douglm@rpi.edu 
    9290 */ 
    93 public interface Calintf extends CalendarsI
     91public interface Calintf extends CalendarsI, EventsI
    9492  /** Must be called to initialise the new object. 
    9593   * 
     
    677675   */ 
    678676  public Collection getSponsorRefs(BwSponsor val) throws CalFacadeException; 
    679  
    680   /* ==================================================================== 
    681    *                   Events 
    682    * ==================================================================== */ 
    683  
    684   /** Return a single event for the current user 
    685    * 
    686    * @param   eventId   int id of the event 
    687    * @return  EventVO   value object representing event. 
    688    * @throws CalFacadeException 
    689    */ 
    690   public BwEvent getEvent(int eventId) throws CalFacadeException; 
    691  
    692   /** Return one or more events using the guid and optionally a sequence number 
    693    * and recurrence-id as a key. 
    694    * 
    695    * <p>For non-recurring events, one and only one event should be returned 
    696    * for any given guid. 
    697    * 
    698    * <p>For recurring events, the guid defines the 'master' event defining 
    699    * the rules together with any exceptions. 
    700    * 
    701    * <p>The sequence number and the recurrence id define a particular instance 
    702    * of a recurrence. 
    703    * 
    704    * <p>To specify the master entry provide a null recurrenceId or use the 
    705    * recurRetrieval parameter. 
    706    * 
    707    * @param   guid      String guid for the event 
    708    * @param   rid       String recurrence id, null for non-recurring, null valued for 
    709    *                    master or non-null-valued for particular occurrence. 
    710    * @param   seqnum    Integer sequence nbr 
    711    * @param recurRetrieval Takes value defined in CalFacadeDefs. 
    712    * @return  Collection of EventInfo objects representing event(s). 
    713    * @throws CalFacadeException 
    714    */ 
    715   public Collection getEvent(String guid, String rid, 
    716                              Integer seqnum, 
    717                              int recurRetrieval) throws CalFacadeException; 
    718  
    719   /** Return the events for the current user within the given date/time 
    720    * range. 
    721    * 
    722    * @param calendar     BwCalendar object restricting search or null. 
    723    * @param filter       BwFilter object restricting search or null. 
    724    * @param startDate    DateTimeVO start - may be null 
    725    * @param endDate      DateTimeVO end - may be null. 
    726    * @param recurRetrieval Takes value defined in CalFacadeDefs 
    727    * @return Collection  populated event value objects 
    728    * @throws CalFacadeException 
    729    */ 
    730   public Collection getEvents(BwCalendar calendar, BwFilter filter, 
    731                               BwDateTime startDate, BwDateTime endDate, 
    732                               int recurRetrieval) 
    733           throws CalFacadeException; 
    734  
    735   /** Add an event to the database. The id and uid will be set in the parameter 
    736    * object. 
    737    * 
    738    * @param val   EventVO object to be added 
    739    * @param overrides    Collection of BwEventProxy objects which override instances 
    740    *                     of the new event 
    741    * @throws CalFacadeException 
    742    */ 
    743   public void addEvent(BwEvent val, 
    744                        Collection overrides) throws CalFacadeException; 
    745  
    746   /** Update an event in the database. 
    747    * 
    748    * <p>This method will set any synchronization state entries to modified 
    749    * unless we are synchronizing in which case that belonging to the current 
    750    * user is set to mark the event as synchronized 
    751    * 
    752    * @param val   EventVO object to be replaced 
    753    * @exception CalFacadeException If there's a db problem or problem with 
    754    *     the event 
    755    * @throws CalFacadeException 
    756    */ 
    757   public void updateEvent(BwEvent val) throws CalFacadeException; 
    758  
    759   /** This class allows the implementations to pass back some information 
    760    * about what happened. If possible it should fill in the supplied fields. 
    761    * 
    762    * A result of zero for counts does not necessarily indicate nothing 
    763    * happened, for example, the implementation may store elarms as part of 
    764    * the event object and they just go as part of event deletion. 
    765    */ 
    766   public static class DelEventResult { 
    767     /**  false if it didn't exist 
    768      */ 
    769     public boolean eventDeleted; 
    770  
    771     /** Number of alarms deleted 
    772      */ 
    773     public int alarmsDeleted; 
    774  
    775     /** Constructor 
    776      * 
    777      * @param eventDeleted 
    778      * @param alarmsDeleted 
    779      */ 
    780     public DelEventResult(boolean eventDeleted, 
    781                           int alarmsDeleted) { 
    782       this.eventDeleted = eventDeleted; 
    783       this.alarmsDeleted = alarmsDeleted; 
    784     } 
    785   } 
    786  
    787   /** Delete an event and any associated alarms 
    788    * Set any referring synch states to deleted. 
    789    * 
    790    * @param val                EventVO object to be deleted 
    791    * @return DelEventResult    result. 
    792    * @exception CalFacadeException If there's a database access problem 
    793    */ 
    794   public DelEventResult deleteEvent(BwEvent val) throws CalFacadeException; 
    795  
    796   /* * Assign a guid to an event which must exist in the db. A noop if this 
    797    * event already has a guid. 
    798    * 
    799    * @param val      EventVO object 
    800    * / 
    801   public void assignGuid(BwEvent val) throws CalFacadeException;*/ 
    802  
    803   /** Return true if this event is editable by the current user 
    804    * 
    805    * @param val                EventVO object to be tested 
    806    * @return boolean 
    807    * @throws CalFacadeException 
    808    */ 
    809   public boolean editable(BwEvent val) throws CalFacadeException; 
    810  
    811   /* ==================================================================== 
    812    *                       Caldav support 
    813    * Caldav as it stands at the moment requires that we save the arbitary 
    814    * names clients might assign to events. 
    815    * ==================================================================== */ 
    816  
    817   /** Get events given the calendar and String name. Return null for not 
    818    * found. For non-recurring there should be only one event. Otherwise we 
    819    * return the currently expanded set of recurring events. 
    820    * 
    821    * @param cal        CalendarVO object 
    822    * @param val        String possible name 
    823    * @return Collection of EventVO or null 
    824    * @throws CalFacadeException 
    825    */ 
    826   public Collection getEventsByName(BwCalendar cal, String val) 
    827           throws CalFacadeException; 
    828677 
    829678  /* ==================================================================== 
  • trunk/calendar3/caldav/src/edu/rpi/cct/uwcal/caldav/CaldavBWIntf.java

    r47 r207  
    268268  public void delete(WebdavNsNode node) throws WebdavIntfException { 
    269269    try { 
    270       CaldavBwNode uwnode = getUwnode(node); 
     270      CaldavBwNode uwnode = getBwnode(node); 
    271271 
    272272      if (!(uwnode instanceof CaldavComponentNode)) { 
     
    298298      throws WebdavIntfException { 
    299299    try { 
    300       CaldavBwNode uwnode = getUwnode(node); 
     300      CaldavBwNode uwnode = getBwnode(node); 
    301301 
    302302      Vector v = new Vector(); 
     
    379379      throws WebdavIntfException { 
    380380    try { 
    381       CaldavBwNode uwnode = getUwnode(node); 
     381      CaldavBwNode uwnode = getBwnode(node); 
    382382 
    383383      return WebdavProperty.getEnumeration(uwnode.getProperties(namespace)); 
     
    403403      } 
    404404 
    405       CaldavBwNode uwnode = getUwnode(node); 
     405      CaldavBwNode uwnode = getBwnode(node); 
    406406 
    407407      return uwnode.getContent(); 
     
    501501      pcr.created = create; 
    502502 
    503       CaldavBwNode uwnode = getUwnode(node); 
    504       CaldavURI cdUri = uwnode.getCDURI(); 
     503      CaldavBwNode bwnode = getBwnode(node); 
     504      CaldavURI cdUri = bwnode.getCDURI(); 
    505505      String entityName = cdUri.getEntityName(); 
    506  
    507       Collection c = trans.fromIcal(new MyReader(contentRdr)); 
     506      BwCalendar cal = cdUri.getCal(); 
     507 
     508      Collection c = trans.fromIcal(cal, new MyReader(contentRdr)); 
    508509 
    509510      /** if more than one event these must all be instances of the same recurrence, i.e the 
     
    546547            pcr.created = true; 
    547548            ev.setName(entityName); 
    548             ev.setCalendar(cdUri.getCal()); 
    549             svci.addEvent(ev, evinfo.getOverrides()); 
     549            svci.addEvent(cal, ev, evinfo.getOverrides()); 
    550550 
    551551            StringBuffer sb = new StringBuffer(cdUri.getPath()); 
     
    634634  public void makeCollection(HttpServletRequest req, WebdavNsNode node) throws WebdavIntfException { 
    635635    try { 
    636       CaldavBwNode uwnode = getUwnode(node); 
     636      CaldavBwNode uwnode = getBwnode(node); 
    637637      CaldavURI cdUri = uwnode.getCDURI(); 
    638638 
     
    822822 
    823823  public void emitAcl(WebdavNsNode node) throws WebdavIntfException { 
    824     CaldavBwNode uwnode = getUwnode(node); 
     824    CaldavBwNode uwnode = getBwnode(node); 
    825825    CaldavURI cdUri = uwnode.getCDURI(); 
    826826    Collection aces = null; 
     
    987987  public void generatePropResourcetype(WebdavNsNode node) 
    988988          throws WebdavIntfException { 
    989     CaldavBwNode uwnode = getUwnode(node); 
     989    CaldavBwNode uwnode = getBwnode(node); 
    990990 
    991991    if (debug) { 
     
    10311031  public Collection query(WebdavNsNode wdnode, int retrieveRecur, 
    10321032                          Filter fltr) throws WebdavIntfException { 
    1033     CaldavBwNode node = getUwnode(wdnode); 
     1033    CaldavBwNode node = getBwnode(wdnode); 
    10341034    CalSvcI svci = getSvci(); 
    10351035    Collection events; 
     
    11041104                                FreeBusyQuery freeBusy) throws WebdavIntfException { 
    11051105    try { 
    1106       CaldavBwNode uwnode = getUwnode(wdnode); 
     1106      CaldavBwNode uwnode = getBwnode(wdnode); 
    11071107      if (!(uwnode instanceof CaldavCalNode)) { 
    11081108        throw WebdavIntfException.badRequest(); 
     
    14371437  } 
    14381438 
    1439   private CaldavBwNode getUwnode(WebdavNsNode node) 
     1439  private CaldavBwNode getBwnode(WebdavNsNode node) 
    14401440      throws WebdavIntfException { 
    14411441    if (!(node instanceof CaldavBwNode)) { 
  • trunk/calendar3/calsvc/src/org/bedework/calsvc/CalSvc.java

    r200 r207  
    14391439  } 
    14401440 
    1441   public Collection getEvent(String guid, String recurrenceId, 
     1441  public Collection getEvent(BwSubscription sub, BwCalendar cal,  
     1442                             String guid, String recurrenceId, 
    14421443                             int recurRetrieval) throws CalFacadeException { 
    1443     return postProcess(getCal().getEvent(guid, recurrenceId, null, recurRetrieval), 
    1444                        (BwSubscription)null); 
     1444    return postProcess(getCal().getEvent(cal, guid, recurrenceId, recurRetrieval), 
     1445                       sub); 
    14451446  } 
    14461447 
     
    15221523      sub = (BwSubscription)it.next(); 
    15231524 
    1524       if (sub.getInternalSubscription() && !sub.getCalendarDeleted()) { 
    1525         BwCalendar calendar = sub.getCalendar(); 
    1526  
    1527         if (calendar == null) { 
    1528           String path; 
    1529           String uri = sub.getUri(); 
    1530  
    1531           if (uri.startsWith(CalFacadeDefs.bwUriPrefix)) { 
    1532             path = uri.substring(CalFacadeDefs.bwUriPrefix.length()); 
    1533           } else { 
    1534             // Shouldn't happen? 
    1535             path = uri; 
    1536           } 
    1537  
    1538           if (debug) { 
    1539             trace("Search for calendar \"" + path + "\""); 
    1540           } 
    1541  
    1542           calendar = getCal().getCalendar(path); 
    1543           if (calendar == null) { 
    1544             // Assume deleted 
    1545             sub.setCalendarDeleted(true); 
    1546             updateSubscription(sub); 
    1547           } else { 
    1548             sub.setCalendar(calendar); 
    1549           } 
    1550         } 
    1551  
    1552         if (calendar != null) { 
    1553           internal.addChild(calendar); 
    1554           putSublookup(sublookup, sub, calendar); 
    1555         } 
     1525      BwCalendar calendar = getSubCalendar(sub); 
     1526       
     1527      if (calendar != null) { 
     1528        internal.addChild(calendar); 
     1529        putSublookup(sublookup, sub, calendar); 
    15561530      } 
    15571531    } 
     
    15631537 
    15641538    return ts; 
     1539  } 
     1540   
     1541  private BwCalendar getSubCalendar(BwSubscription sub) throws CalFacadeException { 
     1542    if (!sub.getInternalSubscription() || sub.getCalendarDeleted()) { 
     1543      return null; 
     1544    } 
     1545     
     1546    BwCalendar calendar = sub.getCalendar(); 
     1547     
     1548    if (calendar != null) { 
     1549      return calendar; 
     1550    } 
     1551     
     1552    String path; 
     1553    String uri = sub.getUri(); 
     1554     
     1555    if (uri.startsWith(CalFacadeDefs.bwUriPrefix)) { 
     1556      path = uri.substring(CalFacadeDefs.bwUriPrefix.length()); 
     1557    } else { 
     1558      // Shouldn't happen? 
     1559      path = uri; 
     1560    } 
     1561     
     1562    if (debug) { 
     1563      trace("Search for calendar \"" + path + "\""); 
     1564    } 
     1565     
     1566    calendar = getCal().getCalendar(path); 
     1567    if (calendar == null) { 
     1568      // Assume deleted 
     1569      sub.setCalendarDeleted(true); 
     1570      updateSubscription(sub); 
     1571    } else { 
     1572      sub.setCalendar(calendar); 
     1573    } 
     1574     
     1575    return calendar; 
    15651576  } 
    15661577   
     
    16081619  } 
    16091620 
    1610   public EventUpdateResult addEvent(BwEvent event, 
     1621  public EventUpdateResult addEvent(BwCalendar cal, 
     1622                                    BwEvent event, 
    16111623                                    Collection overrides) throws CalFacadeException { 
    16121624    EventUpdateResult updResult = new EventUpdateResult(); 
     
    16311643    } 
    16321644 
    1633     /* If no calendar has been assigned to this event set it to the default 
     1645    /* If no calendar has been assigned for this event set it to the default 
    16341646     * calendar for non-public events or reject it for public events. 
    16351647     */ 
    16361648 
    1637     if (event.getCalendar() == null) { 
     1649    if (cal == null) { 
    16381650      if (event.getPublick()) { 
    16391651        throw new CalFacadeException("No calendar assigned"); 
    16401652      } 
    16411653 
    1642       event.setCalendar(getPreferences().getDefaultCalendar()); 
    1643     } 
    1644  
    1645     if (!event.getCalendar().getCalendarCollection()) { 
     1654      cal = getPreferences().getDefaultCalendar(); 
     1655    } 
     1656 
     1657    if (!cal.getCalendarCollection()) { 
    16461658      throw new CalFacadeAccessException(); 
    16471659    } 
     1660     
     1661    event.setCalendar(cal); 
    16481662 
    16491663    event.setDtstamp(new DtStamp(new DateTime(true)).getValue()); 
     
    21442158    } 
    21452159 
    2146     public Collection getEvent(String guid, String rid, 
    2147                                Integer seq, 
     2160    public Collection getEvent(BwCalendar cal, String guid, String rid, 
    21482161                               int recurRetrieval) throws CalFacadeException { 
    2149       return CalSvc.this.getEvent(guid, rid, recurRetrieval); 
     2162      return CalSvc.this.getEvent(BwSubscription.makeSubscription(cal), cal, guid,  
     2163                                  rid, recurRetrieval); 
    21502164    } 
    21512165 
  • trunk/calendar3/calsvci/src/org/bedework/calsvci/CalSvcI.java

    r191 r207  
    10711071  public abstract EventInfo getEvent(int eventId) throws CalFacadeException; 
    10721072 
    1073   /** Return one or more events for the current user using the guid as a key. 
     1073  /** Return one or more events for the current user using the calendar, guid 
     1074   * and the recurrence id as a key. 
    10741075   * 
    10751076   * <p>For non-recurring events, one and only one event should be reurned. 
     
    10771078   * with any exceptions should be returned. 
    10781079   * 
     1080   * @param   sub       BwSubscription object 
     1081   * @param   cal       BwCalendar object 
    10791082   * @param   guid      String guid for the event 
    10801083   * @param   recurrenceId String recurrence id or null 
     
    10831086   * @throws CalFacadeException 
    10841087   */ 
    1085   public abstract Collection getEvent(String guid, String recurrenceId, 
     1088  public abstract Collection getEvent(BwSubscription sub, BwCalendar cal,  
     1089                                      String guid,  
     1090                                      String recurrenceId, 
    10861091                                      int recurRetrieval) 
    10871092        throws CalFacadeException; 
     
    11901195   * will come from the target. 
    11911196   * 
     1197   * @param cal          BwCalendar defining recipient calendar 
    11921198   * @param event        BwEvent object to be added 
    11931199   * @param overrides    Collection of BwEventProxy objects which override instances 
     
    11961202   * @throws CalFacadeException 
    11971203   */ 
    1198   public abstract EventUpdateResult addEvent(BwEvent event, 
     1204  public abstract EventUpdateResult addEvent(BwCalendar cal, 
     1205                                             BwEvent event, 
    11991206                                             Collection overrides) throws CalFacadeException; 
    12001207 
  • trunk/calendar3/deployment/webpublic/webapp/resources/demoskins/default/default/default.xsl

    r204 r207  
    534534          <xsl:variable name="id" select="id"/> 
    535535          <xsl:variable name="subscriptionId" select="subscription/id"/> 
     536          <xsl:variable name="calendarId" select="calendar/id"/> 
    536537          <xsl:variable name="guid" select="guid"/> 
    537538          <xsl:variable name="recurrenceId" select="recurrenceId"/> 
    538           <a href="{$privateCal}/addEventRef.do?eventId={$id}" title="Add event to MyCalendar" target="myCalendar"> 
     539          <a href="{$privateCal}/addEventRef.do?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}" title="Add event to MyCalendar" target="myCalendar"> 
    539540            <img class="addref" src="{$resourcesRoot}/images/add2mycal-icon.gif" width="20" height="26" border="0" alt="Add event to MyCalendar"/> 
    540541          </a> 
    541542          <xsl:variable name="eventIcalName" select="concat($id,'.ics')"/> 
    542           <a href="{$export}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}&amp;nocache=no&amp;skinName=ical&amp;contentType=text/calendar&amp;contentName={$eventIcalName}" title="Download event as ical - for Outlook, PDAs, iCal, and other desktop calendars"> 
     543          <a href="{$export}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}&amp;nocache=no&amp;skinName=ical&amp;contentType=text/calendar&amp;contentName={$eventIcalName}" title="Download event as ical - for Outlook, PDAs, iCal, and other desktop calendars"> 
    543544            <img src="{$resourcesRoot}/images/std-ical_icon.gif" width="20" height="26" border="0" alt="Download this event"/> 
    544545          </a> 
     
    670671              <xsl:variable name="id" select="id"/> 
    671672              <xsl:variable name="subscriptionId" select="subscription/id"/> 
     673              <xsl:variable name="calendarId" select="calendar/id"/> 
    672674              <xsl:variable name="guid" select="guid"/> 
    673675              <xsl:variable name="recurrenceId" select="recurrenceId"/> 
     
    696698                  <xsl:otherwise> 
    697699                    <td class="{$dateRangeStyle} right"> 
    698                       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
     700                      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
    699701                      <xsl:choose> 
    700702                        <xsl:when test="start/allday = 'true' and 
     
    713715                    </td> 
    714716                    <td class="{$dateRangeStyle} center"> 
    715                       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}">-</a> 
     717                      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}">-</a> 
    716718                    </td> 
    717719                    <td class="{$dateRangeStyle} left"> 
    718                       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
     720                      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
    719721                      <xsl:choose> 
    720722                        <xsl:when test="end/allday = 'true' and 
     
    743745                  <xsl:choose> 
    744746                    <xsl:when test="/bedework/appvar[key='summaryMode']/value='details'"> 
    745                       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
     747                      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
    746748                        <strong><xsl:value-of select="summary"/>: </strong> 
    747749                        <xsl:value-of select="description"/>&#160; 
     
    765767                    </xsl:when> 
    766768                    <xsl:otherwise> 
    767                       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
     769                      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}"> 
    768770                        <xsl:value-of select="summary"/>, <xsl:value-of select="location/address"/> 
    769771                      </a> 
     
    773775                <td class="icons"> 
    774776                  <variable name="confId" select="/bedework/confirmationid"/> 
    775                   <a href="{$privateCal}/addEventRef.do?eventId={$id}" title="Add event to MyCalendar" target="myCalendar"> 
     777                  <a href="{$privateCal}/addEventRef.do?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}" title="Add event to MyCalendar" target="myCalendar"> 
    776778                    <img class="addref" src="{$resourcesRoot}/images/add2mycal-icon-small.gif" width="12" height="16" border="0" alt="Add event to MyCalendar"/> 
    777779                  </a> 
    778780                  <xsl:variable name="eventIcalName" select="concat($id,'.ics')"/> 
    779                   <a href="{$export}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}&amp;nocache=no&amp;skinName=ical&amp;contentType=text/calendar&amp;contentName={$eventIcalName}" title="Download event as ical - for Outlook, PDAs, iCal, and other desktop calendars"> 
     781                  <a href="{$export}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}&amp;nocache=no&amp;skinName=ical&amp;contentType=text/calendar&amp;contentName={$eventIcalName}" title="Download event as ical - for Outlook, PDAs, iCal, and other desktop calendars"> 
    780782                    <img src="{$resourcesRoot}/images/std-ical_icon_small.gif" width="12" height="16" border="0" alt="Download event as ical - for Outlook, PDAs, iCal, and other desktop calendars"/> 
    781783                  </a> 
     
    857859    <xsl:param name="dayPos"/> 
    858860    <xsl:variable name="subscriptionId" select="subscription/id"/> 
     861    <xsl:variable name="calendarId" select="calendar/id"/> 
    859862    <xsl:variable name="guid" select="guid"/> 
    860863    <xsl:variable name="recurrenceId" select="recurrenceId"/> 
     
    870873    </xsl:variable> 
    871874    <li> 
    872       <a href="{$eventView}?subid={$subscriptionId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}" class="{$eventClass}"> 
     875      <a href="{$eventView}?subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId}" class="{$eventClass}"> 
    873876        <xsl:value-of select="summary"/> 
    874877        <xsl:variable name="eventTipClass"> 
  • trunk/calendar3/docs/todo.txt

    r176 r207  
    11Todo 
    22 
     3-------------------------------------------------------------------------------- 
     4Remove references to getEvent(id) 
     5-------------------------------------------------------------------------------- 
     6Changes caused by use of calendar id. 
     7The last round of changes were caused by the need to make the guid unique only 
     8within the context of a calendar collection. This requires that the calendar 
     9id be part of the event key. 
     10 
     11All of the url for fetching single events need to change. There are about 8 of 
     12them in the public default stylesheet. 
     13 
     14The changes were relatively simple: 
     15   Change all occurrences of 
     16      subid={$subscriptionId}&amp; 
     17    to 
     18      subid={$subscriptionId}&amp;calid={$calendarId}&amp; 
     19   In 2-3 places you need to define calendarId. Look for occurences of 
     20      <xsl:variable name="subscriptionId" select="subscription/id"/> 
     21   and immediately following add 
     22      <xsl:variable name="calendarId" select="calendar/id"/> 
     23 
     24A further change is to look for the addEventRef.do url and change the text 
     25      eventId={$id} 
     26   to 
     27      subid={$subscriptionId}&amp;calid={$calendarId}&amp;guid={$guid}&amp;recurrenceId={$recurrenceId} 
     28that is, make it the same form as the others. (I found 2 of these) 
     29 
     30These changes will also be required in the user client stylesheet. 
    331-------------------------------------------------------------------------------- 
    432Lost the exrules from the recurrence info hbm - add them 
  • trunk/calendar3/icalendar/src/org/bedework/icalendar/BwEventUtil.java

    r2 r207  
    5555package org.bedework.icalendar; 
    5656 
     57import org.bedework.calfacade.BwCalendar; 
    5758import org.bedework.calfacade.BwCategory; 
    5859import org.bedework.calfacade.BwDateTime; 
     
    132133   * 
    133134   * @param cb          IcalCallback object 
     135   * @param cal 
    134136   * @param evs         Events we already converted - used to check for overrides. 
    135137   * @param val         VEvent object 
     
    139141   */ 
    140142  public static EventInfo toEvent(IcalCallback cb, 
     143                                  BwCalendar cal,  
    141144                                  Collection evs, 
    142145                                  VEvent val, 
     
    232235         * expansions etc. 
    233236         */ 
    234         Collection eis = cb.getEvent(guid, rid, null, 
     237        Collection eis = cb.getEvent(cal, guid, rid,  
    235238                                     CalFacadeDefs.retrieveRecurMaster); 
    236239        if ((eis == null) || (eis.size() == 0)) { 
  • trunk/calendar3/icalendar/src/org/bedework/icalendar/IcalCallback.java

    r50 r207  
    5555package org.bedework.icalendar; 
    5656 
     57import org.bedework.calfacade.BwCalendar; 
    5758import org.bedework.calfacade.BwCategory; 
    5859import org.bedework.calfacade.BwLocation; 
     
    109110   * event with overrides. 
    110111   * 
     112   * @param cal       calendar to search 
    111113   * @param guid 
    112114   * @param rid 
    113    * @param seqnum 
    114115   * @param recurRetrieval Takes value defined in CalFacadeDefs. 
    115116   * @return Collection of EventInfo 
    116117   * @throws CalFacadeException 
    117118   */ 
    118   public Collection getEvent(String guid, String rid, 
    119                              Integer seqnum, 
     119  public Collection getEvent(BwCalendar cal, String guid, String rid, 
    120120                             int recurRetrieval) throws CalFacadeException; 
    121121 
  • trunk/calendar3/icalendar/src/org/bedework/icalendar/IcalTranslator.java

    r170 r207  
    5555package org.bedework.icalendar; 
    5656 
     57import org.bedework.calfacade.BwCalendar; 
    5758import org.bedework.calfacade.BwEvent; 
    5859import org.bedework.calfacade.BwUser; 
     
    263264   * a collection of events which may be empty. 
    264265   * 
     266   * @param cal       calendar 
    265267   * @param val 
    266268   * @return Collection 
    267269   * @throws CalFacadeException 
    268270   */ 
    269   public Collection fromIcal(String val) throws CalFacadeException { 
     271  public Collection fromIcal(BwCalendar cal, String val) throws CalFacadeException { 
    270272    try { 
    271273      CalendarBuilder bldr = new CalendarBuilder(new CalendarParserImpl()); 
    272274 
    273       return fromIcal(bldr.build(new UnfoldingReader(new StringReader(val)))); 
     275      return fromIcal(cal, bldr.build(new UnfoldingReader(new StringReader(val)))); 
    274276    } catch (ParserException pe) { 
    275277      if (debug) { 
     
    286288  /** Convert the Icalendar reader to a Collection of Calendar objects 
    287289   * 
     290   * @param cal       calendar 
    288291   * @param rdr 
    289292   * @return Collection 
    290293   * @throws CalFacadeException 
    291294   */ 
    292   public Collection fromIcal(Reader rdr) throws CalFacadeException { 
     295  public Collection fromIcal(BwCalendar cal, Reader rdr) throws CalFacadeException { 
    293296    try { 
    294297      System.setProperty("ical4j.unfolding.relaxed", "true"); 
    295298      CalendarBuilder bldr = new CalendarBuilder(new CalendarParserImpl()); 
    296299 
    297       return fromIcal(bldr.build(new UnfoldingReader(rdr))); 
     300      return fromIcal(cal, bldr.build(new UnfoldingReader(rdr))); 
    298301    } catch (ParserException pe) { 
    299302      if (debug) { 
     
    310313  /** Convert the Calendar to a Collection of calendar objects. 
    311314   * 
     315   * @param cal       calendar 
    312316   * @param val 
    313317   * @return Collection 
    314318   * @throws CalFacadeException 
    315319   */ 
    316   public Collection fromIcal(Calendar val) throws CalFacadeException { 
     320  public Collection fromIcal(BwCalendar cal, Calendar val) throws CalFacadeException { 
    317321    Vector objs = new Vector(); 
    318322 
     
    329333 
    330334      if (o instanceof VEvent) { 
    331         EventInfo ev = BwEventUtil.toEvent(cb, objs, (VEvent)o, debug); 
     335        EventInfo ev = BwEventUtil.toEvent(cb, cal, objs, (VEvent)o, debug); 
    332336 
    333337        if (ev != null) { 
  • trunk/calendar3/synchml/src/edu/rpi/cct/uwcal/synchml/common/Synchml.java

    r2 r207  
    256256   */ 
    257257  public boolean updateEvent(VEvent val) throws CalFacadeException { 
    258     updateEvent(BwEventUtil.toEvent(svci.getIcalCallback(), null, val, debug).getEvent()); 
     258    // FIXME - We need a subscription to the calendar we are synching - second par 
     259    updateEvent(BwEventUtil.toEvent(svci.getIcalCallback(), null, null, val, debug).getEvent()); 
    259260 
    260261    return true; 
     
    269270   */ 
    270271  public boolean deleteEvent(VEvent val) throws CalFacadeException { 
    271     return deleteEvent(BwEventUtil.toEvent(svci.getIcalCallback(), null, val, debug).getEvent()); 
     272    // FIXME - We need a subscription to the calendar we are synching - second par 
     273    return deleteEvent(BwEventUtil.toEvent(svci.getIcalCallback(), null, null, val, debug).getEvent()); 
    272274  } 
    273275 
     
    353355 
    354356          String evData = synchData.getEventData(); 
    355           Collection c = trans.fromIcal(evData); 
     357          // FIXME - We need a subscription to the calendar we are synching - second par 
     358          Collection c = trans.fromIcal(null, evData); 
    356359          if (c.size() != 1) { 
    357360            throw new CalFacadeException("Invalid event data: " + evData); 
     
    438441   */ 
    439442  public boolean addEvent(BwEvent val) throws CalFacadeException { 
    440     svci.addEvent(val, null); 
     443    // FIXME - We need a subscription to the calendar we are synching - first par 
     444    svci.addEvent(null, val, null); 
    441445 
    442446    return true; 
     
    479483   */ 
    480484  public BwEvent findEvent(String val) throws CalFacadeException { 
    481     Collection eis = svci.getEvent(val, null, CalFacadeDefs.retrieveRecurMaster); 
     485    // FIXME - We need a subscription (first par) to the calendar (second par) 
     486    Collection eis = svci.getEvent(null, null, val, null, CalFacadeDefs.retrieveRecurMaster); 
    482487    if ((eis == null) || (eis.size() == 0)) { 
    483488      return null; 
     
    520525    ev.setSummary("Temp"); 
    521526 
    522     svci.addEvent(ev, null); 
     527    // FIXME - We need a subscription to the calendar we are synching - first par 
     528    svci.addEvent(null, ev, null); 
    523529 
    524530    return ev.getGuid(); 
  • trunk/calendar3/test/src/org/bedework/tests/calsvc/CalSvcTestUtil.java

    r2 r207  
    505505      } 
    506506 
    507 //      if (calendar == null) { 
    508         ev.setCalendar(svci.getCalendar()); 
    509 //      } 
    510  
    511       svci.addEvent(ev, null); 
     507      svci.addEvent(svci.getCalendar(), ev, null); 
    512508      log("Created event, id=" + ev.getId()); 
    513509      return ev.getId(); 
  • trunk/calendar3/test/src/org/bedework/tests/calsvc/CalSvcTestWrapper.java

    r2 r207  
    357357    } 
    358358 
    359     addEvent(ev, null); 
     359    addEvent(null, ev, null); 
    360360 
    361361    return ev.getId(); 
  • trunk/calendar3/test/src/org/bedework/tests/ical/IcalTranslatorTest.java

    r2 r207  
    5555package org.bedework.tests.ical; 
    5656 
     57import org.bedework.calfacade.BwCalendar; 
    5758import org.bedework.calfacade.BwEvent; 
    5859import org.bedework.calfacade.BwLocation; 
     
    207208      System.out.println("==========================================="); 
    208209 
    209       Collection c = makeEvents(icalTrans, icalText); 
     210      BwCalendar cal = svciUtil.getSvci(privateUser1).getCalendar(); 
     211      Collection c = makeEvents(icalTrans, cal, icalText); 
    210212      Iterator it = c.iterator(); 
    211213 
     
    225227   * ==================================================================== */ 
    226228 
    227   /** Get a Collection of EventInfo 
     229  /* Get a Collection of EventInfo 
    228230   * 
    229231   * @param icalTrans 
     232   * @param cal 
    230233   * @param calText 
    231234   * @return Collection 
     
    233236   */ 
    234237  private Collection makeEvents(IcalTranslator icalTrans, 
     238                                BwCalendar cal, 
    235239                                String[] calText) throws Throwable { 
    236240    StringBuffer sb = new StringBuffer(); 
     
    243247    svciUtil.open(privateUser1); 
    244248    try { 
    245       return icalTrans.fromIcal(sb.toString()); 
     249      return icalTrans.fromIcal(cal, sb.toString()); 
    246250    } finally { 
    247251      svciUtil.close(privateUser1); 
  • trunk/calendar3/webadmin/src/org/bedework/webadmin/event/PEUpdateEventAction.java

    r128 r207  
    160160 
    161161    if (form.getAddingEvent()) { 
    162       svci.addEvent(event, null); 
     162      svci.addEvent(event.getCalendar(), event, null); 
    163163    } else { 
    164164      svci.updateEvent(event); 
  • trunk/calendar3/webclient/src/org/bedework/webclient/BwAddEventAction.java

    r55 r207  
    131131    } 
    132132 
    133     svci.addEvent(ev, null); 
     133    svci.addEvent(ev.getCalendar(), ev, null); 
    134134 
    135135    form.resetNewEvent(); 
  • trunk/calendar3/webclient/src/org/bedework/webclient/BwAddEventRefAction.java

    r55 r207  
    5656 
    5757import org.bedework.appcommon.BedeworkDefs; 
    58 import org.bedework.calfacade.BwEvent; 
    5958import org.bedework.calfacade.BwEventProxy; 
    6059import org.bedework.calfacade.svc.EventInfo; 
     
    8382    } 
    8483 
    85     int id = form.getEventId(); 
    86  
    87     if (id < 0) { 
    88       // Do nothing 
    89       form.getErr().emit("org.bedework.client.error.nosuchevent", id); 
    90       return "doNothing"; 
    91     } 
    92  
    9384    CalSvcI svci = form.fetchSvci(); 
    9485 
    95     EventInfo ei = svci.getEvent(id); 
     86    EventInfo ei = findEvent(request, form); 
    9687 
    9788    if (ei == null) { 
    9889      // Do nothing 
    99       form.getErr().emit("org.bedework.client.error.nosuchevent", id); 
    10090      return "doNothing"; 
    10191    } 
     
    10494     * the appropriate fields from the target 
    10595     */ 
    106     BwEvent proxy = BwEventProxy.makeAnnotation(ei.getEvent(), 
     96    BwEventProxy proxy = BwEventProxy.makeAnnotation(ei.getEvent(), 
    10797                                                ei.getEvent().getOwner()); 
    10898 
    109     svci.addEvent(proxy, null); 
     99    svci.addEvent(null, proxy.getTarget(), null); 
    110100 
    111101    form.getMsg().emit("org.bedework.client.message.added.eventrefs", 1); 
  • trunk/calendar3/webcommon/src/org/bedework/webcommon/BwAbstractAction.java

    r163 r207  
    7979import org.bedework.calsvci.CalSvcIPars; 
    8080 
    81 import edu.rpi.sss.util.Util; 
    82  
    8381import edu.rpi.sss.util.jsp.JspUtil; 
    8482import edu.rpi.sss.util.jsp.SessionListener; 
     
    371369      } 
    372370    } 
    373  
    374     String guid = request.getParameter("guid"); 
    375  
    376     if (Util.checkNull(guid) != null) { 
     371     
     372    int calId = getIntReqPar(request, "calid", -1); 
     373    BwCalendar cal = null; 
     374 
     375    if (calId < 0) { 
     376      form.getErr().emit("org.bedework.client.error.missingsubscriptionid"); 
     377      return null; 
     378    } 
     379     
     380    cal = svci.getCalendar(calId); 
     381     
     382    if (cal == null) { 
     383      // Assume no access 
     384      form.getErr().emit("org.bedework.client.error.noaccess"); 
     385      return null; 
     386    } 
     387 
     388    String guid = getReqPar(request, "guid"); 
     389 
     390    if (guid != null) { 
    377391      if (debug) { 
    378392        debugMsg("Get event by guid"); 
    379393      } 
    380       String rid = Util.checkNull(request.getParameter("recurrenceId")); 
     394      String rid = getReqPar(request, "recurrenceId"); 
    381395      int retMethod = CalFacadeDefs.retrieveRecurMaster; 
    382       Collection evs = svci.getEvent(guid, rid, retMethod); 
     396      Collection evs = svci.getEvent(sub, cal, guid, rid, retMethod); 
    383397      if (debug) { 
    384398        debugMsg("Get event by guid found " + evs.size()); 
     
    397411      debugMsg("Get event by guid found " + ev.getEvent()); 
    398412    } 
    399  
    400     ev.setSubscription(sub); 
    401413 
    402414    return ev; 
  • trunk/calendar3/webcommon/src/org/bedework/webcommon/misc/UploadAction.java

    r55 r207  
    5555package org.bedework.webcommon.misc; 
    5656 
     57import org.bedework.calfacade.BwCalendar; 
    5758import org.bedework.calfacade.BwEvent; 
    5859import org.bedework.calfacade.svc.EventInfo; 
     
    9091    } 
    9192 
     93    CalSvcI svci = form.fetchSvci(); 
     94    BwCalendar cal = null; 
     95 
     96    int calId = getIntReqPar(request, "calId", -1); 
     97    if (calId >= 0) { 
     98      cal = svci.getCalendar(calId); 
     99    } 
     100 
     101    if (cal == null) { 
     102      form.getErr().emit("org.bedework.client.error.missingcalendar"); 
     103      return null; 
     104    } 
     105 
    92106    FormFile upFile = form.getUploadFile(); 
    93107 
     
    105119    InputStream is = upFile.getInputStream(); 
    106120 
    107     CalSvcI svci = form.fetchSvci(); 
    108  
    109121    IcalTranslator trans = new IcalTranslator(svci.getIcalCallback(), debug); 
    110122 
    111     Collection objs = trans.fromIcal(new InputStreamReader(is)); 
     123    Collection objs = trans.fromIcal(cal, new InputStreamReader(is)); 
    112124 
    113125    Iterator it = objs.iterator(); 
     
    121133 
    122134        if (ei.getNewEvent()) { 
    123           svci.addEvent(ev, ei.getOverrides()); 
     135          svci.addEvent(cal, ev, ei.getOverrides()); 
    124136        } else { 
    125137          svci.updateEvent(ev);