Bug 541067 [Target] change notification: use publish-subscribe approach

TargetPlatformService: publish
TargetEditor: subscribe
AbstractTargetTest: test

Change-Id: Iab6daf3472c55ed4261df61c0a0d062ac820e8b9
Signed-off-by: Alexander Fedorov <alexander.fedorov@arsysop.ru>
diff --git a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
index 73b7b89..f940f49 100644
--- a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %name
 Bundle-SymbolicName: org.eclipse.pde.core; singleton:=true
-Bundle-Version: 3.12.400.qualifier
+Bundle-Version: 3.13.0.qualifier
 Bundle-Activator: org.eclipse.pde.internal.core.PDECore
 Bundle-Vendor: %provider-name
 Bundle-Localization: plugin
@@ -76,6 +76,8 @@
 Require-Bundle: 
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
+ org.eclipse.e4.core.contexts;bundle-version="[1.8.0,2.0.0)",
+ org.eclipse.e4.core.services;bundle-version="[2.0.0,3.0.0)",
  org.eclipse.jdt.core;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.team.core;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.update.configurator;bundle-version="[3.1.0,4.0.0)",
diff --git a/ui/org.eclipse.pde.core/pom.xml b/ui/org.eclipse.pde.core/pom.xml
index 0cd33a2..2749fc1 100644
--- a/ui/org.eclipse.pde.core/pom.xml
+++ b/ui/org.eclipse.pde.core/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.pde</groupId>
   <artifactId>org.eclipse.pde.core</artifactId>
-  <version>3.12.400-SNAPSHOT</version>
+  <version>3.13.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
   <properties>
     <defaultSigning-excludeInnerJars>true</defaultSigning-excludeInnerJars>
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/target/TargetEvents.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/target/TargetEvents.java
new file mode 100644
index 0000000..23cdcaa
--- /dev/null
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/core/target/TargetEvents.java
@@ -0,0 +1,39 @@
+/********************************************************************************
+ * Copyright (c) 2019 ArSysOp and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - initial API and implementation
+ ********************************************************************************/
+package org.eclipse.pde.core.target;
+
+/**
+ * Target events and event topic definitions
+ *
+ * @since 3.13
+ */
+public class TargetEvents {
+
+	/**
+	 * Base topic for all Target events
+	 */
+	public static final String TOPIC_BASE = "org/eclipse/pde/core/target/TargetEvents"; //$NON-NLS-1$
+
+	/**
+	 * Topic for all Target events
+	 */
+	public static final String TOPIC_ALL = TOPIC_BASE + "/*"; //$NON-NLS-1$
+
+	/**
+	 * Sent when workspace target definition is changed
+	 *
+	 * @see ITargetPlatformService#getWorkspaceTargetDefinition()
+	 */
+	public static final String TOPIC_WORKSPACE_TARGET_CHANGED = TOPIC_BASE + "/workspaceTargetChanged"; //$NON-NLS-1$
+
+}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPlatformService.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPlatformService.java
index 1915c3f..c54cbf0 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPlatformService.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetPlatformService.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2017 IBM Corporation and others.
+ * Copyright (c) 2008, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 541067
  *******************************************************************************/
 package org.eclipse.pde.internal.core.target;
 
@@ -48,6 +49,9 @@
 import org.eclipse.core.runtime.URIUtil;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.events.IEventBroker;
 import org.eclipse.equinox.frameworkadmin.BundleInfo;
 import org.eclipse.equinox.p2.metadata.IInstallableUnit;
 import org.eclipse.osgi.service.datalocation.Location;
@@ -60,6 +64,7 @@
 import org.eclipse.pde.core.target.ITargetPlatformService;
 import org.eclipse.pde.core.target.NameVersionDescriptor;
 import org.eclipse.pde.core.target.TargetBundle;
+import org.eclipse.pde.core.target.TargetEvents;
 import org.eclipse.pde.internal.core.ICoreConstants;
 import org.eclipse.pde.internal.core.PDECore;
 import org.eclipse.pde.internal.core.PDECoreMessages;
@@ -313,7 +318,7 @@
 			target = handle.getTargetDefinition();
 		}
 
-		fWorkspaceTarget = target;
+		setWorkspaceTargetDefinition(target);
 		return target;
 	}
 
