diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt index f5fd103defcd..3b763e3bdf5f 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt @@ -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 = jacksonObjectMapper().readValue( - configStream, + configContent, LinkedHashMap::class.java ) as LinkedHashMap diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt index cb3ed09021e2..ca7d39f1e42e 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt @@ -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 ) diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/Utils.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/Utils.kt index c7cd96d68512..6103ba188164 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/Utils.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/Utils.kt @@ -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 { diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearch.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearch.kt index 9d377ad65887..9b970acabd71 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearch.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearch.kt @@ -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)