Skip to content

Commit

Permalink
CAUSEWAY-2297: convert table models to java records (part 3)
Browse files Browse the repository at this point in the history
  • Loading branch information
andi-huber committed Nov 21, 2024
1 parent 4e32cf5 commit ada4f7d
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface DataColumn {
*/
String columnId();
ObjectAssociation associationMetaModel();
Observable<String> columnFriendlyName();
Observable<Optional<String>> columnDescription();
Observable<String> columnFriendlyNameObservable();
Observable<Optional<String>> columnDescriptionObservable();

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public interface DataRow {
/**
* If the table supports row selection, represents the bindable row selection status for this {@link DataRow}.
*/
Bindable<Boolean> selectToggle();
Bindable<Boolean> selectToggleBindable();

Optional<Tokens> filterTokens();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public Optional<Comparator<ManagedObject>> asComparator(final Can<? extends Data

Observable<String> titleObservable();
Observable<Can<DataColumn>> dataColumnsObservable();
Observable<Can<ManagedObject>> getDataElements();
Observable<Can<DataRow>> getDataRowsFilteredAndSorted();
Observable<Can<ManagedObject>> dataElementsObservable();
Observable<Can<DataRow>> dataRowsFilteredAndSortedObservable();

// -- META DATA

Expand All @@ -94,7 +94,7 @@ public Optional<Comparator<ManagedObject>> asComparator(final Can<? extends Data
// -- ROW COUNT

/**
* Counts number of rows in {@link #getDataRowsFilteredAndSorted()}.
* Counts number of rows in {@link #dataRowsFilteredAndSortedObservable()}.
*/
int getFilteredElementCount();

Expand All @@ -117,7 +117,7 @@ public Optional<Comparator<ManagedObject>> asComparator(final Can<? extends Data

void doProgrammaticToggle(Runnable runnable);
Set<Integer> getSelectedRowIndexes();
Observable<Can<DataRow>> getDataRowsSelected();
Observable<Can<DataRow>> dataRowsSelectedObservable();
void selectRangeOfRowsByIndex(IntStream range, boolean select);
void selectAllFiltered(boolean select);
void selectAll(boolean select);
Expand All @@ -132,7 +132,7 @@ public Optional<Comparator<ManagedObject>> asComparator(final Can<? extends Data

// -- FILTER SUPPORT

Bindable<String> getSearchArgument();
Bindable<String> searchArgumentBindable();
boolean isSearchSupported();
/**
* @apiNote never called when not {@link #isSearchSupported()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
record DataColumnInternal(
@NonNull String columnId,
@NonNull ObjectAssociation associationMetaModel,
@NonNull LazyObservable<String> columnFriendlyName,
@NonNull LazyObservable<Optional<String>> columnDescription)
@NonNull LazyObservable<String> columnFriendlyNameObservable,
@NonNull LazyObservable<Optional<String>> columnDescriptionObservable)
implements DataColumn {

DataColumnInternal(final DataTableInternal parentTable, final ObjectAssociation associationMetaModel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
record DataRowInternal(
int rowIndex,
ManagedObject rowElement,
BooleanBindable selectToggle,
BooleanBindable selectToggleBindable,
DataTableInternal parentTable,
Optional<CollectionFilterService.Tokens> filterTokens
) implements DataRow {
Expand All @@ -50,7 +50,7 @@ record DataRowInternal(
final @NonNull ManagedObject rowElement,
final @Nullable CollectionFilterService.Tokens filterTokens) {
this(rowIndex, rowElement, _Bindables.forBoolean(false), parentTable, Optional.ofNullable(filterTokens));
selectToggle.addListener((event, old, neW)->parentTable.handleRowSelectToggle());
selectToggleBindable.addListener((event, old, neW)->parentTable.handleRowSelectToggle());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,20 @@ public static DataTableInternal forAction(
final @NonNull ManagedMember managedMember;
final @NonNull Where where;

@Getter private final @NonNull LazyObservable<Can<ManagedObject>> dataElements;
@Getter private final @NonNull _BindableAbstract<String> searchArgument; // filter the data rows
@Accessors(fluent=true)
@Getter private final @NonNull LazyObservable<Can<ManagedObject>> dataElementsObservable;

@Accessors(fluent=true)
@Getter private final @NonNull _BindableAbstract<String> searchArgumentBindable; // filter the data rows

@Accessors(fluent=true)
@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRowsObservable;

@Accessors(fluent=true)
@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRowsFilteredAndSortedObservable;

@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRows;
@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRowsFilteredAndSorted;
@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRowsSelected;
@Accessors(fluent=true)
@Getter private final @NonNull LazyObservable<Can<DataRow>> dataRowsSelectedObservable;

@Accessors(fluent=true)
@Getter private final _BindableAbstract<ColumnSort> columnSortBinable;
Expand Down Expand Up @@ -142,38 +150,38 @@ private DataTableInternal(
this.where = where;
this.filterHandler = _FilterUtils.createFilterHandler(elementType);

this.searchArgument = _Bindables.forValue("");
this.searchArgumentBindable = _Bindables.forValue("");
this.columnSortBinable = _Bindables.forValue(null);

this.dataElements = _Observables.lazy(()->elements
this.dataElementsObservable = _Observables.lazy(()->elements
//.map(mmc::injectServicesInto) // I believe is redundant, has major performance impact
//.filter(this::ignoreHidden) // I believe is redundant, has major performance impact
);

this.dataRows = _Observables.lazy(()->
dataElements.getValue().stream()
this.dataRowsObservable = _Observables.lazy(()->
dataElementsObservable.getValue().stream()
.map(IndexedFunction.zeroBased((rowIndex, element)->new DataRowInternal(rowIndex, this, element, tokens(element))))
.collect(Can.toCan()));

this.dataRowsFilteredAndSorted = _Observables.lazy(()->
this.dataRowsFilteredAndSortedObservable = _Observables.lazy(()->
_Streams.sortConditionally(
dataRows.getValue().stream().filter(adaptSearchPredicate()),
dataRowsObservable.getValue().stream().filter(adaptSearchPredicate()),
sortingComparator().orElse(null))
.collect(Can.toCan()));

this.dataRowsSelected = _Observables.lazy(()->
dataRows.getValue().stream()
.filter(dataRow->dataRow.selectToggle().getValue().booleanValue())
this.dataRowsSelectedObservable = _Observables.lazy(()->
dataRowsObservable.getValue().stream()
.filter(dataRow->dataRow.selectToggleBindable().getValue().booleanValue())
.collect(Can.toCan()));

this.selectionChanges = _Bindables.forValue(Boolean.FALSE);

this.searchArgument.addListener((e,o,n)->{
dataRowsFilteredAndSorted.invalidate();
this.searchArgumentBindable.addListener((e,o,n)->{
dataRowsFilteredAndSortedObservable.invalidate();
});

this.columnSortBinable.addListener((e,o,n)->{
dataRowsFilteredAndSorted.invalidate();
dataRowsFilteredAndSortedObservable.invalidate();
});

this.dataColumnsObservable = _Observables.lazy(()->
Expand Down Expand Up @@ -208,15 +216,15 @@ public Optional<TableDecorator> getTableDecoratorIfAny() {
* Count all data rows (the user is allowed to see).
*/
public int getVisibleElementCount() {
return dataElements.getValue().size();
return dataElementsObservable.getValue().size();
}

/**
* Count filtered data rows.
*/
@Override
public int getFilteredElementCount() {
return dataRowsFilteredAndSorted.getValue().size();
return dataRowsFilteredAndSortedObservable.getValue().size();
}

@Override
Expand All @@ -230,7 +238,7 @@ public ObjectSpecification getElementType() {

@Override
public Optional<DataRow> lookupDataRow(final int rowIndex) {
return getDataRows().getValue().get(rowIndex)
return dataRowsObservable().getValue().get(rowIndex)
.map(DataRow.class::cast);
}

Expand All @@ -246,7 +254,7 @@ private Predicate<DataRow> adaptSearchPredicate() {
return filterHandler.isEmpty()
? dataRow->true
: dataRow->filterHandler.get().getDataRowFilter()
.test(dataRow, searchArgument.getValue());
.test(dataRow, searchArgumentBindable.getValue());
}

@Nullable
Expand Down Expand Up @@ -288,38 +296,38 @@ void handleRowSelectToggle() {
}

private void invalidateSelectionThenNotifyListeners() {
dataRowsSelected.invalidate();
dataRowsSelectedObservable.invalidate();
// simply toggles the boolean value, to trigger any listeners
selectionChanges.setValue(!selectionChanges.getValue());
}

@Override
public void selectAll(final boolean select) {
doProgrammaticToggle(()->{
dataRows.getValue()
dataRowsObservable.getValue()
.forEach(dataRow->{
dataRow.selectToggle().setValue(select);
dataRow.selectToggleBindable().setValue(select);
});
});
}

@Override
public void selectAllFiltered(final boolean select) {
doProgrammaticToggle(()->{
dataRowsFilteredAndSorted.getValue()
dataRowsFilteredAndSortedObservable.getValue()
.forEach(dataRow->{
dataRow.selectToggle().setValue(select);
dataRow.selectToggleBindable().setValue(select);
});
});
}

@Override
public void selectRangeOfRowsByIndex(final IntStream range, final boolean select) {
doProgrammaticToggle(()->{
dataRowsFilteredAndSorted.getValue()
dataRowsFilteredAndSortedObservable.getValue()
.pickByIndex(range)
.forEach(dataRow->{
dataRow.selectToggle().setValue(select);
dataRow.selectToggleBindable().setValue(select);
});
});
}
Expand All @@ -343,13 +351,13 @@ public void selectRangeOfRowsByIndex(final IntStream range, final boolean select

@Override
public Can<ManagedObject> getSelected() {
return dataRowsSelected.getValue()
return dataRowsSelectedObservable.getValue()
.map(DataRow::rowElement);
}

@Override
public Set<Integer> getSelectedRowIndexes() {
return dataRowsSelected.getValue()
return dataRowsSelectedObservable.getValue()
.stream()
.map(DataRow::rowIndex)
.collect(Collectors.toSet());
Expand Down Expand Up @@ -377,7 +385,7 @@ public DataTable export() {
titleObservable().getValue(),
dataColumnsObservable().getValue()
.map(DataColumn::associationMetaModel),
getDataRowsFilteredAndSorted().getValue()
dataRowsFilteredAndSortedObservable().getValue()
.stream()
.map(dr->dr.rowElement())
.collect(Can.toCan()));
Expand All @@ -390,7 +398,7 @@ private DataTable exportAll() {
titleObservable().getValue(),
dataColumnsObservable().getValue()
.map(DataColumn::associationMetaModel),
getDataElements().getValue());
dataElementsObservable().getValue());
}

// -- MEMENTO
Expand Down Expand Up @@ -420,7 +428,7 @@ static Memento create(
tableInteractive.managedMember.getIdentifier(),
tableInteractive.where,
tableInteractive.exportAll(),
tableInteractive.searchArgument.getValue(),
tableInteractive.searchArgumentBindable.getValue(),
tableInteractive.getSelectedRowIndexes(),
tableInteractive.columnSortBinable().getValue());
}
Expand Down Expand Up @@ -462,18 +470,18 @@ public DataTableInternal getDataTableModel(final ManagedObject owner) {
if(columnSort!=null) {
dataTableInteractive.columnSortBinable.setValue(columnSort);
}
dataTableInteractive.searchArgument.setValue(searchArgument);
dataTableInteractive.searchArgumentBindable.setValue(searchArgument);
dataTableInteractive.doProgrammaticToggle(()->{
dataTableInteractive.dataRows.getValue().stream()
dataTableInteractive.dataRowsObservable.getValue().stream()
.filter(dataRow->selectedRowIndexes.contains(dataRow.rowIndex()))
.forEach(dataRow->dataRow.selectToggle().setValue(true));
.forEach(dataRow->dataRow.selectToggleBindable().setValue(true));
});
return dataTableInteractive;
}

@Override
public void setupBindings(final DataTableInteractive tableInteractive) {
tableInteractive.getSearchArgument().addListener((e, o, searchArg)->{
tableInteractive.searchArgumentBindable().addListener((e, o, searchArg)->{
this.searchArgument = searchArg;
});
((DataTableInternal)tableInteractive).selectionChanges.addListener((e, o, n)->{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void buildGui() {
config.setSelectable(true);
config.setAllDaySlot(true);

final Iterable<ManagedObject> entityList = model.getDataTableModel().getDataRowsFilteredAndSorted().getValue()
final Iterable<ManagedObject> entityList = model.getDataTableModel().dataRowsFilteredAndSortedObservable().getValue()
.map(DataRow::rowElement);
final Iterable<String> calendarNames = getCalendarNames(entityList);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public EventProviderAbstract(final EntityCollectionModel collectionModel, final
var commonContext = collectionModel.getMetaModelContext();

collectionModel.getDataTableModel()
.getDataElements().getValue()
.dataElementsObservable().getValue()
.stream()
.map(newEvent(commonContext, calendarName))
.filter(Objects::nonNull)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ public class DataTableTester {

public void assertUnfilteredDataElements(final List<Object> expectedPojoElements) {
assertEquals(expectedPojoElements,
dataTable.getDataElements().getValue()
dataTable.dataElementsObservable().getValue()
.map(MmUnwrapUtils::single).toList());
}

public void assertFilteredDataElements(final List<Object> expectedPojoElements) {
assertEquals(expectedPojoElements,
dataTable.getDataRowsFilteredAndSorted().getValue()
dataTable.dataRowsFilteredAndSortedObservable().getValue()
.map(DataRow::rowElement)
.map(MmUnwrapUtils::single).toList());
}

public void assertSelectedDataElements(final List<Object> expectedPojoElements) {
assertEquals(expectedPojoElements,
dataTable.getDataRowsSelected().getValue()
dataTable.dataRowsSelectedObservable().getValue()
.map(DataRow::rowElement)
.map(MmUnwrapUtils::single).toList());
}
Expand All @@ -62,36 +62,36 @@ public void assertDataRowSelectionWhenToggledOn(
final List<Integer> toggleOnIndices,
final List<Object> expectedPojoElements) {
toggleOnIndices.forEach(index->
dataTable.getDataRowsFilteredAndSorted().getValue().getElseFail(index).selectToggle().setValue(true));
dataTable.dataRowsFilteredAndSortedObservable().getValue().getElseFail(index).selectToggleBindable().setValue(true));
assertSelectedDataElements(expectedPojoElements);
}

public void assertDataRowSelectionWhenToggledOff(
final List<Integer> toggleOffIndices,
final List<Object> expectedPojoElements) {
toggleOffIndices.forEach(index->
dataTable.getDataRowsFilteredAndSorted().getValue().getElseFail(index).selectToggle().setValue(false));
dataTable.dataRowsFilteredAndSortedObservable().getValue().getElseFail(index).selectToggleBindable().setValue(false));
assertSelectedDataElements(expectedPojoElements);
}

public void assertDataRowSelectionIsAll() {
assertEquals(
dataTable.getDataRowsFilteredAndSorted().getValue()
dataTable.dataRowsFilteredAndSortedObservable().getValue()
.map(DataRow::rowElement)
.map(MmUnwrapUtils::single).toList(),
dataTable.getDataRowsSelected().getValue()
dataTable.dataRowsSelectedObservable().getValue()
.map(DataRow::rowElement)
.map(MmUnwrapUtils::single).toList());
}

public void assertDataRowSelectionIsEmpty() {
assertEquals(0, dataTable.getDataRowsSelected().getValue().size());
assertEquals(0, dataTable.dataRowsSelectedObservable().getValue().size());
}

public void assertColumnNames(final List<String> expectedColumnNames) {
assertEquals(expectedColumnNames,
dataTable.dataColumnsObservable().getValue().stream()
.map(DataColumn::columnFriendlyName)
.map(DataColumn::columnFriendlyNameObservable)
.map(Observable::getValue)
.collect(Collectors.toList()));
}
Expand Down
Loading

0 comments on commit ada4f7d

Please sign in to comment.