mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
jdks - basic implementation of JDK downloading UI
IDEA-225308 GitOrigin-RevId: 5009e603e0aef7a1b9f0ab0949101963f3db4053
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ff5891846b
commit
7932f60c1a
@@ -68,6 +68,9 @@
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module" module-name="intellij.copyright" />
|
||||
<orderEntry type="library" name="jackson" level="project" />
|
||||
<orderEntry type="library" name="jackson-databind" level="project" />
|
||||
<orderEntry type="library" name="jackson-module-kotlin" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
@@ -289,6 +289,10 @@
|
||||
|
||||
<sdkType implementation="com.intellij.openapi.projectRoots.impl.JavaSdkImpl"/>
|
||||
|
||||
<applicationService serviceImplementation="com.intellij.openapi.projectRoots.impl.JDKDownloader"/>
|
||||
<registryKey key="jdk.downloader.ui" defaultValue="false" description="jdk.downloader.ui.description=Use the list of JDKs to download and install in one click"/>
|
||||
<registryKey key="jdk.downloader.url" description="Custom URL for JDKs list"/>
|
||||
|
||||
<applicationService serviceImplementation="com.intellij.openapi.module.WebModuleTypeRegistrar" preload="true"/>
|
||||
|
||||
<applicationService serviceImplementation="com.intellij.codeInsight.generation.SetterTemplatesManager"/>
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.projectRoots.impl
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.invokeLater
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.SdkModel
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.ui.components.dialog
|
||||
import com.intellij.ui.layout.*
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.io.HttpRequests
|
||||
import javax.swing.DefaultComboBoxModel
|
||||
import javax.swing.JComponent
|
||||
|
||||
class JDKDownloader {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(): JDKDownloader = ApplicationManager.getApplication().getService(JDKDownloader::class.java)
|
||||
|
||||
private val LOG = logger<JDKDownloader>()
|
||||
}
|
||||
|
||||
val isEnabled
|
||||
get() = Registry.`is`("jdk.downloader.ui")
|
||||
|
||||
lateinit var mock: JDKDownloadItem
|
||||
|
||||
fun showCustomCreateUI(sdkModel: SdkModel,
|
||||
parentComponent: JComponent,
|
||||
selectedSdk: Sdk?,
|
||||
sdkCreatedCallback: Consumer<Sdk>) {
|
||||
val project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent)) ?: return
|
||||
|
||||
ProgressManager.getInstance().run(object : Task.Modal(project, "Downloading JDK list...", true) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val model = downloadModel(progress = indicator)
|
||||
mock = model.items.first()
|
||||
|
||||
invokeLater {
|
||||
dialog(title = "Download JDK",
|
||||
parent = parentComponent,
|
||||
resizable = false,
|
||||
project = project,
|
||||
modality = DialogWrapper.IdeModalityType.PROJECT,
|
||||
panel = panel {
|
||||
row("Vendor:") {
|
||||
comboBox(
|
||||
model = DefaultComboBoxModel(model.items.toTypedArray()),
|
||||
prop = ::mock,
|
||||
renderer = listCellRenderer { value, _, _ -> text = "${value.vendor}: ${value.version}" }
|
||||
)
|
||||
}
|
||||
//row("Version") { comboBox() }
|
||||
row {
|
||||
right {
|
||||
button("Download", actionListener = {})
|
||||
}
|
||||
}
|
||||
row { }
|
||||
row("Path to JDK:") {
|
||||
textFieldWithBrowseButton("Select installation path for the JDK", project = project)
|
||||
}
|
||||
|
||||
}).show()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val om = ObjectMapper()
|
||||
|
||||
private val feedUrl: String
|
||||
get() {
|
||||
val registry = runCatching { Registry.get("jdk.downloader.url").asString() }.getOrNull()
|
||||
if (!registry.isNullOrBlank()) return registry
|
||||
|
||||
//let's use CDN URL in once it'd be established
|
||||
return "https://buildserver.labs.intellij.net/guestAuth/repository/download/ijplatform_master_Service_GenerateJDKsJson/lasest.lastSuccessful/feed.zip!/jdks.json"
|
||||
}
|
||||
|
||||
fun downloadModel(progress: ProgressIndicator?): JDKDownloadModel {
|
||||
//use HTTP caches here, in-memory only
|
||||
//note we use 3 copies of data here: String, JSON and Model (first two should GC)
|
||||
val rawData = HttpRequests.request(feedUrl).forceHttps(true).readString(progress)
|
||||
val tree = om.readTree(rawData) as? ObjectNode ?: error("Unexpected JSON data")
|
||||
val items = tree["jdks"] as? ArrayNode ?: error("`jdks` element is missing")
|
||||
|
||||
val expectedOS = when {
|
||||
SystemInfo.isWindows -> "windows"
|
||||
SystemInfo.isMac -> "mac"
|
||||
SystemInfo.isLinux -> "linux"
|
||||
else -> error("Unsupported OS")
|
||||
}
|
||||
|
||||
val result = mutableListOf<JDKDownloadItem>()
|
||||
for (item in items.filterIsInstance<ObjectNode>()) {
|
||||
val vendor = item["vendor"]?.asText() ?: continue
|
||||
val version = item["jdk_version"]?.asText() ?: continue
|
||||
val packages = item["packages"] as? ArrayNode ?: continue
|
||||
val pkg = packages.filterIsInstance<ObjectNode>().singleOrNull { it["os"]?.asText() == expectedOS } ?: continue
|
||||
val arch = pkg["arch"]?.asText() ?: continue
|
||||
val fileType = pkg["package"]?.asText() ?: continue
|
||||
val url = pkg["url"]?.asText() ?: continue
|
||||
val size = pkg["size"]?.asLong() ?: continue
|
||||
val sha256 = pkg["sha256"]?.asText() ?: continue
|
||||
|
||||
result += JDKDownloadItem(vendor = vendor,
|
||||
version = version,
|
||||
arch = arch,
|
||||
fileType = fileType,
|
||||
url = url,
|
||||
size = size,
|
||||
sha256 = sha256)
|
||||
}
|
||||
|
||||
return JDKDownloadModel(result)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class JDKDownloadModel(
|
||||
val items: List<JDKDownloadItem>
|
||||
)
|
||||
|
||||
data class JDKDownloadItem(
|
||||
val vendor: String,
|
||||
val version: String,
|
||||
val arch: String,
|
||||
val fileType: String,
|
||||
val url: String,
|
||||
val size: Long,
|
||||
val sha256: String
|
||||
)
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
@@ -587,4 +588,17 @@ public final class JavaSdkImpl extends JavaSdk {
|
||||
type == JavadocOrderRootType.getInstance() ||
|
||||
type == AnnotationOrderRootType.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsCustomCreateUI() {
|
||||
return JDKDownloader.getInstance().isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCustomCreateUI(@NotNull SdkModel sdkModel,
|
||||
@NotNull JComponent parentComponent,
|
||||
@Nullable Sdk selectedSdk,
|
||||
@NotNull Consumer<Sdk> sdkCreatedCallback) {
|
||||
JDKDownloader.getInstance().showCustomCreateUI(sdkModel, parentComponent, selectedSdk, sdkCreatedCallback);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.projectRoots.impl
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
|
||||
class JDKDownloaderTest {
|
||||
|
||||
@Test
|
||||
fun `model can be downloaded and parsed`() {
|
||||
val data = JDKDownloader().downloadModel(null)
|
||||
Assert.assertTrue(data.items.isNotEmpty())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user