From f89047400d7738e98c6041e3d1348da98ed8fdcd Mon Sep 17 00:00:00 2001 From: georgweiss Date: Tue, 19 May 2026 09:35:13 +0200 Subject: [PATCH 1/3] Remove referenced annotation in save&restore --- .../saveandrestore/ui/BrowserTreeCell.java | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java index 0c43aa11b8..71a8a1a5b0 100644 --- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java +++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java @@ -18,7 +18,6 @@ package org.phoebus.applications.saveandrestore.ui; -import javafx.application.Platform; import javafx.scene.control.Label; import javafx.scene.control.Tooltip; import javafx.scene.control.TreeCell; @@ -39,13 +38,9 @@ import org.phoebus.applications.saveandrestore.model.Node; import org.phoebus.applications.saveandrestore.model.NodeType; import org.phoebus.applications.saveandrestore.model.Tag; -import org.phoebus.applications.saveandrestore.model.search.SearchResult; -import org.phoebus.framework.jobs.JobManager; import org.phoebus.ui.javafx.ImageCache; import org.phoebus.util.time.TimestampFormats; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; import java.util.ArrayList; import java.util.List; @@ -188,7 +183,6 @@ public void updateItem(Node node, boolean empty) { tagImage.setPreserveRatio(true); hBox.getChildren().add(tagImage); } - annotateContainedInCompositeSnapshot(node, hBox); break; case COMPOSITE_SNAPSHOT: hBox.getChildren().add(new ImageView(ImageRepository.COMPOSITE_SNAPSHOT)); @@ -199,7 +193,6 @@ public void updateItem(Node node, boolean empty) { tagImage.setPreserveRatio(true); getChildren().add(tagImage); } - annotateContainedInCompositeSnapshot(node, hBox); break; case CONFIGURATION: hBox.getChildren().add(new ImageView(ImageRepository.CONFIGURATION)); @@ -216,17 +209,4 @@ public void updateItem(Node node, boolean empty) { setGraphic(hBox); } - - private void annotateContainedInCompositeSnapshot(Node node, HBox hbox) { - JobManager.schedule("Annotate contained in snapshot", monitor -> { - MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); - multivaluedMap.put("referenced", List.of(node.getUniqueId())); - SearchResult searchResult = saveAndRestoreController.saveAndRestoreService.search(multivaluedMap); - if (searchResult.getHitCount() > 0) { - Platform.runLater(() -> { - hbox.getChildren().add(new ImageView(ImageRepository.LINK)); - }); - } - }); - } } From bef4dcd526d185541ba209ae46881f4657f7d3b0 Mon Sep 17 00:00:00 2001 From: georgweiss Date: Tue, 19 May 2026 10:59:33 +0200 Subject: [PATCH 2/3] Disable Delete context menu item if snapshot or composite snapshot has references --- app/save-and-restore/app/doc/index.rst | 8 +---- .../ui/SaveAndRestoreController.java | 31 ++++++++++++++++++- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/app/save-and-restore/app/doc/index.rst b/app/save-and-restore/app/doc/index.rst index 5753aeaef7..8ca16a478e 100644 --- a/app/save-and-restore/app/doc/index.rst +++ b/app/save-and-restore/app/doc/index.rst @@ -51,12 +51,6 @@ tags is indicated with a symbol to the right of the node name: .. image:: images/snapshot-with-tag.png -Similarly, snapshots and composite snapshots referenced in other composite snapshots are annotated with a symbol to the -right of the node name: - -.. image:: images/snapshot-with-references.png - - Node names and ordering ----------------------- @@ -279,7 +273,7 @@ The composite snapshot can be saved when a case sensitive name and a description * The combined list of PV names in the referenced snapshots must not contain duplicates. This is checked for each item dropped into the list when editing a composite snapshot. If duplicates are detected, an error dialog is shown. -* Snapshots and composite snapshots cannot be deleted if referenced in a composite snapshot. +* Snapshots and composite snapshots cannot be deleted if referenced in any composite snapshot. This is indicated by disabling the Delete context menu item. Edit Composite Snapshot using drag-n-drop ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 7274e4da5a..d300049f94 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 @@ -134,6 +134,8 @@ import java.util.ServiceLoader; import java.util.Stack; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -1405,10 +1407,37 @@ public void configureContextMenu(ContextMenuEvent e) { compareSnapshotsMenuItem.disableProperty().set(!compareSnapshotsPossible()); deleteNodeMenuItem.disableProperty().set(getUserIdentity().isNull().get() || selectedItemsProperty.stream().anyMatch(n -> n.getUniqueId().equals(Node.ROOT_FOLDER_UNIQUE_ID)) || - !hasSameParent()); + !hasSameParent() || + hasReferences(selectedItemsProperty.get(0))); pasteMenuItem.disableProperty().set(!mayPaste()); } + /** + * Queries service if the specified {@link Node} is referenced in any composite snapshot. + * + * @param node The node to check. + * @return true if the {@link Node} is referenced. + */ + private boolean hasReferences(Node node) { + if (node.getNodeType().equals(NodeType.FOLDER) || node.getNodeType().equals(NodeType.CONFIGURATION)) { + return false; + } + AtomicBoolean hasReferences = new AtomicBoolean(false); + CountDownLatch countDownLatch = new CountDownLatch(1); + JobManager.schedule("Find references", monitor -> { + MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); + multivaluedMap.put("referenced", List.of(node.getUniqueId())); + hasReferences.set(saveAndRestoreService.search(multivaluedMap).getHitCount() > 0); + countDownLatch.countDown(); + }); + try { + countDownLatch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.log(Level.WARNING, "Timeout when checking references for node " + node.getUniqueId(), e); + } + return hasReferences.get(); + } + /** * Adds a create log menu item based on current selection and logbook client availability */ From c8be537b843cef5624f8d4ceffb4c2f17c4d4e35 Mon Sep 17 00:00:00 2001 From: georgweiss Date: Tue, 19 May 2026 11:11:01 +0200 Subject: [PATCH 3/3] Catch potential exception to ensure method returns quickly --- .../saveandrestore/ui/SaveAndRestoreController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 d300049f94..1bdefc4f94 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 @@ -1427,7 +1427,11 @@ private boolean hasReferences(Node node) { JobManager.schedule("Find references", monitor -> { MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); multivaluedMap.put("referenced", List.of(node.getUniqueId())); - hasReferences.set(saveAndRestoreService.search(multivaluedMap).getHitCount() > 0); + try { + hasReferences.set(saveAndRestoreService.search(multivaluedMap).getHitCount() > 0); + } catch (Exception e) { + logger.log(Level.WARNING, "Failed to check for references for node " + node.getUniqueId(), e); + } countDownLatch.countDown(); }); try {