Skip to content

Commit

Permalink
Fix sorted data provider data change event propagation
Browse files Browse the repository at this point in the history
This patch adds a test set for BackEndDataProvider.

Change-Id: I32dfedb692ba71247d74a682f79afdfaf8751de3
  • Loading branch information
Teemu Suo-Anttila authored and Vaadin Code Review committed Nov 29, 2016
1 parent 8ba5295 commit 7ff852f
Show file tree
Hide file tree
Showing 6 changed files with 555 additions and 226 deletions.
Expand Up @@ -21,6 +21,7 @@
import java.util.stream.Stream; import java.util.stream.Stream;


import com.vaadin.server.SerializableFunction; import com.vaadin.server.SerializableFunction;
import com.vaadin.shared.Registration;


/** /**
* A {@link DataProvider} for any back end. * A {@link DataProvider} for any back end.
Expand Down Expand Up @@ -71,16 +72,30 @@ public int size(Query<T, F> query) {
* directions * directions
* @return new data provider with modified sorting * @return new data provider with modified sorting
*/ */
@SuppressWarnings("serial")
public BackEndDataProvider<T, F> sortingBy( public BackEndDataProvider<T, F> sortingBy(
List<SortOrder<String>> sortOrders) { List<SortOrder<String>> sortOrders) {
return new BackEndDataProvider<>(query -> { BackEndDataProvider<T, F> parent = this;
return new BackEndDataProvider<T, F>(query -> {
List<SortOrder<String>> queryOrder = new ArrayList<>( List<SortOrder<String>> queryOrder = new ArrayList<>(
query.getSortOrders()); query.getSortOrders());
queryOrder.addAll(sortOrders); queryOrder.addAll(sortOrders);
return request.apply(new Query<>(query.getLimit(), return parent.fetch(new Query<>(query.getOffset(), query.getLimit(),
query.getOffset(), queryOrder, query.getInMemorySorting(), queryOrder, query.getInMemorySorting(),
query.getFilter().orElse(null))); query.getFilter().orElse(null)));
}, sizeCallback); }, sizeCallback) {

@Override
public Registration addDataProviderListener(
DataProviderListener listener) {
return parent.addDataProviderListener(listener);
}

@Override
public void refreshAll() {
parent.refreshAll();
}
};
} }


@Override @Override
Expand Down
19 changes: 17 additions & 2 deletions server/src/main/java/com/vaadin/server/data/ListDataProvider.java
Expand Up @@ -23,6 +23,7 @@
import java.util.stream.Stream; import java.util.stream.Stream;


import com.vaadin.server.SerializablePredicate; import com.vaadin.server.SerializablePredicate;
import com.vaadin.shared.Registration;


/** /**
* {@link DataProvider} wrapper for {@link Collection}s. This class does not * {@link DataProvider} wrapper for {@link Collection}s. This class does not
Expand Down Expand Up @@ -73,7 +74,7 @@ public Stream<T> fetch(Query<T, SerializablePredicate<T>> query) {
.filter(t -> query.getFilter().orElse(p -> true).test(t)); .filter(t -> query.getFilter().orElse(p -> true).test(t));


Optional<Comparator<T>> comparing = Stream Optional<Comparator<T>> comparing = Stream
.of(sortOrder, query.getInMemorySorting()) .of(query.getInMemorySorting(), sortOrder)
.filter(c -> c != null) .filter(c -> c != null)
.reduce((c1, c2) -> c1.thenComparing(c2)); .reduce((c1, c2) -> c1.thenComparing(c2));


Expand All @@ -94,8 +95,22 @@ public Stream<T> fetch(Query<T, SerializablePredicate<T>> query) {
* a {@link Comparator} providing the needed sorting order * a {@link Comparator} providing the needed sorting order
* @return new data provider with modified sorting * @return new data provider with modified sorting
*/ */
@SuppressWarnings("serial")
public ListDataProvider<T> sortingBy(Comparator<T> sortOrder) { public ListDataProvider<T> sortingBy(Comparator<T> sortOrder) {
return new ListDataProvider<>(backend, sortOrder); ListDataProvider<T> parent = this;
return new ListDataProvider<T>(backend, sortOrder) {

@Override
public Registration addDataProviderListener(
DataProviderListener listener) {
return parent.addDataProviderListener(listener);
}

@Override
public void refreshAll() {
parent.refreshAll();
}
};
} }


