summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorAnastasia Smirnova <anasmi@utu.fi>2018-03-22 15:39:18 +0200
committerTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2018-03-22 15:39:18 +0200
commit6fb2d1a98076c6fbb9ba014fab37d7bf7a6e6a62 (patch)
tree21e73157bb46a84baf2a3fc1cf2b5f7c52df949f /server
parent1187cf22f06df587b2a1ec1068be88e2b70c888d (diff)
downloadvaadin-framework-6fb2d1a98076c6fbb9ba014fab37d7bf7a6e6a62.tar.gz
vaadin-framework-6fb2d1a98076c6fbb9ba014fab37d7bf7a6e6a62.zip
Correctly handle data providers with overriden getId (#10728)
Fixes #10647 Fixes #10498
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java37
-rw-r--r--server/src/test/java/com/vaadin/ui/AbstractMultiSelectUsingIdTest.java97
2 files changed, 130 insertions, 4 deletions
diff --git a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
index fdc4f5d4a1..558545d653 100644
--- a/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
+++ b/server/src/main/java/com/vaadin/ui/AbstractMultiSelect.java
@@ -323,16 +323,25 @@ public abstract class AbstractMultiSelect<T> extends AbstractListing<T>
// if there are duplicates, some item is both added & removed, just
// discard that and leave things as was before
- addedItems.removeIf(item -> removedItems.remove(item));
+ DataProvider<T, ?> dataProvider = internalGetDataProvider();
+ addedItems.removeIf(item -> {
+ Object addedId = dataProvider.getId(item);
+ return removedItems.stream().map(dataProvider::getId)
+ .anyMatch(addedId::equals)? removedItems.remove(item):false;
+ });
- if (selection.containsAll(addedItems)
- && Collections.disjoint(selection, removedItems)) {
+ if (isAllSelected(addedItems) && isNoneSelected(removedItems)) {
return;
}
updateSelection(set -> {
// order of add / remove does not matter since no duplicates
- set.removeAll(removedItems);
+ set.removeIf(item -> {
+ Object itemId = dataProvider.getId(item);
+
+ return removedItems.stream().map(dataProvider::getId)
+ .anyMatch(itemId::equals);
+ });
set.addAll(addedItems);
}, userOriginated);
}
@@ -359,6 +368,26 @@ public abstract class AbstractMultiSelect<T> extends AbstractListing<T>
}
+ private boolean isAllSelected(Collection<T> items) {
+ for (T item : items) {
+ if (!isSelected(item)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean isNoneSelected(Collection<T> items) {
+ for (T item : items) {
+ if (isSelected(item)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/**
* Deselects the given item. If the item is not currently selected, does
* nothing.
diff --git a/server/src/test/java/com/vaadin/ui/AbstractMultiSelectUsingIdTest.java b/server/src/test/java/com/vaadin/ui/AbstractMultiSelectUsingIdTest.java
new file mode 100644
index 0000000000..4f131ba23d
--- /dev/null
+++ b/server/src/test/java/com/vaadin/ui/AbstractMultiSelectUsingIdTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.ui;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.data.provider.ListDataProvider;
+
+public class AbstractMultiSelectUsingIdTest {
+
+ public TwinColSelect<ItemWithId> selectToTest;
+
+ public static class ItemWithId {
+ private int id;
+
+ public ItemWithId() {
+ }
+
+ public ItemWithId(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ selectToTest = new TwinColSelect<>();
+ List<ItemWithId> items = new ArrayList<>();
+ items.add(new ItemWithId(3));
+ items.add(new ItemWithId(2));
+ items.add(new ItemWithId(1));
+ items.add(new ItemWithId(8));
+ items.add(new ItemWithId(7));
+ items.add(new ItemWithId(4));
+ items.add(new ItemWithId(6));
+ ListDataProvider<ItemWithId> dataProvider = new ListDataProvider<ItemWithId>(
+ items) {
+ @Override
+ public Object getId(ItemWithId item) {
+ return item.getId();
+ }
+ };
+ selectToTest.setDataProvider(dataProvider);
+
+ }
+
+ @Test
+ public void selectTwiceSelectsOnce() {
+ selectToTest.select(new ItemWithId(1));
+ assertSelectionOrder(1);
+ selectToTest.select(new ItemWithId(1));
+ assertSelectionOrder(1);
+ }
+
+ @Test
+ public void deselectWorks() {
+ selectToTest.select(new ItemWithId(1));
+ selectToTest.deselect(new ItemWithId(1));
+ assertSelectionOrder();
+ }
+
+ private void assertSelectionOrder(Integer... selectionOrder) {
+ List<Integer> asList = Arrays.asList(selectionOrder);
+ assertEquals(asList, selectToTest.getSelectedItems().stream()
+ .map(ItemWithId::getId).collect(Collectors.toList()));
+ }
+
+}