@@ -328,6 +333,10 @@
 	 */
 	public void setWorkspaceTargetDefinition(ITargetDefinition target) {
 		fWorkspaceTarget = target;
+
+		IEclipseContext context = EclipseContextFactory.getServiceContext(PDECore.getDefault().getBundleContext());
+		IEventBroker broker = context.get(IEventBroker.class);
+		broker.send(TargetEvents.TOPIC_WORKSPACE_TARGET_CHANGED, target);
 	}
 
 	/**
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/WorkspaceFileTargetHandle.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/WorkspaceFileTargetHandle.java
index 9533f1b..ba824d4 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/WorkspaceFileTargetHandle.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/WorkspaceFileTargetHandle.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2017 IBM Corporation and others.
+ * Copyright (c) 2008, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 541067
  *******************************************************************************/
 package org.eclipse.pde.internal.core.target;
 
@@ -18,7 +19,6 @@
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.util.HashMap;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
@@ -44,11 +44,6 @@
 	static final String SCHEME = "resource"; //$NON-NLS-1$
 
 	/**
-	 * Map of all target editor file and the workspace editor
-	 */
-	public static HashMap<IFile, Object> mapFileTarget = new HashMap<>();
-
-	/**
 	 * Returns a handle for the given URI.
 	 *
 	 * @param uri URI
@@ -146,19 +141,4 @@
 		return fFile;
 	}
 
-	/**
-	 * Returns the workspace editor from target file.
-	 *
-	 * @return target
-	 */
-	public Object getWorkspaceEditor() {
-		return mapFileTarget.get(fFile);
-	}
-
-	/**
-	 * Updates the map with the file and workspace target
-	 */
-	public void setWorkspaceEditor(Object target) {
-		mapFileTarget.put(fFile, target);
-	}
 }
diff --git a/ui/org.eclipse.pde.genericeditor.extension/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.genericeditor.extension/META-INF/MANIFEST.MF
index 6153a0c..d74ddf3 100644
--- a/ui/org.eclipse.pde.genericeditor.extension/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.genericeditor.extension/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.pde.genericeditor.extension;singleton:=true
-Bundle-Version: 1.0.400.qualifier
+Bundle-Version: 1.0.500.qualifier
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.jface.text,
diff --git a/ui/org.eclipse.pde.genericeditor.extension/pom.xml b/ui/org.eclipse.pde.genericeditor.extension/pom.xml
index 8e6f236..3e7fde0 100644
--- a/ui/org.eclipse.pde.genericeditor.extension/pom.xml
+++ b/ui/org.eclipse.pde.genericeditor.extension/pom.xml
@@ -19,6 +19,6 @@
   </parent>
   <groupId>org.eclipse.pde.ui</groupId>
   <artifactId>org.eclipse.pde.genericeditor.extension</artifactId>
-  <version>1.0.400-SNAPSHOT</version>
+  <version>1.0.500-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/ui/org.eclipse.pde.genericeditor.extension/src/org/eclipse/pde/internal/genericeditor/target/extension/codemining/TargetDefinitionActivationCodeMining.java b/ui/org.eclipse.pde.genericeditor.extension/src/org/eclipse/pde/internal/genericeditor/target/extension/codemining/TargetDefinitionActivationCodeMining.java
index c929b13..b3330d7 100644
--- a/ui/org.eclipse.pde.genericeditor.extension/src/org/eclipse/pde/internal/genericeditor/target/extension/codemining/TargetDefinitionActivationCodeMining.java
+++ b/ui/org.eclipse.pde.genericeditor.extension/src/org/eclipse/pde/internal/genericeditor/target/extension/codemining/TargetDefinitionActivationCodeMining.java
@@ -1,5 +1,5 @@
 /********************************************************************************
- * Copyright (c) 2018 vogella GmbH and others
+ * Copyright (c) 2018, 2019 vogella GmbH and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License 2.0 which is available at
@@ -9,7 +9,7 @@
  *
  * Contributors:
  *     Lars Vogel (vogella GmbH) - initial API and implementation
- *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 534758
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 534758, Bug 541067
  ********************************************************************************/
 package org.eclipse.pde.internal.genericeditor.target.extension.codemining;
 
@@ -38,7 +38,6 @@
 import org.eclipse.pde.internal.core.PDECore;
 import org.eclipse.pde.internal.ui.PDEPlugin;
 import org.eclipse.pde.internal.ui.PDEUIMessages;
-import org.eclipse.pde.internal.ui.editor.targetdefinition.TargetEditor;
 import org.eclipse.swt.events.MouseEvent;
 
 @SuppressWarnings("restriction")
@@ -94,7 +93,6 @@
 			ITargetHandle targetHandle = getTargetHandle();
 			ITargetDefinition toLoad = targetHandle.getTargetDefinition();
 			LoadTargetDefinitionJob.load(toLoad);
