Completed lifecycle phase refactoring and queueing algorithm.
- Moved buildView() from ViewService to ViewLifecycle.
- Added isInitialized(), isModelApplied(), isFinal(), and isRendered() methods to Component.
- Moved performComponentApplyModel() and all related methods from ViewLifecycle to discrete lifecycle phase processing task ApplyModelComponentPhase.
- Moved performComponentFinalize() and all related methods from ViewLifecycle to discrete lifecycle phase processing task FinalizeComponentPhase.
- Changed spawnSubLifecycle to queue sub-lifecycle phases after applying component IDs, rather than process inline.
- Modified inline references to performComponentInitialize to call spawnSubLifecycle instead.
Cleanup following implementation of the queueing algorithm took a little longer than expected. I had initially set IAE to be thrown when attempting to queue a lifecycle phase for a component that already has the targeted view status, and for ISE to be thrown when attempting to process a component without the required view status. This helped uncover some lifecycle processing issues, but prior to commit I downgraded these to warning conditions for further review without impacting stability. Cleanup uncovered by these conditions:
- Duplicate entry of breadcrumb items in View.getComponentsForLifecycle()
- Inclusion of fieldLabel as nested under FieldBase when isLabelRendered() is true. In this case, the label becomes a child of the owning group when LabelSeparateModifier runs.
- Several areas where performApplyModel was called twice: once from spawnSubLifecycle, then again as a nested component.
The only page I found where invalid status warnings still appear is Kitchen Sink "Other Examples". Remaining KRAD pages in sampleapp and krad-sampleapp appear to work well without lifecycle phase violations in single-threaded mode.
Will configure a thread pool and convert queueing to multi-threaded operation once
KULRICE-10548 is complete.