/** /**
Expand Down
132 changes: 132 additions & 0 deletions server/src/main/java/com/vaadin/server/data/Sort.java
@@ -0,0 +1,132 @@
/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.server.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.vaadin.shared.data.sort.SortDirection;

/**
* Helper class for constructing SortOrders.
*
* @author Vaadin Ltd
* @since 8.0
*/
public abstract class Sort implements Serializable {

/**
* SortBuilder is a helper class with fluent API for constructing sort order
* lists. When the sort order is ready to be passed on, calling
* {@link #build()} will create the list of sort orders
*
* @param <S>
* sort order data type
*
* @see Sort
* @see Sort#asc(Object)
* @see Sort#desc(Object)
* @see #build()
*/
public static class SortBuilder<S> implements Serializable {
private List<SortOrder<S>> sortOrder = new ArrayList<>();

/**
* Constructs an empty SortBuilder.
*/
protected SortBuilder() {
}

/**
* Appends sorting with ascending sort direction.
*
* @param by
* the object to sort by
* @return this sort builder
*/
public SortBuilder<S> thenAsc(S by) {
return append(by, SortDirection.ASCENDING);
}

/**
* Appends sorting with descending sort direction.
*
* @param by
* the object to sort by
* @return this sort builder
*/
public SortBuilder<S> thenDesc(S by) {
return append(by, SortDirection.DESCENDING);
}

/**
* Appends sorting with given sort direction.
*
* @param by
* the object to sort by
* @param direction
* the sort direction
*
* @return this sort builder
*/
protected SortBuilder<S> append(S by, SortDirection direction) {
sortOrder.add(new SortOrder<>(by, direction));
return this;
}

/**
* Returns an unmodifiable list of the current sort order in this sort
* builder.
*
* @return the unmodifiable sort order list
*/
public List<SortOrder<S>> build() {
return Collections.unmodifiableList(sortOrder);
}
}

/**
* Creates a new sort builder with given sorting using ascending sort
* direction.
*
* @param by
* the object to sort by
* @param <S>
* sort order data type
*
* @return the sort builder
*/
public static <S> SortBuilder<S> asc(S by) {
return new SortBuilder<S>().thenAsc(by);
}

/**
* Creates a new sort builder with given sorting using descending sort
* direction.
*
* @param by
* the object to sort by
* @param <S>
* sort order data type
*
* @return the sort builder
*/
public static <S> SortBuilder<S> desc(S by) {
return new SortBuilder<S>().thenDesc(by);
}
}
@@ -0,0 +1,62 @@
package com.vaadin.server.data.provider;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.vaadin.server.SerializablePredicate;
import com.vaadin.server.data.BackEndDataProvider;
import com.vaadin.server.data.SortOrder;
import com.vaadin.shared.data.sort.SortDirection;

public class BackendDataProviderTest extends
DataProviderTestBase<BackEndDataProvider<StrBean, SerializablePredicate<StrBean>>> {

private static Map<String, Comparator<StrBean>> propertyToComparatorMap = new HashMap<>();

static {
propertyToComparatorMap.put("value",
Comparator.comparing(StrBean::getValue));
propertyToComparatorMap.put("id", Comparator.comparing(StrBean::getId));
propertyToComparatorMap.put("randomNumber",
Comparator.comparing(StrBean::getRandomNumber));
}

private Comparator<StrBean> getComparator(SortOrder<String> so) {
Comparator<StrBean> comparator = propertyToComparatorMap
.get(so.getSorted());
if (so.getDirection() == SortDirection.DESCENDING) {
comparator = comparator.reversed();
}
return comparator;
}

@Override
protected BackEndDataProvider<StrBean, SerializablePredicate<StrBean>> createDataProvider() {
return dataProvider = new BackEndDataProvider<>(query -> {
Stream<StrBean> stream = data.stream()
.filter(t -> query.getFilter().orElse(s -> true).test(t));
if (!query.getSortOrders().isEmpty()) {
Comparator<StrBean> sorting = query.getSortOrders().stream()
.map(this::getComparator)
.reduce((c1, c2) -> c1.thenComparing(c2)).get();
stream = stream.sorted(sorting);
}
List<StrBean> list = stream.skip(query.getOffset())
.limit(query.getLimit()).collect(Collectors.toList());
list.forEach(s -> System.err.println(s.toString()));
return list.stream();
}, query -> (int) data.stream()
.filter(t -> query.getFilter().orElse(s -> true).test(t))
.count());
}

@Override
protected BackEndDataProvider<StrBean, SerializablePredicate<StrBean>> sortingBy(
List<SortOrder<String>> sortOrder, Comparator<StrBean> comp) {
return getDataProvider().sortingBy(sortOrder);
}
}

0 comments on commit 7ff852f

Please sign in to comment.