Class AgendaInvitationLandingService

java.lang.Object
org.exoplatform.agenda.service.AgendaInvitationLandingService

@Service public class AgendaInvitationLandingService extends Object
Lands an invitation a user received by mail in their personal eXo calendar, for a user whose calendar no calendar server holds (EXO-90866) — the counterpart of caldav-integration's landing (EXO-90848), whose rules it keeps. A user who connected a remote calendar account to agenda (Google, Office 365, Exchange through agenda-connectors, or CalDAV) is not landed for: their mail server has usually filed the invitation there, and the connector shows or syncs that copy.

What each click does

An invitation accepted or tentatively accepted, or added without an answer, is created in the user's personal calendar with the user as its only attendee, carrying the answer given; when the user holds it already, the organiser's strictly newer revision (SEQUENCE) rewrites it, and the answer is set on it. A decline creates nothing — a meeting turned down and never added does not belong in the calendar — and is set on an event the user holds. A cancellation removes the event the user holds, and does nothing for one they never added. Nothing is ever mailed: the reader sent the answer, and agenda answers here without broadcasting it.

How a later message finds the event

The invitation's UID is kept with the event, in the event's own properties (the agendaEvent metadata agenda already stores per event), under a value naming the user too: two users holding the same meeting hold two events, and the lookup reads only this user's. An event found that way is held only when it is a series or single event the user created, in a calendar the user owns — a property anybody able to edit an event can set is a hint, not a proof. Beside it the SEQUENCE landed and the organiser's address, which is what a later message is compared with. The remote-event mapping is deliberately not used: it holds one row per user and event, which the calendar connectors overwrite with their own identifiers.

What is trusted

The object is the sender's (MailInvitationReader bounds and narrows it). Only an invitation, a published event or a cancellation is landed — a REPLY or a COUNTER speaks to an organiser, not to a calendar — and never a message about one occurrence alone. An organiser is required where the message speaks for one: an invitation, a cancellation, an answer. An event the user holds is rewritten, answered or removed only on a message from its own organiser (RFC 5546 section 3.2.2), never when the user organises it themselves, and a cancellation older than what the user holds removes nothing. One of this deployment's own meetings — its UID agenda-event-<id>@<this host>, or its URL this deployment's agenda link — is never landed: it is in agenda already, so adding it hands back its page as already held when the user may read it and the message describes it, and an answer or a cancellation carried by such a message is refused. The only person acted for is the user who asked, in their own calendar; no attendee line is resolved to anybody. The link handed back is agenda's own, built from the platform's domain and the event's id.

Limits

