Enhancement
Critical
Major
Detail
Detail
Critical
#26311
GridComponent: Programmatic invalidation after multi-selection leads to undefined behavior
When using the GridComponent to tabulate persistent objects and turning on multi-selection (via the checkbox column), a condition can be induced where the inner GUI model of the component becomes inconsistent, leading to undefined behavior. The scenario for this is as follows:
- Select multiple rows in the GridComponent using the checkbox column.
- Invalidate the component programmatically (via GridComponent.invalidate()) using e.g. a button.
- Select an additional line
=> A ClassCastException is thrown and the selection does not correspond to the expected one. Sometimes completely different rows are selected or suddenly nothing at all.
=== Analysis In com.top_logic.element.layout.grid.AbstractGridHandler.selectionToFormGroups(Object) only sets are handled correctly. After programmatic invalidation, however, the selection seems to be in the form of a list. Among other things, this also leads to the server-side GUI model (the FormGroups) being annotated incorrectly, so that one and the same line is provided with several subject objects under GridComponent.PROP_ATTRIBUTED.
If you now try to execute subject code - based on the selection - the subject code is executed on completely wrong objects.
Improvement
In the course of #24566 some improvements were made to the grid selection, which resulted in selections suddenly being stored as lists and not as sets. Since the program is not designed for this, this leads to the described behavior. To save the selection as a set again the return value of com.top_logic.element.layout.grid.GridUtil.getBusinessObjectsFromInternalRows(Collection<?>) (and all methods called in it) was changed from List to LinkedHashSet.
Test
**On TL_6x:** Create a view with Grid that supports multi-selection. Alternatively, you can just use this view: Technical Demo > Tests > External Selection > External Selection in Grid. Additionally a button for invalidating has to be added. To customize grid in the upper left corner the following must be added to gridExternalSelection.xml in the grid named "gridDemo1": {{#!xml <buttons>
<reference command-id="invalidate"/>
</buttons> }} Now start the application and switch to the appropriate view. In the customized grid, select some rows and then click on the newly inserted invalidate button. The selection must be preserved and no error message must be generated. Also further selections must not generate error messages and must work.
**On TL_7x** Since the corresponding functions are not used here here is a refactoring.