From 69f8d95193dee676fba704d9b71c154610292bf9 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 10 Apr 2014 13:46:14 +0200 Subject: [PATCH] plugin updater: prefer plugins from hosts (IDEA-123350); ensure download progress is cancelable --- .../plugins/InstalledPluginsTableModel.java | 6 +-- .../ide/plugins/PluginHostsConfigurable.java | 4 +- .../intellij/ide/plugins/PluginInstaller.java | 12 ++--- .../ide/plugins/PluginManagerMain.java | 5 +- .../updateSettings/impl/PluginDownloader.java | 3 +- .../impl/PluginUpdateInfoDialog.java | 6 +-- .../updateSettings/impl/UpdateChecker.java | 52 +++++++++++-------- 7 files changed, 47 insertions(+), 41 deletions(-) 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 9ca9addc7da2..b41ce30f773f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsTableModel.java @@ -154,10 +154,10 @@ public class InstalledPluginsTableModel extends PluginTableModel { final JDOMExternalizableStringList pluginHosts = UpdateSettings.getInstance().myPluginHosts; for (String host : pluginHosts) { try { - final ArrayList downloaded = new ArrayList(); + final Map downloaded = new HashMap(); UpdateChecker.checkPluginsHost(host, downloaded, false, null); - for (PluginDownloader downloader : downloaded) { - myPlugin2host.put(downloader.getPluginId(), host); + for (PluginId pluginId : downloaded.keySet()) { + myPlugin2host.put(pluginId.getIdString(), host); } } catch (Exception ignored) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHostsConfigurable.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHostsConfigurable.java index 919c7bb173d6..686e6f9db79e 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginHostsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginHostsConfigurable.java @@ -16,6 +16,7 @@ package com.intellij.ide.plugins; import com.intellij.ide.IdeBundle; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.options.BaseConfigurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.progress.ProgressManager; @@ -42,6 +43,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; public class PluginHostsConfigurable extends BaseConfigurable { @@ -187,7 +189,7 @@ public class PluginHostsConfigurable extends BaseConfigurable { public void run() { try { result[0] = - UpdateChecker.checkPluginsHost(correctRepositoryRule(getTextField().getText()), new ArrayList()); + UpdateChecker.checkPluginsHost(correctRepositoryRule(getTextField().getText()), new HashMap(), true, ProgressManager.getInstance().getProgressIndicator()); } catch (Exception e1) { ex[0] = e1; diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java index 2dfc3eb6c7a9..3f5e43ce21cf 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java @@ -26,13 +26,14 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.updateSettings.impl.PluginDownloader; import com.intellij.openapi.updateSettings.impl.UpdateChecker; -import com.intellij.openapi.util.Comparing; import com.intellij.ui.GuiUtils; import com.intellij.util.ArrayUtil; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author stathik @@ -162,16 +163,11 @@ public class PluginInstaller { final String repositoryName = pluginNode.getRepositoryName(); if (repositoryName != null) { try { - final List downloaders = new ArrayList(); + final Map downloaders = new HashMap(); if (!UpdateChecker.checkPluginsHost(repositoryName, downloaders)) { return false; } - for (PluginDownloader pluginDownloader : downloaders) { - if (Comparing.strEqual(pluginDownloader.getPluginId(), pluginNode.getPluginId().getIdString())) { - downloader = pluginDownloader; - break; - } - } + downloader = downloaders.get(pluginNode.getPluginId()); if (downloader == null) return false; } catch (Exception e) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index 8b491d9efad6..bce1a97ccdae 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -32,6 +32,7 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; @@ -315,10 +316,10 @@ public abstract class PluginManagerMain implements Disposable { } for (String host : UpdateSettings.getInstance().myPluginHosts) { if (!acceptHost(host)) continue; - final ArrayList downloaded = new ArrayList(); + final Map downloaded = new HashMap(); try { UpdateChecker.checkPluginsHost(host, downloaded, false, null); - for (PluginDownloader downloader : downloaded) { + for (PluginDownloader downloader : downloaded.values()) { final PluginNode pluginNode = PluginDownloader.createPluginNode(host, downloader); if (pluginNode != null) { if (list == null) list = new ArrayList(); diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java index 1c57424a2141..bdc23622a66b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java @@ -43,7 +43,6 @@ import org.jetbrains.annotations.Nullable; import java.io.*; import java.net.HttpURLConnection; -import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.util.List; @@ -84,6 +83,8 @@ public class PluginDownloader { myPluginName = pluginName; } + @SuppressWarnings("UnusedDeclaration") + @Deprecated public boolean prepareToInstall() throws IOException { return prepareToInstall(new ProgressIndicatorBase()); } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java index 60a8c8ea6337..d1eeff5fe3d0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java @@ -23,15 +23,15 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.List; +import java.util.Collection; /** * @author pti */ class PluginUpdateInfoDialog extends AbstractUpdateDialog { - private final List myUploadedPlugins; + private final Collection myUploadedPlugins; - protected PluginUpdateInfoDialog(@NotNull List updatePlugins, boolean enableLink) { + protected PluginUpdateInfoDialog(@NotNull Collection updatePlugins, boolean enableLink) { super(enableLink); myUploadedPlugins = updatePlugins; init(); diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index 10898f5cf01e..03a6a5308ced 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -166,7 +166,7 @@ public final class UpdateChecker { } boolean platformUpdate = newChannelReady(result.getChannelToPropose()) || result.getUpdatedChannel() != null; - final List updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, project, hostsConfigurable, indicator); + final Collection updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, project, hostsConfigurable, indicator); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override @@ -179,11 +179,11 @@ public final class UpdateChecker { }); } - private static List updatePlugins(boolean manualCheck, - @Nullable Project project, - @Nullable PluginHostsConfigurable hostsConfigurable, - @Nullable ProgressIndicator indicator) { - final List downloaded = new ArrayList(); + private static Collection updatePlugins(boolean manualCheck, + @Nullable Project project, + @Nullable PluginHostsConfigurable hostsConfigurable, + @Nullable ProgressIndicator indicator) { + final Map downloaded = new HashMap(); final Set failed = new HashSet(); for (String host : getPluginHosts(hostsConfigurable)) { try { @@ -206,8 +206,8 @@ public final class UpdateChecker { } } - for (Iterator iterator = downloaded.iterator(); iterator.hasNext(); ) { - if (!toUpdate.containsKey(iterator.next().getPluginId())) { + for (Iterator iterator = downloaded.keySet().iterator(); iterator.hasNext(); ) { + if (!toUpdate.containsKey(iterator.next().getIdString())) { iterator.remove(); } } @@ -237,11 +237,11 @@ public final class UpdateChecker { if (!toUpdate.containsKey(idString)) continue; final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString); if (installedPlugin == null) { - prepareToInstall(downloaded, loadedPlugin); + prepareToInstall(downloaded, loadedPlugin, indicator); } else if (StringUtil.compareVersionNumbers(loadedPlugin.getVersion(), installedPlugin.getVersion()) > 0) { updateSettings.myOutdatedPlugins.add(idString); if (!disabledPlugins.contains(idString)) { - prepareToInstall(downloaded, loadedPlugin); + prepareToInstall(downloaded, loadedPlugin, indicator); } } } @@ -258,13 +258,19 @@ public final class UpdateChecker { showErrorMessage(manualCheck, project, IdeBundle.message("updates.error.plugin.description.failed", StringUtil.join(failed, ","))); } - return downloaded.isEmpty() ? null : downloaded; + return downloaded.isEmpty() ? null : downloaded.values(); } - private static void prepareToInstall(List downloaded, IdeaPluginDescriptor loadedPlugin) throws IOException { - final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin); - if (downloader.prepareToInstall()) { - downloaded.add(downloader); + private static void prepareToInstall(Map downloaded, + IdeaPluginDescriptor loadedPlugin, + ProgressIndicator indicator) throws IOException { + final PluginId pluginId = loadedPlugin.getPluginId(); + //prefer plugins from plugin hosts + if (!downloaded.containsKey(pluginId)) { + final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin); + if (downloader.prepareToInstall(indicator)) { + downloaded.put(pluginId, downloader); + } } } @@ -297,7 +303,7 @@ public final class UpdateChecker { return hosts; } - public static boolean checkPluginsHost(final String host, final List downloaded) throws Exception { + public static boolean checkPluginsHost(final String host, final Map downloaded) throws Exception { try { return checkPluginsHost(host, downloaded, true, null); } @@ -307,7 +313,7 @@ public final class UpdateChecker { } public static boolean checkPluginsHost(final String host, - final List downloaded, + final Map downloaded, final boolean collectToUpdate, @Nullable ProgressIndicator indicator) throws Exception { InputStream inputStream = loadVersionInfo(host); if (inputStream == null) return false; @@ -324,7 +330,7 @@ public final class UpdateChecker { final List descriptors = RepositoryHelper.loadPluginsFromDescription(inputStream, indicator); for (IdeaPluginDescriptor descriptor : descriptors) { ((PluginNode)descriptor).setRepositoryName(host); - downloaded.add(PluginDownloader.createDownloader(descriptor)); + downloaded.put(descriptor.getPluginId(), PluginDownloader.createDownloader(descriptor)); } boolean success = true; @@ -372,8 +378,8 @@ public final class UpdateChecker { progressIndicator.setText2(finalPluginUrl); } final PluginDownloader downloader = new PluginDownloader(pluginId, finalPluginUrl, pluginVersion); - if (downloader.prepareToInstall()) { - downloaded.add(downloader); + if (downloader.prepareToInstall(progressIndicator)) { + downloaded.put(PluginId.getId(pluginId), downloader); } } catch (IOException e) { @@ -392,7 +398,7 @@ public final class UpdateChecker { final PluginDownloader downloader = new PluginDownloader(pluginId, pluginUrl, pluginVersion); downloader.setDescription(description); downloader.setDepends(dependsPlugins); - downloaded.add(downloader); + downloaded.put(PluginId.getId(pluginId), downloader); } } return success; @@ -447,7 +453,7 @@ public final class UpdateChecker { @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") private static void showUpdateResult(@Nullable final Project project, final CheckForUpdateResult checkForUpdateResult, - final List updatedPlugins, + final Collection updatedPlugins, final boolean enableLink, final boolean alwaysShowResults) { final UpdateChannel channelToPropose = checkForUpdateResult.getChannelToPropose(); @@ -649,7 +655,7 @@ public final class UpdateChecker { return ""; } - public static boolean install(List downloaders) { + public static boolean install(Collection downloaders) { boolean installed = false; for (PluginDownloader downloader : downloaders) { if (getDisabledToUpdatePlugins().contains(downloader.getPluginId())) continue;