-			TargetEditor.updateTargetEditors(targetHandle);
 		} catch (CoreException e) {
 			PDEPlugin.log(e.getStatus());
 		}
diff --git a/ui/org.eclipse.pde.ui.tests/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.ui.tests/META-INF/MANIFEST.MF
index c9f3cb0..313c41f 100644
--- a/ui/org.eclipse.pde.ui.tests/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.ui.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: PDE JUnit Tests
 Bundle-SymbolicName: org.eclipse.pde.ui.tests; singleton:=true
-Bundle-Version: 3.10.400.qualifier
+Bundle-Version: 3.10.500.qualifier
 Bundle-ClassPath: tests.jar
 Bundle-Activator: org.eclipse.pde.ui.tests.PDETestsPlugin
 Bundle-Vendor: Eclipse.org
@@ -11,6 +11,9 @@
  org.eclipse.ui,
  org.eclipse.core.resources,
  org.eclipse.core.runtime,
+ org.eclipse.osgi.services,
+ org.eclipse.e4.core.contexts,
+ org.eclipse.e4.core.services,
  org.eclipse.jdt.core,
  org.eclipse.test.performance;resolution:=optional,
  org.eclipse.ui.ide,
diff --git a/ui/org.eclipse.pde.ui.tests/pom.xml b/ui/org.eclipse.pde.ui.tests/pom.xml
index 3ba4fb6..75e831e 100644
--- a/ui/org.eclipse.pde.ui.tests/pom.xml
+++ b/ui/org.eclipse.pde.ui.tests/pom.xml
@@ -19,7 +19,7 @@
   </parent>
   <groupId>org.eclipse.pde</groupId>
   <artifactId>org.eclipse.pde.ui.tests</artifactId>
-  <version>3.10.400-SNAPSHOT</version>
+  <version>3.10.500-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
 
   <properties>
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/AbstractTargetTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/AbstractTargetTest.java
index 3797087..9497d34 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/AbstractTargetTest.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/AbstractTargetTest.java
@@ -21,11 +21,17 @@
 import junit.framework.TestCase;
 import org.eclipse.core.filebuffers.*;
 import org.eclipse.core.runtime.*;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.events.IEventBroker;
 import org.eclipse.equinox.frameworkadmin.BundleInfo;
 import org.eclipse.pde.core.plugin.TargetPlatform;
 import org.eclipse.pde.core.target.*;
+import org.eclipse.pde.internal.core.PDECore;
 import org.eclipse.pde.ui.tests.PDETestsPlugin;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.event.EventHandler;
 
 /**
  * Common utility methods for target definition tests
@@ -219,6 +225,13 @@
 	 * @throws CoreException
 	 */
 	protected void setTargetPlatform(ITargetDefinition target) throws CoreException {
+		final Object[] payload = new Object[1];
+		BundleContext bundleContext = PDECore.getDefault().getBundleContext();
+		IEclipseContext context = EclipseContextFactory.getServiceContext(bundleContext);
+		IEventBroker eventBroker = context.get(IEventBroker.class);
+		EventHandler handler = e -> payload[0] = e.getProperty(IEventBroker.DATA);
+		eventBroker.subscribe(TargetEvents.TOPIC_WORKSPACE_TARGET_CHANGED, handler);
+
 		// Create the job to load the target, but then join with the job's thread
 		LoadTargetDefinitionJob job = new LoadTargetDefinitionJob(target);
 		job.schedule();
@@ -227,11 +240,13 @@
 		} catch (InterruptedException e) {
 			assertFalse("Target platform reset interrupted", true);
 		}
+		eventBroker.unsubscribe(handler);
 		ITargetHandle handle = null;
 		if (target != null) {
 			handle = target.getHandle();
 		}
 		assertEquals("Wrong target platform handle preference setting", handle, getTargetService().getWorkspaceTargetHandle());
