Class CalendarEvent

java.lang.Object
org.apache.juneau.console.widgets.CalendarEvent

public class CalendarEvent extends Object
A single calendar event — also the element type of the per-month event GET envelope's events.

Bean-only (juneau-console-widgets): the emitter and runtime live in juneau-console-views. Titles, tooltips, and labels are painted with textContent by the runtime, never as markup.

end is layout-significant, with split inclusivity:
  • All-day (date-only end): inclusive. start=2026-03-02, end=2026-03-04 occupies three day cells.
  • Timed (date-time end): exclusive. start=…T09:00, end=…T10:00 occupies [09:00, 10:00) — the start day only. A timed event crossing midnight is a spanning bar using the exclusive end, never intra-day chips on each crossed day.
  • Omitted end: start-only, and valid. An all-day event occupies the start day cell; a timed event occupies the start instant as a zero-width chip on the start day (never a spanning bar).
  • An all-day end equal to start is a single-day event; a timed end equal to start is zero-duration and is rejected, as is any end before start.
All-day agreement and the malformed set:

Agreement between allDay and the shape of end is decided by effectiveAllDay(), never by the raw allDay field, so a null allDay paired with matching start/end shapes stays valid. An event is malformed for exactly these reasons — and no others:

  1. a missing/blank id, title, or start;
  2. an unparseable start/end civil date, or an end that is not after (all-day: not on or after) start;
  3. a declared allDay/end disagreement — allDay == true with a date-time end, or allDay == false with a date-only end;
  4. mixed start/end shapes with a null allDay.

A malformed event is dropped by CalendarDef.validate() and by a per-month GET handler that filters through retainWellFormed(Collection) — the same rule on both paths. Neither fails the whole definition nor the whole month payload. An omitted end is not malformed.

Timezone contract:

start/end are interpreted as an ISO-8601 local date (yyyy-MM-dd) or local date-time (yyyy-MM-ddTHH:mm). A trailing offset or Z is fail-soft ignored, never rejected — a seeded 2026-03-02T09:00:00Z keeps validating and keeps rendering at 09:00 in the server's injected clock zone. The same parse applies on the seed path and on the per-month GET path.

