From 7a0db19e7a65f518dd61c4568d60259c71d06d67 Mon Sep 17 00:00:00 2001 From: georgweiss Date: Thu, 18 Jun 2026 13:14:15 +0200 Subject: [PATCH] Improve error message if deletion fails --- .../applications/saveandrestore/Messages.java | 1 + .../ui/SaveAndRestoreController.java | 56 +++++++++---------- .../saveandrestore/messages.properties | 3 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java index 38a8034493..1ef56f2ad0 100644 --- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java +++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java @@ -79,6 +79,7 @@ public class Messages { public static String currentReadbackValue; public static String currentSetpointValue; public static String dateTimePickerTitle; + public static String deleteFailed; public static String deleteFilter; public static String deleteFilterFailed; diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java index 1bdefc4f94..4e700769c2 100644 --- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java +++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java @@ -227,12 +227,12 @@ public class SaveAndRestoreController extends SaveAndRestoreBaseController new RestoreFromClientMenuItem(this, selectedItemsProperty, () -> { disabledUi.set(true); - RestoreUtil.restore(RestoreMode.CLIENT_RESTORE, saveAndRestoreService, selectedItemsProperty.get(0), () -> disabledUi.set(false)); + RestoreUtil.restore(RestoreMode.CLIENT_RESTORE, saveAndRestoreService, selectedItemsProperty.getFirst(), () -> disabledUi.set(false)); }), new RestoreFromServiceMenuItem(this, selectedItemsProperty, () -> { disabledUi.set(true); - RestoreUtil.restore(RestoreMode.SERVICE_RESTORE, saveAndRestoreService, selectedItemsProperty.get(0), () -> disabledUi.set(false)); + RestoreUtil.restore(RestoreMode.SERVICE_RESTORE, saveAndRestoreService, selectedItemsProperty.getFirst(), () -> disabledUi.set(false)); }), new SeparatorMenuItem(), new EditCompositeMenuItem(this, selectedItemsProperty, this::editCompositeSnapshot), @@ -391,7 +391,7 @@ public void loadInitialData() { // Check if there is a save tree structure. Also check that the first node id (=tree root) // has the same unique id as the actual root node retrieved from the remote service. This check // is needed to handle the case when the client connects to a different save-and-restore service. - if (savedTreeViewStructure != null && !savedTreeViewStructure.isEmpty() && savedTreeViewStructure.get(0).equals(rootNode.getUniqueId())) { + if (savedTreeViewStructure != null && !savedTreeViewStructure.isEmpty() && savedTreeViewStructure.getFirst().equals(rootNode.getUniqueId())) { HashMap>> childNodesMap = new HashMap<>(); savedTreeViewStructure.forEach(s -> { List childNodes = saveAndRestoreService.getChildNodes(Node.builder().uniqueId(s).build()); @@ -417,7 +417,7 @@ public void loadInitialData() { // Event handler for expanding nodes treeView.getRoot().addEventHandler(TreeItem.branchExpandedEvent(), e -> expandTreeNode(e.getTreeItem())); treeInitializationCountDownLatch.countDown(); - filtersList.add(0, null); + filtersList.addFirst(null); String savedFilterName = getSavedFilterName(); if (savedFilterName != null) { Optional f = filtersComboBox.getItems().stream().filter(filter -> filter.getName().equals(savedFilterName)).findFirst(); @@ -475,7 +475,7 @@ protected void expandTreeNode(TreeItem targetItem) { * Action when user requests comparison between an opened snapshot and the selected {@link Node}. */ private void compareSnapshot() { - Node node = browserSelectionModel.getSelectedItems().get(0).getValue(); + Node node = browserSelectionModel.getSelectedItems().getFirst().getValue(); Tab tab = tabPane.getSelectionModel().getSelectedItem(); if (tab == null) { return; @@ -518,9 +518,7 @@ private void deleteTreeItems(ObservableList> items) { saveAndRestoreService.deleteNodes(nodeIds); disabledUi.set(false); } catch (Exception e) { - ExceptionDetailsErrorDialog.openError(Messages.errorGeneric, - MessageFormat.format(Messages.errorDeleteNodeFailed, items.get(0).getValue().getName()), - e); + ExceptionDetailsErrorDialog.openError(Messages.deleteFailed, Messages.errorDeleteNodeFailed, e); disabledUi.set(false); } }); @@ -530,7 +528,7 @@ private void deleteTreeItems(ObservableList> items) { * Opens a new snapshot view tab associated with the selected configuration. */ private void openConfigurationForSnapshot() { - TreeItem treeItem = browserSelectionModel.getSelectedItems().get(0); + TreeItem treeItem = browserSelectionModel.getSelectedItems().getFirst(); SnapshotTab tab = new SnapshotTab(treeItem.getValue(), saveAndRestoreService); tab.newSnapshot(treeItem.getValue()); @@ -548,7 +546,7 @@ public SearchAndFilterTab openSearchWindow() { return (SearchAndFilterTab) searchTabOptional.get(); } else { SearchAndFilterTab searchAndFilterTab = new SearchAndFilterTab(this); - tabPane.getTabs().add(0, searchAndFilterTab); + tabPane.getTabs().addFirst(searchAndFilterTab); tabPane.getSelectionModel().select(searchAndFilterTab); return searchAndFilterTab; } @@ -558,7 +556,7 @@ public SearchAndFilterTab openSearchWindow() { * Creates a new folder {@link Node}. */ private void createNewFolder() { - TreeItem parentTreeItem = browserSelectionModel.getSelectedItems().get(0); + TreeItem parentTreeItem = browserSelectionModel.getSelectedItems().getFirst(); List existingFolderNames = parentTreeItem.getChildren().stream() .filter(item -> item.getValue().getNodeType().equals(NodeType.FOLDER)) @@ -714,11 +712,11 @@ private Tab getTab(String id) { * Creates a new configuration in the selected tree node. */ private void createNewConfiguration() { - launchTabForNewConfiguration(browserSelectionModel.getSelectedItems().get(0).getValue()); + launchTabForNewConfiguration(browserSelectionModel.getSelectedItems().getFirst().getValue()); } private void createNewCompositeSnapshot() { - launchTabForNewCompositeSnapshot(browserSelectionModel.getSelectedItems().get(0).getValue(), + launchTabForNewCompositeSnapshot(browserSelectionModel.getSelectedItems().getFirst().getValue(), Collections.emptyList()); } @@ -735,7 +733,7 @@ private void copyUniqueNodeIdToClipboard() { * the user is shown a suitable error dialog and the name of the node is restored. */ private void renameNode() { - TreeItem node = browserSelectionModel.getSelectedItems().get(0); + TreeItem node = browserSelectionModel.getSelectedItems().getFirst(); List existingSiblingNodes = node.getParent().getChildren().stream() .filter(item -> item.getValue().getNodeType().equals(node.getValue().getNodeType())) @@ -957,7 +955,7 @@ public void handleTabClosed() { * Imports configuration or snapshot from CSV. */ private void importFromCSV() { - Node node = browserSelectionModel.getSelectedItems().get(0).getValue(); + Node node = browserSelectionModel.getSelectedItems().getFirst().getValue(); try { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(node.getNodeType().equals(NodeType.FOLDER) ? Messages.importConfigurationLabel : Messages.importSnapshotLabel); @@ -975,7 +973,7 @@ private void importFromCSV() { * Exports configuration or snapshot to CSV. */ private void exportToCSV() { - Node node = browserSelectionModel.getSelectedItems().get(0).getValue(); + Node node = browserSelectionModel.getSelectedItems().getFirst().getValue(); try { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(node.getNodeType().equals(NodeType.FOLDER) ? Messages.exportConfigurationLabel : Messages.exportSnapshotLabel); @@ -1031,7 +1029,7 @@ public boolean selectedNodesOfSameType() { if (selectedItems.size() < 2) { return true; } - NodeType nodeType = selectedItems.get(0).getValue().getNodeType(); + NodeType nodeType = selectedItems.getFirst().getValue().getNodeType(); for (int i = 1; i < selectedItems.size(); i++) { if (!selectedItems.get(i).getValue().getNodeType().equals(nodeType)) { return false; @@ -1234,11 +1232,11 @@ public boolean mayCopy() { if (selectedItemsProperty.stream().anyMatch(n -> n.getNodeType().equals(NodeType.FOLDER))) { return false; } - NodeType nodeTypeOfFirst = selectedItemsProperty.get(0).getNodeType(); + NodeType nodeTypeOfFirst = selectedItemsProperty.getFirst().getNodeType(); if (selectedItemsProperty.stream().anyMatch(n -> !n.getNodeType().equals(nodeTypeOfFirst))) { return false; } - TreeItem parentOfFirst = browserSelectionModel.getSelectedItems().get(0).getParent(); + TreeItem parentOfFirst = browserSelectionModel.getSelectedItems().getFirst().getParent(); return browserSelectionModel.getSelectedItems().stream().filter(t -> !t.getParent().equals(parentOfFirst)).findFirst().isEmpty(); } @@ -1262,13 +1260,13 @@ public boolean mayPaste() { return false; } if (selectedItemsProperty.size() != 1 || - selectedItemsProperty.get(0).getUniqueId().equals(Node.ROOT_FOLDER_UNIQUE_ID) || - (!selectedItemsProperty.get(0).getNodeType().equals(NodeType.FOLDER) && !selectedItemsProperty.get(0).getNodeType().equals(NodeType.CONFIGURATION))) { + selectedItemsProperty.getFirst().getUniqueId().equals(Node.ROOT_FOLDER_UNIQUE_ID) || + (!selectedItemsProperty.getFirst().getNodeType().equals(NodeType.FOLDER) && !selectedItemsProperty.getFirst().getNodeType().equals(NodeType.CONFIGURATION))) { return false; } // Check is made if target node is of supported type for the clipboard content. List selectedNodes = (List) clipBoardContent; - NodeType nodeTypeOfFirst = selectedNodes.get(0).getNodeType(); + NodeType nodeTypeOfFirst = selectedNodes.getFirst().getNodeType(); NodeType nodeTypeOfTarget = browserSelectionModel.getSelectedItem().getValue().getNodeType(); if ((nodeTypeOfFirst.equals(NodeType.COMPOSITE_SNAPSHOT) || nodeTypeOfFirst.equals(NodeType.CONFIGURATION)) && !nodeTypeOfTarget.equals(NodeType.FOLDER)) { @@ -1309,7 +1307,7 @@ public boolean hasSameParent() { if (selectedItems.size() == 1) { return true; } - Node parentNodeOfFirst = selectedItems.get(0).getParent().getValue(); + Node parentNodeOfFirst = selectedItems.getFirst().getParent().getValue(); for (int i = 1; i < selectedItems.size(); i++) { TreeItem treeItem = selectedItems.get(i); if (!treeItem.getParent().getValue().getUniqueId().equals(parentNodeOfFirst.getUniqueId())) { @@ -1332,7 +1330,7 @@ public boolean hasSameParent() { */ public boolean compareSnapshotsPossible() { if (selectedItemsProperty.size() != 1 || - !selectedItemsProperty.get(0).getNodeType().equals(NodeType.SNAPSHOT)) { + !selectedItemsProperty.getFirst().getNodeType().equals(NodeType.SNAPSHOT)) { return false; } Node[] configAndSnapshotNode = getConfigAndSnapshotForActiveSnapshotTab(); @@ -1397,8 +1395,8 @@ public void configureContextMenu(ContextMenuEvent e) { selectedItemsProperty.setAll(selectedItems.stream().map(TreeItem::getValue).toList()); tagWithComment.disableProperty().set(userIdentity.isNull().get() || - (!selectedItemsProperty.get(0).getNodeType().equals(NodeType.SNAPSHOT) && - !selectedItemsProperty.get(0).getNodeType().equals(NodeType.COMPOSITE_SNAPSHOT))); + (!selectedItemsProperty.getFirst().getNodeType().equals(NodeType.SNAPSHOT) && + !selectedItemsProperty.getFirst().getNodeType().equals(NodeType.COMPOSITE_SNAPSHOT))); configureTagContextMenu(tagWithComment); addOptionalLoggingMenuItem(); @@ -1408,7 +1406,7 @@ public void configureContextMenu(ContextMenuEvent e) { deleteNodeMenuItem.disableProperty().set(getUserIdentity().isNull().get() || selectedItemsProperty.stream().anyMatch(n -> n.getUniqueId().equals(Node.ROOT_FOLDER_UNIQUE_ID)) || !hasSameParent() || - hasReferences(selectedItemsProperty.get(0))); + hasReferences(selectedItemsProperty.getFirst())); pasteMenuItem.disableProperty().set(!mayPaste()); } @@ -1449,7 +1447,7 @@ private void addOptionalLoggingMenuItem() { // If logbook has been configured, add the Create Log menu item if (LogbookPreferences.is_supported) { SelectionService.getInstance().setSelection(SaveAndRestoreApplication.NAME, - selectedItemsProperty.size() == 1 ? List.of(selectedItemsProperty.get(0)) : Collections.emptyList()); + selectedItemsProperty.size() == 1 ? List.of(selectedItemsProperty.getFirst()) : Collections.emptyList()); List supported = ContextMenuService.getInstance().listSupportedContextMenuEntries(); supported.forEach(action -> { @@ -1548,6 +1546,6 @@ public boolean doCloseCheck() { private void findReferences() { SearchAndFilterTab searchAndFilterTab = openSearchWindow(); - searchAndFilterTab.getController().findReferencesForSnapshot(treeView.getSelectionModel().getSelectedItems().get(0).getValue().getUniqueId()); + searchAndFilterTab.getController().findReferencesForSnapshot(treeView.getSelectionModel().getSelectedItems().getFirst().getValue().getUniqueId()); } } diff --git a/app/save-and-restore/app/src/main/resources/org/phoebus/applications/saveandrestore/messages.properties b/app/save-and-restore/app/src/main/resources/org/phoebus/applications/saveandrestore/messages.properties index 12f05b08bb..0e3a852bc8 100644 --- a/app/save-and-restore/app/src/main/resources/org/phoebus/applications/saveandrestore/messages.properties +++ b/app/save-and-restore/app/src/main/resources/org/phoebus/applications/saveandrestore/messages.properties @@ -70,6 +70,7 @@ currentReadbackValue=Current Readback PV Value currentSetpointValue=Current Setpoint Value cut=Cut dateTimePickerTitle=Select date and time +deleteFailed=Failed to delete deleteFilter=Delete Filter deleteFilterFailed=Failed to delete filter description=Description @@ -85,7 +86,7 @@ errorActionFailed=Action failed errorAddTagFailed=Failed to add tag errorCreateFolderFailed=Failed to create folder. errorCreateConfigurationFailed=Failed to create/update configuration -errorDeleteNodeFailed=Failed to delete "{0}". +errorDeleteNodeFailed=At least one object could not be deleted (e.g. due to insufficient privileges).\r\n errorDeleteTagFailed=Failed to delete tag errorGeneric=Error errorUnableToRetrieveData=Unable to retrieve data