diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupport.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupport.java index 8cca518c52..24b5aaf858 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupport.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupport.java @@ -11,14 +11,26 @@ package org.eclipse.jdt.ls.core.internal.managers; import java.nio.file.Path; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.eclipse.jdt.ls.core.internal.ProjectUtils; import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.internal.MavenPluginActivator; +import org.eclipse.m2e.core.internal.project.ProjectConfigurationManager; +import org.eclipse.m2e.core.internal.project.registry.ProjectRegistryManager; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.project.IMavenProjectRegistry; import org.eclipse.m2e.core.project.IProjectConfigurationManager; import org.eclipse.m2e.core.project.MavenUpdateRequest; @@ -28,11 +40,17 @@ */ public class MavenBuildSupport implements IBuildSupport { private IProjectConfigurationManager configurationManager; + private ProjectRegistryManager projectManager; private DigestStore digestStore; + private IMavenProjectRegistry registry; + private boolean shouldCollectProjects; public MavenBuildSupport() { this.configurationManager = MavenPlugin.getProjectConfigurationManager(); + this.projectManager = MavenPluginActivator.getDefault().getMavenProjectManagerImpl(); this.digestStore = JavaLanguageServerPlugin.getDigestStore(); + this.registry = MavenPlugin.getMavenProjectRegistry(); + this.shouldCollectProjects = true; } @Override @@ -48,9 +66,35 @@ public void update(IProject project, boolean force, IProgressMonitor monitor) th Path pomPath = project.getFile("pom.xml").getLocation().toFile().toPath(); if (digestStore.updateDigest(pomPath) || force) { JavaLanguageServerPlugin.logInfo("Starting Maven update for " + project.getName()); - //TODO collect dependent projects and update them as well? i.e in case a parent project was modified - MavenUpdateRequest request = new MavenUpdateRequest(project, MavenPlugin.getMavenConfiguration().isOffline(), true); - configurationManager.updateProjectConfiguration(request, monitor); + if (shouldCollectProjects()) { + Set projectSet = new LinkedHashSet<>(); + collectProjects(projectSet, project, monitor); + IProject[] projects = projectSet.toArray(new IProject[0]); + MavenUpdateRequest request = new MavenUpdateRequest(projects, MavenPlugin.getMavenConfiguration().isOffline(), true); + ((ProjectConfigurationManager) configurationManager).updateProjectConfiguration(request, true, true, monitor); + } else { + MavenUpdateRequest request = new MavenUpdateRequest(project, MavenPlugin.getMavenConfiguration().isOffline(), true); + configurationManager.updateProjectConfiguration(request, monitor); + } + } + } + + public void collectProjects(Collection projects, IProject project, IProgressMonitor monitor) { + if (!ProjectUtils.isMavenProject(project)) { + return; + } + projects.add(project); + IMavenProjectFacade projectFacade = registry.create(project, monitor); + if ("pom".equals(projectFacade.getPackaging())) { + List modules = projectFacade.getMavenProjectModules(); + for (String module : modules) { + IPath pomPath = ResourcesPlugin.getWorkspace().getRoot().getFullPath().append(module).append("pom.xml"); + IFile pom = ResourcesPlugin.getWorkspace().getRoot().getFile(pomPath); + IProject p = pom.getProject(); + if (p.isOpen()) { + collectProjects(projects, p, monitor); + } + } } } @@ -60,4 +104,12 @@ public boolean isBuildFile(IResource resource) { //Check pom.xml is at the root of the project && resource.getProject().equals(resource.getParent()); } + + public boolean shouldCollectProjects() { + return shouldCollectProjects; + } + + public void setShouldCollectProjects(boolean shouldCollectProjects) { + this.shouldCollectProjects = shouldCollectProjects; + } } diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java index 87bd5054aa..619a6bbeff 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporter.java @@ -187,6 +187,7 @@ private void updateProjects(Collection projects, long lastWorkspaceSta @Override public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { MavenBuildSupport mavenBuildSupport = new MavenBuildSupport(); + mavenBuildSupport.setShouldCollectProjects(false); for (IProject project : projects) { if (monitor.isCanceled()) { return Status.CANCEL_STATUS; diff --git a/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module1/pom.xml b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module1/pom.xml new file mode 100644 index 0000000000..f8fdf8c27e --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module1/pom.xml @@ -0,0 +1,8 @@ + + 4.0.0 + foo.bar + module1 + 0.0.1-SNAPSHOT + jar + + \ No newline at end of file diff --git a/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module2/pom.xml b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module2/pom.xml new file mode 100644 index 0000000000..250938012d --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/module2/pom.xml @@ -0,0 +1,8 @@ + + 4.0.0 + foo.bar + module2 + 0.0.1-SNAPSHOT + jar + + \ No newline at end of file diff --git a/org.eclipse.jdt.ls.tests/projects/maven/multimodule/pom.xml b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/pom.xml new file mode 100644 index 0000000000..e6383f4b08 --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/maven/multimodule/pom.xml @@ -0,0 +1,12 @@ + + 4.0.0 + foo.bar + multimodule + 0.0.1-SNAPSHOT + pom + + + module1 + module2 + + \ No newline at end of file diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupportTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupportTest.java index 5f21842b03..529dea1b66 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupportTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenBuildSupportTest.java @@ -17,10 +17,13 @@ import static org.junit.Assert.assertFalse; import java.net.URI; +import java.util.LinkedHashSet; +import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.Job; @@ -82,6 +85,14 @@ public void testCompileWithEclipseTychoJdt() throws Exception { testNonStandardCompilerId("compile-with-tycho-jdt"); } + @Test + public void testMultipleProjects() throws Exception { + IProject project = importMavenProject("multimodule"); + Set projects = new LinkedHashSet<>(); + new MavenBuildSupport().collectProjects(projects, project, new NullProgressMonitor()); + assertEquals(projects.size(), 3); + } + @Test public void testIgnoreInnerPomChanges() throws Exception { IProject project = importMavenProject("archetyped");