diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/META-INF/MANIFEST.MF b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/META-INF/MANIFEST.MF
index eaf6d387a..897595a44 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/META-INF/MANIFEST.MF
+++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/META-INF/MANIFEST.MF
@@ -26,7 +26,6 @@ Require-Bundle: org.junit,
org.reactivestreams.reactive-streams;bundle-version="1.0.0",
io.projectreactor.reactor-core;bundle-version="[3.3.1,3.3.2)",
org.apache.commons.lang,
- org.hamcrest;bundle-version="[1.1.0,1.2.0)",
org.eclipse.lsp4e,
org.eclipse.lsp4j,
org.springframework.ide.eclipse.boot.dash;bundle-version="3.9.12",
@@ -47,7 +46,8 @@ Require-Bundle: org.junit,
org.springframework.ide.eclipse.buildship30,
org.eclipse.ui.console,
org.springframework.ide.eclipse.docker.client;bundle-version="3.9.14",
- org.springsource.ide.eclipse.commons.boot.ls;bundle-version="4.8.1"
+ org.springsource.ide.eclipse.commons.boot.ls;bundle-version="4.8.1",
+ org.hamcrest.library;bundle-version="1.3.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.core.runtime,
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java
index ebc6bcb07..2cc4398ce 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java
+++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java
@@ -26,6 +26,8 @@ import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.assert
import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.assertNotContains;
import static org.springsource.ide.eclipse.commons.tests.util.StsTestCase.createFile;
+import static org.mockito.ArgumentMatchers.*;
+
import java.net.URI;
import java.time.Duration;
import java.util.ArrayList;
@@ -51,6 +53,7 @@ import org.eclipse.swt.graphics.Color;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
+import org.mockito.ArgumentMatchers;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.springframework.ide.eclipse.beans.ui.live.model.LiveBeansModel;
@@ -618,7 +621,6 @@ public class BootDashDockerTests {
String containerId = con.getName();
assertEquals(1, listContainersWithId(containerId).size());
-// when(ui().confirmOperation(eq("Deleting Elements"), any())).thenAnswer(answer);
DeleteElementsAction> delete = actions().getDeleteAppsAction();
harness.selection.setElements(con);
assertTrue(delete.isEnabled());
@@ -1121,8 +1123,15 @@ public class BootDashDockerTests {
//if (ui().confirmOperation("Deleting Elements", modifiable.getDeletionConfirmationMessage(workitem.getValue()))) {
-// confirm popup was disabled.
-// when(ui().confirmOperation("Deleting Elements", "Delete webby ?")).thenReturn(true);
+ RunTargetType rtt = model.getRunTarget().getType();
+ Mockito.when(ui().confirmWithToggle(eq(DeleteElementsAction.PREF_SKIP_CONFIRM_DELETE(rtt)),
+ // String title,
+ eq("Deleting Elements"),
+ // String message,
+ anyString(),
+ // String toggleMessage
+ anyString()
+ )).thenReturn(true);
deleteAction.run();
ACondition.waitFor("Everything is deleted", 5_000, () -> {
@@ -1136,6 +1145,7 @@ public class BootDashDockerTests {
// client().listImages(ListImagesParam.allImages()).stream().
});
+// verifyNoMoreInteractions(ui());
}
@Test
@@ -1162,6 +1172,14 @@ public class BootDashDockerTests {
assertTrue(delete.isEnabled());
assertTrue(delete.isVisible());
+ Mockito.when(ui().confirmWithToggle(eq(DeleteElementsAction.PREF_SKIP_CONFIRM_DELETE(model.getRunTarget().getType())),
+ // String title,
+ eq("Deleting Elements"),
+ // String message,
+ anyString(),
+ // String toggleMessage
+ anyString()
+ )).thenReturn(true);
delete.run();
ACondition.waitFor("Image and container deletion", 10_000, () -> {
@@ -1244,7 +1262,7 @@ public class BootDashDockerTests {
Model model = (Model) invocation.getArguments()[0];
//model.performOk(); //no clicking ok, so that's like when dialog is 'canceled'.
return null;
- }).when(ui()).selectDockerDaemonDialog(Matchers.any());
+ }).when(ui()).selectDockerDaemonDialog(any());
createTarget.run();
createTarget.waitFor(Duration.ofMillis(2000));
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml
index af594d2c0..920c98636 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml
+++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml
@@ -240,6 +240,13 @@
id="org.springframework.ide.eclipse.boot.dash.ngrok.NGROKInstallPreferencePage"
name="ngrok">
+
+
+
extends Nameable {
default MissingLiveInfoMessages getMissingLiveInfoMessages() {
return MissingLiveInfoMessages.DEFAULT;
}
+
+ /**
+ * Must return true if the models of this type are {@link DeletionCapabableModel}s.
+ */
+ default boolean supportsDeletion() {
+ return true; // true for most models, so we make this the default implementation
+ }
}
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteBootDashModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteBootDashModel.java
index bfb651036..f50c248ef 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteBootDashModel.java
+++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteBootDashModel.java
@@ -13,6 +13,7 @@ package org.springframework.ide.eclipse.boot.dash.model.remote;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -23,6 +24,7 @@ import org.eclipse.jdt.core.IJavaProject;
import org.springframework.ide.eclipse.boot.dash.api.App;
import org.springframework.ide.eclipse.boot.dash.api.Deletable;
import org.springframework.ide.eclipse.boot.dash.api.ProjectDeploymentTarget;
+import org.springframework.ide.eclipse.boot.dash.api.Styleable;
import org.springframework.ide.eclipse.boot.dash.cloudfoundry.RemoteBootDashModel;
import org.springframework.ide.eclipse.boot.dash.livexp.DisposingFactory;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
@@ -144,10 +146,41 @@ public class GenericRemoteBootDashModel extends RemoteBootDashMo
}
@Override
- public String getDeletionConfirmationMessage(Collection value) {
+ public String getDeletionConfirmationMessage(Collection elements) {
+
+ Set withChild = new LinkedHashSet<>();
+ for (BootDashElement toDelete : elements) {
+ ImmutableSet children = toDelete.getChildren().getValues();
+ for (BootDashElement child : children) {
+ if (!elements.contains(child)) {
+ //child is implicitly deleted. So we should warn/confirm
+ // See: https://www.pivotaltracker.com/story/show/173538290
+ withChild.add(toDelete);
+ }
+ }
+ }
+ if (!withChild.isEmpty()) {
+ StringBuilder confirmMessage = new StringBuilder("These elements have children, which will be deleted implicitly:\n");
+ boolean first = true;
+ for (BootDashElement bde : withChild) {
+ if (!first) {
+ confirmMessage.append(", ");
+ }
+ confirmMessage.append(niceName(bde));
+ first = false;
+ }
+ return confirmMessage.toString();
+ }
return null; // no confirmation asked.
}
+ private String niceName(BootDashElement bde) {
+ if (bde instanceof Styleable) {
+ return ((Styleable) bde).getStyledName(null).getString();
+ }
+ return bde.getName();
+ }
+
@Override
public boolean canBeAdded(List