Since:
10.0.0
  • Field Details

    • id

      public String id
      Stable id; required, non-blank. Used for de-duplication and coalesce keys.
    • title

      public String title
      Required, non-blank display title; painted with textContent.
    • start

      public String start
      Required ISO-8601 date (yyyy-MM-dd) or date-time; the civil date drives chip placement.
    • end

      public String end
      Optional ISO-8601 date/date-time bound. Layout-significant: inclusive for an all-day (date-only) value, exclusive for a timed (date-time) value. Omitting it is valid and means start-only.
    • allDay

      public Boolean allDay
      Optional all-day flag; defaults to true when start is a date with no time (see effectiveAllDay()).
    • categoryId

      Optional category id; must reference a declared EventCategory for a seed event; unknown wire ids paint NEUTRAL.
    • href

      public String href
      Optional same-origin document URL (SafePathTemplate.isSafeDocumentUrl(String) semantics).
    • tooltip

      public String tooltip
      Optional tooltip; painted with textContent.
  • Constructor Details

  • Method Details

    • create

      public static CalendarEvent create()
      Creates an empty event.
      Returns:
      A new CalendarEvent.
    • id

      public CalendarEvent id(String value)
      Sets the stable id.
      Parameters:
      value - The id. Must not be null or blank.
      Returns:
      This object.
    • title

      public CalendarEvent title(String value)
      Sets the display title.
      Parameters:
      value - The title. Must not be null or blank.
      Returns:
      This object.
    • start

      public CalendarEvent start(String value)
      Sets the ISO-8601 start.
      Parameters:
      value - A yyyy-MM-dd date or ISO date-time. Must not be null.
      Returns:
      This object.
    • end

      public CalendarEvent end(String value)
      Sets the optional ISO-8601 end.
      Parameters:
      value - A yyyy-MM-dd date or ISO date-time; must be >= start when present.
      Returns:
      This object.
    • allDay

      public CalendarEvent allDay(boolean value)
      Sets the all-day flag.
      Parameters:
      value - The all-day flag.
      Returns:
      This object.
    • categoryId

      Sets the category id.
      Parameters:
      value - The category id.
      Returns:
      This object.
    • href

      public CalendarEvent href(String value)
      Sets the same-origin document href.
      Parameters:
      value - The href.
      Returns:
      This object.
    • tooltip

      public CalendarEvent tooltip(String value)
      Sets the tooltip.
      Parameters:
      value - The tooltip.
      Returns:
      This object.
    • effectiveAllDay

      public boolean effectiveAllDay()
      The effective all-day flag: the declared allDay when set, otherwise true when start is a date with no time component.
      Returns:
      The effective all-day flag.
    • civilStart

      The civil date the chip paints on — the yyyy-MM-dd prefix of start (a date-time start is coerced to its leading civil date; a trailing offset is ignored).
      Returns:
      The civil start date.
      Throws:
      IllegalArgumentException - If start is null or not a parseable ISO date/date-time.
    • civilEnd

      public LocalDate civilEnd()
      The civil date of end, or null when end is omitted.

      This is the raw civil date of the bound, before inclusivity is applied — use lastDay() for the last day cell the event actually occupies.

      Returns:
      The civil end date, or null when end is omitted or blank.
      Throws:
      IllegalArgumentException - If end is present but not a parseable ISO date/date-time.
    • lastDay

      public LocalDate lastDay()
      The last day cell this event occupies, applying the split inclusivity rule (see the class javadoc).

      Equals civilStart() when end is omitted. For an all-day event the date-only end is inclusive; for a timed event the date-time end is exclusive, so an end of exactly midnight lands on the previous day. Never earlier than civilStart().

      Returns:
      The inclusive last occupied day.
      Throws:
      IllegalArgumentException - If start/end are not parseable.
    • spanning

      public boolean spanning()
      Whether this event covers more than one day cell and therefore renders as a spanning bar rather than a chip.
      Returns:
      true if lastDay() is after civilStart().
      Throws:
      IllegalArgumentException - If start/end are not parseable.
    • startTimeLabel

      The leading HH:mm time label a timed chip renders, or null for an all-day event or an unparseable time.
      Returns:
      The HH:mm label, or null.
    • malformedReason

      The reason this event is malformed, or null when it is well-formed.

      This is the single drop predicate shared by CalendarDef.validate() (the seed path) and by retainWellFormed(Collection) (the per-month GET path); see the class javadoc for the complete, closed list of malformed reasons. It is a pure shape check: an unknown categoryId, an unsafe href, and an off-month start are author errors reported by validate(Set,Integer,Integer), not drop reasons.

      Returns:
      A human-readable reason, or null when this event is well-formed.
    • retainWellFormed

      Returns the well-formed events of the given collection, dropping the malformed ones and continuing.

      A per-month GET handler filters its payload through this before serialization so the dynamic path drops exactly what CalendarDef.validate() drops on the seed path. A null element is dropped too.

      Parameters:
      values - The events to filter. May be null.
      Returns:
      A new mutable list of the well-formed events, in the original order. Never null.
    • validate

      public void validate(Set<String> knownCategoryIds, Integer initialYear, Integer initialMonth)
      Fail-closed shape check for a seed event, reused by CalendarDef.validate() and by an endpoint handler that wants to validate its own payload before serialization.

      Throws for a malformed event (see malformedReason()) and for the author errors a seed definition must not contain: an undeclared categoryId, a cross-origin href, and a start outside the rendered window. Callers that want the drop-and-continue posture of the seed and per-month GET paths use malformedReason()/retainWellFormed(Collection) instead.

      Parameters:
      knownCategoryIds - The declared category ids; a set categoryId must be a member. May be null (then any categoryId fails).
      initialYear - The initial year the seed month is rendered for, or null to skip the off-month check.
      initialMonth - The 1-based initial month, or null to skip the off-month check.
      Throws:
      IllegalArgumentException - If this event is not well-formed.