diff --git a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java index df37787719e1..40810097762d 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java +++ b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationInfoEx.java @@ -73,6 +73,8 @@ public abstract class ApplicationInfoEx extends ApplicationInfo { public abstract String getPluginsListUrl(); + public abstract String getChannelsListUrl(); + public abstract String getPluginsDownloadUrl(); public abstract String getBuiltinPluginsUrl(); diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java index dde556ddeee8..d42d26f24198 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -88,6 +88,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern private String myReleaseFeedbackUrl; private String myPluginManagerUrl; private String myPluginsListUrl; + private String myChannelsListUrl; private String myPluginsDownloadUrl; private String myBuiltinPluginsUrl; private String myWhatsNewUrl; @@ -162,6 +163,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern private static final String ATTRIBUTE_EAP_URL = "eap-url"; private static final String ELEMENT_PLUGINS = "plugins"; private static final String ATTRIBUTE_LIST_URL = "list-url"; + private static final String ATTRIBUTE_CHANNEL_LIST_URL = "channel-list-url"; private static final String ATTRIBUTE_DOWNLOAD_URL = "download-url"; private static final String ATTRIBUTE_BUILTIN_URL = "builtin-url"; private static final String ATTRIBUTE_WEBHELP_URL = "webhelp-url"; @@ -414,6 +416,11 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern return myPluginsListUrl; } + @Override + public String getChannelsListUrl() { + return myChannelsListUrl; + } + @Override public String getPluginsDownloadUrl() { return myPluginsDownloadUrl; @@ -733,6 +740,9 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern String listUrl = pluginsElement.getAttributeValue(ATTRIBUTE_LIST_URL); myPluginsListUrl = listUrl != null ? listUrl : myPluginManagerUrl + (closed ? "" : "/") + "plugins/list/"; + String channelListUrl = pluginsElement.getAttributeValue(ATTRIBUTE_CHANNEL_LIST_URL); + myChannelsListUrl = channelListUrl != null ? channelListUrl : myPluginManagerUrl + (closed ? "" : "/") + "channels/list/"; + String downloadUrl = pluginsElement.getAttributeValue(ATTRIBUTE_DOWNLOAD_URL); myPluginsDownloadUrl = downloadUrl != null ? downloadUrl : myPluginManagerUrl + (closed ? "" : "/") + "pluginManager/"; @@ -743,12 +753,14 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern else { myPluginManagerUrl = DEFAULT_PLUGINS_HOST; myPluginsListUrl = DEFAULT_PLUGINS_HOST + "/plugins/list/"; + myChannelsListUrl = DEFAULT_PLUGINS_HOST + "/channels/list/"; myPluginsDownloadUrl = DEFAULT_PLUGINS_HOST + "/pluginManager/"; } final String pluginsHost = System.getProperty("idea.plugins.host"); if (pluginsHost != null) { myPluginsListUrl = myPluginsListUrl.replace(DEFAULT_PLUGINS_HOST, pluginsHost); + myChannelsListUrl = myChannelsListUrl.replace(DEFAULT_PLUGINS_HOST, pluginsHost); myPluginsDownloadUrl = myPluginsDownloadUrl.replace(DEFAULT_PLUGINS_HOST, pluginsHost); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java index a9538321b4f2..aaae9d0ee292 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java @@ -23,18 +23,24 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.openapi.util.BuildNumber; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.io.HttpRequests; import com.intellij.util.io.RequestBuilder; import com.intellij.util.io.URLUtil; import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.io.JsonReaderEx; +import org.jetbrains.io.JsonUtil; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -104,9 +110,66 @@ public class RepositoryHelper { return loadPlugins(repositoryUrl, buildnumber, forceHttps, indicator); } + @NotNull + public static List loadPlugins(@Nullable final String repositoryUrl, + @Nullable BuildNumber buildnumber, + boolean forceHttps, + @Nullable final ProgressIndicator indicator) throws IOException { + List plugins = loadPlugins(repositoryUrl, buildnumber, null, forceHttps, indicator); + + Map>> pluginsFromChannels = loadPluginsFromChannels(buildnumber, indicator); + + return plugins; + } + + @NotNull + public static Map>> loadPluginsFromChannels(@Nullable BuildNumber buildnumber, + @Nullable final ProgressIndicator indicator) + throws IOException { + Map>> result = new LinkedHashMap>>(); + + String url; + try { + URIBuilder uriBuilder = new URIBuilder(ApplicationInfoImpl.getShadowInstance().getChannelsListUrl()); + uriBuilder.addParameter("build", + (buildnumber != null ? buildnumber.asString() : ApplicationInfoImpl.getShadowInstance().getApiVersion())); + url = uriBuilder.build().toString(); + } + catch (URISyntaxException e) { + throw new IOException(e); + } + + boolean forceHttps = IdeaApplication.isLoaded() && UpdateSettings.getInstance().canUseSecureConnection(); + List channelList = + HttpRequests.request(url).forceHttps(forceHttps).connect(new HttpRequests.RequestProcessor>() { + @Override + public List process(@NotNull HttpRequests.Request request) throws IOException { + //{"channels":["alpha","eap","ideadev","nightly"]} + return (List)JsonUtil.nextObject(new JsonReaderEx(request.getReader().readLine())).get("channels"); + } + }); + + + for (String channel : channelList) { + List channelPlugins = loadPlugins(null, buildnumber, channel, forceHttps, indicator); + for (IdeaPluginDescriptor plugin : channelPlugins) { + PluginId pluginId = plugin.getPluginId(); + List> pluginChannelDescriptors = result.get(pluginId); + if (pluginChannelDescriptors == null) { + pluginChannelDescriptors = new SmartList>(); + result.put(pluginId, pluginChannelDescriptors); + } + pluginChannelDescriptors.add(Pair.create(channel, plugin)); + } + } + + return result; + } + @NotNull public static List loadPlugins(@Nullable String repositoryUrl, @Nullable BuildNumber buildnumber, + @Nullable String channel, boolean forceHttps, @Nullable final ProgressIndicator indicator) throws IOException { final String url; @@ -117,7 +180,7 @@ public class RepositoryHelper { URIBuilder uriBuilder; if (repositoryUrl == null) { uriBuilder = new URIBuilder(ApplicationInfoImpl.getShadowInstance().getPluginsListUrl()); - pluginListFile = new File(PathManager.getPluginsPath(), PLUGIN_LIST_FILE); + pluginListFile = new File(PathManager.getPluginsPath(), channel == null ? PLUGIN_LIST_FILE : channel + "_" + PLUGIN_LIST_FILE); if (pluginListFile.length() > 0) { uriBuilder.addParameter("crc32", Files.hash(pluginListFile, Hashing.crc32()).toString()); } @@ -128,7 +191,9 @@ public class RepositoryHelper { } if (!URLUtil.FILE_PROTOCOL.equals(uriBuilder.getScheme())) { - uriBuilder.addParameter("build", (buildnumber != null ? buildnumber.asString() : ApplicationInfoImpl.getShadowInstance().getApiVersion())); + uriBuilder.addParameter("build", + (buildnumber != null ? buildnumber.asString() : ApplicationInfoImpl.getShadowInstance().getApiVersion())); + if (channel != null) uriBuilder.addParameter("channel", channel); } host = uriBuilder.getHost();