[maven] IDEA-313767 refactoring: MavenProjectsManagerEx

GitOrigin-RevId: 5079a02d3a497806baea7c23afd6515b23fe111e
This commit is contained in:
Dmitry Kichinsky
2023-05-21 19:02:14 +00:00
committed by intellij-monorepo-bot
parent b91d8896c5
commit 40b82f500e
13 changed files with 161 additions and 147 deletions
@@ -54,7 +54,7 @@ class MavenFolderResolver(private val project: Project) {
}
if (projectsManager.hasScheduledProjects()) {
projectsManager.importProjects()
projectsManager.importMavenProjectsSync()
//myProjectsManager.fireProjectImportCompleted()
}
}
@@ -13,8 +13,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
import com.intellij.openapi.externalSystem.service.project.autoimport.ExternalSystemProjectsWatcherImpl;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
@@ -83,8 +81,8 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@State(name = "MavenProjectsManager")
public class MavenProjectsManager extends MavenSimpleProjectComponent
implements PersistentStateComponent<MavenProjectsManagerState>, SettingsSavingComponentJavaAdapter, Disposable {
public abstract class MavenProjectsManager extends MavenSimpleProjectComponent
implements PersistentStateComponent<MavenProjectsManagerState>, SettingsSavingComponentJavaAdapter, Disposable, MavenAsyncProjectsManager {
private static final int IMPORT_DELAY = 1000;
private final ReentrantLock initLock = new ReentrantLock();
@@ -105,11 +103,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
private MavenProjectsProcessor myArtifactsDownloadingProcessor;
private MavenProjectsProcessor myPostProcessor;
private MavenMergingUpdateQueue myImportingQueue;
private final ConcurrentHashMap<MavenProject, MavenProjectChanges> myProjectsToImport = new ConcurrentHashMap<>();
protected MavenMergingUpdateQueue myImportingQueue;
protected final ConcurrentHashMap<@NotNull MavenProject, @NotNull MavenProjectChanges> myProjectsToImport = new ConcurrentHashMap<>();
private final Set<MavenProject> myProjectsToResolve = ConcurrentHashMap.newKeySet();
private final AtomicBoolean myImportModuleGroupsRequired = new AtomicBoolean(false);
protected final AtomicBoolean myImportModuleGroupsRequired = new AtomicBoolean(false);
private final EventDispatcher<MavenProjectsTree.Listener> myProjectsTreeDispatcher =
EventDispatcher.create(MavenProjectsTree.Listener.class);
@@ -122,7 +120,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
private final AtomicReference<MavenSyncConsole> mySyncConsole = new AtomicReference<>();
private final MavenMergingUpdateQueue mySaveQueue;
private static final int SAVE_DELAY = 1000;
private Module myPreviewModule;
protected Module myPreviewModule;
private transient boolean forceUpdateSnapshots = false;
public static MavenProjectsManager getInstance(@NotNull Project project) {
@@ -1166,7 +1164,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
runWhenFullyOpen(() -> myImportingQueue.queue(new Update(this) {
@Override
public void run() {
result.setResult(importProjects());
result.setResult(importMavenProjectsSync());
fireProjectImportCompleted();
}
}));
@@ -1182,7 +1180,7 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
project -> new Pair<>(project, MavenProjectChanges.ALL)
);
myProjectsToImport.putAll(projectsToImport);
importProjects();
importMavenProjectsSync();
fireProjectImportCompleted();
}
}));
@@ -1316,32 +1314,13 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
});
}
/**
* @deprecated Use {@link #importMavenProjectsSync()}}
*/
@Deprecated
// used in third-party plugins
public List<Module> importProjects() {
return importProjects(ProjectDataManager.getInstance().createModifiableModelsProvider(myProject));
}
public List<Module> importProjects(IdeModifiableModelsProvider modelsProvider) {
Map<MavenProject, MavenProjectChanges> projectsToImportWithChanges;
boolean importModuleGroupsRequired;
projectsToImportWithChanges = Collections.unmodifiableMap(new LinkedHashMap<>(myProjectsToImport));
projectsToImportWithChanges.forEach(myProjectsToImport::remove);
importModuleGroupsRequired = myImportModuleGroupsRequired.getAndSet(false);
return new MavenProjectsManagerImporter(
modelsProvider,
projectsToImportWithChanges,
importModuleGroupsRequired
).importMavenProjectsBlocking(this);
}
void restartImportingQueueTimer() {
myImportingQueue.restartTimer();
}
Module getPreviewModule() {
return myPreviewModule;
return importMavenProjectsSync();
}
@ApiStatus.Internal
@@ -0,0 +1,133 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.maven.project
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.writeAction
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager
import com.intellij.openapi.externalSystem.statistics.ProjectImportCollector
import com.intellij.openapi.externalSystem.statistics.importActivityStarted
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.progress.withBackgroundProgress
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.intellij.util.concurrency.annotations.RequiresBlockingContext
import com.intellij.util.concurrency.annotations.RequiresEdt
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.idea.maven.importing.MavenImportStats
import org.jetbrains.idea.maven.importing.MavenProjectImporter
import org.jetbrains.idea.maven.utils.MavenUtil
import org.jetbrains.idea.maven.utils.runBlockingCancellableUnderIndicator
import java.util.*
@ApiStatus.Experimental
interface MavenAsyncProjectsManager {
suspend fun importMavenProjects(): List<Module>
fun importMavenProjectsSync(): List<Module>
fun importMavenProjectsSync(modelsProvider: IdeModifiableModelsProvider): List<Module>
}
open class MavenProjectsManagerEx(project: Project) : MavenProjectsManager(project) {
override suspend fun importMavenProjects(): List<Module> {
TODO("Not yet implemented")
}
override fun importMavenProjectsSync(): List<Module> {
return importMavenProjectsSync(ProjectDataManager.getInstance().createModifiableModelsProvider(myProject))
}
override fun importMavenProjectsSync(modelsProvider: IdeModifiableModelsProvider): List<Module> {
val projectsToImportWithChanges = Collections.unmodifiableMap(LinkedHashMap(myProjectsToImport))
projectsToImportWithChanges.forEach { (key: MavenProject, value: MavenProjectChanges) ->
myProjectsToImport.remove(key, value)
}
val importModuleGroupsRequired = myImportModuleGroupsRequired.getAndSet(false)
return MavenProjectsManagerImporter(
modelsProvider,
projectsToImportWithChanges,
importModuleGroupsRequired
).importMavenProjectsBlocking()
}
private data class ImportResult(val createdModules: List<Module>, val postTasks: List<MavenProjectsProcessorTask>)
private inner class MavenProjectsManagerImporter(private val modelsProvider: IdeModifiableModelsProvider,
private val projectsToImportWithChanges: Map<MavenProject, MavenProjectChanges>,
private val importModuleGroupsRequired: Boolean) {
private val title = MavenProjectBundle.message("maven.project.importing")
@RequiresBlockingContext
fun importMavenProjectsBlocking(): List<Module> {
val importer = this
if (ApplicationManager.getApplication().isDispatchThread) {
return importer.importMavenProjectsEdt()
}
else {
return runBlockingCancellableUnderIndicator { importMavenProjects() }
}
}
@RequiresEdt
fun importMavenProjectsEdt(): List<Module> {
val createdModules = this.doImport()
VirtualFileManager.getInstance().syncRefresh()
return createdModules
}
@RequiresBackgroundThread
suspend fun importMavenProjects(): List<Module> {
return withBackgroundProgress(project, title, false) {
val createdModules = doImport()
val fm = VirtualFileManager.getInstance()
val noBackgroundMode = MavenUtil.isNoBackgroundMode()
val shouldKeepTasksAsynchronousInHeadlessMode = CoreProgressManager.shouldKeepTasksAsynchronousInHeadlessMode()
if (noBackgroundMode && !shouldKeepTasksAsynchronousInHeadlessMode) {
writeAction {
fm.syncRefresh()
}
}
else {
fm.asyncRefresh()
}
return@withBackgroundProgress createdModules
}
}
private fun doImport(): List<Module> {
project.messageBus.syncPublisher<MavenImportListener>(MavenImportListener.TOPIC).importStarted()
val importResult = this.runImportActivity()
schedulePostImportTasks(importResult.postTasks)
// do not block user too often
myImportingQueue.restartTimer();
val createdModules = importResult.createdModules
project.messageBus.syncPublisher(MavenImportListener.TOPIC).importFinished(projectsToImportWithChanges.keys, createdModules)
return createdModules
}
private fun runImportActivity(): ImportResult {
val activity = importActivityStarted(project, MavenUtil.SYSTEM_ID) {
listOf(ProjectImportCollector.TASK_CLASS.with(MavenImportStats.ImportingTaskOld::class.java))
}
try {
val projectImporter = MavenProjectImporter.createImporter(
project, projectsTree, projectsToImportWithChanges, importModuleGroupsRequired,
modelsProvider, importingSettings, myPreviewModule, activity
)
val postTasks = projectImporter.importProject()
return ImportResult(projectImporter.createdModules(), postTasks ?: emptyList())
}
finally {
activity.finished()
}
}
}
}
@@ -1,99 +0,0 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.maven.project
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.writeAction
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.statistics.ProjectImportCollector
import com.intellij.openapi.externalSystem.statistics.importActivityStarted
import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.impl.CoreProgressManager
import com.intellij.openapi.progress.withBackgroundProgress
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
import com.intellij.util.concurrency.annotations.RequiresBlockingContext
import com.intellij.util.concurrency.annotations.RequiresEdt
import org.jetbrains.idea.maven.importing.MavenImportStats.ImportingTaskOld
import org.jetbrains.idea.maven.importing.MavenProjectImporter.Companion.createImporter
import org.jetbrains.idea.maven.utils.MavenUtil
import org.jetbrains.idea.maven.utils.runBlockingCancellableUnderIndicator
internal class MavenProjectsManagerImporter(private val modelsProvider: IdeModifiableModelsProvider,
private val projectsToImportWithChanges: Map<MavenProject, MavenProjectChanges>,
private val importModuleGroupsRequired: Boolean) {
private val title = MavenProjectBundle.message("maven.project.importing")
@RequiresBlockingContext
fun MavenProjectsManager.importMavenProjectsBlocking(): List<Module> {
val importer = this
if (ApplicationManager.getApplication().isDispatchThread) {
return importer.importMavenProjectsEdt()
}
else {
return runBlockingCancellableUnderIndicator { importer.importMavenProjects() }
}
}
@RequiresEdt
fun MavenProjectsManager.importMavenProjectsEdt(): List<Module> {
val createdModules = this.doImport()
VirtualFileManager.getInstance().syncRefresh()
return createdModules
}
@RequiresBackgroundThread
suspend fun MavenProjectsManager.importMavenProjects(): List<Module> {
val manager = this
return withBackgroundProgress(project, title, false) {
val createdModules = manager.doImport()
val fm = VirtualFileManager.getInstance()
val noBackgroundMode = MavenUtil.isNoBackgroundMode()
val shouldKeepTasksAsynchronousInHeadlessMode = CoreProgressManager.shouldKeepTasksAsynchronousInHeadlessMode()
if (noBackgroundMode && !shouldKeepTasksAsynchronousInHeadlessMode) {
writeAction {
fm.syncRefresh()
}
}
else {
fm.asyncRefresh()
}
return@withBackgroundProgress createdModules
}
}
private fun MavenProjectsManager.doImport(): List<Module> {
project.messageBus.syncPublisher<MavenImportListener>(MavenImportListener.TOPIC).importStarted()
val importResult = this.runImportActivity()
schedulePostImportTasks(importResult.postTasks)
// do not block user too often
restartImportingQueueTimer()
val createdModules = importResult.createdModules
project.messageBus.syncPublisher(MavenImportListener.TOPIC).importFinished(projectsToImportWithChanges.keys, createdModules)
return createdModules
}
private data class ImportResult(val createdModules: List<Module>, val postTasks: List<MavenProjectsProcessorTask>)
private fun MavenProjectsManager.runImportActivity(): ImportResult {
val activity = importActivityStarted(project, MavenUtil.SYSTEM_ID) {
listOf(ProjectImportCollector.TASK_CLASS.with(ImportingTaskOld::class.java))
}
try {
val projectImporter = createImporter(
project, projectsTree, projectsToImportWithChanges, importModuleGroupsRequired,
modelsProvider, importingSettings, previewModule, activity
)
val postTasks = projectImporter.importProject()
return ImportResult(projectImporter.createdModules(), postTasks ?: emptyList())
}
finally {
activity.finished()
}
}
}
@@ -258,10 +258,10 @@ public final class MavenProjectBuilder extends ProjectImportBuilder<MavenProject
List<Module> createdModules;
if (isFromUI) {
var modelsProvider = new IdeUIModifiableModelsProvider(project, model, (ModulesConfigurator)modulesProvider, artifactModel);
createdModules = manager.importProjects(modelsProvider);
createdModules = manager.importMavenProjectsSync(modelsProvider);
}
else {
createdModules = manager.importProjects();
createdModules = manager.importMavenProjectsSync();
}
return createdModules;
}
@@ -100,7 +100,8 @@
<applicationService serviceImplementation="org.jetbrains.idea.maven.indices.archetype.MavenCatalogManager"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.indices.MavenArchetypeManager"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.indices.MavenIndicesManager"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.project.MavenProjectsManager" preload="true"/>
<projectService serviceInterface="org.jetbrains.idea.maven.project.MavenProjectsManager"
serviceImplementation="org.jetbrains.idea.maven.project.MavenProjectsManagerEx" preload="true"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.navigator.MavenProjectsNavigator" preload="true"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.tasks.MavenTasksManager" preload="true"/>
<projectService serviceImplementation="org.jetbrains.idea.maven.tasks.MavenShortcutsManager" preload="true"/>
@@ -74,7 +74,7 @@ open class DependenciesSubstitutionTest : MavenMultiVersionImportingTestCase() {
ApplicationManager.getApplication().invokeAndWait {
myProjectsManager.waitForResolvingCompletion()
myProjectsManager.scheduleImportInTests(files)
myProjectsManager.importProjects()
myProjectsManager.importMavenProjectsSync()
}
}
}
@@ -30,14 +30,14 @@ public abstract class MavenPerformanceTest extends MavenMultiVersionImportingTes
@Test
public void testImporting() {
waitForReadingCompletion();
measure(8, () -> myProjectsManager.importProjects());
measure(8, () -> myProjectsManager.importMavenProjectsSync());
}
@Test
public void testReImporting() {
waitForReadingCompletion();
myProjectsManager.importProjects();
measure(2, () -> myProjectsManager.importProjects());
myProjectsManager.importMavenProjectsSync();
measure(2, () -> myProjectsManager.importMavenProjectsSync());
}
@Test
@@ -484,7 +484,7 @@ public class MiscImportingTest extends MavenMultiVersionImportingTestCase {
assertModules("project", "m1", "m2");
myProjectsManager.scheduleImportInTests(myProjectsManager.getProjectsFiles());
myProjectsManager.importProjects(new IdeModifiableModelsProviderImpl(myProject) {
myProjectsManager.importMavenProjectsSync(new IdeModifiableModelsProviderImpl(myProject) {
@Override
public void commit() {
ModifiableModuleModel model = ModuleManager.getInstance(myProject).getModifiableModel();
@@ -77,7 +77,7 @@ public class MavenMultiProjectImportTest extends ProjectWizardTestCase<AbstractP
manager.resetManagedFilesAndProfilesInTests(Collections.singletonList(file), MavenExplicitProfiles.NONE);
ApplicationManager.getApplication().invokeAndWait(() -> {
manager.scheduleImportInTests(Collections.singletonList(file));
manager.importProjects();
manager.importMavenProjectsSync();
});
Promise<?> promise = manager.waitForImportCompletion();
@@ -212,7 +212,7 @@ public class MavenImportWizardTest extends ProjectWizardTestCase<AbstractProject
manager.waitForImportCompletion();
ApplicationManager.getApplication().invokeAndWait(() -> {
manager.scheduleImportInTests(Collections.singletonList(file));
manager.importProjects();
manager.importMavenProjectsSync();
});
}
@@ -80,7 +80,7 @@ abstract class MavenNewProjectWizardTestCase : NewProjectWizardTestCase() {
manager.waitForImportCompletion()
ApplicationManager.getApplication().invokeAndWait {
manager.scheduleImportInTests(listOf(file))
manager.importProjects()
manager.importMavenProjectsSync()
}
}
val promise = manager.waitForImportCompletion()
@@ -520,7 +520,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
ApplicationManager.getApplication().invokeAndWait(() -> {
myProjectsManager.scheduleImportInTests(files);
});
myProjectsManager.importProjects();
myProjectsManager.importMavenProjectsSync();
Promise<?> promise = myProjectsManager.waitForImportCompletion();
ApplicationManager.getApplication().invokeAndWait(() -> PlatformTestUtil.waitForPromise(promise));