Class WidgetsMixin.WidgetValidationProcessor

java.lang.Object
org.apache.juneau.console.widgets.WidgetsMixin.WidgetValidationProcessor
All Implemented Interfaces:
ResponseProcessor
Enclosing class:
WidgetsMixin

public static class WidgetsMixin.WidgetValidationProcessor extends Object implements ResponseProcessor
The serving-path Widget.validate() gate: fail-closed structural validation for any REST response content that is a Widget, giving the JSON serving path the same gate the juneau-console-views HTML emitters already give every Widget they consume.
Why this is a ResponseProcessor, not a RestContext hook

juneau-rest-server does not (and must not) depend on this module, so a hard-coded validation step inside it cannot see Widget without inverting that dependency. A ResponseProcessor declared here, discovered by every classpath that carries this module via ServiceLoader, needs no such reflection or hoisted marker interface — see the class Javadoc.

Why NEXT, never FINISHED

This processor validates and declines to handle: it never claims the response, so it cannot perturb chain ordering, content-type negotiation, or the NotImplemented fallthrough. Non-Widget content (including the unrelated examples.views.Widget demo row bean and the legacy org.apache.juneau.rest.server.widget.Widget SVL resolver — see the module Javadoc's naming collision note) costs one instanceof test and is otherwise untouched.

Why InternalServerError (500), not the caller's problem

A malformed Widget reaching the serving path is a server defect — the client asked for a dialog correctly and the server built a broken one — not an inbound-validation failure of the kind ValidationException (400) is scoped to. The underlying IllegalArgumentException rides as the cause so the message names the failing rule.

Deliberately not deduplicated against ModalDef.checked()/FormDef.checked()

A widget that already called checked() is validated twice per response: once at build time, once here. No validated flag is added to skip the second pass — a mutable "already validated" flag on a wire bean would re-introduce an order-dependence bug in the validation dimension (mutate-after-checked) that this module's contract deliberately avoids elsewhere. validate() is cheap and idempotent, so the repeat costs nothing worth building around.

Traversal is top-level only

Only res.getContent() itself is tested. Nested widgets are covered by the beans' own recursive validate() (e.g. ModalDef.validate() → FormDef.validate()); a Widget inside a Collection/Map envelope is not walked into — no endpoint in this tree returns that shape, and walking one would collide with the unrelated examples.views.Widget row-bean lists some example endpoints do return.

Escape hatch

A resource that must serve a deliberately-invalid Widget can override the response-processor chain entirely with a @Bean ResponseProcessorList factory method, which replaces the whole list. There is no narrower, dedicated opt-out.

Since:
10.0.0
  • Constructor Details

  • Method Details

    • process

      public int process(RestOpSession opSession)
      Description copied from interface: ResponseProcessor
      Process this response if possible.
      Specified by:
      process in interface ResponseProcessor
      Parameters:
      opSession - The HTTP call.
      Returns:
      One of the following codes:
      • 0 - The processor could not handle the request.
      • 1 - The processor was able to fully handle the request.
      • 2 - The processor was able to partially handle the request by replacing the output. The response processors should start over.