Class ActionResult

java.lang.Object
org.apache.juneau.console.views.ActionResult

@BeanType(properties="contractVersion,outcome,replay,refusalCode,message,row,resultForm") public class ActionResult extends Object
The typed result a row action's submit returns — the load-bearing half of the write path.

A raw HTML fragment response cannot carry the distinction the consumer's non-optimistic UI rule requires: a row must not show "acknowledged" because a request was sent, only because the remote system was read back and said so. This typed result carries exactly that distinction — an outcome discriminator, the authoritative row data to re-render from, a replay marker, and a refusalCode — so the juneau-views.js runtime can paint what actually happened (success, failure, a named refusal, or an honest unknown) rather than what the request asked for.

Its own, independent contract version

The action-result is a third independently-versioned wire contract, alongside VIEW_META and the FTL card/slot envelope. Its CONTRACT_VERSION is deliberately its own constant and is not aliased to VIEW_META: aliasing a per-view contract's version onto a separate contract couples two unrelated client/server locksteps, so this contract versions itself.

Refusals are an opaque, namespaced code — not a framework-closed enum

A refusal's refusalCode is an opaque namespaced string, not a framework-closed enum and not a free-text message. Refusals span two independent sources, and the framework must be able to render a refusal it has never heard of:

  • Framework transport codes come from BoundaryReason.name() (e.g. CSRF_TOKEN_MISSING), already on the wire as the X-Request-Boundary header and the rejection envelope's reason.
  • Consumer codes are namespaced app: / write-guard: strings for concepts Juneau knows nothing about ("not armed", "arming expired", "confirmation does not match this incident", "a previous attempt's outcome is unknown").

The runtime renders ANY code as a visible named refusal without the framework needing to know consumer concepts exist.

Reserved async terminal outcomes

cancelled and cancelled-after-effect are reserved from day one (as VIEW_META reserved rowActions before it was implemented), even though a synchronous write never emits them. A future async/streaming variant can therefore emit them without a second result-contract bump and a three-sided lockstep.

Example:

// A success carrying the authoritative row read back from the remote system. ActionResult ok = ActionResult.success(incidentReadBack); // A named refusal from the consumer's write gate. ActionResult no = ActionResult.refusal("write-guard:not-armed"); // A recorded prior outcome, labelled as a replay rather than re-calling. ActionResult again = ActionResult.success(incidentReadBack).replay(true);

See Also:
Since:
10.0.0
  • Field Details

    • CONTRACT_VERSION

      public static final String CONTRACT_VERSION
      The frozen action-result contract version — its own discriminator, deliberately NOT aliased to VIEW_META. Bumped only on a breaking wire change to this contract.
      See Also:
    • contractVersion

      The frozen contract-version discriminator (always "1" for this contract).
    • outcome

      public String outcome
      The outcome discriminator wire token (see ActionResult.Outcome.wire()).
    • replay

      public Boolean replay
      Whether this result is a recorded prior outcome replayed rather than re-executed; omitted from the wire when unset (the common, non-replay case).
    • refusalCode

      The opaque, namespaced refusal code for a refusal; omitted from the wire for any other outcome. Framework codes come from Enum.name(); consumer codes are namespaced app: / write-guard: strings (see the class javadoc).
    • message

      public String message
      Optional human-readable supplementary message for any outcome; omitted from the wire when unset.
    • row

      public Object row
      The authoritative row payload the runtime re-renders the row from (the MERGE_ROW case); omitted from the wire when unset. This is the row as the remote system actually reports it, not what the request asked for.
    • resultForm

      The follow-up read-only form-source URL a receipt is painted from; omitted from the wire when unset.
      Honored on success only

      This is the mechanical form of a receipt must never look like a receipt for a write that didn't happen. On a failure, a refusal, an unknown, or a transport failure this field is ignored, no follow-up GET is issued, and nothing is swapped — so no result host can appear for a write that did not commit.

      The served payload must not carry a form

      The URL serves a ModalDef, and that payload must not declare a form. A result host is terminal by definition: the write already committed, so there is nothing left to gate. A payload carrying inputs is refused visibly rather than rendered read-only or silently stripped, because it is a consumer authoring bug and should be visible as one.

      It is a swap, not a new dialog

      The runtime paints the receipt into the dialog that is already open, at the same layer depth, and only when that dialog opted in with ModalDef.keepOpenOnSubmit. Set on a result whose dialog did not opt in, the swap is dropped, the success is reported unchanged, and the runtime emits one non-alarming diagnostic rather than either opening a layer or making a successful write look failed.

  • Constructor Details

  • Method Details

    • success

      public static ActionResult success(Object row)
      Starts a success result carrying the authoritative row read back from the remote system.
      Parameters:
      row - The authoritative row payload to re-render from. Can be null (e.g. a navigate/redraw action that carries no row).
      Returns:
      A new ActionResult.
    • ok

      public static ActionResult ok()
      Readability alias for success(null) — a success result that carries no row (e.g. a delete, or a navigate/redraw action).
      Example:

      // Equivalent to ActionResult.success(null).message(...) return ActionResult.ok().message("Deleted");

      Returns:
      A new ActionResult.
    • ok

      public static ActionResult ok(Object row)
      Readability alias for success(Object).
      Example:

      return ActionResult.ok(store.updatePet(pet)).message("Saved");

      Parameters:
      row - The authoritative row payload to re-render from. Can be null.
      Returns:
      A new ActionResult.
    • failure

      public static ActionResult failure()
      Starts a failure result.
      Returns:
      A new ActionResult.
    • refusal

      public static ActionResult refusal(String refusalCode)
      Starts a refusal result carrying the named, opaque refusal code.
      Parameters:
      refusalCode - The opaque, namespaced refusal code. Must not be null or blank (a refusal with no code is exactly the free-text-message anti-pattern this contract forbids).
      Returns:
      A new ActionResult.
      Throws:
      IllegalArgumentException - If refusalCode is null or blank.
    • unknown

      public static ActionResult unknown()
      Starts an unknown result — an honest, non-optimistic terminal state.
      Returns:
      A new ActionResult.
    • row

      public ActionResult row(Object value)
      Sets the authoritative row payload to re-render from.
      Parameters:
      value - The new value. Can be null to unset.
      Returns:
      This object.
    • replay

      public ActionResult replay(Boolean value)
      Marks this result as a recorded prior outcome replayed rather than re-executed.
      Parameters:
      value - true to mark this a replay; false/null to unset (omitting it from the wire).
      Returns:
      This object.
    • message

      public ActionResult message(String value)
      Sets the optional human-readable supplementary message.
      Parameters:
      value - The new value. Can be null to unset.
      Returns:
      This object.
    • refusalCode

      Sets the opaque, namespaced refusal code (see refusalCode).
      Parameters:
      value - The new value. Can be null to unset.
      Returns:
      This object.
    • resultForm

      public ActionResult resultForm(String value)
      Sets the follow-up read-only form-source URL a receipt is painted from (see resultForm).
      Parameters:
      value - The new value. Can be null to unset.
      Returns:
      This object.