Class CalendarShareStorage

java.lang.Object
org.exoplatform.agenda.storage.CalendarShareStorage

@Component public class CalendarShareStorage extends Object
Maps calendar shares between their rows and CalendarShare, and caches the two reads every ACL decision relies on (EXO-90357).

Two caches, both keyed by one explicit identifier. "agenda.calendarShare.byViewer" holds, per reader identity, the calendars shared with them and the level of each share (EXO-90378): what every event and calendar read asks, and what every write path asks too, once per request, on the reader's own key — a viewer is never served another's map, and the level is a field of the cached value, never folded into its key. "agenda.calendarShare.byCalendar" holds, per calendar, its shares: what the owner's drawer and the delivery reads ask. A write evicts exactly the keys it touches, so a revoke makes the refusal immediate; the bulk deletions that cannot name their keys evict the whole cache, which they may — they run on a calendar or a user being deleted.

The cached reads are reached through a lazy self-reference from the other methods of this bean: a plain this call bypasses the proxy and, silently, the cache.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Cache of the shares of a calendar, keyed by calendar id.
    static final String
    Cache of the calendar identifiers shared with a reader, keyed by reader identity id.
    static final int
    Most shares one calendar listing reads.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Builds the storage.
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    clearDelivery(long ownerIdentityId, String channelId)
    Forgets that a channel carries the shares of an owner's calendars.
    countShareesByCalendar(long ownerIdentityId)
    How many colleagues each calendar of an owner is shared with, from one query.
    boolean
    delete(long calendarId, long shareeIdentityId)
    Deletes the share of a calendar with one colleague.
    int
    deleteByCalendarId(long calendarId)
    Deletes every share of a calendar.
    int
    deleteOfUser(long identityId)
    Deletes every share a colleague received, and every share of the calendars they own.
    org.exoplatform.agenda.model.CalendarShare
    getShare(long calendarId, long shareeIdentityId)
    The share of a calendar with one colleague, read through the calendar's cached shares.
    getSharedCalendarIds(long viewerIdentityId)
    The identifiers of every calendar shared with a reader, derived from the cached level map.
    org.exoplatform.agenda.constant.CalendarShareLevel
    getShareLevel(long calendarId, long viewerIdentityId)
    The level a calendar is shared with a reader at: one cache hit on the reader's key.
    Map<Long,org.exoplatform.agenda.constant.CalendarShareLevel>
    getShareLevels(long viewerIdentityId)
    Every calendar shared with a reader and the level it is shared at (EXO-90378).
    List<org.exoplatform.agenda.model.CalendarShare>
    getShares(long calendarId)
    The shares of a calendar, oldest first.
    List<org.exoplatform.agenda.model.CalendarShare>
    getSharesOfSharee(long shareeIdentityId, int limit)
    The shares a colleague received, newest first.
    boolean
    isSharedWith(long calendarId, long viewerIdentityId)
    Whether a calendar is shared with a reader: one cache hit on the reader's key.
    org.exoplatform.agenda.model.CalendarShare
    save(long calendarId, long shareeIdentityId, long grantedById, org.exoplatform.agenda.constant.CalendarShareLevel level, org.exoplatform.agenda.constant.CalendarShareSource source, String deliveredTo, String deliveryRef, Date createdDate)
    Writes a new share.
    org.exoplatform.agenda.model.CalendarShare
    setDelivery(long calendarId, long shareeIdentityId, String deliveredTo, String deliveryRef)
    Records which channel carries a share, and under which reference; null both to record that none does.
    org.exoplatform.agenda.model.CalendarShare
    setHidden(long calendarId, long shareeIdentityId, boolean hidden)
    Records the sharee's choice to hide the calendar, or to show it again.
    org.exoplatform.agenda.model.CalendarShare
    setLevel(long calendarId, long shareeIdentityId, org.exoplatform.agenda.constant.CalendarShareLevel level)
    Records what a colleague may do with the calendar (EXO-90378).
    void
    Receives the proxied bean, so that the methods of this class reach the cached reads through the cache rather than through this.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • BY_VIEWER_CACHE

      public static final String BY_VIEWER_CACHE
      Cache of the calendar identifiers shared with a reader, keyed by reader identity id.
      See Also:
    • BY_CALENDAR_CACHE

      public static final String BY_CALENDAR_CACHE
      Cache of the shares of a calendar, keyed by calendar id.
      See Also:
    • MAX_SHARES

      public static final int MAX_SHARES
      Most shares one calendar listing reads.
      See Also:
  • Constructor Details

    • CalendarShareStorage

      @Autowired public CalendarShareStorage(CalendarShareDAO calendarShareDAO)
      Builds the storage.
      Parameters:
      calendarShareDAO - the repository of share rows
  • Method Details

    • setSelf

      @Autowired public void setSelf(@Lazy CalendarShareStorage self)
      Receives the proxied bean, so that the methods of this class reach the cached reads through the cache rather than through this.
      Parameters:
      self - the proxied storage
    • getShareLevels

      @Cacheable(cacheNames="agenda.calendarShare.byViewer", key="#viewerIdentityId", sync=true) public Map<Long,org.exoplatform.agenda.constant.CalendarShareLevel> getShareLevels(long viewerIdentityId)
      Every calendar shared with a reader and the level it is shared at (EXO-90378). The one cached read behind every share decision: cached per reader, loaded once under concurrent misses, and read through the proxy by the two derived methods below so that they cost one cache hit, not a second statement.
      Parameters:
      viewerIdentityId - identity identifier of the reader
      Returns:
      the level of each shared calendar by calendar identifier, never null, empty when nothing is shared with them
    • getSharedCalendarIds

      public List<Long> getSharedCalendarIds(long viewerIdentityId)
      The identifiers of every calendar shared with a reader, derived from the cached level map.
      Parameters:
      viewerIdentityId - identity identifier of the reader
      Returns:
      the calendar identifiers, never null
    • getShareLevel

      public org.exoplatform.agenda.constant.CalendarShareLevel getShareLevel(long calendarId, long viewerIdentityId)
      The level a calendar is shared with a reader at: one cache hit on the reader's key.
      Parameters:
      calendarId - technical identifier of the calendar
      viewerIdentityId - identity identifier of the reader
      Returns:
      the level, or null when the calendar is not shared with them
    • isSharedWith

      public boolean isSharedWith(long calendarId, long viewerIdentityId)
      Whether a calendar is shared with a reader: one cache hit on the reader's key.
      Parameters:
      calendarId - technical identifier of the calendar
      viewerIdentityId - identity identifier of the reader
      Returns:
      true when a share exists
    • getShares

      @Cacheable(cacheNames="agenda.calendarShare.byCalendar", key="#calendarId", sync=true) public List<org.exoplatform.agenda.model.CalendarShare> getShares(long calendarId)
      The shares of a calendar, oldest first. Cached per calendar.
      Parameters:
      calendarId - technical identifier of the calendar
      Returns:
      the shares, never null
    • getShare

      public org.exoplatform.agenda.model.CalendarShare getShare(long calendarId, long shareeIdentityId)
      The share of a calendar with one colleague, read through the calendar's cached shares.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      Returns:
      a copy of the share, or null when there is none
    • getSharesOfSharee

      public List<org.exoplatform.agenda.model.CalendarShare> getSharesOfSharee(long shareeIdentityId, int limit)
      The shares a colleague received, newest first. Not cached: read once per panel load, and the hidden flag on it changes at the colleague's hand.
      Parameters:
      shareeIdentityId - identity identifier of the colleague
      limit - most shares to read
      Returns:
      the shares
    • countShareesByCalendar

      public Map<Long,Long> countShareesByCalendar(long ownerIdentityId)
      How many colleagues each calendar of an owner is shared with, from one query.
      Parameters:
      ownerIdentityId - identity identifier owning the calendars
      Returns:
      sharee counts by calendar identifier, absent when zero
    • save

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",key="#shareeIdentityId") @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public org.exoplatform.agenda.model.CalendarShare save(long calendarId, long shareeIdentityId, long grantedById, org.exoplatform.agenda.constant.CalendarShareLevel level, org.exoplatform.agenda.constant.CalendarShareSource source, String deliveredTo, String deliveryRef, Date createdDate)
      Writes a new share. Two owners' clicks — or one owner's double click — recording the same share at the same moment both find no row, and the unique key refuses the second insert; that refusal is not an error, the row that won is returned. The insert is flushed so the refusal surfaces here on every engine, and caught as Spring's translated exception and as the raw JPA one, as CalendarLinkStorage does.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      grantedById - identity identifier of the user recording the share
      level - what the colleague may do with the calendar; null is stored as CalendarShareLevel.VIEW
      source - where the record comes from
      deliveredTo - the channel carrying it, may be null
      deliveryRef - the channel's reference, may be null
      createdDate - when the share is created
      Returns:
      the stored share
    • setDelivery

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",key="#shareeIdentityId") @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public org.exoplatform.agenda.model.CalendarShare setDelivery(long calendarId, long shareeIdentityId, String deliveredTo, String deliveryRef)
      Records which channel carries a share, and under which reference; null both to record that none does.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      deliveredTo - the channel, or null
      deliveryRef - the channel's reference, or null
      Returns:
      the updated share, or null when there is no such share
    • setLevel

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",key="#shareeIdentityId") @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public org.exoplatform.agenda.model.CalendarShare setLevel(long calendarId, long shareeIdentityId, org.exoplatform.agenda.constant.CalendarShareLevel level)
      Records what a colleague may do with the calendar (EXO-90378). The two keys this touches are evicted exactly as a delivery or a hiding evicts them, so a downgrade is refused on the reader's very next request: the reader's map is dropped, and so is the owner's view of the calendar's shares.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      level - the new level, null read as CalendarShareLevel.VIEW
      Returns:
      the updated share, or null when there is no such share
    • setHidden

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",key="#shareeIdentityId") @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public org.exoplatform.agenda.model.CalendarShare setHidden(long calendarId, long shareeIdentityId, boolean hidden)
      Records the sharee's choice to hide the calendar, or to show it again.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      hidden - whether hidden
      Returns:
      the updated share, or null when there is no such share
    • delete

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",key="#shareeIdentityId") @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public boolean delete(long calendarId, long shareeIdentityId)
      Deletes the share of a calendar with one colleague.
      Parameters:
      calendarId - technical identifier of the calendar
      shareeIdentityId - identity identifier of the colleague
      Returns:
      true when a share was deleted
    • deleteByCalendarId

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",allEntries=true) @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",key="#calendarId") public int deleteByCalendarId(long calendarId)
      Deletes every share of a calendar. The sharees are not read first, so every reader's cached list is dropped.
      Parameters:
      calendarId - technical identifier of the calendar
      Returns:
      how many shares went
    • deleteOfUser

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",allEntries=true) @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",allEntries=true) public int deleteOfUser(long identityId)
      Deletes every share a colleague received, and every share of the calendars they own.
      Parameters:
      identityId - identity identifier of the user
      Returns:
      how many shares went
    • clearDelivery

      @CacheEvict(cacheNames="agenda.calendarShare.byViewer",allEntries=true) @CacheEvict(cacheNames="agenda.calendarShare.byCalendar",allEntries=true) public int clearDelivery(long ownerIdentityId, String channelId)
      Forgets that a channel carries the shares of an owner's calendars.
      Parameters:
      ownerIdentityId - identity identifier of the owner
      channelId - the channel
      Returns:
      how many shares were cleared