|
36 | 36 | import java.util.stream.Stream;
|
37 | 37 |
|
38 | 38 | import org.slf4j.LoggerFactory;
|
| 39 | +import org.springframework.data.domain.Pageable; |
39 | 40 |
|
40 | 41 | import com.vaadin.flow.component.AttachEvent;
|
41 | 42 | import com.vaadin.flow.component.ClientCallable;
|
|
131 | 132 | import com.vaadin.flow.internal.JsonUtils;
|
132 | 133 | import com.vaadin.flow.internal.ReflectTools;
|
133 | 134 | import com.vaadin.flow.shared.Registration;
|
| 135 | +import com.vaadin.flow.spring.data.VaadinSpringDataHelpers; |
134 | 136 |
|
135 | 137 | import elemental.json.Json;
|
136 | 138 | import elemental.json.JsonArray;
|
@@ -2916,6 +2918,130 @@ public GridLazyDataView<T> setItems(
|
2916 | 2918 | return getLazyDataView();
|
2917 | 2919 | }
|
2918 | 2920 |
|
| 2921 | + public interface SpringData extends Serializable { |
| 2922 | + /** |
| 2923 | + * Callback interface for fetching a list of items from a backend based |
| 2924 | + * on a Spring Data Pageable. |
| 2925 | + * |
| 2926 | + * @param <T> |
| 2927 | + * the type of the items to fetch |
| 2928 | + */ |
| 2929 | + @FunctionalInterface |
| 2930 | + public interface FetchCallback<PAGEABLE, T> extends Serializable { |
| 2931 | + |
| 2932 | + /** |
| 2933 | + * Fetches a list of items based on a pageable. The pageable defines |
| 2934 | + * the paging of the items to fetch and the sorting. |
| 2935 | + * |
| 2936 | + * @param pageable |
| 2937 | + * the pageable that defines which items to fetch and the |
| 2938 | + * sort order |
| 2939 | + * @return a list of items |
| 2940 | + */ |
| 2941 | + List<T> fetch(PAGEABLE pageable); |
| 2942 | + } |
| 2943 | + |
| 2944 | + /** |
| 2945 | + * Callback interface for counting the number of items in a backend |
| 2946 | + * based on a Spring Data Pageable. |
| 2947 | + */ |
| 2948 | + @FunctionalInterface |
| 2949 | + public interface CountCallback<PAGEABLE> extends Serializable { |
| 2950 | + /** |
| 2951 | + * Counts the number of available items based on a pageable. The |
| 2952 | + * pageable defines the paging of the items to fetch and the sorting |
| 2953 | + * and is provided although it is generally not needed for |
| 2954 | + * determining the number of items. |
| 2955 | + * |
| 2956 | + * @param pageable |
| 2957 | + * the pageable that defines which items to fetch and the |
| 2958 | + * sort order |
| 2959 | + * @return the number of available items |
| 2960 | + */ |
| 2961 | + long count(PAGEABLE pageable); |
| 2962 | + } |
| 2963 | + } |
| 2964 | + |
| 2965 | + /** |
| 2966 | + * Supply items lazily with a callback from a backend based on a Spring Data |
| 2967 | + * Pageable. The component will automatically fetch more items and adjust |
| 2968 | + * its size until the backend runs out of items. Usage example: |
| 2969 | + * <p> |
| 2970 | + * {@code component.setItemsPageable(pageable -> orderService.getOrders(pageable));} |
| 2971 | + * <p> |
| 2972 | + * The returned data view object can be used for further configuration, or |
| 2973 | + * later on fetched with {@link #getLazyDataView()}. For using in-memory |
| 2974 | + * data, like {@link java.util.Collection}, use |
| 2975 | + * {@link HasListDataView#setItems(Collection)} instead. |
| 2976 | + * |
| 2977 | + * @param fetchCallback |
| 2978 | + * a function that returns a sorted list of items from the |
| 2979 | + * backend based on the given pageable |
| 2980 | + * @return a data view for further configuration |
| 2981 | + */ |
| 2982 | + public GridLazyDataView<T> setItemsPageable( |
| 2983 | + SpringData.FetchCallback<Pageable, T> fetchCallback) { |
| 2984 | + return setItems( |
| 2985 | + query -> handleSpringFetchCallback(query, fetchCallback)); |
| 2986 | + } |
| 2987 | + |
| 2988 | + /** |
| 2989 | + * Supply items lazily with callbacks: the first one fetches a list of items |
| 2990 | + * from a backend based on a Spring Data Pageable, the second provides the |
| 2991 | + * exact count of items in the backend. Use this in case getting the count |
| 2992 | + * is cheap and the user benefits from the component showing immediately the |
| 2993 | + * exact size. Usage example: |
| 2994 | + * <p> |
| 2995 | + * {@code component.setItemsPageable( |
| 2996 | + * pageable -> orderService.getOrders(pageable), |
| 2997 | + * pageable -> orderService.countOrders());} |
| 2998 | + * <p> |
| 2999 | + * The returned data view object can be used for further configuration, or |
| 3000 | + * later on fetched with {@link #getLazyDataView()}. For using in-memory |
| 3001 | + * data, like {@link java.util.Collection}, use |
| 3002 | + * {@link HasListDataView#setItems(Collection)} instead. |
| 3003 | + * |
| 3004 | + * @param fetchCallback |
| 3005 | + * a function that returns a sorted list of items from the |
| 3006 | + * backend based on the given pageable |
| 3007 | + * @param countCallback |
| 3008 | + * a function that returns the number of items in the back end |
| 3009 | + * @return LazyDataView instance for further configuration |
| 3010 | + */ |
| 3011 | + public GridLazyDataView<T> setItemsPageable( |
| 3012 | + SpringData.FetchCallback<Pageable, T> fetchCallback, |
| 3013 | + SpringData.CountCallback<Pageable> countCallback) { |
| 3014 | + return setItems( |
| 3015 | + query -> handleSpringFetchCallback(query, fetchCallback), |
| 3016 | + query -> handleSpringCountCallback(query, countCallback)); |
| 3017 | + } |
| 3018 | + |
| 3019 | + @SuppressWarnings("unchecked") |
| 3020 | + private static <PAGEABLE, T> Stream<T> handleSpringFetchCallback( |
| 3021 | + Query<T, Void> query, |
| 3022 | + SpringData.FetchCallback<PAGEABLE, T> fetchCallback) { |
| 3023 | + PAGEABLE pageable = (PAGEABLE) VaadinSpringDataHelpers |
| 3024 | + .toSpringPageRequest(query); |
| 3025 | + List<T> itemList = fetchCallback.fetch(pageable); |
| 3026 | + return itemList.stream(); |
| 3027 | + } |
| 3028 | + |
| 3029 | + @SuppressWarnings("unchecked") |
| 3030 | + private static <PAGEABLE> int handleSpringCountCallback( |
| 3031 | + Query<?, Void> query, |
| 3032 | + SpringData.CountCallback<PAGEABLE> countCallback) { |
| 3033 | + PAGEABLE pageable = (PAGEABLE) VaadinSpringDataHelpers |
| 3034 | + .toSpringPageRequest(query); |
| 3035 | + long count = countCallback.count(pageable); |
| 3036 | + if (count > Integer.MAX_VALUE) { |
| 3037 | + LoggerFactory.getLogger(Grid.class).warn( |
| 3038 | + "The count of items in the backend ({}) exceeds the maximum supported by the Grid.", |
| 3039 | + count); |
| 3040 | + return Integer.MAX_VALUE; |
| 3041 | + } |
| 3042 | + return (int) count; |
| 3043 | + } |
| 3044 | + |
2919 | 3045 | /**
|
2920 | 3046 | * Gets the lazy data view for the grid. This data view should only be used
|
2921 | 3047 | * when the items are provided lazily from the backend with:
|
|
0 commit comments