Interface AgendaAvailabilityService
Every method takes the asking user's identity, and every method
enforces it. Availability is calendar content: knowing when someone
is busy is knowing that they have a meeting, and over a long enough window
it maps their working life. The rule applied here is not a new one — it is
Utils.canAccessCalendar, the same check
AgendaEventService.getEvents(org.exoplatform.agenda.model.EventFilter, java.time.ZoneId, long) applies to a calendar owner. For a
personal calendar that check resolves to "its owner, and no one else", so in
practice a user may currently ask about their own availability only.
That is deliberately the narrow reading. Whether, and to whom, a user should be able to expose their free/busy is a product decision that has not been taken; until it is, this service enforces the guard that already exists rather than inventing a sharing policy of its own. When such a policy arrives it belongs here, in this one place, so that every surface built on this service — REST, MCP, the UI — moves together and none of them can drift.
-
Method Summary
Modifier and TypeMethodDescriptiongetAvailability(List<Long> targetIdentityIds, ZonedDateTime start, ZonedDateTime end, long userIdentityId) Computes the busy and free blocks of each given user over a window.getConflicts(List<Long> attendeeIdentityIds, ZonedDateTime start, ZonedDateTime end, long userIdentityId) Reports which of the given attendees clash with a proposed window.rankDateOptionsByAvailability(List<EventDateOption> dateOptions, List<Long> attendeeIdentityIds, long userIdentityId) Orders date-poll options so that the ones suiting the most attendees come first.suggestMeetingTime(List<Long> attendeeIdentityIds, Duration duration, ZonedDateTime windowStart, ZonedDateTime windowEnd, boolean morningsOnly, boolean afternoonsOnly, int limit, long userIdentityId) Proposes the slots of the given length, inside the given window, over which every one of the given attendees is free.
-
Method Details
-
getAvailability
List<UserAvailability> getAvailability(List<Long> targetIdentityIds, ZonedDateTime start, ZonedDateTime end, long userIdentityId) throws IllegalAccessException Computes the busy and free blocks of each given user over a window.- Parameters:
targetIdentityIds- technical identifiers of the users whose availability is asked forstart- window start, inclusiveend- window end, exclusiveuserIdentityId- technical identifier of the user asking- Returns:
- one
UserAvailabilityper requested user, in the order asked - Throws:
IllegalAccessException- when the asking user is not allowed to read the availability of any one of the requested usersIllegalArgumentException- when the window or the user list is missing or empty, or when the window ends before it starts
-
suggestMeetingTime
List<TimeBlock> suggestMeetingTime(List<Long> attendeeIdentityIds, Duration duration, ZonedDateTime windowStart, ZonedDateTime windowEnd, boolean morningsOnly, boolean afternoonsOnly, int limit, long userIdentityId) throws IllegalAccessException Proposes the slots of the given length, inside the given window, over which every one of the given attendees is free.The proposal is only worth as much as the calendars behind it, so this method refuses rather than guesses: if the asking user cannot read one attendee's availability, no slot is proposed at all. Silently proposing slots computed from a subset of the attendees would return a confident answer that is not backed by the data.
- Parameters:
attendeeIdentityIds- technical identifiers of the users who must all be freeduration- the length a slot must havewindowStart- earliest acceptable startwindowEnd- latest acceptable endmorningsOnly- restrict candidate starts to before noonafternoonsOnly- restrict candidate starts to noon and afterlimit- maximum number of slots to proposeuserIdentityId- technical identifier of the user asking- Returns:
- the candidate slots, earliest first, at most
limitof them - Throws:
IllegalAccessException- when the asking user is not allowed to read the availability of any one of the attendeesIllegalArgumentException- when the attendee list, the duration or the window is missing or invalid
-
getConflicts
AvailabilityConflicts getConflicts(List<Long> attendeeIdentityIds, ZonedDateTime start, ZonedDateTime end, long userIdentityId) Reports which of the given attendees clash with a proposed window.Unlike
getAvailability(java.util.List<java.lang.Long>, java.time.ZonedDateTime, java.time.ZonedDateTime, long)this method does not refuse: it is an enrichment of an operation the user is already allowed to perform — creating or updating an event — and failing it would deny a legitimate write over information the user never asked for. It reports on the attendees it may read and names the ones it may not, so the answer is partial but never misleading. SeeAvailabilityConflicts.- Parameters:
attendeeIdentityIds- technical identifiers of the event's attendees; non-user identities are ignoredstart- proposed window startend- proposed window enduserIdentityId- technical identifier of the user asking- Returns:
- the clash report, never
null
-
rankDateOptionsByAvailability
List<EventDateOption> rankDateOptionsByAvailability(List<EventDateOption> dateOptions, List<Long> attendeeIdentityIds, long userIdentityId) Orders date-poll options so that the ones suiting the most attendees come first.Only the attendees the asking user may read are counted; an attendee whose availability is not readable counts for no option, so they shift no option relative to another. Like
getConflicts(java.util.List<java.lang.Long>, java.time.ZonedDateTime, java.time.ZonedDateTime, long)this degrades rather than refusing — an unreadable attendee costs ordering quality, not the poll.- Parameters:
dateOptions- the options to orderattendeeIdentityIds- technical identifiers of the event's attendeesuserIdentityId- technical identifier of the user asking- Returns:
- the options, most-available first, keeping the original order between equally available ones
-