Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Wellmann2022-03-20 13:40:25 +0000
committerHannes Wellmann2022-03-23 08:18:51 +0000
commitfb5ad5bf72c88c5f7bf6076abadbc5e488e897be (patch)
tree0c61b0b738d6c150b37a12be75046e21d4d4b8b6
parentaaff700e878c90b57a50b0fce2aea648b5a1cf3e (diff)
downloadeclipse.pde.ui-fb5ad5bf72c88c5f7bf6076abadbc5e488e897be.tar.gz
eclipse.pde.ui-fb5ad5bf72c88c5f7bf6076abadbc5e488e897be.tar.xz
eclipse.pde.ui-fb5ad5bf72c88c5f7bf6076abadbc5e488e897be.zip
Bug 578990 - react to changes in derived resources and add tests
and unify attachment of resource change listeners. Products in derived resources are only considered if the derived resources is contained in a src-folder. Change-Id: I034039b74dd2aefed2509b418c5e5ad8e721a912 Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net> Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/192077 Tested-by: PDE Bot <pde-bot@eclipse.org>
-rw-r--r--ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java15
-rw-r--r--ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java63
-rw-r--r--ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java7
-rw-r--r--ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/AllPDECoreTests.java14
-rw-r--r--ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceModelManagerTest.java247
-rw-r--r--ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceProductModelManagerTest.java155
-rw-r--r--ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDEMinimalTests.java4
-rw-r--r--ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDETests.java4
-rw-r--r--ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/features/model/WorkspaceProductModelManager.java19
9 files changed, 463 insertions, 65 deletions
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
index 8ef92ba971..235a0ce87d 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2017 IBM Corporation and others.
+ * Copyright (c) 2006, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -16,7 +16,6 @@ package org.eclipse.pde.internal.core;
import java.util.Map.Entry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.pde.core.IModelProviderEvent;
import org.eclipse.pde.internal.core.feature.WorkspaceFeatureModel;
@@ -69,18 +68,6 @@ public class WorkspaceFeatureModelManager extends WorkspaceModelManager<IFeature
}
}
- @Override
- protected void addListeners() {
- int event = IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.POST_CHANGE;
- PDECore.getWorkspace().addResourceChangeListener(this, event);
- }
-
- @Override
- protected void removeListeners() {
- PDECore.getWorkspace().removeResourceChangeListener(this);
- super.removeListeners();
- }
-
protected IFeatureModel[] getFeatureModels() {
initialize();
return getModelsMap().values().toArray(new IFeatureModel[getModelsMap().size()]);
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
index ea74d7b835..f313971a60 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2018 IBM Corporation and others.
+ * Copyright (c) 2003, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -30,6 +30,7 @@ import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.pde.core.IModel;
import org.eclipse.pde.core.IModelProviderEvent;
@@ -129,7 +130,16 @@ public abstract class WorkspaceModelManager<T> extends AbstractModelManager
protected abstract T removeModel(IProject project);
- protected abstract void addListeners();
+ protected void addListeners() {
+ IWorkspace workspace = PDECore.getWorkspace();
+ workspace.addResourceChangeListener(this, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.POST_CHANGE);
+ }
+
+ @Override
+ protected void removeListeners() {
+ PDECore.getWorkspace().removeResourceChangeListener(this);
+ super.removeListeners();
+ }
protected T getModel(IProject project) {
initialize();
@@ -161,34 +171,33 @@ public abstract class WorkspaceModelManager<T> extends AbstractModelManager
@Override
public boolean visit(IResourceDelta delta) throws CoreException {
if (delta != null) {
-
final IResource resource = delta.getResource();
- if (!resource.isDerived()) {
- switch (resource.getType()) {
-
- case IResource.ROOT :
- return true;
- case IResource.PROJECT : {
- IProject project = (IProject) resource;
- if (isInterestingProject(project) && (delta.getKind() == IResourceDelta.ADDED || (delta.getFlags() & IResourceDelta.OPEN) != 0)) {
- createModel(project, true);
- return false;
- } else if (delta.getKind() == IResourceDelta.REMOVED) {
- removeModel(project);
- return false;
- }
- return true;
+ switch (resource.getType())
+ {
+ case IResource.ROOT:
+ return true;
+ case IResource.PROJECT: {
+ IProject project = (IProject) resource;
+ boolean addedOrOpened = delta.getKind() == IResourceDelta.ADDED
+ || (delta.getFlags() & IResourceDelta.OPEN) != 0;
+ if (isInterestingProject(project) && addedOrOpened) {
+ createModel(project, true);
+ return false;
+ } else if (delta.getKind() == IResourceDelta.REMOVED) {
+ removeModel(project);
+ return false;
+ }
+ return true;
+ }
+ case IResource.FOLDER:
+ return isInterestingFolder((IFolder) resource);
+ case IResource.FILE:
+ // do not process
+ if (isContentChange(delta)) {
+ handleFileDelta(delta);
+ return false;
}
- case IResource.FOLDER :
- return isInterestingFolder((IFolder) resource);
- case IResource.FILE :
- // do not process
- if (isContentChange(delta)) {
- handleFileDelta(delta);
- return false;
- }
}
- }
}
return false;
}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
index c8588958f2..e60e790b07 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2017 IBM Corporation and others.
+ * Copyright (c) 2006, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -35,7 +35,6 @@ import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.JavaCore;
@@ -450,8 +449,7 @@ public class WorkspacePluginModelManager extends WorkspaceModelManager<IPluginMo
*/
@Override
protected void addListeners() {
- IWorkspace workspace = PDECore.getWorkspace();
- workspace.addResourceChangeListener(this, IResourceChangeEvent.PRE_CLOSE);
+ PDECore.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_CLOSE);
// PDE must process the POST_CHANGE events before the Java model
// for the PDE container classpath update to proceed smoothly
JavaCore.addPreProcessingResourceChangedListener(this, IResourceChangeEvent.POST_CHANGE);
@@ -463,7 +461,6 @@ public class WorkspacePluginModelManager extends WorkspaceModelManager<IPluginMo
*/
@Override
protected void removeListeners() {
- PDECore.getWorkspace().removeResourceChangeListener(this);
JavaCore.removePreProcessingResourceChangedListener(this);
if (!fExtensionListeners.isEmpty()) {
fExtensionListeners.clear();
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/AllPDECoreTests.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/AllPDECoreTests.java
new file mode 100644
index 0000000000..75b2508e9c
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/AllPDECoreTests.java
@@ -0,0 +1,14 @@
+package org.eclipse.pde.core.tests.internal;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ //
+ DependencyManagerTest.class, //
+ WorkspaceModelManagerTest.class, //
+ WorkspaceProductModelManagerTest.class, //
+})
+public class AllPDECoreTests {
+}
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceModelManagerTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceModelManagerTest.java
new file mode 100644
index 0000000000..b3ba65a2f6
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceModelManagerTest.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 Hannes Wellmann and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Hannes Wellmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.core.tests.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.pde.core.IModelProviderEvent;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.internal.core.WorkspaceModelManager;
+import org.eclipse.pde.internal.core.WorkspacePluginModelManager;
+import org.eclipse.pde.internal.core.project.PDEProject;
+import org.eclipse.pde.ui.tests.util.ProjectUtils;
+import org.junit.*;
+import org.junit.rules.TestRule;
+import org.osgi.framework.Constants;
+
+/**
+ * Tests for the abstract {@link WorkspaceModelManager}, using Plug-in projects
+ * and therefore the {@link WorkspacePluginModelManager} as
+ * 'test'-implementation.
+ */
+public class WorkspaceModelManagerTest {
+ @ClassRule
+ public static final TestRule CLEAR_WORKSPACE = ProjectUtils.DELETE_ALL_WORKSPACE_PROJECTS_BEFORE_AND_AFTER;
+
+ @Rule
+ public final TestRule deleteCreatedTestProjectsAfter = ProjectUtils.DELETE_CREATED_WORKSPACE_PROJECTS_AFTER;
+
+ private static final Set<WorkspaceModelManager<?>> openManagers = ConcurrentHashMap.newKeySet();
+
+ @After
+ public void tearDown() {
+ openManagers.forEach(WorkspaceModelManager::shutdown);
+ }
+
+ @Test
+ public void testGetModel_projectCreated() throws CoreException {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ IProject project = getWorkspaceProject("plugin.a");
+ assertNull(mm.getModel(project));
+ createModelProject("plugin.a", "1.0.0");
+ IPluginModelBase model = mm.getModel(project);
+ assertExistingModel("plugin.a", "1.0.0", model);
+ }
+
+ @Test
+ public void testGetModel_workspaceStartUpWithExistingProject() throws CoreException {
+ // simulate start-up with workspace with existing, open projects
+ IProject existingProject = createModelProject("plugin.a", "1.0.0");
+ TestWorkspaceModelManager mm = createWorkspaceModelManager(false);
+ IPluginModelBase model = mm.getModel(existingProject);
+ assertExistingModel("plugin.a", "1.0.0", model);
+ }
+
+ @Test
+ public void testChangeEvents_singleModelCreated() throws CoreException {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ List<IModelProviderEvent> events = new ArrayList<>();
+ mm.addModelProviderListener(events::add);
+
+ IPluginModelBase model = mm.getModel(createModelProject("plugin.a", "1.0.0"));
+
+ assertEquals(1, events.size());
+ IModelProviderEvent event = events.get(0);
+ assertEquals(IModelProviderEvent.MODELS_ADDED, event.getEventTypes());
+ assertEquals(1, event.getAddedModels().length);
+ assertEquals(0, event.getChangedModels().length);
+ assertEquals(0, event.getRemovedModels().length);
+ assertSame(model, event.getAddedModels()[0]);
+ assertSame(mm, event.getEventSource());
+
+ mm.shutdown();
+ }
+
+ // MODELS_CHANGED events are not properly handled if multiple
+ // WorkspaceModelManager exist because the first one re-loads the model into
+ // the same model object so all subsequently notified managers do not detect
+ // a difference -> This case is skipped for now
+
+ @Test
+ public void testChangeEvents_singleModelRemoved() throws CoreException {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ IProject project = createModelProject("plugin.a", "1.0.0");
+ IPluginModelBase model = mm.getModel(project);
+ List<IModelProviderEvent> events = new ArrayList<>();
+ mm.addModelProviderListener(events::add);
+
+ project.delete(true, true, null);
+
+ assertEquals(1, events.size());
+ IModelProviderEvent event = events.get(0);
+ assertEquals(IModelProviderEvent.MODELS_REMOVED, event.getEventTypes());
+ assertEquals(0, event.getAddedModels().length);
+ assertEquals(0, event.getChangedModels().length);
+ assertEquals(1, event.getRemovedModels().length);
+ assertSame(model, event.getRemovedModels()[0]);
+ assertSame(mm, event.getEventSource());
+ }
+
+ @Test
+ public void testBundleRootHandling_projectCreatedWithNonDefaultBundleRoot() throws CoreException {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ IPath bundleRootPath = Path.forPosix("other/root");
+
+ IProject project = ProjectUtils.createPluginProject("plugin.a", "plugin.a", "1.0.0", (description, service) -> {
+ description.setBundleRoot(bundleRootPath);
+ });
+
+ IPluginModelBase model = mm.getModel(project);
+ assertExistingModel("plugin.a", "1.0.0", model);
+ assertFalse(manifest(project).exists());
+ assertTrue(project.getFile("other/root/META-INF/MANIFEST.MF").exists());
+ assertEquals(project.getFile("other/root/META-INF/MANIFEST.MF"), model.getUnderlyingResource());
+ }
+
+ @Test
+ public void testOpenAndClose_projectWithChangedBundleRoot() throws Exception {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ IProject project = createModelProject("plugin.a", "1.0.0");
+
+ copyFile(manifest(project), manifestIn(project, "otherRoot"), replaceVersionTo("2.0.0"));
+ setBundleRoot(project, "otherRoot");
+ manifest(project).delete(true, null);
+
+ project.close(null);
+
+ assertNull(mm.getModel(project));
+
+ project.open(null);
+
+ IPluginModelBase model = mm.getModel(project);
+ assertExistingModel("plugin.a", "2.0.0", model);
+ assertEquals(manifestIn(project, "otherRoot"), model.getUnderlyingResource());
+ }
+
+ @Test
+ public void testDelete_projectWithChangedBundleRoot() throws Exception {
+ TestWorkspaceModelManager mm = createWorkspaceModelManager();
+ IProject project = createModelProject("plugin.a", "1.0.0");
+
+ copyFile(manifest(project), manifestIn(project, "otherRoot"), replaceVersionTo("2.0.0"));
+ setBundleRoot(project, "otherRoot");
+ manifest(project).delete(true, null);
+
+ project.delete(true, null);
+ assertNull(mm.getModel(project));
+ }
+
+ // --- utilities ---
+
+ // This class tests tests the abstract WorkspaceModelManager using the
+ // specific WorkspacePluginModelManager as 'example'.
+ private static class TestWorkspaceModelManager extends WorkspacePluginModelManager {
+ // Make protected methods visible to tests
+ @Override
+ public IPluginModelBase getModel(IProject project) {
+ return super.getModel(project);
+ }
+
+ @Override
+ protected IPluginModelBase[] getPluginModels() {
+ return super.getPluginModels();
+ }
+ }
+
+ private TestWorkspaceModelManager createWorkspaceModelManager() {
+ return createWorkspaceModelManager(true);
+ }
+
+ protected static TestWorkspaceModelManager createWorkspaceModelManager(boolean init) {
+ TestWorkspaceModelManager mm = new TestWorkspaceModelManager();
+ openManagers.add(mm);
+ if (init) {
+ // ensure manager is initialized, otherwise events can be missed
+ assertEquals(0, mm.getPluginModels().length);
+ }
+ return mm;
+ }
+
+ protected static IProject getWorkspaceProject(String name) {
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ }
+
+ private static IProject createModelProject(String symbolicName, String version) throws CoreException {
+ IProject project = ProjectUtils.createPluginProject(symbolicName, symbolicName, version);
+ project.build(IncrementalProjectBuilder.FULL_BUILD, null);
+ return project;
+ }
+
+ private static IFile manifest(IProject project) {
+ return project.getFile("META-INF/MANIFEST.MF");
+ }
+
+ private static IFile manifestIn(IProject project, String path) {
+ return project.getFile(path + "/META-INF/MANIFEST.MF");
+ }
+
+ private void setBundleRoot(IProject project, String path) throws CoreException {
+ PDEProject.setBundleRoot(project, path != null ? project.getFolder(path) : null);
+ }
+
+ private void copyFile(IFile source, IFile target, UnaryOperator<String> modifications)
+ throws IOException, CoreException {
+ try (Stream<String> lines = Files.lines(java.nio.file.Path.of(source.getLocationURI()))) {
+ Iterable<String> bs = lines.map(modifications)::iterator;
+ java.nio.file.Path targetPath = java.nio.file.Path.of(target.getLocationURI());
+ Files.createDirectories(targetPath.getParent());
+ Files.write(targetPath, bs);
+ target.refreshLocal(IResource.DEPTH_INFINITE, null);
+ }
+ }
+
+ private static UnaryOperator<String> replaceVersionTo(String newVersion) {
+ return l -> l.startsWith(Constants.BUNDLE_VERSION) ? Constants.BUNDLE_VERSION + ": " + newVersion : l;
+ }
+
+ private static void assertExistingModel(String symbolicName, String version, IPluginModelBase model) {
+ assertNotNull(model);
+ assertEquals(symbolicName, model.getPluginBase().getId());
+ assertEquals(version, model.getPluginBase().getVersion());
+ }
+
+}
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceProductModelManagerTest.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceProductModelManagerTest.java
new file mode 100644
index 0000000000..fa759d9e88
--- /dev/null
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/WorkspaceProductModelManagerTest.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2022, 2022 Hannes Wellmann and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Hannes Wellmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.core.tests.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.pde.internal.core.WorkspaceModelManager;
+import org.eclipse.pde.internal.core.iproduct.IProductModel;
+import org.eclipse.pde.internal.ui.views.features.model.WorkspaceProductModelManager;
+import org.eclipse.pde.internal.ui.wizards.product.BaseProductCreationOperation;
+import org.eclipse.pde.ui.tests.util.ProjectUtils;
+import org.junit.*;
+import org.junit.rules.TestRule;
+
+public class WorkspaceProductModelManagerTest {
+
+ @ClassRule
+ public static final TestRule CLEAR_WORKSPACE = ProjectUtils.DELETE_ALL_WORKSPACE_PROJECTS_BEFORE_AND_AFTER;
+
+ @Rule
+ public final TestRule deleteCreatedTestProjectsAfter = ProjectUtils.DELETE_CREATED_WORKSPACE_PROJECTS_AFTER;
+
+ private static final Set<WorkspaceModelManager<?>> openManagers = ConcurrentHashMap.newKeySet();
+
+ @After
+ public void tearDown() {
+ openManagers.forEach(WorkspaceModelManager::shutdown);
+ }
+
+ @Test
+ public void testProducts_productAddedAndRemoved() throws Exception {
+ TestWorkspaceProductModelManager mm = createWorkspaceModelManager();
+ IProject project = createProject();
+
+ createProduct(project, "aProduct");
+
+ Collection<IProductModel> products = mm.getModel(project);
+ assertSingleProductWithId("aProduct", products);
+
+ project.getFile("aProduct.product").delete(true, null);
+ assertNull(mm.getModel(project));
+ }
+
+ @Test
+ public void testProducts_productAddedToDerivedFolder() throws Exception {
+ TestWorkspaceProductModelManager mm = createWorkspaceModelManager();
+ IProject project = createProject();
+
+ IFolder folder = project.getFolder("folder1");
+ folder.create(true, true, null);
+ folder.setDerived(true, null);
+
+ createProduct(project, "folder1/aProduct");
+
+ assertNull(mm.getModel(project));
+ }
+
+ @Test
+ public void testProducts_productAddedToDerivedSourceFolder() throws Exception {
+ TestWorkspaceProductModelManager mm = createWorkspaceModelManager();
+ IProject project = createPluginProject("plugin.a");
+
+ IFolder srcFolder = project.getFolder("src");
+ srcFolder.setDerived(true, null);
+ createProduct(project, "src/aProduct");
+
+ Collection<IProductModel> products = mm.getModel(project);
+ assertSingleProductWithId("aProduct", products);
+ }
+
+ @Test
+ public void testProducts_productAddedToDeriveFolderNestedInSrcFolder() throws Exception {
+ TestWorkspaceProductModelManager mm = createWorkspaceModelManager();
+ IProject project = createPluginProject("plugin.a");
+
+ IFolder folder = project.getFolder("src/subFolder");
+ folder.create(true, true, null);
+ folder.setDerived(true, null);
+ createProduct(project, "src/subFolder/aProduct");
+
+ Collection<IProductModel> products = mm.getModel(project);
+ assertSingleProductWithId("aProduct", products);
+ }
+
+ // --- utilities ---
+
+ private class TestWorkspaceProductModelManager extends WorkspaceProductModelManager {
+ @Override // Make protected methods visible to tests
+ public Collection<IProductModel> getModel(IProject project) {
+ return super.getModel(project);
+ }
+
+ @Override
+ public IProductModel[] getProductModels() {
+ return super.getProductModels();
+ }
+ }
+
+ private TestWorkspaceProductModelManager createWorkspaceModelManager() {
+ TestWorkspaceProductModelManager mm = new TestWorkspaceProductModelManager();
+ openManagers.add(mm);
+ // ensure manager is initialized, otherwise events can be missed
+ assertEquals(0, mm.getProductModels().length);
+ return mm;
+ }
+
+ private static IProject createProject() throws CoreException {
+ IProject project = WorkspaceModelManagerTest.getWorkspaceProject("products");
+ project.create(null);
+ project.open(null);
+ return project;
+ }
+
+ private static void createProduct(IProject project, String pathName) throws Exception {
+ IFile f = project.getFile(pathName + ".product");
+ new BaseProductCreationOperation(f).run(null);
+ }
+
+ private static IProject createPluginProject(String symbolicName) throws CoreException {
+ IProject project = ProjectUtils.createPluginProject(symbolicName, symbolicName, "1.0.0", (d, s) -> {
+ d.setBundleClasspath(null);
+ });
+ IFolder srcFolder = project.getFolder("src");
+ srcFolder.create(true, true, null);
+ IClasspathEntry cpEntry = JavaCore.newSourceEntry(srcFolder.getFullPath());
+ JavaCore.create(project).setRawClasspath(new IClasspathEntry[] { cpEntry }, null);
+ project.build(IncrementalProjectBuilder.FULL_BUILD, null);
+ return project;
+ }
+
+ private static void assertSingleProductWithId(String expectedId, Collection<IProductModel> products) {
+ assertEquals(1, products.size());
+ IProductModel product = products.iterator().next();
+ assertEquals(expectedId, product.getProduct().getId());
+ }
+}
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDEMinimalTests.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDEMinimalTests.java
index 757c993a34..7700d84afe 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDEMinimalTests.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDEMinimalTests.java
@@ -13,7 +13,7 @@
*******************************************************************************/
package org.eclipse.pde.ui.tests;
-import org.eclipse.pde.core.tests.internal.DependencyManagerTest;
+import org.eclipse.pde.core.tests.internal.AllPDECoreTests;
import org.eclipse.pde.core.tests.internal.classpath.ClasspathResolutionTest;
import org.eclipse.pde.core.tests.internal.util.PDESchemaHelperTest;
import org.eclipse.pde.ui.tests.build.properties.AllValidatorTests;
@@ -49,7 +49,7 @@ import org.junit.runners.Suite.SuiteClasses;
DynamicPluginProjectReferencesTest.class,
// ClasspathContributorTest.class
ClasspathResolutionTest.class,
- DependencyManagerTest.class
+ AllPDECoreTests.class
})
public class AllPDEMinimalTests {
diff --git a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDETests.java b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDETests.java
index 539e3c2d14..d0dc6224ea 100644
--- a/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDETests.java
+++ b/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/AllPDETests.java
@@ -13,7 +13,7 @@
*******************************************************************************/
package org.eclipse.pde.ui.tests;
-import org.eclipse.pde.core.tests.internal.DependencyManagerTest;
+import org.eclipse.pde.core.tests.internal.AllPDECoreTests;
import org.eclipse.pde.core.tests.internal.classpath.ClasspathResolutionTest;
import org.eclipse.pde.ui.tests.build.properties.AllValidatorTests;
import org.eclipse.pde.ui.tests.classpathcontributor.ClasspathContributorTest;
@@ -55,7 +55,7 @@ import org.junit.runners.Suite.SuiteClasses;
ClasspathContributorTest.class,
DynamicPluginProjectReferencesTest.class,
ClasspathResolutionTest.class,
- DependencyManagerTest.class
+ AllPDECoreTests.class
})
public class AllPDETests {
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/features/model/WorkspaceProductModelManager.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/features/model/WorkspaceProductModelManager.java
index f9f2c2248b..d6bb85671b 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/features/model/WorkspaceProductModelManager.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/views/features/model/WorkspaceProductModelManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2019 Ed Scadding.
+ * Copyright (c) 2019, 2022 Ed Scadding.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -17,8 +17,8 @@ import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.pde.core.IModelProviderEvent;
-import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.WorkspaceModelManager;
import org.eclipse.pde.internal.core.iproduct.IProductModel;
import org.eclipse.pde.internal.core.product.WorkspaceProductModel;
@@ -34,7 +34,8 @@ public class WorkspaceProductModelManager extends WorkspaceModelManager<Collecti
@Override
protected boolean isInterestingFolder(IFolder folder) {
- return true;
+ // Only consider products in non-derived or src-folders
+ return !folder.isDerived() || JavaCore.create(folder.getProject()).isOnClasspath(folder);
}
@Override
@@ -111,18 +112,6 @@ public class WorkspaceProductModelManager extends WorkspaceModelManager<Collecti
}
}
- @Override
- protected void addListeners() {
- int event = IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.POST_CHANGE;
- PDECore.getWorkspace().addResourceChangeListener(this, event);
- }
-
- @Override
- protected void removeListeners() {
- PDECore.getWorkspace().removeResourceChangeListener(this);
- super.removeListeners();
- }
-
protected IProductModel[] getProductModels() {
initialize();

Back to the top