Skip to content

Commit

Permalink
feat: support DataProviderWrapper better in AbstractDataView (#18317)
Browse files Browse the repository at this point in the history
* feat: support DataProviderWrapper better in AbstractDataView

Adds in `AbstractDataView` a better support for wrapper data providers that implements `DataProviderWrapper`. `AbstractDataView` won't throw exception anymore if wrapped data container is supported by the data view implementation. Adds public `getWrappedDataProvider` method in `DataProviderWrapper`.

Related-to: #18088

* chore: changed getWrappedDataProvider to package-private
  • Loading branch information
tltv authored Dec 15, 2023
1 parent 64b220e commit cdfde35
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public AbstractDataView(
* the data provider.
*/
if (isDataProviderInitialized(dataProviderType)) {
verifyDataProviderType(dataProviderType);
verifyDataProviderType(dataProviderSupplier.get());
}
}

Expand Down Expand Up @@ -115,6 +115,32 @@ protected final void verifyDataProviderType(Class<?> dataProviderType) {
}
}

/**
* Verifies an obtained {@link DataProvider} type is appropriate for current
* Data View type. If the data provider is a wrapper, then the wrapped data
* provider is verified too.
*
* @param dataProvider
* data provider to be verified
* @throws IllegalStateException
* if data provider type is incompatible with data view type
*/
protected final void verifyDataProviderType(
DataProvider<T, ?> dataProvider) {
try {
verifyDataProviderType(dataProvider.getClass());
} catch (IllegalStateException e) {
if (DataProviderWrapper.class
.isAssignableFrom(dataProvider.getClass())) {
verifyDataProviderType(
((DataProviderWrapper<T, ?, ?>) dataProvider)
.getWrappedDataProvider());
} else {
throw e;
}
}
}

