1package autotest.common.table;
2
3import autotest.common.JSONArrayList;
4import autotest.common.table.DataSource.DefaultDataCallback;
5import autotest.common.table.DataSource.Query;
6
7import com.google.gwt.json.client.JSONArray;
8import com.google.gwt.json.client.JSONNumber;
9import com.google.gwt.json.client.JSONObject;
10
11import java.util.List;
12import java.util.Set;
13
14public class DynamicTableSelectionManager extends SelectionManager {
15    /**
16     * see deselectFiltered()
17     */
18    private final DefaultDataCallback deselectFilteredCallback = new DefaultDataCallback() {
19        @Override
20        public void onQueryReady(Query query) {
21            query.getPage(null, null, null, this);
22        }
23
24        @Override
25        public void handlePage(List<JSONObject> data) {
26            // use set intersection to get objects from the selected object set, rather than using
27            // the objects returned by the server.  we have to do this because ArrayDataSource uses
28            // object identity and not value equality of JSONObjects.
29            Set<JSONObject> filteredRows = new JSONObjectSet<JSONObject>(data);
30            Set<JSONObject> rowsToRemove = new JSONObjectSet<JSONObject>(getSelectedObjects());
31            rowsToRemove.retainAll(filteredRows);
32            deselectObjects(rowsToRemove);
33        }
34    };
35
36    private DynamicTable attachedDynamicTable;
37
38    public DynamicTableSelectionManager(DynamicTable table, boolean selectOnlyOne) {
39        super(table, selectOnlyOne);
40        attachedDynamicTable = table;
41    }
42
43
44    @Override
45    /**
46     * Select all objects covering all pages, not just the currently displayed page in the table.
47     */
48    public void selectAll() {
49        attachedDynamicTable.getCurrentQuery().getPage(null, null, null, new DefaultDataCallback() {
50            @Override
51            public void handlePage(List<JSONObject> data) {
52                selectObjects(data);
53            }
54        });
55    }
56
57    @Override
58    public void onSelectNone() {
59        deselectFiltered();
60    }
61
62    /**
63     * Only deselect items included in the current filters.
64     */
65    private void deselectFiltered() {
66        if (!attachedDynamicTable.isAnyUserFilterActive()) {
67            deselectAll();
68            return;
69        }
70
71        JSONObject params = attachedDynamicTable.getCurrentQuery().getParams();
72        params.put("id__in", selectedIdList());
73        attachedDynamicTable.getDataSource().query(params, deselectFilteredCallback);
74    }
75
76    private JSONArray selectedIdList() {
77        JSONArrayList<JSONNumber> idList = new JSONArrayList<JSONNumber>();
78        for (JSONObject object : getSelectedObjects()) {
79            JSONNumber id = object.get("id").isNumber();
80            assert id != null;
81            idList.add(id);
82        }
83        return idList.getBackingArray();
84    }
85}
86