We need some form of event override mechanism to handle situations where a user may wish to modify an event for which they have no write access. A further use is handling overrides - exceptions - in recurring events.
A scheme has been partially implemented.
Updating read-only events
A user may have a reference in their personal calendar to a public event or some other users event which MUST exist in a different calendar. They may wish to annotate this event, for example, if it is a two hour performance for which they intend to stay only 1 hour, they may wish to change the end time to reflect that. Also they may synch it to a device which doesn't deal with references or ownership and the event may get changed on that device and synched back.
A problem may occur if we develop a chain of annotations. For example:
- the event is owned by user A
- user B annotates it and limits the access to user C
- user C annotates it and gives access to user D
- user D can access the annnotations but is unable to access the annotation added by B
Is that bogus
Where do we put the override?
If the event is in a subscribed calendar, le's say /public/Meetings we can't put the annotation in that calendar as the user has no access. We could put the annotation in one of the users calendars but it just looks like another event and the original event will still be visible in its unannotated fom in the original calendar.
Maybe we limit annotations to overrides and eventrefs.
A particular instance is represented by an annotation to a master event - created dynamically on recurrence retrieval. The user may wish to update the instance by changing the time or simply adding annotations for their own private use. In that case there is an annotation stored in the db.
If the recurring event has an instance overriden by the owner in the same calendar as the master it is a normal recurrence override.
In addition, that user or another with access to the event, may wish to annotate a particular instance. If that user has write access they may simply update the event, all with access will see that change which is, again, a normal overrride.
On the other hand, they may wish, or be forced, to create an annotated version which does not alter to shared version. If that annotation appears in another calendar it probably needs to be treated as a single non-recurring event. That is, it is probably impractical to allow a user to create an override to a single instance of a recurring event in another calendar and have that override appear as part of a recurrence.
If a user has write access to a recurring event and they override it, the override should be owned by the owner of the master.
HOWEVER: what happens if somebody annotates or has a reference to a master event?
This involves the classes,
If an event is annotated we save the annotation to the database as a sparsely populated BwEventAnnotation?. The annotation has two references which may refer to the same object, one is the target of the annottaion, which may itself be an annotation, the other is the master event, which is the end of the chain of annotations.
The BwEventProxy? is returned on retrieveal when there is a BwEventAnnotation?. The BwEventProxy? has a reference to the annotation and handles figuring out which value to return from a getter method, For example, if the annotation has a description, we return the description in the annotation rather than the target.
Handling a simple text field seems simple enough but has its own problems. For example, if we annotated the location, does the user want the annotation location added to the target event location or to replace it?
How do we indicate that we want to entirely suppress the contents of a text field?
Harder than that is the problem of dealing with Collections. If we have attendees in the target what does the presence of attendees in the annotation mean. Replacement, addition?
We will assume that if a simple String field has been changed it overrides the value of the field. In our client we can still offer the option of digging down to the annotated object.
A similar approach works for something like attendees. The user modifies the attendee list so we copy the whole of the modified list into the annotation class.
We do have a problem with indicating we have deleted all objecst - for example - we don't want any of the alarms. This is handled by a flag in the annotatuion object which indicates that the Collection was explcitly emptied in the annotated form.