diff options
| author | Hannes Wellmann | 2022-03-20 13:40:25 +0000 |
|---|---|---|
| committer | Hannes Wellmann | 2022-03-23 08:18:51 +0000 |
| commit | fb5ad5bf72c88c5f7bf6076abadbc5e488e897be (patch) | |
| tree | 0c61b0b738d6c150b37a12be75046e21d4d4b8b6 | |
| parent | aaff700e878c90b57a50b0fce2aea648b5a1cf3e (diff) | |
| download | eclipse.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>
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(); |
