Bug 447191 - [EditorMgmt] EditorPart#isSaveOnCloseNeeded() not honoured
when closing dirty Editor Part that is split

Change-Id: I88b6ec3c1abc123b249877f865786e2c95650316
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.ui.workbench.addons.swt/META-INF/MANIFEST.MF
index c7d5089..410fc0b 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/META-INF/MANIFEST.MF
@@ -30,6 +30,6 @@
 Export-Package: org.eclipse.e4.ui.workbench.addons.cleanupaddon;x-internal:=true,
  org.eclipse.e4.ui.workbench.addons.dndaddon;x-internal:=true,
  org.eclipse.e4.ui.workbench.addons.minmax;x-internal:=true,
- org.eclipse.e4.ui.workbench.addons.splitteraddon;x-internal:=true,
+ org.eclipse.e4.ui.workbench.addons.splitteraddon;x-friends:="org.eclipse.ui.workbench",
  org.eclipse.e4.ui.workbench.addons.swt;x-internal:=true
 Automatic-Module-Name: org.eclipse.e4.ui.workbench.addons.swt
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitHost.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitHost.java
index f2bb9ea..ccec744 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitHost.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitHost.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2014 IBM Corporation and others.
+ * Copyright (c) 2013, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -45,6 +45,11 @@
 	@Inject
 	MCompositePart myPart;
 
+	/**
+	 * The Contributing URI value that is set for the MCompositePart associated with this SplitHost.
+	 */
+	public static String SPLIT_HOST_CONTRIBUTOR_URI = "bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.splitteraddon.SplitHost"; //$NON-NLS-1$
+
 	List<MPart> getSubParts() {
 		return ms.findElements(myPart, null, MPart.class);
 	}
diff --git a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitterAddon.java b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitterAddon.java
index 8c7ad88..6de2117 100644
--- a/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitterAddon.java
+++ b/bundles/org.eclipse.e4.ui.workbench.addons.swt/src/org/eclipse/e4/ui/workbench/addons/splitteraddon/SplitterAddon.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2015 IBM Corporation and others.
+ * Copyright (c) 2011, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -131,7 +131,7 @@
 		compPart.setTooltip(originalPart.getTooltip());
 		compPart.setIconURI(originalPart.getIconURI());
 		compPart.setCloseable(true);
-		compPart.setContributionURI("bundleclass://org.eclipse.e4.ui.workbench.addons.swt/org.eclipse.e4.ui.workbench.addons.splitteraddon.SplitHost"); //$NON-NLS-1$
+		compPart.setContributionURI(SplitHost.SPLIT_HOST_CONTRIBUTOR_URI);
 
 		// Check if icon from MPart was overridden
 		Object overriddenImage = originalPart.getTransientData().get(IPresentationEngine.OVERRIDE_ICON_IMAGE_KEY);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
index 4bed5cd..3d5065c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -73,6 +73,7 @@
 import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
 import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
+import org.eclipse.e4.ui.model.application.ui.basic.MCompositePart;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
 import org.eclipse.e4.ui.model.application.ui.basic.MTrimElement;
@@ -88,6 +89,7 @@
 import org.eclipse.e4.ui.services.EContextService;
 import org.eclipse.e4.ui.workbench.IPresentationEngine;
 import org.eclipse.e4.ui.workbench.UIEvents;
+import org.eclipse.e4.ui.workbench.addons.splitteraddon.SplitHost;
 import org.eclipse.e4.ui.workbench.modeling.EModelService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
@@ -592,6 +594,10 @@
 									true, WorkbenchWindow.this);
 							return saveResult != null;
 						}
+					} else {
+						if (isSaveOnCloseNotNeededSplitEditorPart(dirtyPart)) {
+							return true;
+						}
 					}
 					return super.save(dirtyPart, confirm);
 				}
@@ -721,6 +727,48 @@
 					}
 				}
 
+				private void removeSaveOnCloseNotNeededSplitEditorParts(List<MPart> parts) {
+					for (Iterator<MPart> it = parts.iterator(); it.hasNext();) {
+						MPart part = it.next();
+						if (isSaveOnCloseNotNeededSplitEditorPart(part)) {
+							it.remove();
+						}
+					}
+				}
+
+				private boolean isSaveOnCloseNotNeededSplitEditorPart(MPart part) {
+					boolean notNeeded = false;
+					if (part instanceof MCompositePart
+							&& SplitHost.SPLIT_HOST_CONTRIBUTOR_URI.equals(part.getContributionURI())) {
+						MCompositePart compPart = (MCompositePart) part;
+						List<MPart> elements = modelService.findElements(compPart, null, MPart.class);
+						if (elements != null && elements.size() > 1) {
+							elements.remove(0);
+							for (MPart mpart : elements) {
+								Object object = mpart.getObject();
+								if (object instanceof CompatibilityPart) {
+									IWorkbenchPart workbenchPart = ((CompatibilityPart) object).getPart();
+									if (!SaveableHelper.isSaveable(workbenchPart)) {
+										notNeeded = true;
+									} else {
+										ISaveablePart saveable = SaveableHelper.getSaveable(workbenchPart);
+										if (saveable == null || !saveable.isSaveOnCloseNeeded()) {
+											notNeeded = true;
+										} else {
+											notNeeded = false;
+											break;
+										}
+									}
+								} else {
+									notNeeded = false;
+									break;
+								}
+							}
+						}
+					}
+					return notNeeded;
+				}
+
 				@Override
 				public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm, boolean closing, boolean addNonPartSources) {
 					ArrayList<IWorkbenchPart> saveableParts = new ArrayList<>();
@@ -739,6 +787,9 @@
 					if (!saveableParts.isEmpty() && closing) {
 						removeSaveOnCloseNotNeededParts(saveableParts);
 					}
+					if (!nonCompatibilityParts.isEmpty() && closing) {
+						removeSaveOnCloseNotNeededSplitEditorParts(nonCompatibilityParts);
+					}
 					if (saveableParts.isEmpty()) {
 						if (nonCompatibilityParts.isEmpty()) {
 							// nothing to save