fix: treat HierarchicalDataProvider.refreshItem(null) as virtual root - #25100
fix: treat HierarchicalDataProvider.refreshItem(null) as virtual root#25100arimu1 wants to merge 10 commits into
Conversation
182a45e to
36738ba
Compare
|
Re-triggered CI after CLA was signed. Local verification (JBR 17):
Null item is treated as the virtual hierarchy root → |
|
Fixed TeamCity Formatter failures: Spotless javadoc line wraps in |
|
@vursen Thanks for the review — simplified per your suggestions. A. Simplified: B. Same-reference in-place refresh C. Root viewport resend / NPE fix retained: Local: |
|
Follow-up after TeamCity red + local investigation: Local Locally now:
Also rebased onto current |
f05157e to
510ad78
Compare
null is the virtual root (parent of root-level items) in TreeData-style hierarchies. Calling refreshItem(null) previously threw NPE in DataRefreshEvent. Allow null in DataRefreshEvent for hierarchical virtual-root semantics. refreshItem(null) refreshes root-level items only; refreshItem(null, true) re-fetches root children via HierarchicalDataCommunicator without a full reset()/refreshAll() (acknowledging that equating null to refreshAll is too broad). Fixes vaadin#19377
TeamCity Formatter failed on javadoc line wrapping in DataChangeEvent and HierarchicalDataCommunicator. spotless:apply only; behavior unchanged.
Per maintainer review (@vursen): differentiating refreshChildren for the virtual root was inconsistent with non-null item semantics and the same-reference in-place path was effectively a no-op. Null is the virtual hierarchy root (call sites use refreshItem(getParent(item), true) for roots → null). Always map it to refreshAll()/reset() regardless of refreshChildren. Keep DataRefreshEvent allowing null so the NPE from vaadin#19377 stays fixed.
reset() preserves expand state; after refresh(null) with Item 0 expanded and a new root, flattened size is 4 not 3. Aligns with refreshAll behavior.
510ad78 to
1816aec
Compare
|
Rebased onto latest |
|
Hi @vursen — following up on the TeamCity failures. After the last rebase + force-push, all five TeamCity jobs (Formatter / Gradle Tests / API-DIFF labeling / Validation / Validation-SlowTests) are still red simultaneously. I tried to read the TeamCity logs but they require authentication (no guest access succeeded). Locally I verified the minimal change set against The spotless plugin is configured to enforce Could you share the TeamCity log (or confirm whether this is a known infra issue for fork-based PRs)? Happy to adjust if there is a real finding — I just cannot see past the auth wall. |
| if (item == null) { | ||
| // Virtual root: always full hierarchy refresh. refreshChildren is | ||
| // intentionally ignored (same as HierarchicalDataCommunicator). | ||
| refreshAll(); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Is this required? This is already handled by HierarchicalDataCommunicator#refresh.
| if (item == null) { | ||
| refreshAll(); | ||
| return; | ||
| } |
There was a problem hiding this comment.
Is this required? This is already handled by HierarchicalDataCommunicator#refresh.
|
After giving it a second thought, I'm not sure the current change fully solves the problem. It removes one confusion, but adds another one. Previously, it wasn't possible to use It now seems to me that, if anything, this change makes sense only for
|
I agree. For consistency reason I approved the current implementation already, but limiting it only for |
Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>
Co-authored-by: Sergey Vinogradov <mr.vursen@gmail.com>
|
@claude Change this to only affect |
|
Claude finished @tltv's task in 8m 10s —— View job Done — narrowed to
|
| Call | Result |
|---|---|
refreshItem(null, true) |
full refresh — refreshAll() / reset() |
refreshItem(null, false) |
no-op |
refreshItem(null) |
no-op |
refreshItem(item, …) |
unchanged |
DataRefreshEvent still permits a null item so the virtual-root event can reach the communicator without an NPE; the non-hierarchical DataCommunicator.refresh(T) continues to reject null via its existing requireNonNull, so nothing changes for flat data providers.
Note
Please review the changes yourself and mark the PR ready when you're happy with it.
• fix/19377-refreshitem-null
Description
HierarchicalDataProvider.refreshItem(null)threw aNullPointerExceptionbecauseDataRefreshEventrequired a non-null item.In hierarchical data models such as
TreeData,nullis the virtual root (the parent of root-level items). Call sites that dorefreshItem(getParent(item), true)therefore hit NPE when the item is a root.Semantics (simplified after review)
Per @vursen and the original expectation on #19377:
refreshItem(null)is equivalent torefreshAll()/ communicatorreset(), regardless ofrefreshChildren. Differentiating on that flag for the virtual root was inconsistent with non-null item semantics; the same-reference in-place path was a no-op and was removed.DataRefreshEventstill allowsnullso the hierarchical virtual-root path does not throw.Changes
DataChangeEvent.DataRefreshEvent: allownullitem (virtual root)AbstractHierarchicalDataProvider:refreshItem(null[, *])→refreshAll()HierarchicalDataCommunicator.refresh(null, *)→reset()Fixes #19377
Local verification
mvn -pl flow-data -Dtest=HierarchicalDataCommunicatorDataRefreshTest test— 19/19 (JDK 21)mvn -pl flow-data spotless:check— clean