Class CaldavConnectionStorage

java.lang.Object
org.exoplatform.caldav.storage.CaldavConnectionStorage

@Component public class CaldavConnectionStorage extends Object
Reads and writes who each connected eXo user is on their CalDAV server (EXO-90243).

No business logic: when a principal is recorded, forgotten or believed is the service's decision. What lives here is the mechanical part — that a recording which changes nothing writes nothing, and that "connected as this principal" means exactly this principal whatever the database's collation thinks equal.

  • Constructor Details

    • CaldavConnectionStorage

      public CaldavConnectionStorage()
  • Method Details

    • getRecordedPrincipal

      public String getRecordedPrincipal(long userIdentityId, long serverId)
      The principal recorded for one user on one server.
      Parameters:
      userIdentityId - the eXo user
      serverId - the declared server registration
      Returns:
      the principal, canonical, or null when none is recorded for that user on that server
    • getPrincipalsOn

      public Map<Long,String> getPrincipalsOn(long serverId)
      The principals recorded on one server, by user, lowest identity first, at most CONNECTIONS_ON_SERVER_READ.
      Parameters:
      serverId - the declared server registration
      Returns:
      user identity to canonical principal, in identity order
    • savePrincipal

      @Transactional public boolean savePrincipal(long userIdentityId, long serverId, String principal)
      Records the principal a user is connected as on one server, replacing whatever was recorded for that user before.

      A recording that matches the stored row writes nothing: this is asked on every discovery, and a pass that found the account unchanged must cost one indexed read, not a write.

      Parameters:
      userIdentityId - the eXo user
      serverId - the declared server registration
      principal - the principal, canonical and not blank
      Returns:
      true when a row was inserted or updated, false when it already said this
    • deletePrincipal

      @Transactional public void deletePrincipal(long userIdentityId)
      Removes the principal recorded for a user, on whichever server.
      Parameters:
      userIdentityId - the eXo user
    • countActiveUsersWithoutIdentity

      public long countActiveUsersWithoutIdentity(long serverId)
      How many users hold an active pair on one server without an identity recorded for that server.
      Parameters:
      serverId - the declared server registration
      Returns:
      the number of such users, zero when every one is recorded
    • getUsersConnectedAs

      public List<Long> getUsersConnectedAs(long serverId, String principal)
      The users recorded as connected under exactly one principal on one server, lowest identity first, at most CONNECTED_USERS_READ.

      The database answers the candidates and this keeps only the exact matches: MySQL and MariaDB give the NVARCHAR column the national character set, utf8mb3 with utf8mb3_general_ci, whatever the table's own collation, and compare it case- and accent-insensitively — so /dav/pal/josé equals /dav/pal/JOSE there, and an owner mapped to the wrong person through a collation is worse than an owner not mapped at all.

      The bound applies to the candidates, before that filter: on such a collation, more than CONNECTED_USERS_READ lookalike rows with lower identities could push the exact ones off the page. No server hands out a population of principals differing only by case or accent, and that case is accepted rather than paid for with an unbounded read.

      Parameters:
      serverId - the declared server registration
      principal - the principal, canonical
      Returns:
      the users' identities, empty for a blank principal