Files
NeitzelFXDesigner/docs/binding-discovery.md
T

34 lines
6.0 KiB
Markdown

# Shared Model and binding-target discovery
This is the first stage-4 implementation slice: a read-only binding browser shared by standalone and IntelliJ. The [DirectBinding inspector](direct-binding-inspector.md) now uses discovered targets to start editable declarations. [Converter discovery and DirectBinding validation](converter-validation.md) now extend this slice; [custom ViewModel and Computed metadata](viewmodel-computed-validation.md) extend discovery further. Generated metadata and the complete inspector remain subsequent work.
## Use
Build and Refresh a fixture, expand **Bindings**, open **Discover targets**, and select **Discover bindings**. Select a Model path and direction (`view`, `model`, `both`); compatible targets appear first, followed by unresolved targets and mismatches with explanations. Discovery leaves the authoritative FXML and undo history untouched. Errors leave source editing available.
The document explicitly declares its Model in `<?neitzel-model fixture.model.Person?>`. A missing declaration prompts for it; an example Model is not silently substituted. Fixtures now declare Person for Person/Full Views and Address for their Component resources.
For Person the browser exposes `name`, `rank`, `home`, `home.street`, and `visits`, including Address as the collection element type. The current document's controls are indexed by fx:id. Nested Component internals belong to their own documents. The browser does not offer fx:define objects as scene controls.
## Metadata boundary
The fresh target worker loads classes without initialization and inspects signatures. It never constructs Models, Controllers, providers, controls or Converters, never invokes getters/property accessors, and never starts JavaFX. Application types stay outside both hosts. The independently negotiated `bindings-v4` capability adds the BINDINGS operation; it uses bounded UTF-8 metadata, build/context identity and document revisions, with zero image dimensions. Existing wire operation ordinals remain unchanged.
Model fallback follows NeitzelLib's public read/write JavaBean Attribute rules and simple/complex/collection classification. Nested paths expand to depth four with cycle diagnostics; collection paths expose declared element types without pretending a collection is a single nested Model. Explicit custom BeanInfo is not executed: types requiring it report a generated-metadata diagnostic. Custom/replacement ViewModels, built-in message properties and Computed methods now follow the [signature-based selection rules](viewmodel-computed-validation.md). Generated metadata and arbitrary dynamic property APIs remain unresolved.
Targets come from public instance JavaFX observable-property accessors. The runtime requires writable `Property` accessors, so read-only targets remain visible as incompatible. Generic observable signatures and getter types identify the value type; incomplete or contradictory signatures remain unresolved. Component `model` targets use the Component resource's explicit Model declaration instead of treating Object as a specific type. Component resource metadata comes from the selected build; current-document metadata comes from the captured draft.
Compatibility uses boxed declared types and target-runtime assignability: `view` tests Model-to-control, `model` the reverse, and `both` requires both. No implicit numeric/string conversion is assumed. Type mismatches require a compatible Converter; Converter availability and optional capabilities are checked by the DirectBinding inspector. Unknown Object types and collection variance remain unresolved, rather than being advertised as verified bindings. Results are potential type matches, not a check that a target is currently unbound or that all runtime access/injection conditions hold.
## Freshness and limits
Discovery owns a separate workflow so it does not replace the canvas or interactive worker. It uses a leased successful build and a captured current-document overlay. Generation and document-revision checks reject obsolete replies. Document changes clear the target list and require rediscovery; Build and Refresh invalidates the panel. Explicit retained-build selection is identified in the displayed provenance. Closed editors cancel their metadata worker.
FXML parsing disables external entities and DOCTYPE. Inputs, scene-node counts, path expansion, target counts and protocol payloads are bounded. Ambiguous imports, duplicate IDs, missing classes, invalid XML and absent declarations produce diagnostics. Attached-property binding discovery, open child-draft metadata overlays, generated metadata precedence and complete collection compatibility remain later extensions, not silently inferred support.
## Qualification
Tests cover non-initializing signature discovery, nested and collection metadata, direction-dependent assignability, read-only targets, incompatible targets, secure parsing, metadata codec bounds and capability negotiation. Real classpath/module-path Person fixtures check Component Model compatibility and absence of Model, Controller and provider construction/initialization. Connected contracts test the worker protocol in both document adapters; live shared Kit checks use the same browser in standalone and the registered IntelliJ editor and verify source preservation.
Qualification on 2026-11-13 passed: 69 Maven tests and 7 IntelliJ adapter tests; 34 target processes with 424 assertions; connected discovery checks in both document adapters (112 total workflow assertions); live shared-browser checks in standalone and registered IntelliJ for classpath and module-path applications. The existing 48 worker lifecycle cycles, owner-death checks, JavaFX 26 native isolation, package/bytecode boundaries and documentation checks also passed. No new native crash report appeared. Local run logs are `/tmp/binding-bootstrap.log` and `/tmp/binding-registered-ide.log`. The remaining stage-3 human tests are [explicitly skipped by user decision](manual-runtime-navigation.md); automated evidence and reported manual passes remain distinct.