+		assertEquals("Wrong workspaceTargetChanged event payload", target, payload[0]);
 	}
 
 	/**
diff --git a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
index b3825fe..4beb5f3 100644
--- a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %name
 Bundle-SymbolicName: org.eclipse.pde.ui; singleton:=true
-Bundle-Version: 3.10.700.qualifier
+Bundle-Version: 3.11.0.qualifier
 Bundle-Activator: org.eclipse.pde.internal.ui.PDEPlugin
 Bundle-Vendor: %provider-name
 Bundle-Localization: plugin
@@ -69,8 +69,11 @@
  org.eclipse.pde.ui.templates,
  org.eclipse.ui.internal.views.log.jdt;x-internal:=true
 Require-Bundle: 
- org.eclipse.pde.core;bundle-version="[3.6.0,4.0.0)";visibility:=reexport,
+ org.eclipse.pde.core;bundle-version="[3.13.0,4.0.0)";visibility:=reexport,
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.osgi.services;bundle-version="[3.8.0,4.0.0)",
+ org.eclipse.e4.core.contexts;bundle-version="[1.8.0,2.0.0)",
+ org.eclipse.e4.core.services;bundle-version="[2.0.0,3.0.0)",
  org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.ui.views;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.jface.text;bundle-version="[3.7.0,4.0.0)",
diff --git a/ui/org.eclipse.pde.ui/pom.xml b/ui/org.eclipse.pde.ui/pom.xml
index a040765..9d9c4fc 100644
--- a/ui/org.eclipse.pde.ui/pom.xml
+++ b/ui/org.eclipse.pde.ui/pom.xml
@@ -19,6 +19,6 @@
   </parent>
   <groupId>org.eclipse.pde</groupId>
   <artifactId>org.eclipse.pde.ui</artifactId>
-  <version>3.10.700-SNAPSHOT</version>
+  <version>3.11.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/targetdefinition/TargetEditor.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/targetdefinition/TargetEditor.java
index 3b283f6..99ec63e 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/targetdefinition/TargetEditor.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/targetdefinition/TargetEditor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2018 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,6 +13,7 @@
  *     Lucas Bullen (Red Hat Inc.) - Bug 520216 - Add generic editor as a tab
  *                                 - Bug 531226 - Update to reflect addition of source tab
  *                                 - Bug 531602 - formatting munged by editor
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 541067
  *******************************************************************************/
 package org.eclipse.pde.internal.ui.editor.targetdefinition;
 
@@ -27,11 +28,15 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.events.IEventBroker;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.ControlContribution;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.text.*;
+import org.eclipse.jface.text.source.ISourceViewerExtension5;
 import org.eclipse.jface.wizard.WizardDialog;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.pde.core.target.*;
