From ce0fa456dfe9d8aae584f70f5660f7940a8ac48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Garc=C3=ADa?= Date: Fri, 8 Nov 2024 08:12:13 +0100 Subject: [PATCH] Batch selection is not in sync between search results and record view. Fixes #8295 --- .../fao/geonet/kernel/SelectionManager.java | 45 +++++++------------ .../org/fao/geonet/api/es/EsHTTPProxy.java | 4 +- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/org/fao/geonet/kernel/SelectionManager.java b/core/src/main/java/org/fao/geonet/kernel/SelectionManager.java index a42a9e982e9..230bf390ff6 100644 --- a/core/src/main/java/org/fao/geonet/kernel/SelectionManager.java +++ b/core/src/main/java/org/fao/geonet/kernel/SelectionManager.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2016 Food and Agriculture Organization of the + * Copyright (C) 2001-2024 Food and Agriculture Organization of the * United Nations (FAO-UN), United Nations World Food Programme (WFP) * and United Nations Environment Programme (UNEP) * @@ -51,9 +51,9 @@ * Manage objects selection for a user session. */ public class SelectionManager { - public static final String SELECTION_METADATA = "metadata"; - public static final String SELECTION_BUCKET = "bucket"; + // Bucket name used in the search UI to store the selected the metadata + public static final String SELECTION_BUCKET = "s101"; // used to limit select all if get system setting maxrecords fails or contains value we can't parse public static final int DEFAULT_MAXHITS = 1000; public static final String ADD_ALL_SELECTED = "add-all"; @@ -61,20 +61,20 @@ public class SelectionManager { public static final String ADD_SELECTED = "add"; public static final String REMOVE_SELECTED = "remove"; public static final String CLEAR_ADD_SELECTED = "clear-add"; - private Hashtable> selections = null; + private Hashtable> selections; private SelectionManager() { - selections = new Hashtable>(0); + selections = new Hashtable<>(0); Set MDSelection = Collections - .synchronizedSet(new HashSet(0)); + .synchronizedSet(new HashSet<>(0)); selections.put(SELECTION_METADATA, MDSelection); } public Map getSelectionsAndSize() { return selections.entrySet().stream().collect(Collectors.toMap( - e -> e.getKey(), + Map.Entry::getKey, e -> e.getValue().size() )); } @@ -183,7 +183,7 @@ public int updateSelection(String type, // Get the selection manager or create it Set selection = this.getSelection(type); if (selection == null) { - selection = Collections.synchronizedSet(new HashSet()); + selection = Collections.synchronizedSet(new HashSet<>()); this.selections.put(type, selection); } @@ -192,30 +192,21 @@ public int updateSelection(String type, this.selectAll(type, context, session); else if (selected.equals(REMOVE_ALL_SELECTED)) this.close(type); - else if (selected.equals(ADD_SELECTED) && listOfIdentifiers.size() > 0) { + else if (selected.equals(ADD_SELECTED) && !listOfIdentifiers.isEmpty()) { // TODO ? Should we check that the element exist first ? - for (String paramid : listOfIdentifiers) { - selection.add(paramid); - } - } else if (selected.equals(REMOVE_SELECTED) && listOfIdentifiers.size() > 0) { + selection.addAll(listOfIdentifiers); + } else if (selected.equals(REMOVE_SELECTED) && !listOfIdentifiers.isEmpty()) { for (String paramid : listOfIdentifiers) { selection.remove(paramid); } - } else if (selected.equals(CLEAR_ADD_SELECTED) && listOfIdentifiers.size() > 0) { + } else if (selected.equals(CLEAR_ADD_SELECTED) && !listOfIdentifiers.isEmpty()) { this.close(type); - for (String paramid : listOfIdentifiers) { - selection.add(paramid); - } + selection.addAll(listOfIdentifiers); } } // Remove empty/null element from the selection - Iterator iter = selection.iterator(); - while (iter.hasNext()) { - Object element = iter.next(); - if (element == null) - iter.remove(); - } + selection.removeIf(Objects::isNull); return selection.size(); } @@ -241,14 +232,12 @@ public void selectAll(String type, ServiceContext context, UserSession session) if (StringUtils.isNotEmpty(type)) { JsonNode request = (JsonNode) session.getProperty(Geonet.Session.SEARCH_REQUEST + type); - if (request == null) { - return; - } else { + if (request != null) { final SearchResponse searchResponse; try { EsSearchManager searchManager = context.getBean(EsSearchManager.class); searchResponse = searchManager.query(request.get("query"), FIELDLIST_UUID, 0, maxhits); - List uuidList = new ArrayList(); + List uuidList = new ArrayList<>(); ObjectMapper objectMapper = new ObjectMapper(); for (Hit h : (List) searchResponse.hits().hits()) { uuidList.add((String) objectMapper.convertValue(h.source(), Map.class).get(Geonet.IndexFieldNames.UUID)); @@ -293,7 +282,7 @@ public Set getSelection(String type) { Set sel = selections.get(type); if (sel == null) { Set MDSelection = Collections - .synchronizedSet(new HashSet(0)); + .synchronizedSet(new HashSet<>(0)); selections.put(type, MDSelection); } return selections.get(type); diff --git a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java index caf3c9ea8ad..dca972556b7 100644 --- a/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java +++ b/services/src/main/java/org/fao/geonet/api/es/EsHTTPProxy.java @@ -301,7 +301,7 @@ private static boolean hasOperation(ObjectNode doc, ReservedGroup group, Reserve @ResponseStatus(value = HttpStatus.OK) @ResponseBody public void search( - @RequestParam(defaultValue = SelectionManager.SELECTION_METADATA) + @RequestParam(defaultValue = SelectionManager.SELECTION_BUCKET) String bucket, @Parameter(description = "Type of related resource. If none, no associated resource returned.", required = false @@ -387,7 +387,7 @@ public void msearch( @PreAuthorize("hasAuthority('Administrator')") @ResponseBody public void call( - @RequestParam(defaultValue = SelectionManager.SELECTION_METADATA) + @RequestParam(defaultValue = SelectionManager.SELECTION_BUCKET) String bucket, @Parameter(description = "'_search' for search service.") @PathVariable String endPoint,