diff --git a/platform/platform-impl/api-dump-unreviewed.txt b/platform/platform-impl/api-dump-unreviewed.txt index a085c9cd0914..67df09404cda 100644 --- a/platform/platform-impl/api-dump-unreviewed.txt +++ b/platform/platform-impl/api-dump-unreviewed.txt @@ -3198,7 +3198,6 @@ c:com.intellij.ide.plugins.InstalledPluginsTableModel - pf:sessionId:java.util.UUID - pf:view:java.util.List - (com.intellij.openapi.project.Project):V -- (com.intellij.openapi.project.Project,java.util.Collection,java.util.Collection):V - pf:getEnabledMap():java.util.Map - pf:getProject():com.intellij.openapi.project.Project - p:handleBeforeChangeEnableState(com.intellij.ide.plugins.IdeaPluginDescriptor,com.intellij.openapi.util.Pair):V diff --git a/platform/platform-impl/api-dump.txt b/platform/platform-impl/api-dump.txt index 658402b02124..9c2a055080dd 100644 --- a/platform/platform-impl/api-dump.txt +++ b/platform/platform-impl/api-dump.txt @@ -214,6 +214,8 @@ com.intellij.ide.navigationToolbar.NavBarModelExtension - normalizeChildren():Z - processChildren(java.lang.Object,java.lang.Object,com.intellij.util.Processor):Z - uiDataSnapshot(com.intellij.openapi.actionSystem.DataSink,com.intellij.openapi.actionSystem.DataSnapshot):V +f:com.intellij.ide.plugins.InstalledPluginsState +- getInstalledWithoutRestartPlugins():java.util.Collection com.intellij.ide.plugins.PluginEnableStateChangedListener - a:stateChanged(java.util.Collection,Z):V com.intellij.ide.plugins.PluginManagerMain$PluginEnabler diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java index 585dbaf7a847..10cb9c61da1d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java @@ -69,6 +69,12 @@ public final class InstalledPluginsState { } } + public @NotNull Collection getInstalledWithoutRestartPlugins() { + synchronized (myLock) { + return Collections.unmodifiableCollection(myInstalledWithoutRestartPlugins); + } + } + public @NotNull Collection getUpdatedPlugins() { synchronized (myLock) { return Collections.unmodifiableCollection(myUpdatedPlugins); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java index d5f31cd4ebd1..34ec7f83487d 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -2,6 +2,7 @@ package com.intellij.ide.plugins; import com.intellij.ide.IdeBundle; +import com.intellij.ide.plugins.marketplace.InitSessionResult; import com.intellij.ide.plugins.newui.PluginManagerSession; import com.intellij.ide.plugins.newui.PluginManagerSessionService; import com.intellij.ide.plugins.newui.PluginUiModel; @@ -32,28 +33,12 @@ public class InstalledPluginsTableModel { protected final PluginManagerSession mySession = initializeAndGetSession(); public InstalledPluginsTableModel(@Nullable Project project) { - this(project, new ArrayList<>(UiPluginManager.getInstance().getPlugins()), UiPluginManager.getInstance().getInstalledPlugins()); - } - - public InstalledPluginsTableModel(@Nullable Project project, - @NotNull Collection allPlugins, - @NotNull Collection installedPlugins) { myProject = project; - ApplicationInfo appInfo = ApplicationInfo.getInstance(); - for (PluginUiModel plugin : allPlugins) { - PluginId pluginId = plugin.getPluginId(); - if (appInfo.isEssentialPlugin(pluginId)) { - setEnabled(pluginId, PluginEnabledState.ENABLED); - } - else { - view.add(plugin); - } - } - view.addAll(installedPlugins); - - for (PluginUiModel descriptor : view) { - setEnabled(descriptor); - } + InitSessionResult initSessionResult = UiPluginManager.getInstance().initSession(sessionId); + view.addAll(initSessionResult.getVisiblePluginsList()); + initSessionResult.getPluginStates().forEach((pluginId, pluginState) -> { + myEnabled.put(pluginId, pluginState ? PluginEnabledState.ENABLED : PluginEnabledState.DISABLED); + }); } protected final @Nullable Project getProject() { @@ -64,7 +49,7 @@ public class InstalledPluginsTableModel { return isLoaded(pluginId, getEnabledMap()); } - private PluginManagerSession initializeAndGetSession(){ + private PluginManagerSession initializeAndGetSession() { UiPluginManager.getInstance().createSession(sessionId); PluginManagerSession session = PluginManagerSessionService.getInstance().getSession(sessionId); if (session == null) { @@ -86,7 +71,7 @@ public class InstalledPluginsTableModel { @ApiStatus.NonExtendable protected void setEnabled(@NotNull PluginId pluginId, - @Nullable PluginEnabledState enabled) { + @Nullable PluginEnabledState enabled) { myEnabled.put(pluginId, enabled); } @@ -122,7 +107,6 @@ public class InstalledPluginsTableModel { } - protected void handleBeforeChangeEnableState(@NotNull IdeaPluginDescriptor descriptor, @NotNull Pair pair) { } @@ -135,7 +119,7 @@ public class InstalledPluginsTableModel { @ApiStatus.Internal public static boolean isDisabled(@NotNull PluginId pluginId, - @NotNull Map enabledMap) { + @NotNull Map enabledMap) { PluginEnabledState state = enabledMap.get(pluginId); return state == null || state.isDisabled(); } @@ -162,7 +146,7 @@ public class InstalledPluginsTableModel { @ApiStatus.Internal public static @NotNull @NonNls String getPluginNameOrId(@NotNull PluginId pluginId, - @Nullable IdeaPluginDescriptor descriptor) { + @Nullable IdeaPluginDescriptor descriptor) { return descriptor != null ? descriptor.getName() : pluginId.getIdString(); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerPanelFactory.kt b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerPanelFactory.kt index 70bb7eeeccde..7aba40655171 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerPanelFactory.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerPanelFactory.kt @@ -41,7 +41,7 @@ object PluginManagerPanelFactory { ) val errorCheckResults = pluginManager.loadErrors(myPluginModel.sessionId.toString()) - val errors = myPluginModel.getErrors(errorCheckResults) + val errors = MyPluginModel.getErrors(errorCheckResults) try { for (query in queries) { val result = pluginManager.executeMarketplaceQuery(query, 18, false) @@ -63,19 +63,19 @@ object PluginManagerPanelFactory { @ApiStatus.Internal fun createInstalledPanel(cs: CoroutineScope, myPluginModel: MyPluginModel, callback: (CreateInstalledPanelModel) -> Unit) { cs.launch { - try { - PluginLogo.startBatchMode() - - val pluginManager = UiPluginManager.getInstance() - val installedPlugins = pluginManager.getInstalledPlugins() - val visiblePlugins = pluginManager.getVisiblePlugins(Registry.`is`("plugins.show.implementation.details")) - val errorCheckResults = pluginManager.loadErrors(myPluginModel.sessionId.toString()) - val errors = myPluginModel.getErrors(errorCheckResults) - withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) { + val pluginManager = UiPluginManager.getInstance() + val installedPlugins = pluginManager.getInstalledPlugins() + val visiblePlugins = pluginManager.getVisiblePlugins(Registry.`is`("plugins.show.implementation.details")) + val errorCheckResults = pluginManager.loadErrors(myPluginModel.sessionId.toString()) + val errors = MyPluginModel.getErrors(errorCheckResults) + withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) { + try { + PluginLogo.startBatchMode() callback(CreateInstalledPanelModel(installedPlugins, visiblePlugins, errors)) } - } finally { - PluginLogo.endBatchMode() + finally { + PluginLogo.endBatchMode() + } } } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/ApplyPluginsStateResult.kt b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/ApplyPluginsStateResult.kt index 768b24447160..94291146c68b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/ApplyPluginsStateResult.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/ApplyPluginsStateResult.kt @@ -2,6 +2,7 @@ package com.intellij.ide.plugins.marketplace import com.intellij.openapi.extensions.PluginId +import com.intellij.openapi.util.NlsSafe import kotlinx.serialization.Serializable import org.jetbrains.annotations.ApiStatus @@ -9,5 +10,6 @@ import org.jetbrains.annotations.ApiStatus @Serializable data class ApplyPluginsStateResult( val pluginsToEnable: Set = emptySet(), - var needRestart: Boolean = false + var needRestart: Boolean = false, + @get:NlsSafe var error: String? = null, ) \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InitSessionResult.kt b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InitSessionResult.kt new file mode 100644 index 000000000000..d7f7a6a60f29 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InitSessionResult.kt @@ -0,0 +1,20 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.plugins.marketplace + +import com.intellij.ide.plugins.api.PluginDto +import com.intellij.ide.plugins.newui.PluginUiModel +import com.intellij.openapi.extensions.PluginId +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import org.jetbrains.annotations.ApiStatus +import kotlin.collections.ifEmpty + +@Serializable +@ApiStatus.Internal +data class InitSessionResult( + @Transient val visiblePlugins: List = emptyList(), + val pluginStates: Map = emptyMap(), + val visiblePluginDtos: List = visiblePlugins.map(PluginDto::fromModel), +) { + fun getVisiblePluginsList(): List = visiblePlugins.ifEmpty { visiblePluginDtos } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InstallPluginResult.kt b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InstallPluginResult.kt index 9aa836bd1c30..06c24868a97e 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InstallPluginResult.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/marketplace/InstallPluginResult.kt @@ -17,5 +17,5 @@ class InstallPluginResult { var restartRequired: Boolean = true var dynamicRestartRequired = false var pluginsToDisable: Set = emptySet() - var errors: CheckErrorsResult? = null + var errors: Map = emptyMap() } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/DefaultUiPluginManagerController.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/DefaultUiPluginManagerController.kt index 3ede806e32e6..b8884f71637e 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/DefaultUiPluginManagerController.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/DefaultUiPluginManagerController.kt @@ -14,6 +14,7 @@ import com.intellij.ide.plugins.PluginManagerCore.looksLikePlatformPluginAlias import com.intellij.ide.plugins.PluginUtils.toPluginDescriptors import com.intellij.ide.plugins.api.PluginDto import com.intellij.ide.plugins.marketplace.* +import com.intellij.openapi.application.ApplicationInfo import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.application.PathManager @@ -31,8 +32,8 @@ import com.intellij.openapi.util.Pair import com.intellij.openapi.util.io.FileUtil import com.intellij.util.concurrency.annotations.RequiresBackgroundThread import com.intellij.util.concurrency.annotations.RequiresReadLockAbsence -import com.intellij.xml.util.XmlStringUtil import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.Nls import java.io.File import java.io.IOException import java.nio.file.FileVisitResult @@ -49,6 +50,24 @@ object DefaultUiPluginManagerController : UiPluginManagerController { return PluginManagerCore.plugins.map { PluginUiModelAdapter(it).withSource() } } + override fun initSession(sessionId: String): InitSessionResult { + val session = findSession(sessionId) ?: return InitSessionResult(emptyList(), emptyMap()) + val applicationInfo = ApplicationInfo.getInstance() + val visiblePlugins = mutableListOf() + for (plugin in getInstalledAndPendingPlugins()) { + val pluginId: PluginId = plugin.pluginId + if (applicationInfo.isEssentialPlugin(pluginId)) { + session.pluginStates[pluginId] = PluginEnabledState.ENABLED + } + else { + val state = if (PluginManagerCore.isLoaded(pluginId)) PluginEnabledState.ENABLED else PluginEnabledState.DISABLED + session.pluginStates[pluginId] = state + visiblePlugins.add(PluginUiModelAdapter(plugin)) + } + } + return InitSessionResult(visiblePlugins, session.pluginStates.mapValues { it.value.isEnabled }) + } + override fun getVisiblePlugins(showImplementationDetails: Boolean): List { return PluginManager.getVisiblePlugins(showImplementationDetails).map { PluginUiModelAdapter(it) }.toList().withSource() } @@ -127,7 +146,10 @@ object DefaultUiPluginManagerController : UiPluginManagerController { val pluginIdMap = buildPluginIdMap() val contentModuleIdMap = getPluginSet().buildContentModuleIdMap() val pluginsToEnable = updatePluginDependencies(session, pluginIdMap, contentModuleIdMap) - assertCanApply(session, pluginIdMap) + val errorMessage = getApplyError(session, pluginIdMap) + if (errorMessage != null) { + return ApplyPluginsStateResult(error = errorMessage) + } val pluginEnabler = PluginEnabler.getInstance() val uninstallsRequiringRestart: MutableSet = mutableSetOf() @@ -242,8 +264,8 @@ object DefaultUiPluginManagerController : UiPluginManagerController { return PluginInstallationState(plugin != null, status) } - override fun getPluginInstallationStates(pluginIds: List): Map { - return pluginIds.associateWith { pluginId -> + override fun getPluginInstallationStates(): Map { + return getAllInstalledPlugins().associateWith { pluginId -> return@associateWith getPluginInstallationState(pluginId) } } @@ -380,7 +402,7 @@ object DefaultUiPluginManagerController : UiPluginManagerController { setNewEnabled(descriptors, tempEnabled, action) val pluginIdMap: Map = buildPluginIdMap() - val contentModuleIdMap = getPluginSet().buildContentModuleIdMap() + val contentModuleIdMap = getPluginSet().buildContentModuleIdMap() val descriptorsToUpdate = if (action.isEnable) { getDependenciesToEnable(descriptors, tempEnabled, pluginIdMap, contentModuleIdMap) } @@ -432,7 +454,7 @@ object DefaultUiPluginManagerController : UiPluginManagerController { requiredPlugins.add(result) } } - return enableDependencies(session, requiredPlugins.toList(), PluginEnableDisableAction.ENABLE_GLOBALLY, + return enableDependencies(session, requiredPlugins.toList(), PluginEnableDisableAction.ENABLE_GLOBALLY, buildPluginIdMap(), getPluginSet().buildContentModuleIdMap()).pluginsIdsToSwitch } @@ -740,15 +762,15 @@ object DefaultUiPluginManagerController : UiPluginManagerController { LOG.warn("pending dynamic plugins probably won't finish their installation: " + session.dynamicPluginsToInstall + " " + session.dynamicPluginsToUninstall) } } - result.errors = getErrors(session, request.pluginId) + result.errors = getPlugins().map { it.pluginId }.associateWith { getErrors(session, it) } installCallback(result) } @Throws(ConfigurationException::class) - private fun assertCanApply( + private fun getApplyError( session: PluginManagerSession, pluginIdMap: Map, - ) { + ): @Nls String? { val descriptors = mutableListOf() for (entry in session.dependentToRequiredListMap.entries) { val pluginId: PluginId = entry.key @@ -772,15 +794,21 @@ object DefaultUiPluginManagerController : UiPluginManagerController { if (!descriptors.isEmpty()) { val pluginNames = MyPluginModel.getPluginNames(descriptors) - val message = IdeBundle.message("dialog.message.unable.to.apply.changes", pluginNames.size, MyPluginModel.joinPluginNamesOrIds(pluginNames)) - throw ConfigurationException(XmlStringUtil.wrapInHtml(message)).withHtmlMessage() + return IdeBundle.message("dialog.message.unable.to.apply.changes", pluginNames.size, MyPluginModel.joinPluginNamesOrIds(pluginNames)) } + return null } private fun getInstalledAndPendingPlugins(): List { return InstalledPluginsState.getInstance().installedPlugins + PluginManagerCore.plugins } + private fun getAllInstalledPlugins(): Set { + val installedPluginsState = InstalledPluginsState.getInstance() + val ids = installedPluginsState.installedPlugins.map { it.pluginId } + installedPluginsState.installedWithoutRestartPlugins + PluginManagerCore.plugins.map { it.pluginId } + return ids.toSet() + } + private fun isBundledUpdate(descriptor: IdeaPluginDescriptor?): Boolean { if (descriptor == null || descriptor.isBundled) { return false diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/InstallPluginInfo.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/InstallPluginInfo.java index ef3284ee007e..10ce78e06c3b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/InstallPluginInfo.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/InstallPluginInfo.java @@ -4,6 +4,7 @@ package com.intellij.ide.plugins.newui; import com.intellij.ide.IdeBundle; import com.intellij.ide.plugins.PluginManagerConfigurable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.progress.TaskInfo; import com.intellij.openapi.util.text.HtmlChunk; import com.intellij.openapi.wm.ex.StatusBarEx; @@ -11,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Map; /** * @author Alexander Lobas @@ -64,7 +66,7 @@ final class InstallPluginInfo { } public synchronized void finish(boolean success, boolean cancel, boolean showErrors, boolean restartRequired, - List errors) { + @NotNull Map> errors) { if (myClosed) { return; } @@ -80,7 +82,7 @@ final class InstallPluginInfo { } } else if (!cancel) { - myPluginModel.finishInstall(myDescriptor, myInstalledDescriptor, success, showErrors, restartRequired, errors); + myPluginModel.finishInstall(myDescriptor, myInstalledDescriptor, errors, success, showErrors, restartRequired); } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java b/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java index fe7f25f820ec..9c2beef24af8 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/MyPluginModel.java @@ -36,6 +36,7 @@ import com.intellij.platform.util.coroutines.CoroutineScopeKt; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.accessibility.AccessibleAnnouncerUtil; +import com.intellij.xml.util.XmlStringUtil; import kotlinx.coroutines.CoroutineScope; import kotlinx.coroutines.Dispatchers; import org.jetbrains.annotations.*; @@ -124,6 +125,10 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE */ public boolean apply(@Nullable JComponent parent) throws ConfigurationException { ApplyPluginsStateResult applyResult = UiPluginManager.getInstance().applySession(sessionId.toString(), parent, getProject()); + String error = applyResult.getError(); + if (error != null) { + throw new ConfigurationException(XmlStringUtil.wrapInHtml(error)).withHtmlMessage(); + } applyResult.getPluginsToEnable().forEach(id -> setEnabled(id, PluginEnabledState.ENABLED)); myUninstalled.clear(); updateButtons(); @@ -335,13 +340,12 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE indicator, MyPluginModel.this, result -> { - applyInstallResult(result, info); - callback.accept(result.getSuccess()); + applyInstallResult(result, info, callback); return null; }); } - private void applyInstallResult(InstallPluginResult result, InstallPluginInfo info) { + private void applyInstallResult(InstallPluginResult result, InstallPluginInfo info, Consumer callback) { PluginDto installedDescriptor = result.getInstalledDescriptor(); if (result.getSuccess()) { PluginUiModelKt.addInstalledSource(descriptor, controller.getTarget()); @@ -355,16 +359,17 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE myPluginManagerCustomizer.updateAfterModification(() -> { info.finish(result.getSuccess(), result.getCancel(), result.getShowErrors(), result.getRestartRequired(), getErrors(result)); + callback.accept(result.getSuccess()); return null; }); } else { info.finish(result.getSuccess(), result.getCancel(), result.getShowErrors(), result.getRestartRequired(), getErrors(result)); + callback.accept(result.getSuccess()); } } - private static @NotNull List getErrors(InstallPluginResult result) { - if (result.getErrors() == null) return Collections.emptyList(); + private static @NotNull Map> getErrors(InstallPluginResult result) { return MyPluginModel.getErrors(result.getErrors()); } @@ -463,10 +468,9 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE */ void finishInstall(@NotNull PluginUiModel descriptor, @Nullable PluginUiModel installedDescriptor, - boolean success, + @NotNull Map> errors, boolean success, boolean showErrors, - boolean restartRequired, - List errors) { + boolean restartRequired) { InstallPluginInfo info = finishInstall(descriptor); if (myInstallingWithUpdatesPlugins.isEmpty()) { @@ -475,6 +479,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE PluginId pluginId = descriptor.getPluginId(); List marketplaceComponents = myMarketplacePluginComponentMap.get(pluginId); + List errorList = errors.getOrDefault(pluginId, Collections.emptyList()); if (marketplaceComponents != null) { for (ListPluginComponent gridComponent : marketplaceComponents) { if (installedDescriptor != null) { @@ -482,7 +487,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE } gridComponent.hideProgress(success, restartRequired); if (gridComponent.myInstalledDescriptorForMarketplace != null) { - gridComponent.updateErrors(errors); + gridComponent.updateErrors(errorList); } } } @@ -493,7 +498,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE listComponent.setPluginModel(installedDescriptor); } listComponent.hideProgress(success, restartRequired); - listComponent.updateErrors(errors); + listComponent.updateErrors(errorList); } } for (PluginDetailsPageComponent panel : myDetailPanels) { @@ -516,8 +521,8 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE myInstalledPanel.doLayout(); } if (success) { - appendOrUpdateDescriptor(installedDescriptor != null ? installedDescriptor : descriptor, restartRequired, errors); - appendDependsAfterInstall(success, restartRequired); + appendOrUpdateDescriptor(installedDescriptor != null ? installedDescriptor : descriptor, restartRequired, errorList); + appendDependsAfterInstall(success, restartRequired, errors); if (installedDescriptor == null && descriptor.isFromMarketplace() && myDownloaded != null && myDownloaded.ui != null) { ListPluginComponent component = myDownloaded.ui.findComponent(descriptor.getPluginId()); if (component != null) { @@ -587,7 +592,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE static void addProgress(@NotNull IdeaPluginDescriptor descriptor, @NotNull ProgressIndicatorEx indicator) { InstallPluginInfo info = myInstallingInfos.get(descriptor.getPluginId()); - if(info == null) return; + if (info == null) return; info.indicator.addStateDelegate(indicator); } @@ -609,18 +614,17 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE myInstalling = installing; } - private void appendDependsAfterInstall(boolean success, boolean restartRequired) { + private void appendDependsAfterInstall(boolean success, boolean restartRequired, Map> errors) { if (myDownloaded == null || myDownloaded.ui == null) { return; } - Map errorCheckResult = UiPluginManager.getInstance().loadErrorsBlocking(sessionId.toString()); for (IdeaPluginDescriptor descriptor : InstalledPluginsState.getInstance().getInstalledPlugins()) { PluginId pluginId = descriptor.getPluginId(); if (myDownloaded.ui.findComponent(pluginId) != null) { continue; } - appendOrUpdateDescriptor(new PluginUiModelAdapter(descriptor), restartRequired, getErrors(errorCheckResult.get(pluginId))); + appendOrUpdateDescriptor(new PluginUiModelAdapter(descriptor), restartRequired, errors.get(pluginId)); String id = pluginId.getIdString(); @@ -964,7 +968,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE uninstallAndUpdateUi(descriptor, UiPluginManager.getInstance().getController()); } - public Map> getErrors(Map errorCheckResults) { + public static Map> getErrors(Map errorCheckResults) { return errorCheckResults.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, @@ -997,7 +1001,8 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE } return null; }); - } finally { + } + finally { for (PluginDetailsPageComponent panel : myDetailPanels) { if (panel.getDescriptorForActions() == descriptor) { panel.hideProgress(); @@ -1026,7 +1031,7 @@ public class MyPluginModel extends InstalledPluginsTableModel implements PluginE } } for (ListPluginComponent component : myInstalledPluginComponents) { - component.updateErrors(errors.get(component.getPluginModel().getPluginId())); + component.updateErrors(errors.getOrDefault(component.getPluginModel().getPluginId(), Collections.emptyList())); } for (List plugins : myMarketplacePluginComponentMap.values()) { for (ListPluginComponent plugin : plugins) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.kt index 7d7006ec6068..bc6c7da90035 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginDetailsPageComponent.kt @@ -545,6 +545,7 @@ class PluginDetailsPageComponent @JvmOverloads constructor( updateModel, modalityState) ?: return + } private fun updateAdditionalText() { @@ -1403,7 +1404,7 @@ class PluginDetailsPageComponent @JvmOverloads constructor( false, false, true, - Collections.emptyList()) + Collections.emptyMap()) } } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginManagerCustomizer.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginManagerCustomizer.kt index 47f8370163d2..f96ae5f85dea 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginManagerCustomizer.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginManagerCustomizer.kt @@ -45,7 +45,7 @@ interface PluginManagerCustomizer { @JvmStatic fun getInstance(): PluginManagerCustomizer? { if (Registry.`is`("reworked.plugin.manager.enabled")) { - return EP_NAME.extensionList.first() + return EP_NAME.extensionList.firstOrNull() } return null } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginModelFacade.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginModelFacade.kt index 44da093e5e14..07cc33c8fd6f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginModelFacade.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/PluginModelFacade.kt @@ -66,8 +66,8 @@ open class PluginModelFacade(private val pluginModel: MyPluginModel) { return pluginModel.isEnabled(model.getDescriptor()) } - fun finishInstall(model: PluginUiModel, installedModel: PluginUiModel?, success: Boolean, showErrors: Boolean, restartRequired: Boolean, errors: List) { - pluginModel.finishInstall(model, installedModel, success, showErrors, restartRequired, errors) + fun finishInstall(model: PluginUiModel, installedModel: PluginUiModel?, success: Boolean, showErrors: Boolean, restartRequired: Boolean, errors: Map>) { + pluginModel.finishInstall(model, installedModel, errors, success, showErrors, restartRequired) } fun isPluginRequiredForProject(model: PluginUiModel): Boolean { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManager.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManager.kt index b155cc97d46b..a30da92e6ada 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManager.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManager.kt @@ -4,6 +4,7 @@ package com.intellij.ide.plugins.newui import com.intellij.ide.plugins.marketplace.ApplyPluginsStateResult import com.intellij.ide.plugins.marketplace.CheckErrorsResult import com.intellij.ide.plugins.marketplace.IdeCompatibleUpdate +import com.intellij.ide.plugins.marketplace.InitSessionResult import com.intellij.ide.plugins.marketplace.IntellijPluginMetadata import com.intellij.ide.plugins.marketplace.PluginReviewComment import com.intellij.ide.plugins.marketplace.PluginSearchResult @@ -41,6 +42,10 @@ class UiPluginManager { getController().closeSession(uuid.toString()) } + fun initSession(uuid: UUID): InitSessionResult { + return getController().initSession(uuid.toString()) + } + fun executeMarketplaceQuery(query: String, count: Int, includeUpgradeToCommercialIde: Boolean): PluginSearchResult { return getController().executePluginsSearch(query, count, includeUpgradeToCommercialIde) } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManagerController.kt b/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManagerController.kt index d9713e7f587b..1ca7bc98208f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManagerController.kt +++ b/platform/platform-impl/src/com/intellij/ide/plugins/newui/UiPluginManagerController.kt @@ -6,6 +6,7 @@ import com.intellij.ide.plugins.PluginEnabler import com.intellij.ide.plugins.marketplace.ApplyPluginsStateResult import com.intellij.ide.plugins.marketplace.CheckErrorsResult import com.intellij.ide.plugins.marketplace.IdeCompatibleUpdate +import com.intellij.ide.plugins.marketplace.InitSessionResult import com.intellij.ide.plugins.marketplace.InstallPluginResult import com.intellij.ide.plugins.marketplace.IntellijPluginMetadata import com.intellij.ide.plugins.marketplace.PluginReviewComment @@ -28,6 +29,7 @@ interface UiPluginManagerController { fun getTarget(): PluginSource fun getPlugins(): List fun getVisiblePlugins(showImplementationDetails: Boolean): List + fun initSession(sessionId: String): InitSessionResult fun getInstalledPlugins(): List fun getUpdates(): List fun isPluginDisabled(pluginId: PluginId): Boolean @@ -64,8 +66,8 @@ interface UiPluginManagerController { fun filterPluginsRequiringUltimateButItsDisabled(pluginIds: List): List fun findPluginNames(pluginIds: List): List fun findPlugin(pluginId: PluginId): PluginUiModel? - fun getLastCompatiblePluginUpdateModel(pluginId: PluginId, buildNumber: String? = null, indicator: ProgressIndicator? = null): PluginUiModel? + fun getLastCompatiblePluginUpdateModel(pluginId: PluginId, buildNumber: String? = null, indicator: ProgressIndicator? = null): PluginUiModel? fun getLastCompatiblePluginUpdate(allIds: Set, throwExceptions: Boolean, buildNumber: String? = null): List fun updateDescriptorsForInstalledPlugins() fun isNeedUpdate(pluginId: PluginId): Boolean @@ -73,9 +75,10 @@ interface UiPluginManagerController { fun getAllPluginsTags(): Set fun getAllVendors(): Set fun getPluginInstallationState(pluginId: PluginId): PluginInstallationState - fun getPluginInstallationStates(pluginIds: List): Map + fun getPluginInstallationStates(): Map fun checkPluginCanBeDownloaded(pluginUiModel: PluginUiModel, progressIndicator: ProgressIndicator?): Boolean fun setPluginStatus(sessionId: String, pluginIds: List, enable: Boolean) + suspend fun loadErrors(sessionId: String): Map suspend fun resetSession(sessionId: String, removeSession: Boolean, parentComponent: JComponent? = null): Map diff --git a/platform/pluginManager/backend/src/com/intellij/platform/pluginManager/backend/rpc/BackendPluginManagerApi.kt b/platform/pluginManager/backend/src/com/intellij/platform/pluginManager/backend/rpc/BackendPluginManagerApi.kt index 2ffadf9ba432..5be8db62f289 100644 --- a/platform/pluginManager/backend/src/com/intellij/platform/pluginManager/backend/rpc/BackendPluginManagerApi.kt +++ b/platform/pluginManager/backend/src/com/intellij/platform/pluginManager/backend/rpc/BackendPluginManagerApi.kt @@ -9,6 +9,7 @@ import com.intellij.platform.pluginManager.shared.rpc.PluginManagerApi import com.intellij.ide.plugins.api.PluginDto import com.intellij.ide.plugins.marketplace.CheckErrorsResult import com.intellij.ide.plugins.marketplace.IdeCompatibleUpdate +import com.intellij.ide.plugins.marketplace.InitSessionResult import com.intellij.ide.plugins.marketplace.IntellijPluginMetadata import com.intellij.ide.plugins.marketplace.PluginReviewComment import com.intellij.ide.plugins.marketplace.PluginSearchResult @@ -84,8 +85,8 @@ class BackendPluginManagerApi : PluginManagerApi { return DefaultUiPluginManagerController.getPluginInstallationState(pluginId) } - override suspend fun getPluginInstallationStates(pluginIds: List): Map { - return DefaultUiPluginManagerController.getPluginInstallationStates(pluginIds) + override suspend fun getPluginInstallationStates(): Map { + return DefaultUiPluginManagerController.getPluginInstallationStates() } override suspend fun getCustomRepoPlugins(): List { @@ -209,4 +210,9 @@ class BackendPluginManagerApi : PluginManagerApi { override suspend fun loadErrors(sessionId: String): Map { return DefaultUiPluginManagerController.loadErrors(sessionId) } + + override suspend fun initSession(sessionId: String): InitSessionResult { + val initSessionResult = DefaultUiPluginManagerController.initSession(sessionId) + return InitSessionResult(initSessionResult.visiblePlugins.map { PluginDto.fromModel(it) }, initSessionResult.pluginStates) + } } \ No newline at end of file diff --git a/platform/pluginManager/frontend/src/com/intellij/platform/pluginManager/frontend/BackendUiPluginManagerController.kt b/platform/pluginManager/frontend/src/com/intellij/platform/pluginManager/frontend/BackendUiPluginManagerController.kt index e0fa3d825b46..5f7685086283 100644 --- a/platform/pluginManager/frontend/src/com/intellij/platform/pluginManager/frontend/BackendUiPluginManagerController.kt +++ b/platform/pluginManager/frontend/src/com/intellij/platform/pluginManager/frontend/BackendUiPluginManagerController.kt @@ -7,6 +7,7 @@ import com.intellij.ide.plugins.api.PluginDto import com.intellij.ide.plugins.marketplace.ApplyPluginsStateResult import com.intellij.ide.plugins.marketplace.CheckErrorsResult import com.intellij.ide.plugins.marketplace.IdeCompatibleUpdate +import com.intellij.ide.plugins.marketplace.InitSessionResult import com.intellij.ide.plugins.marketplace.InstallPluginResult import com.intellij.ide.plugins.marketplace.IntellijPluginMetadata import com.intellij.ide.plugins.marketplace.PluginReviewComment @@ -49,6 +50,10 @@ class BackendUiPluginManagerController() : UiPluginManagerController { return awaitForResult { PluginManagerApi.getInstance().getVisiblePlugins(showImplementationDetails).withSource() } } + override fun initSession(sessionId: String): InitSessionResult { + return awaitForResult { PluginManagerApi.getInstance().initSession(sessionId) } + } + override fun getInstalledPlugins(): List { return awaitForResult { PluginManagerApi.getInstance().getInstalledPlugins().withSource() } } @@ -111,8 +116,8 @@ class BackendUiPluginManagerController() : UiPluginManagerController { return awaitForResult { PluginManagerApi.getInstance().getPluginInstallationState(pluginId) } } - override fun getPluginInstallationStates(pluginIds: List): Map { - return awaitForResult { PluginManagerApi.getInstance().getPluginInstallationStates(pluginIds) } + override fun getPluginInstallationStates(): Map { + return awaitForResult { PluginManagerApi.getInstance().getPluginInstallationStates() } } override fun checkPluginCanBeDownloaded(pluginUiModel: PluginUiModel, progressIndicator: ProgressIndicator?): Boolean { diff --git a/platform/pluginManager/shared/src/com/intellij/platform/pluginManager/shared/rpc/PluginManagerApi.kt b/platform/pluginManager/shared/src/com/intellij/platform/pluginManager/shared/rpc/PluginManagerApi.kt index 2c76eb22f858..d2f272f04b54 100644 --- a/platform/pluginManager/shared/src/com/intellij/platform/pluginManager/shared/rpc/PluginManagerApi.kt +++ b/platform/pluginManager/shared/src/com/intellij/platform/pluginManager/shared/rpc/PluginManagerApi.kt @@ -5,6 +5,7 @@ import com.intellij.ide.plugins.marketplace.MarketplaceSearchPluginData import com.intellij.ide.plugins.api.PluginDto import com.intellij.ide.plugins.marketplace.CheckErrorsResult import com.intellij.ide.plugins.marketplace.IdeCompatibleUpdate +import com.intellij.ide.plugins.marketplace.InitSessionResult import com.intellij.ide.plugins.marketplace.IntellijPluginMetadata import com.intellij.ide.plugins.marketplace.IntellijUpdateMetadata import com.intellij.ide.plugins.marketplace.PluginReviewComment @@ -62,9 +63,10 @@ interface PluginManagerApi : RemoteApi { suspend fun disposeUpdaterService(sessionId: String) suspend fun notifyUpdateFinished(sessionId: String) suspend fun getPluginInstallationState(pluginId: PluginId): PluginInstallationState - suspend fun getPluginInstallationStates(pluginIds: List): Map + suspend fun getPluginInstallationStates(): Map suspend fun checkPluginCanBeDownloaded(plugin: PluginDto): Boolean suspend fun loadErrors(sessionId: String): Map + suspend fun initSession(sessionId: String): InitSessionResult companion object { suspend fun getInstance(): PluginManagerApi {