@@ -53,6 +58,9 @@
 import org.eclipse.ui.internal.genericeditor.ExtensionBasedTextEditor;
 import org.eclipse.ui.part.FileEditorInput;
 import org.eclipse.ui.progress.UIJob;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
 import org.xml.sax.SAXException;
 
 /**
@@ -74,7 +82,11 @@
 	private InputHandler fInputHandler = new InputHandler();
 	private TargetChangedListener fTargetChangedListener;
 	private boolean fDirty;
-	private ArrayList<ImageHyperlink> arrayHyperLink = new ArrayList<>();
+
+	private ImageHyperlink fLoadHyperlink;
+
+	private EventHandler fEventHandler = e -> handleBrokerEvent(e);
+
 	@Override
 	protected FormToolkit createToolkit(Display display) {
 		return new FormToolkit(PDEPlugin.getDefault().getFormColors(display));
@@ -91,6 +103,10 @@
 		} catch (CoreException e) {
 			PDEPlugin.log(e);
 		}
+		BundleContext bundleContext = PDECore.getDefault().getBundleContext();
+		IEclipseContext context = EclipseContextFactory.getServiceContext(bundleContext);
+		IEventBroker eventBroker = context.get(IEventBroker.class);
+		eventBroker.subscribe(TargetEvents.TOPIC_WORKSPACE_TARGET_CHANGED, fEventHandler);
 	}
 
 	@Override
@@ -215,6 +231,11 @@
 
 	@Override
 	public void dispose() {
+		BundleContext bundleContext = PDECore.getDefault().getBundleContext();
+		IEclipseContext context = EclipseContextFactory.getServiceContext(bundleContext);
+		IEventBroker eventBroker = context.get(IEventBroker.class);
+		eventBroker.unsubscribe(fEventHandler);
+
 		// Cancel any resolution jobs that are runnning
 		Job.getJobManager().cancel(getTargetChangedListener().getJobFamily());
 		getTargetChangedListener().setContentTree(null);
@@ -261,6 +282,7 @@
 
 	public void contributeToToolbar(final ScrolledForm form, String contextID) {
 		ControlContribution setAsTarget = new ControlContribution("Set") { //$NON-NLS-1$
+
 			@Override
 			protected Control createControl(Composite parent) {
 				PDEPreferencesManager preferences = PDECore.getDefault().getPreferencesManager();
@@ -277,16 +299,11 @@
 						hyperLinkText = PDEUIMessages.AbstractTargetPage_reloadTarget;
 					}
 				}
-				ImageHyperlink hyperlink = new ImageHyperlink(parent, SWT.NONE | SWT.NO_FOCUS);
-				hyperlink.setText(hyperLinkText);
-				if (!arrayHyperLink.isEmpty()) {
-					// if hyperlink exist, update text from it.
-					hyperlink.setText(arrayHyperLink.get(0).getText());
-				}
-				arrayHyperLink.add(hyperlink);
-				hyperlink.setUnderlined(true);
-				hyperlink.setForeground(getToolkit().getHyperlinkGroup().getForeground());
-				hyperlink.addHyperlinkListener(new IHyperlinkListener() {
+				fLoadHyperlink = new ImageHyperlink(parent, SWT.NONE | SWT.NO_FOCUS);
+				fLoadHyperlink.setText(hyperLinkText);
+				fLoadHyperlink.setUnderlined(true);
+				fLoadHyperlink.setForeground(getToolkit().getHyperlinkGroup().getForeground());
+				fLoadHyperlink.addHyperlinkListener(new IHyperlinkListener() {
 					@Override
 					public void linkActivated(HyperlinkEvent e) {
 						IEditorPart editorPart = TargetEditor.this;
@@ -296,12 +313,6 @@
 						}
 						ITargetDefinition target = getTarget();
 						LoadTargetDefinitionJob.load(target);
-						try {
-							updateTargetEditors(target.getHandle());
-						} catch (CoreException ce) {
-							PDEPlugin.log(ce);
-							hyperlink.setText(PDEUIMessages.AbstractTargetPage_reloadTarget);
-						}
 					}
 
 					@Override
@@ -309,7 +320,7 @@
 						HyperlinkGroup hyperlinkGroup = getHyperlinkGroup();
 
 						if (hyperlinkGroup != null) {
-							hyperlink.setForeground(hyperlinkGroup.getActiveForeground());
+							fLoadHyperlink.setForeground(hyperlinkGroup.getActiveForeground());
 						}
 					}
 
@@ -318,7 +329,7 @@
 						HyperlinkGroup hyperlinkGroup = getHyperlinkGroup();
 
 						if (hyperlinkGroup != null) {
-							hyperlink.setForeground(hyperlinkGroup.getForeground());
+							fLoadHyperlink.setForeground(hyperlinkGroup.getForeground());
 						}
 					}
 
@@ -331,7 +342,7 @@
 						return hyperlinkGroup;
 					}
 				});
-				return hyperlink;
+				return fLoadHyperlink;
 			}
 		};
 
@@ -449,9 +460,6 @@
 				if (fInput instanceof IFileEditorInput) {
 					ITargetHandle fileHandle = service.getTarget(((IFileEditorInput) fInput).getFile());
 					fTarget = fileHandle.getTargetDefinition();
-					if (fileHandle instanceof WorkspaceFileTargetHandle) {
-						((WorkspaceFileTargetHandle) fileHandle).setWorkspaceEditor(TargetEditor.this);
-					}
 				} else if (fInput instanceof IURIEditorInput) {
 					ITargetHandle externalTarget = service.getTarget(((IURIEditorInput) fInput).getURI());
 					fTarget = externalTarget.getTargetDefinition();
@@ -642,41 +650,48 @@
 		}
 	}
 
-	public void updateHyperlinkText(String s) {
-		for (Hyperlink hyperlink : arrayHyperLink) {
-			if (hyperlink == null || hyperlink.isDisposed()) {
-				continue;
-			}
-			hyperlink.setText(s);
+	private void updateHyperlinkText(String s) {
+		if (fLoadHyperlink != null && !fLoadHyperlink.isDisposed()) {
+			fLoadHyperlink.setText(s);
 		}
-		updateTextualEditor();
+		ITextViewer viewer = fTextualEditor.getAdapter(ITextViewer.class);
+		if (viewer instanceof ISourceViewerExtension5) {
+			ISourceViewerExtension5 extension5 = (ISourceViewerExtension5) viewer;
+			extension5.updateCodeMinings();
+		}
 	}
 
-	public static void updateTargetEditors(ITargetHandle targetHandle) throws CoreException {
-		String targetMemento = targetHandle.getMemento();
-		IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
-		for (IWorkbenchWindow window : windows) {
-			IWorkbenchPage[] pages = window.getPages();
-			for (IWorkbenchPage page : pages) {
-				IEditorReference[] references = page.getEditorReferences();
-				for (IEditorReference reference : references) {
-					IEditorPart editor = reference.getEditor(false);
-					if (editor instanceof TargetEditor) {
-						TargetEditor targetEditor = (TargetEditor) editor;
-						ITargetDefinition target = targetEditor.getTarget();
-						if (target == null) {
-							continue;
-						}
-						ITargetHandle handle = target.getHandle();
-						String memento = handle.getMemento();
-						boolean isCurrent = Objects.equals(memento, targetMemento);
-						String label = isCurrent ? PDEUIMessages.AbstractTargetPage_reloadTarget
-								: PDEUIMessages.AbstractTargetPage_setTarget;
-						targetEditor.updateHyperlinkText(label);
-					}
-				}
-			}
+	private void handleBrokerEvent(Event event) {
+		String topic = event.getTopic();
+		if (TargetEvents.TOPIC_WORKSPACE_TARGET_CHANGED.equals(topic)) {
+			ITargetDefinition workspaceTarget = extractTargetDefinition(event);
+			handleWorkspaceTargetChanged(workspaceTarget);
 		}
 	}
 
+	private void handleWorkspaceTargetChanged(ITargetDefinition workspaceTarget) {
+		ITargetDefinition editorTarget = getTarget();
+		if (editorTarget == null) {
+			return;
+		}
+		ITargetHandle editorHandle = editorTarget.getHandle();
+		ITargetHandle changedHandle = workspaceTarget.getHandle();
+		try {
+			final boolean isCurrent = Objects.equals(editorHandle.getMemento(), changedHandle.getMemento());
+			final String label = isCurrent ? PDEUIMessages.AbstractTargetPage_reloadTarget
+					: PDEUIMessages.AbstractTargetPage_setTarget;
+			Display.getDefault().asyncExec(() -> updateHyperlinkText(label));
+		} catch (CoreException e) {
+			PDECore.log(e.getStatus());
+		}
+	}
+
+	private ITargetDefinition extractTargetDefinition(Event event) {
+		Object data = event.getProperty(IEventBroker.DATA);
+		if (data instanceof ITargetDefinition) {
+			return (ITargetDefinition) data;
+		}
+		return null;
+	}
+
 }
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage.java
index d6cfaa7..86a7e0e 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 EclipseSource Corporation and others.
+ * Copyright (c) 2009, 2019 EclipseSource Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -11,6 +11,7 @@
  * Contributors:
  *     EclipseSource Corporation - initial API and implementation
  *     IBM Corporation - ongoing enhancements
+ *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 541067
  *******************************************************************************/
 package org.eclipse.pde.internal.ui.preferences;
 
