Class AccountCalendarOwners
CaldavOutboundService#ownershipOf hears
(EXO-90347), asked at most once per account per pass.
The three other witnesses cannot tell a colleague's calendar the account subscribed to from the account's own when neither was minted by this deployment: on BlueMind the DAV listing puts the subscribed calendar under the account's own home and names the account as its owner, the slug names an anchor nobody here holds, and the container uid is eXo's shape rather than one that carries an owner. So a calendar a colleague had imported from elsewhere and then shared was adopted as the sharee's own — observed live as eric's "Perso" coming back as root's calendar 24. BlueMind's subscription listing carries the owner of every calendar in the account's view; this is that listing, reduced to the one question the classifier asks of it.
Four words, and what each costs the classifier.
AccountCalendarOwners.Word.SILENT is a server that was not asked — one that is not
BlueMind's, where the current behaviour is kept unchanged.
AccountCalendarOwners.Word.ACCOUNTS_OWN and AccountCalendarOwners.Word.ANOTHERS are answers.
AccountCalendarOwners.Word.UNKNOWN is a question that could not be answered: the listing
could not be fetched, the session was not the account's, or the calendar
is simply not in it. The classifier fails closed on it for adoption alone
— adopting on missing evidence is exactly the defect — and leaves the
calendar for the next pass.
Deferred, and memoised. The listing costs a REST login, a GET and a
logout, while most passes never need it: a collection outside eXo's
naming never reaches this witness, and one inside it is settled by the
user's own pairs or the deployment's pairs before this witness is heard.
The sweep's skip line and its retirement of a bound subscription never
fetch either: the one reads what was already heard, the other hears the silent witness. So the listing is fetched the
first time a question reaches it and kept for the rest of the pass —
one fetch per account per pass at most, none when nothing asks — which is
the bound the sweep is held to. Across passes the fetch is served from
CaldavServerOwnerStorage's cache, so most first questions cost no
request either.
One refresh per pass, for a calendar the listing does not name. A cached listing predates every share made since it was written, and a new share met as "not in the listing" would sit unclassified — neither adopted nor listed as shared — until the entry expired. So a deferred witness may carry a second supplier: heard once per pass, the first time a question about a calendar the present listing does not name comes in, and never for a listing that could not be had at all (a failed fetch is one attempt per pass, as before the cache). A refresh that yields nothing keeps the listing already in hand.
Services-local like CollectionOwnership: an answer held for the
length of one pass or one listing, persisted nowhere.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordThe server's word on one calendar, and the owner it named.static enumWhat the server said about one calendar. -
Method Summary
Modifier and TypeMethodDescriptionstatic AccountCalendarOwnersdeferred(Supplier<AccountCalendarOwners> fetch) A listing fetched on the first question and kept for every later one.static AccountCalendarOwnersdeferred(Supplier<AccountCalendarOwners> fetch, Supplier<AccountCalendarOwners> refresh) A listing fetched on the first question, kept for every later one, and read again at most once for a calendar it does not name.static AccountCalendarOwnersA listing in hand.ownerAlreadyHeard(String containerUid) The word already heard on one calendar, fetching and refreshing nothing: what a line written after the classification may cite without costing the account a request.The server's word on one calendar.static AccountCalendarOwnerssilent()A server that is not asked: every calendar isAccountCalendarOwners.Word.SILENT, and the classifier behaves as it did before this witness existed.static AccountCalendarOwnersA server that was asked and could not answer: every calendar isAccountCalendarOwners.Word.UNKNOWN.
-
Method Details
-
silent
A server that is not asked: every calendar isAccountCalendarOwners.Word.SILENT, and the classifier behaves as it did before this witness existed.- Returns:
- the silent witness
-
of
A listing in hand.- Parameters:
accountUid- the directory entry uid the listing was read as; a blank uid makes every calendarAccountCalendarOwners.Word.UNKNOWN, since an owner cannot be compared to nobodyownerByContainerUid- the owner uid of each listed calendar, keyed by container uid- Returns:
- the witness
-
deferred
A listing fetched on the first question and kept for every later one.The supplier runs at most once, however many calendars are asked about and whatever it answers — an unavailable listing is not fetched again within the pass either. A supplier that throws is read as
unavailable(); the caller that built it is expected to have caught and said what it wanted to say.- Parameters:
fetch- how to get the listing- Returns:
- the deferred witness, with no refresh
-
deferred
public static AccountCalendarOwners deferred(Supplier<AccountCalendarOwners> fetch, Supplier<AccountCalendarOwners> refresh) A listing fetched on the first question, kept for every later one, and read again at most once for a calendar it does not name.The refresh runs the first time a question about an absent calendar reaches a listing that is present — never when the fetch failed, since a failure is one attempt per pass — and whatever it answers it is not run again in this witness's life. A refresh that answers null, or throws, leaves the listing in hand as it was.
- Parameters:
fetch- how to get the listingrefresh- how to read it again, fresh from the server; null for no refresh- Returns:
- the deferred witness
-
ownerOf
The server's word on one calendar.- Parameters:
containerUid- the calendar's container uid, the last segment of its collection path- Returns:
- the verdict, never null
-
ownerAlreadyHeard
The word already heard on one calendar, fetching and refreshing nothing: what a line written after the classification may cite without costing the account a request.A deferred witness whose fetch has not run answers
AccountCalendarOwners.Word.UNKNOWNfor every calendar — the listing was never needed, so nothing is known of it — and one that has run answers from the listing it holds, the fresh one when the refresh replaced it. The sweep's skip line asks this for a share the deployment's own pairs settled: the listing may never have been read for it, and the line must not be the reason it is.- Parameters:
containerUid- the calendar's container uid- Returns:
- the verdict, never null
-