A series lands with its rule, its excluded dates and its overridden occurrences; RDATE is not read. A newer revision rewrites the series, which drops every exceptional occurrence agenda held for it, and the revision's own exclusions and overrides are applied again. An exclusion or an override agenda cannot place is skipped, the series kept. A floating time is read at UTC.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The event property holding the organiser's address, null for a published event.
    static final String
    The event property holding the SEQUENCE landed.
    static final String
    The event property holding the user and the invitation's UID, looked up by.
    static final String
    The event property saying the event was added from a mail without an answer: agenda then holds its creator's line as ACCEPTED, which nobody said.
  • Constructor Summary

    Constructors
    Constructor
    Description
    AgendaInvitationLandingService(org.exoplatform.social.core.manager.IdentityManager identityManager, org.exoplatform.agenda.service.AgendaCalendarService agendaCalendarService, org.exoplatform.agenda.service.AgendaEventService agendaEventService, org.exoplatform.agenda.service.AgendaEventAttendeeService agendaEventAttendeeService, org.exoplatform.agenda.service.AgendaEventReminderService agendaEventReminderService, org.exoplatform.agenda.service.AgendaEventConferenceService agendaEventConferenceService, org.exoplatform.agenda.service.AgendaRemoteEventService agendaRemoteEventService, org.exoplatform.agenda.service.AgendaUserSettingsService agendaUserSettingsService, org.exoplatform.social.metadata.MetadataService metadataService, AgendaEventStorage agendaEventStorage)
    Builds the service over agenda's own services and the metadata the event properties are kept in.
  • Method Summary

    Modifier and Type
    Method
    Description
    held(String username, String attendeeAddress, String uid, String recurrenceId, String organizer)
    The event the user's personal calendar holds for an invitation, for the mail reader to say so when the invitation is opened (EXO-90873): found by the same lookup a landing makes — this user's key, an event they created in a calendar they own — with the answer agenda holds for them and the SEQUENCE landed.
    boolean
    Whether agenda holds a calendar for the user: an enabled user of the platform, whose personal calendar agenda creates on first use, and who has no remote calendar account connected to agenda.
    land(MailInvitation invitation)
    Lands the invitation in the user's personal calendar: creates or updates the event, answers it, or removes it, as the message and the click say.

    Methods inherited from class java.lang.Object

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

    • UID_PROPERTY

      public static final String UID_PROPERTY
      The event property holding the user and the invitation's UID, looked up by.
      See Also:
    • SEQUENCE_PROPERTY

      public static final String SEQUENCE_PROPERTY
      The event property holding the SEQUENCE landed.
      See Also:
    • ORGANIZER_PROPERTY

      public static final String ORGANIZER_PROPERTY
      The event property holding the organiser's address, null for a published event.
      See Also:
    • UNANSWERED_PROPERTY

      public static final String UNANSWERED_PROPERTY
      The event property saying the event was added from a mail without an answer: agenda then holds its creator's line as ACCEPTED, which nobody said.
      See Also:
  • Constructor Details

    • AgendaInvitationLandingService

      @Autowired public AgendaInvitationLandingService(org.exoplatform.social.core.manager.IdentityManager identityManager, org.exoplatform.agenda.service.AgendaCalendarService agendaCalendarService, org.exoplatform.agenda.service.AgendaEventService agendaEventService, org.exoplatform.agenda.service.AgendaEventAttendeeService agendaEventAttendeeService, org.exoplatform.agenda.service.AgendaEventReminderService agendaEventReminderService, org.exoplatform.agenda.service.AgendaEventConferenceService agendaEventConferenceService, org.exoplatform.agenda.service.AgendaRemoteEventService agendaRemoteEventService, org.exoplatform.agenda.service.AgendaUserSettingsService agendaUserSettingsService, org.exoplatform.social.metadata.MetadataService metadataService, AgendaEventStorage agendaEventStorage)
      Builds the service over agenda's own services and the metadata the event properties are kept in.
      Parameters:
      identityManager - resolves the user
      agendaCalendarService - the user's personal calendar
      agendaEventService - creates, updates and removes the event
      agendaEventAttendeeService - sets the user's answer
      agendaEventReminderService - the reminders an update keeps
      agendaEventConferenceService - the conferences an update keeps
      agendaRemoteEventService - the remote mapping an update keeps
      agendaUserSettingsService - the user's default reminders
      metadataService - the event properties the invitation is found by
      agendaEventStorage - the exceptional occurrences a newer revision drops
  • Method Details

    • holdsCalendarFor

      public boolean holdsCalendarFor(String username)
      Whether agenda holds a calendar for the user: an enabled user of the platform, whose personal calendar agenda creates on first use, and who has no remote calendar account connected to agenda. Whether another add-on holds that user's calendar instead is not agenda's to read here; the plugin asks them. No round trip to a server: an identity read (cached) and a settings read (one small query for the remote providers).
      Parameters:
      username - the user's login
      Returns:
      true when the invitation is agenda's to land
    • land

      public LandedMailInvitation land(MailInvitation invitation)
      Lands the invitation in the user's personal calendar: creates or updates the event, answers it, or removes it, as the message and the click say.

      Not atomic, as agenda's own event writes are not: a newer revision is written in steps -- the event updated, the previous revision's exceptions dropped and the next days' occurrences materialised again, the new exceptions placed, the user's answer set -- each committed on its own. When agenda refuses the update, nothing was written: the user keeps the previous revision whole, its cancelled and moved dates included. A failure past the update leaves the steps already done in place: the revision applied, without the exceptions not placed yet, with whatever answer agenda's update left on it, while the reader is told the calendar could not be updated. A date the revision cancels or moves and that cannot be placed is left out and logged, the rest of the series landed.

      Parameters:
      invitation - the invitation, the user and what they asked
      Returns:
      what was done, or null when the user cannot have a calendar here or connected a remote calendar account, or when there was nothing to do — a decline, or a cancellation, of an event the user never added
      Throws:
      IllegalArgumentException - when the message cannot be landed as it is — unreadable or over a cap, about another event than the one shown, about one occurrence only, a method that is not landed, naming no organiser where one is needed, naming one of this deployment's meetings for an answer or a cancellation, or touching an event of another organiser's
      IllegalStateException - when the landing was attempted and agenda refused it
    • held

      public HeldMailInvitation held(String username, String attendeeAddress, String uid, String recurrenceId, String organizer)
      The event the user's personal calendar holds for an invitation, for the mail reader to say so when the invitation is opened (EXO-90873): found by the same lookup a landing makes — this user's key, an event they created in a calendar they own — with the answer agenda holds for them and the SEQUENCE landed. Reads only, no round trip to a server. What it answers never licenses a change: land(org.exoplatform.agenda.model.MailInvitation) changes or removes an event the user holds only for a mail the reader established as its organiser's (MailInvitation.fromOrganizer()), whatever this answered. An event added without an answer, whose line agenda still holds as its creator's ACCEPTED, is told with no answer: an acceptance given later from the mail is then said by the reader's own record of it, not by this.

      Null wherever a landing would not act: a user agenda cannot serve or who connected a remote calendar account, a message about one occurrence alone, an event the user does not hold — one of this deployment's own meetings included, which is never landed and so never found — an event cancelled since, and an event the message's organiser is not the organiser of, or that the user organises: the UID is the sender's, and only an event's own organiser speaks for it.

      Parameters:
      username - the user's login
      attendeeAddress - the user's mailbox address, may be null
      uid - the invitation's UID
      recurrenceId - the occurrence the message is about, null for the series or a single event
      organizer - the message's organiser, null for a published event naming none
      Returns:
      the event held, or null