Move resource reading and fallback to the dedicated utility method

(cherry picked from commit 02de810b56bb9792373f41c5773f19d5dd10a8b4)

IJ-MR-176799

GitOrigin-RevId: 49e71502751ff85910b804b46d20a4ac43f855a1
This commit is contained in:
Egor Malyshev
2025-10-21 21:01:55 +00:00
committed by intellij-monorepo-bot
parent e7325cf896
commit 4f45ffbbaf
4 changed files with 59 additions and 49 deletions
@@ -43,7 +43,7 @@ class HelpContentRequestHandler : HelpRequestHandlerBase() {
val response = DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.PERMANENT_REDIRECT)
var location = "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}/help/${
var location = "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}${getRequestLocalePath(request)}/help/${
map.getUrlForId(
name
)
@@ -61,16 +61,16 @@ class HelpContentRequestHandler : HelpRequestHandlerBase() {
}
}
val locale = getRequestLocalePath(request)
when (val resourceName: String = urlDecoder.path().substringAfterLast("/")) {
"config.json" -> {
val configStream = ResourceUtil.getResourceAsStream(
HelpContentRequestHandler::class.java.classLoader,
"topics", "config.json"
)
val configContent = Utils.getResourceWithFallback("topics", resourceName, locale)
@Suppress("UNCHECKED_CAST")
val configJson: LinkedHashMap<String, Any> = jacksonObjectMapper().readValue(
configStream,
configContent,
LinkedHashMap::class.java
) as LinkedHashMap<String, Any>
@@ -1,14 +1,12 @@
// Copyright 2000-2020 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.jetbrains.builtInHelp
import com.intellij.util.ResourceUtil
import io.netty.channel.Channel
import io.netty.handler.codec.http.FullHttpRequest
import io.netty.handler.codec.http.HttpHeaders
import io.netty.handler.codec.http.HttpRequest
import org.jetbrains.annotations.NonNls
import org.jetbrains.ide.HttpRequestHandler
import java.io.IOException
import kotlin.io.path.Path
import kotlin.io.path.extension
import kotlin.io.path.nameWithoutExtension
@@ -51,33 +49,10 @@ abstract class HelpRequestHandlerBase : HttpRequestHandler() {
else -> resourceName
}
val resStream = ResourceUtil.getResourceAsStream(
HelpRequestHandlerBase::class.java.classLoader,
if (isImage) "images" else "${getRequestLocalePath(request)}/topics", retrieveName
)
//First, try to deliver a topic from the selected locale and fallback to en-us when needed
val contentToSend = resStream.use { res ->
try {
res.readAllBytes()
}
catch (e: IOException) {
LOG.warn(e)
//Because of space concerns, images are only shipped for en-us anyway and stored under /images
if (!isImage) {
ResourceUtil.getResourceAsStream(
HelpRequestHandlerBase::class.java.classLoader,
"topics", retrieveName
).use { res ->
res.readAllBytes()
}
}
else null
}
}
val content = Utils.getResourceWithFallback(if (isImage) "images" else "topics",
retrieveName, getRequestLocalePath(request))
return sendData(
contentToSend ?: throw Exception("$resourceName not found in $resourceLocation via ${request.uri()}"), resourceName,
content ?: throw Exception("$resourceName not found in $resourceLocation via ${request.uri()}"), resourceName,
request, channel,
extraHeaders
)
@@ -5,18 +5,51 @@ import com.intellij.credentialStore.CredentialAttributes
import com.intellij.credentialStore.Credentials
import com.intellij.ide.passwordSafe.PasswordSafe
import com.intellij.ide.util.PropertiesComponent
import com.intellij.util.ResourceUtil
import com.jetbrains.builtInHelp.settings.SettingsPage
import org.jetbrains.annotations.NonNls
import java.io.IOException
class Utils {
companion object {
@NonNls
private const val EMPTY_STRING = ""
@NonNls
const val BASE_HELP_URL: String = "https://www.jetbrains.com/"
private val secureKey = CredentialAttributes("Web Help Bundle")
fun getResourceWithFallback(resPath: String, resName: String, localePath: String): ByteArray? {
val resStream = ResourceUtil.getResourceAsStream(
HelpRequestHandlerBase::class.java.classLoader,
"${if (localePath.isNotEmpty()) "$localePath/" else ""}$resPath", resName
)
return resStream.use { res ->
try {
res.readAllBytes()
}
catch (e: IOException) {
LOG.warn(e)
//So we couldn't find any localized resource, try the default English one
ResourceUtil.getResourceAsStream(
HelpRequestHandlerBase::class.java.classLoader,
resPath, resName
).use { res ->
try {
res.readAllBytes()
}
catch (e: IOException) {
null
}
}
}
}
}
@JvmStatic
@NonNls
fun getStoredValue(key: SettingsPage.SettingKey, default: String): String {
@@ -5,8 +5,8 @@ package com.jetbrains.builtInHelp.search
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.ResourceUtil
import com.intellij.util.io.safeOutputStream
import com.jetbrains.builtInHelp.Utils
import org.apache.lucene.analysis.standard.StandardAnalyzer
import org.apache.lucene.index.DirectoryReader
import org.apache.lucene.queryparser.simple.SimpleQueryParser
@@ -19,6 +19,7 @@ import org.apache.lucene.store.NIOFSDirectory
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.NotNull
import java.io.BufferedReader
import java.io.ByteArrayInputStream
import java.io.InputStreamReader
import java.nio.file.Files
import java.nio.file.Path
@@ -48,22 +49,23 @@ class HelpSearch {
val indexDirPath = indexDir.toAbsolutePath().toString()
Files.createDirectories(indexDir)
//Read required names from rlist and then load resources based off of them
ResourceUtil.getResourceAsStream(HelpSearch::class.java.classLoader, "${locale}/search", "rlist")
.use { resourceList ->
BufferedReader(InputStreamReader(resourceList)).useLines { lines ->
lines.forEach { line ->
val path = Paths.get(indexDirPath, line)
ResourceUtil.getResourceAsStream(HelpSearch::class.java.classLoader,
"$locale/search", line)
?.use { resourceStream ->
path.safeOutputStream().use { resourceOutput ->
resourceOutput.write(resourceStream.readAllBytes())
}
}
}
//Read required names from the rlist file and then load resources based off of them
val searchList = Utils.getResourceWithFallback("search", "rlist", locale)
?: return NOT_FOUND
BufferedReader(InputStreamReader(ByteArrayInputStream(searchList))).useLines { lines ->
lines.forEach { line ->
val path = Paths.get(indexDirPath, line)
val dataToDeploy = Utils.getResourceWithFallback("search", line, locale)
?: return@forEach
path.safeOutputStream().use { resourceOutput ->
resourceOutput.write(dataToDeploy)
}
}
}
indexDirectory = NIOFSDirectory(indexDir)
reader = DirectoryReader.open(indexDirectory)