Class AgendaRemoteCopyService

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

@Service public class AgendaRemoteCopyService extends Object
Whether a recipient is going to hold a synced copy of a meeting in a remote calendar account — asked of the add-on that would write it, not guessed at (EXO-90247).

The defect this exists to make impossible

Two repositories were each predicting what the other would do. Agenda read the recipient's settings to decide whether to attach event.ics to the invitation mail; the CalDAV add-on read its own, different set of conditions to decide whether to write the copy. Neither knew the other's rules, so the two answers drifted — and the drift is invisible in both repositories' tests, because each is right about its own half.

Both directions of the drift were live at once. The add-on's server-side seeding pass writes a copy for a user whose automaticPushEvents is off, while agenda's prediction requires that switch and so attached the file as well: the meeting twice. And when the add-on gained a reason of its own to decline a copy for a particular invitee, agenda still predicted one and left the file out: the meeting nowhere at all, which is what the first attempt at EXO-90247 shipped and what the rig measured.

The fix is not to align the two predicates by hand — they would drift again, and the next drift is the next silent invitation. It is to leave exactly one party holding the answer: whoever writes the copy says whether it is coming.

Why the plugins are looked up when the question is asked

The contributing add-on depends on agenda, so its WAR boots after agenda's. Injecting a List of the plugins would take a snapshot at agenda's own refresh; asking the context at call time takes none, so nothing here depends on the boot order of the two add-ons. It costs a type lookup Spring caches, on a path that already builds a mail.

What it answers when it cannot ask

Agenda ships alone in deployments where no add-on writes copies at all, and there the settings-derived prediction is still the best available answer — so it stays, as the fallback for "nobody to ask", and is used nowhere else.

  • Constructor Summary

    Constructors
    Constructor
    Description
    AgendaRemoteCopyService(org.springframework.context.ApplicationContext applicationContext)
    Builds the service over the context the plugins are collected from.
  • Method Summary

    Modifier and Type
    Method
    Description
    boolean
    shouldAttachIcsFile(org.exoplatform.agenda.model.Event event, long recipientIdentityId, org.exoplatform.agenda.model.AgendaUserSettings recipientSettings)
    Whether the event.ics file must be attached to the notification built for this recipient.

    Methods inherited from class java.lang.Object

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

    • AgendaRemoteCopyService

      @Autowired public AgendaRemoteCopyService(org.springframework.context.ApplicationContext applicationContext)
      Builds the service over the context the plugins are collected from.

      The context is taken through the constructor rather than a field so the wiring can be exercised end to end: a test can stand one of these up over a context holding a chosen plugin, register it in the container, and assert on the mail the notification builder actually produces.

      Parameters:
      applicationContext - the Spring context of this WAR, into which the bridge has published every other WAR's exported beans
  • Method Details

    • shouldAttachIcsFile

      public boolean shouldAttachIcsFile(org.exoplatform.agenda.model.Event event, long recipientIdentityId, org.exoplatform.agenda.model.AgendaUserSettings recipientSettings)
      Whether the event.ics file must be attached to the notification built for this recipient.

      The file is left out only for a recipient a copy of this meeting is really going to be written for. Everything else — a guest, a user no add-on claims, a meeting the add-on will not copy, an add-on that cannot answer — gets the file, because a redundant file is a visible nuisance and a missing one is an invitation nobody ever receives.

      Parameters:
      event - the meeting the notification is about, null when it no longer exists (a cancellation), in which case no add-on can be asked about it and the settings-derived prediction stands
      recipientIdentityId - organization identity id of the recipient, 0 when the recipient is a guest
      recipientSettings - agenda settings of that recipient, possibly null
      Returns:
      true when the file must be attached