Interface AgendaCalendarShareService


public interface AgendaCalendarShareService
Sharing a personal calendar, read-only, with colleagues (EXO-90357).

The rules, all held here. Only the owner of a personal calendar that is not a subscription shares it; a sharee may read the calendar and its events and nothing else, a private event as busy time only; a sharee may hide the calendar from their agenda without the share being deleted. Space calendars are not shareable in this version, nor is a share with a space or a group.

The status contract of every method taking a user: the calendar must exist (ObjectNotFoundException), the user must be its owner (IllegalAccessException), then the arguments are validated (IllegalArgumentException with a message code).

Delivery channels (CalendarShareChannelPlugin) are asked after the record is written and never decide whether it exists.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Broadcast once the owner changes what a colleague may do with a shared calendar (EXO-90378); source the CalendarShare as it now stands, data the owner identity id.
    static final String
    Broadcast once a share is recorded; source the CalendarShare, data the owner identity id.
    static final String
    Broadcast once a share is deleted by its owner; source the CalendarShare, data the owner identity id.
    static final String
    Message code: the calendar identifier is not positive.
    static final String
    Message code: no access level was given for a share (EXO-90378).
    static final String
    Message code: the channel carrying a share did not narrow its grant to the lower level asked for, so the level is unchanged (EXO-90378).
    static final String
    Message code: no channel carries this share, so nothing can be removed there.
    static final String
    Message code: the sharee has no record on this calendar.
    static final String
    Message code: the channel could not remove a share held on its server.
    static final String
    Message code: the sharee's account is disabled or deleted.
    static final String
    Message code: the sharee is the owner.
    static final String
    Message code: the sharee is not a known user.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    clearDelivery(long ownerIdentityId, String channelId)
    Forgets that a channel carries the shares of a user's calendars, once the user disconnected from that channel: the eXo shares stay, the channel's grants are left as the channel's truth.
    How many colleagues each of the user's own calendars is shared with, from one query; a calendar shared with nobody is absent.
    void
    deleteShares(long calendarId)
    Deletes every share of a calendar, once the calendar is deleted.
    void
    deleteSharesOfUser(long identityId)
    Deletes every share a deleted user held, as sharee and as owner of the shared calendars.
    getChannelShares(long calendarId, String ownerUsername)
    What every channel has to say about a calendar in one pass (EXO-90385): the access held outside eXo, as getExternalShares(long, java.lang.String) answers it, and whether a channel writes the owner's eXo meeting copies into it, as holdsMeetingCopies(long, java.lang.String) answers it.
    getExternalShares(long calendarId, String ownerUsername)
    The access a calendar's channels hold outside eXo, read live from every channel.
    getSharedCalendarIds(long viewerIdentityId)
    The identifiers of every calendar shared with an identity.
    The calendars shared with a user, newest share first, hidden ones included (they say so).
    getShareLevel(long calendarId, long viewerIdentityId)
    The level a calendar is shared with an identity at (EXO-90378): the write primitive, read from the same cached map as isSharedWith(long, long).
    getShareLevels(long viewerIdentityId)
    Every calendar shared with an identity and the level of each (EXO-90378): what a listing asks once, instead of asking per event.
    getShares(long calendarId, String ownerUsername)
    The colleagues a calendar is shared with, oldest share first.
    boolean
    holdsMeetingCopies(long calendarId, String ownerUsername)
    Whether a channel writes copies of the owner's eXo meetings into the calendar: what the drawer asks a confirmation for before sharing it (EXO-90345), since a share then exposes every meeting the owner attends.
    boolean
    isSharedWith(long calendarId, long viewerIdentityId)
    Whether a calendar is shared with an identity: the read primitive every ACL path relies on.
    void
    removeExternalShare(long calendarId, String channelId, String externalId, String ownerUsername)
    Removes a share on a channel's server, at the owner's request.
    void
    setHidden(long calendarId, String username, boolean hidden)
    Hides, or shows again, a calendar shared with the user.
    setLevel(long calendarId, long shareeIdentityId, CalendarShareLevel level, String ownerUsername)
    Changes what a colleague may do with a calendar shared with them (EXO-90378), then asks the delivery channels to make their grant match the new level.
    share(long calendarId, String shareeUsername, CalendarShareLevel level, String ownerUsername)
    Shares a calendar with a colleague, then asks every delivery channel to carry it.
    void
    unshare(long calendarId, long shareeIdentityId, String ownerUsername)
    Withdraws a share from the channel that carries it, then deletes the record.
  • Field Details

    • SHAREE_UNKNOWN

      static final String SHAREE_UNKNOWN
      Message code: the sharee is not a known user.
      See Also:
    • SHAREE_IS_OWNER

      static final String SHAREE_IS_OWNER
      Message code: the sharee is the owner.
      See Also:
    • SHAREE_DISABLED

      static final String SHAREE_DISABLED
      Message code: the sharee's account is disabled or deleted.
      See Also:
    • INVALID_CALENDAR

      static final String INVALID_CALENDAR
      Message code: the calendar identifier is not positive.
      See Also:
    • NO_CHANNEL

      static final String NO_CHANNEL
      Message code: no channel carries this share, so nothing can be removed there.
      See Also:
    • SHARE_NOT_REMOVED

      static final String SHARE_NOT_REMOVED
      Message code: the channel could not remove a share held on its server.
      See Also:
    • SHARE_NOT_FOUND

      static final String SHARE_NOT_FOUND
      Message code: the sharee has no record on this calendar.
      See Also:
    • LEVEL_MANDATORY

      static final String LEVEL_MANDATORY
      Message code: no access level was given for a share (EXO-90378).
      See Also:
    • LEVEL_NOT_NARROWED

      static final String LEVEL_NOT_NARROWED
      Message code: the channel carrying a share did not narrow its grant to the lower level asked for, so the level is unchanged (EXO-90378).
      See Also:
    • CALENDAR_SHARED_EVENT

      static final String CALENDAR_SHARED_EVENT
      Broadcast once a share is recorded; source the CalendarShare, data the owner identity id.
      See Also:
    • CALENDAR_UNSHARED_EVENT

      static final String CALENDAR_UNSHARED_EVENT
      Broadcast once a share is deleted by its owner; source the CalendarShare, data the owner identity id.
      See Also:
    • CALENDAR_SHARE_LEVEL_CHANGED_EVENT

      static final String CALENDAR_SHARE_LEVEL_CHANGED_EVENT
      Broadcast once the owner changes what a colleague may do with a shared calendar (EXO-90378); source the CalendarShare as it now stands, data the owner identity id.
      See Also:
  • Method Details

    • share

      CalendarShare share(long calendarId, String shareeUsername, CalendarShareLevel level, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Shares a calendar with a colleague, then asks every delivery channel to carry it. Delivery is invisible to the user sharing: the record stands whatever a channel answers, a channel that fails is logged and the record's deliveredTo stays null. Sharing again with the same colleague changes nothing in eXo and only asks the channels again for a delivery that has not happened.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeUsername - the colleague
      level - what the colleague may do with the calendar (EXO-90378); null shares at CalendarShareLevel.VIEW, the default of the drawer and of every share made before that feature. Sharing again with a colleague who already has a record does not change their level — setLevel(long, long, org.exoplatform.agenda.constant.CalendarShareLevel, java.lang.String) is what changes it, so that a repeated share can never quietly widen a right.
      ownerUsername - the user sharing, who must own the calendar
      Returns:
      the record
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it, or it is a space calendar or a subscription
      IllegalArgumentException - when the sharee is unknown, disabled, or the owner
    • setLevel

      CalendarShare setLevel(long calendarId, long shareeIdentityId, CalendarShareLevel level, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Changes what a colleague may do with a calendar shared with them (EXO-90378), then asks the delivery channels to make their grant match the new level. The owner's call, and only theirs: a colleague — an editor included — can neither level themselves nor level anyone else, because this goes through the same owner check as sharing and unsharing.

      Setting the level a share already has is not an error and still asks the channels: a level change is a fresh chance for a delivery that never happened, exactly as sharing again is. Raising a level stays invisible: a channel that cannot carry it is logged at WARN and the eXo level stands, which is what decides every right inside eXo, the server merely showing the colleague less.

      Lowering a delivered share is not invisible. The channel that carries it is asked to narrow its grant first, and the eXo level changes only when it did: a colleague who keeps the wider grant on the server would keep writing the owner's events there, and those writes reach eXo. When the channel fails, throws, or answers a level wider than the one asked for, the level is unchanged and LEVEL_NOT_NARROWED is thrown, for the owner to try again. A channel that answers that it no longer carries the share — the colleague left the server, the collection is gone — blocks nothing: the level changes and the delivery is forgotten, so a later unshare withdraws nothing there.

      Downgrading CalendarShareLevel.EDIT to CalendarShareLevel.VIEW moves nothing: the events the colleague created are the calendar's, and they simply stop being theirs to change.

      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      level - the new level, never null
      ownerUsername - the user levelling, who must own the calendar
      Returns:
      the record as it now stands
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist, or it is not shared with that colleague
      IllegalAccessException - when the user does not own the calendar
      IllegalArgumentException - when no level is given
      IllegalStateException - with LEVEL_NOT_NARROWED when the channel carrying the share did not narrow its grant
    • unshare

      void unshare(long calendarId, long shareeIdentityId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Withdraws a share from the channel that carries it, then deletes the record. The record is deleted even when the channel could not withdraw: the grant then shows up among the external shares, with its own removal. Unsharing a colleague who has no record succeeds silently.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      ownerUsername - the user unsharing, who must own the calendar
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it
    • getShares

      List<CalendarShare> getShares(long calendarId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      The colleagues a calendar is shared with, oldest share first.
      Parameters:
      calendarId - technical identifier of the calendar
      ownerUsername - the owner
      Returns:
      the records, possibly empty
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it
    • getExternalShares

      List<ExternalShare> getExternalShares(long calendarId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      The access a calendar's channels hold outside eXo, read live from every channel. A read-only grant to a user of this deployment is not answered: it is recorded, silently and without touching the server, as an adopted share (CalendarShareSource.ADOPTED, delivered to the channel that listed it), from then on a native share like any other — counted, seen by the colleague under "Shared with me", revocable. Recording is idempotent and notifies nobody: the colleague already had access. What is answered is the rest: an address outside eXo, the whole server, a published link, a colleague holding more than reading.

      The Share drawer reads getChannelShares(long, java.lang.String), which answers this and holdsMeetingCopies(long, java.lang.String) in one ask of each channel; this method stays for a caller that needs the shares alone, and it pays for the flag too.

      Parameters:
      calendarId - technical identifier of the calendar
      ownerUsername - the owner
      Returns:
      the access held outside eXo, possibly empty
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it
    • holdsMeetingCopies

      boolean holdsMeetingCopies(long calendarId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Whether a channel writes copies of the owner's eXo meetings into the calendar: what the drawer asks a confirmation for before sharing it (EXO-90345), since a share then exposes every meeting the owner attends.

      The Share drawer reads getChannelShares(long, java.lang.String); this method stays for a caller that needs the flag alone.

      Parameters:
      calendarId - technical identifier of the calendar
      ownerUsername - the owner
      Returns:
      true when any channel says so
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it
    • getChannelShares

      ChannelShares getChannelShares(long calendarId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      What every channel has to say about a calendar in one pass (EXO-90385): the access held outside eXo, as getExternalShares(long, java.lang.String) answers it, and whether a channel writes the owner's eXo meeting copies into it, as holdsMeetingCopies(long, java.lang.String) answers it.

      What the Share drawer asks, and the reason this exists: asking the two separately makes every channel hold the same conversation with its server twice, which on a remote CalDAV server is seconds of latency per opening. The adoption of a read-only grant into an eXo record happens here exactly as it does in getExternalShares(long, java.lang.String) — same rule, same silence.

      Parameters:
      calendarId - technical identifier of the calendar
      ownerUsername - the owner
      Returns:
      the access held outside eXo and the meeting-copies flag, never null
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist
      IllegalAccessException - when the user does not own it
    • removeExternalShare

      void removeExternalShare(long calendarId, String channelId, String externalId, String ownerUsername) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Removes a share on a channel's server, at the owner's request.
      Parameters:
      calendarId - technical identifier of the calendar
      channelId - the channel that listed it
      externalId - the channel's identifier of the grant
      ownerUsername - the owner
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar does not exist, or no channel with that id is registered
      IllegalAccessException - when the user does not own the calendar
    • countShareesByCalendar

      Map<Long,Long> countShareesByCalendar(String ownerUsername) throws IllegalAccessException
      How many colleagues each of the user's own calendars is shared with, from one query; a calendar shared with nobody is absent.
      Parameters:
      ownerUsername - the owner
      Returns:
      sharee counts by calendar identifier
      Throws:
      IllegalAccessException - when the user has no usable identity
    • getSharedWithMe

      List<CalendarShare> getSharedWithMe(String username) throws IllegalAccessException
      The calendars shared with a user, newest share first, hidden ones included (they say so). Shares whose calendar or owner is gone are left out.
      Parameters:
      username - the sharee
      Returns:
      the records
      Throws:
      IllegalAccessException - when the user has no usable identity
    • setHidden

      void setHidden(long calendarId, String username, boolean hidden) throws org.exoplatform.commons.exception.ObjectNotFoundException, IllegalAccessException
      Hides, or shows again, a calendar shared with the user. Never deletes the share.
      Parameters:
      calendarId - technical identifier of the calendar
      username - the sharee
      hidden - whether to hide it
      Throws:
      org.exoplatform.commons.exception.ObjectNotFoundException - when the calendar is not shared with the user
      IllegalAccessException - when the user has no usable identity
    • isSharedWith

      boolean isSharedWith(long calendarId, long viewerIdentityId)
      Whether a calendar is shared with an identity: the read primitive every ACL path relies on. Cached per viewer; a revoke evicts the viewer's entry so the refusal is immediate.
      Parameters:
      calendarId - technical identifier of the calendar
      viewerIdentityId - identity identifier of the reader
      Returns:
      true when a record exists
    • getSharedCalendarIds

      List<Long> getSharedCalendarIds(long viewerIdentityId)
      The identifiers of every calendar shared with an identity.
      Parameters:
      viewerIdentityId - identity identifier of the reader
      Returns:
      the calendar identifiers, possibly empty, never null
    • getShareLevel

      CalendarShareLevel getShareLevel(long calendarId, long viewerIdentityId)
      The level a calendar is shared with an identity at (EXO-90378): the write primitive, read from the same cached map as isSharedWith(long, long).
      Parameters:
      calendarId - technical identifier of the calendar
      viewerIdentityId - identity identifier of the user
      Returns:
      the level, or null when the calendar is not shared with them
    • getShareLevels

      Map<Long,CalendarShareLevel> getShareLevels(long viewerIdentityId)
      Every calendar shared with an identity and the level of each (EXO-90378): what a listing asks once, instead of asking per event.
      Parameters:
      viewerIdentityId - identity identifier of the user
      Returns:
      the levels by calendar identifier, possibly empty, never null
    • deleteShares

      void deleteShares(long calendarId)
      Deletes every share of a calendar, once the calendar is deleted. No channel is asked: the calendar is gone.
      Parameters:
      calendarId - technical identifier of the calendar
    • deleteSharesOfUser

      void deleteSharesOfUser(long identityId)
      Deletes every share a deleted user held, as sharee and as owner of the shared calendars.
      Parameters:
      identityId - identity identifier of the deleted user
    • clearDelivery

      void clearDelivery(long ownerIdentityId, String channelId)
      Forgets that a channel carries the shares of a user's calendars, once the user disconnected from that channel: the eXo shares stay, the channel's grants are left as the channel's truth.
      Parameters:
      ownerIdentityId - identity identifier of the owner
      channelId - the channel the owner left