@@ -39,7 +40,6 @@
 import org.eclipse.pde.internal.core.*;
 import org.eclipse.pde.internal.core.target.*;
 import org.eclipse.pde.internal.ui.*;
-import org.eclipse.pde.internal.ui.editor.targetdefinition.TargetEditor;
 import org.eclipse.pde.internal.ui.shared.target.*;
 import org.eclipse.pde.internal.ui.shared.target.Messages;
 import org.eclipse.pde.internal.ui.util.SWTUtil;
@@ -956,24 +956,8 @@
 				}
 			};
 
-			if (fPrevious.getHandle() instanceof WorkspaceFileTargetHandle) {
-				WorkspaceFileTargetHandle wrkHandle = (WorkspaceFileTargetHandle) fPrevious.getHandle();
-				Object object = wrkHandle.getWorkspaceEditor();
-				if (object instanceof TargetEditor) {
-					TargetEditor targetEditor = (TargetEditor) object;
-					targetEditor.updateHyperlinkText(PDEUIMessages.AbstractTargetPage_setTarget);
-				}
-			}
 			LoadTargetDefinitionJob.load(toLoad, listener);
 
-			if ((toLoad != null) && (toLoad.getHandle() instanceof WorkspaceFileTargetHandle)) {
-				WorkspaceFileTargetHandle wrkHandle = (WorkspaceFileTargetHandle) toLoad.getHandle();
-				Object object = wrkHandle.getWorkspaceEditor();
-				if (object instanceof TargetEditor) {
-					TargetEditor targetEditor = (TargetEditor) object;
-					targetEditor.updateHyperlinkText(PDEUIMessages.AbstractTargetPage_reloadTarget);
-				}
-			}
 			fPrevious = toLoad == null ? null : toLoad;
 
 			// Start a separate job to clean p2 bundle pool