@Override
public Stream<T> getItems() {
return dataProviderSupplier.get().fetch(new Query<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public AbstractLazyDataView(DataCommunicator<T> dataCommunicator,
* @return the data communicator
*/
protected DataCommunicator<T> getDataCommunicator() {
verifyDataProviderType(dataCommunicator.getDataProvider().getClass());
verifyDataProviderType(dataCommunicator.getDataProvider());
return dataCommunicator;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ protected Class<?> getSupportedDataProviderType() {
protected ListDataProvider<T> getDataProvider() {
final DataProvider<T, ?> dataProvider = dataProviderSupplier.get();
Objects.requireNonNull(dataProvider, "DataProvider cannot be null");
verifyDataProviderType(dataProvider.getClass());
verifyDataProviderType(dataProvider);
return (ListDataProvider<T>) dataProvider;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ protected DataProviderWrapper(DataProvider<T, M> dataProvider) {
"The wrapped data provider cannot be null.");
}

/**
* Gets wrapped data provider.
*
* @return the wrapped data provider
*/
DataProvider<T, M> getWrappedDataProvider() {
return dataProvider;
}

@Override
public boolean isInMemory() {
return dataProvider.isInMemory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentUtil;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.function.SerializablePredicate;
import com.vaadin.flow.function.SerializableSupplier;
import com.vaadin.flow.shared.Registration;
import com.vaadin.flow.tests.data.bean.Item;
import org.junit.Assert;
import org.junit.Before;
Expand All @@ -38,6 +41,8 @@ public class AbstractDataViewTest {

private ListDataProvider<Item> dataProvider;

private DataProvider<Item, ?> wrapperDataProvider;

private AbstractDataView<Item> dataView;

private Component component;
Expand Down Expand Up @@ -100,6 +105,139 @@ public void refreshAll_listenersNotified() {
Assert.assertEquals(dataProvider, refreshAllEvent.get().getSource());
}

@Test
public void verifyDataProviderType_wrappedDataProviderIsSupported() {
// starting with EmptyDataProvider to bypass checking too early in
// the DataViewImpl constructor.
wrapperDataProvider = new DataCommunicator.EmptyDataProvider<>();
DataViewImpl dataView = new DataViewImpl(() -> wrapperDataProvider,
component) {
@Override
public Class<?> getSupportedDataProviderType() {
return InMemoryDataProvider.class;
}
};
wrapperDataProvider = getWrapperDataProvider();
dataView.verifyDataProviderType(wrapperDataProvider);
}

@Test
public void verifyDataProviderType_withConfigurableFilter_wrappedDataProviderIsSupported() {
wrapperDataProvider = new DataCommunicator.EmptyDataProvider<>();
DataViewImpl dataView = new DataViewImpl(() -> wrapperDataProvider,
component) {
@Override
public Class<?> getSupportedDataProviderType() {
return InMemoryDataProvider.class;
}
};
wrapperDataProvider = dataProvider.withConfigurableFilter();
dataView.verifyDataProviderType(wrapperDataProvider);
}

@Test
public void verifyDataProviderType_wrappedDataProviderIsNotSupported() {
wrapperDataProvider = new DataCommunicator.EmptyDataProvider<>();
DataViewImpl dataView = new DataViewImpl(() -> wrapperDataProvider,
component) {
@Override
public Class<?> getSupportedDataProviderType() {
return BackEndDataProvider.class;
}
};
wrapperDataProvider = getWrapperDataProvider();
Assert.assertThrows(IllegalStateException.class,
() -> dataView.verifyDataProviderType(wrapperDataProvider));
}

@Test
public void verifyDataProviderType_withConfigurableFilter_wrappedDataProviderIsNotSupported() {
wrapperDataProvider = new DataCommunicator.EmptyDataProvider<>();
DataViewImpl dataView = new DataViewImpl(() -> wrapperDataProvider,
component) {
@Override
public Class<?> getSupportedDataProviderType() {
return BackEndDataProvider.class;
}
};
wrapperDataProvider = dataProvider.withConfigurableFilter();
Assert.assertThrows(IllegalStateException.class,
() -> dataView.verifyDataProviderType(wrapperDataProvider));
}

@Test
public void verifyDataProviderType_wrapperIsBackEndDataProvider_wrapperDataProviderIsSupported() {
wrapperDataProvider = new DataCommunicator.EmptyDataProvider<>();
DataViewImpl dataView = new DataViewImpl(() -> wrapperDataProvider,
component) {
@Override
public Class<?> getSupportedDataProviderType() {
return BackEndDataProvider.class;
}
};
wrapperDataProvider = new BackEndDataProviderWrapper(dataProvider);
dataView.verifyDataProviderType(wrapperDataProvider);
}

private DataProvider<Item, Object> getWrapperDataProvider() {
return new DataProviderWrapper<Item, Object, SerializablePredicate<Item>>(
dataProvider) {
@Override
protected SerializablePredicate<Item> getFilter(Query query) {
return null;
}

@Override
public Stream fetch(Query query) {
return null;
}
};
}

// BackEndDataProvider that is also a DataProviderWrapper
private static class BackEndDataProviderWrapper extends
DataProviderWrapper<Item, Object, SerializablePredicate<Item>>
implements BackEndDataProvider<Item, Object> {
protected BackEndDataProviderWrapper(
DataProvider<Item, SerializablePredicate<Item>> dataProvider) {
super(dataProvider);
}

@Override
public Stream fetch(Query query) {
return null;
}

@Override
public void setSortOrders(List<QuerySortOrder> sortOrders) {
}

@Override
public int size(Query<Item, Object> query) {
return 0;
}

@Override
protected SerializablePredicate<Item> getFilter(
Query<Item, Object> query) {
return null;
}

@Override
public void refreshItem(Item item) {
}

@Override
public void refreshAll() {
}

@Override
public Registration addDataProviderListener(
DataProviderListener<Item> listener) {
return null;
}
}

/**
* setIdentifierProvider is tested in AbstractListDataView since it has the
* container(T item) method.
Expand Down

0 comments on commit cdfde35

Please sign in to comment.