diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/BuiltInHelpPlugin.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/BuiltInHelpPlugin.kt index 9e0dc8f80fc7..9cfd19293229 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/impl/BuiltInHelpPlugin.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/impl/BuiltInHelpPlugin.kt @@ -13,6 +13,7 @@ import java.nio.file.Files import java.nio.file.Path private const val MODULE_NAME = "intellij.platform.builtInHelp" +private val LUCENE_LIBRARIES = setOf("lucene-queryparser", "lucene-highlighter", "lucene-memory") internal fun buildHelpPlugin(pluginVersion: String, context: BuildContext): PluginLayout? { val productName = context.applicationInfo.productName @@ -46,6 +47,7 @@ internal fun buildHelpPlugin(pluginVersion: String, context: BuildContext): Plug content = pluginXml(buildContext, pluginVersion), overwrite = true) } + LUCENE_LIBRARIES.forEach { spec.withProjectLibrary(it) } } } @@ -82,7 +84,7 @@ private suspend fun buildResourcesForHelpPlugin(resourceRoot: Path, classPath: L spanBuilder("index help topics").useWithScope { runIdea(context = context, mainClass = "com.jetbrains.builtInHelp.indexer.HelpIndexer", args = listOf(resourceRoot.resolve("search").toString(), - resourceRoot.resolve("topics").toString()), + resourceRoot.resolve("topics").toString()), jvmArgs = emptyList(), classPath = classPath) diff --git a/plugins/built-in-help/intellij.platform.builtInHelp.iml b/plugins/built-in-help/intellij.platform.builtInHelp.iml index 93c31cdda4eb..109252c9b495 100644 --- a/plugins/built-in-help/intellij.platform.builtInHelp.iml +++ b/plugins/built-in-help/intellij.platform.builtInHelp.iml @@ -19,7 +19,6 @@ - @@ -31,5 +30,9 @@ + + + + \ No newline at end of file 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 82983060dce9..b759a61cbf7a 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpContentRequestHandler.kt @@ -1,58 +1,104 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.builtInHelp +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.openapi.util.text.StringUtil +import com.intellij.util.ResourceUtil import com.jetbrains.builtInHelp.mapping.HelpMap import com.jetbrains.builtInHelp.mapping.HelpMapId import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.http.* import org.jetbrains.builtInWebServer.BuiltInServerOptions -import org.jetbrains.io.addCommonHeaders import org.jetbrains.io.send import javax.xml.bind.JAXBContext @Suppress("unused") class HelpContentRequestHandler : HelpRequestHandlerBase() { - override fun process(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): Boolean { - if (request.uri().contains("config.json")) { + private val propsToRemove = listOf( + "searchAlgoliaApiKey", "searchAlgoliaId", + "searchAlgoliaIndexName", "versionsService" + ) - val config = HelpRequestHandlerBase::class.java.getResource("/topics/config.json") - .openStream().bufferedReader().use { it.readText() }.replace("https://data.services.jetbrains.com", - "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}").replace( - "true", "false") + override fun process( + urlDecoder: QueryStringDecoder, + request: FullHttpRequest, + context: ChannelHandlerContext + ): Boolean { + for (name: String in urlDecoder.parameters().keys) { + val param = urlDecoder.parameters()[name] + if (param != null && (param.isEmpty() || StringUtil.isEmpty(param[0]))) { + val mapStream = ResourceUtil.getResourceAsStream( + HelpContentRequestHandler::class.java.classLoader, + "topics", "Map.jhm" + ) + val map: HelpMap = JAXBContext.newInstance( + HelpMap::class.java, HelpMapId::class.java + ).createUnmarshaller().unmarshal( + mapStream + ) as HelpMap - sendData(config.toByteArray(Charsets.UTF_8), "config.json", request, context.channel(), request.headers()) - return true + val response = DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.TEMPORARY_REDIRECT) + response.headers().add( + "Location", + "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}/help/${ + map.getUrlForId( + name + ) + }" + ) + context.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE) + return true + } } - if (urlDecoder.parameters().isNotEmpty()) { - for (name: String in urlDecoder.parameters().keys) { - val param = urlDecoder.parameters()[name] - if (param != null && (param.isEmpty() || StringUtil.isEmpty(param[0]))) { - val map: HelpMap = JAXBContext.newInstance( - HelpMap::class.java, HelpMapId::class.java).createUnmarshaller().unmarshal( - HelpRequestHandlerBase::class.java.getResource("/topics/Map.jhm")) as HelpMap - val response = DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FOUND) - response.addCommonHeaders() - response.headers().add("Location", prefix + map.getUrlForId(name)) - context.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE) - return true + when (val resourceName: String = urlDecoder.path().substringAfterLast("/")) { + "config.json" -> { + val configStream = ResourceUtil.getResourceAsStream( + HelpContentRequestHandler::class.java.classLoader, + "topics", "config.json" + ) + + @Suppress("UNCHECKED_CAST") + val configJson: LinkedHashMap = jacksonObjectMapper().readValue( + configStream, + LinkedHashMap::class.java + ) as LinkedHashMap + + configJson.keys.removeAll { propsToRemove.contains(it) } + + configJson.keys.forEach { + if (configJson[it] is String) { + val current: String = configJson[it] as String + configJson[it] = current.replace( + "https://data.services.jetbrains.com", + "http://127.0.0.1:${BuiltInServerOptions.getInstance().effectiveBuiltInServerPort}" + ).replace( + "true", "false" + ) + } + } + sendData( + jacksonObjectMapper().writeValueAsBytes(configJson), + "config.json", + request, + context.channel(), + request.headers() + ) + } + else -> { + try { + sendResource( + resourceName, urlDecoder.path().substringBeforeLast("/"), + request, context.channel(), request.headers() + ) + } + catch (e: Throwable) { + HttpResponseStatus.NOT_FOUND.send(context.channel(), request, e.message) } } } - val resName: String = urlDecoder.path().substring(request.uri().lastIndexOf("/") + 1) - - if (StringUtil.isNotEmpty(resName)) { - try { - sendResource(resName, request, context.channel(), request.headers()) - return true - } - catch (e: Exception) { - HttpResponseStatus.NOT_FOUND.send(context.channel(), request) - } - } - return false + return true } } \ No newline at end of file diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpProcessingRequestBase.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpProcessingRequestBase.kt index 17d92ee9faef..44a150ddd5c2 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpProcessingRequestBase.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpProcessingRequestBase.kt @@ -1,4 +1,4 @@ -// 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. +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.builtInHelp import io.netty.channel.ChannelHandlerContext @@ -6,8 +6,6 @@ import io.netty.handler.codec.http.FullHttpRequest import io.netty.handler.codec.http.QueryStringDecoder abstract class HelpProcessingRequestBase : HelpRequestHandlerBase() { - abstract override val prefix: String - override fun process(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): Boolean { val num: String? = urlDecoder.parameters()["num"]?.get(0) @@ -15,7 +13,6 @@ abstract class HelpProcessingRequestBase : HelpRequestHandlerBase() { val dataToSend = getProcessedData(urlDecoder.parameters()["q"]?.get(0)!!, if (num != null) Integer.valueOf(num) else 100).toByteArray(Charsets.UTF_8) - sendData(dataToSend, "data.json", request, context.channel(), request.headers()) return true } 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 2b0397975c84..69741367a5ac 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpRequestHandlerBase.kt @@ -1,13 +1,14 @@ // 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.apache.commons.compress.utils.IOUtils -import org.jetbrains.ide.HttpRequestHandler +import org.apache.commons.compress.utils.FileNameUtils import org.jetbrains.annotations.NonNls +import org.jetbrains.ide.HttpRequestHandler /** * Created by Egor.Malyshev on 7/13/2017. @@ -17,12 +18,33 @@ abstract class HelpRequestHandlerBase : HttpRequestHandler() { open val prefix: String = "/help/" override fun isAccessible(request: HttpRequest): Boolean { - return super.isAccessible(request) && request.uri().startsWith(prefix) + return super.isAccessible(request) && request.uri().contains(prefix) } - protected fun sendResource(resourceName: String, request: FullHttpRequest, channel: Channel, extraHeaders: HttpHeaders): Boolean { - return sendData(IOUtils.toByteArray(HelpRequestHandlerBase::class.java.getResourceAsStream( - (if (request.uri().contains("/img/")) "/images/" else "/topics/") + resourceName) ?: throw Exception("$resourceName not found")), - resourceName, request, channel, extraHeaders) + protected fun sendResource( + resourceName: String, + resourceLocation: String, + request: FullHttpRequest, + channel: Channel, + extraHeaders: HttpHeaders + ): Boolean { + + val isImage = resourceLocation.contains("/img/") + val retrieveName = when (isImage) { + true -> { + val baseName = FileNameUtils.getBaseName(resourceName) + """${baseName.substringBeforeLast("_dark")}.${FileNameUtils.getExtension(resourceName)}""" + } + else -> resourceName + } + val resStream = ResourceUtil.getResourceAsStream( + HelpRequestHandlerBase::class.java.classLoader, + if (isImage) "images" else "topics", retrieveName + ) + return sendData( + resStream?.readAllBytes() ?: 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/HelpSearchRequestHandler.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpSearchRequestHandler.kt index 7fe9b9befcf4..3a8266ae2a16 100644 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpSearchRequestHandler.kt +++ b/plugins/built-in-help/src/com/jetbrains/builtInHelp/HelpSearchRequestHandler.kt @@ -2,14 +2,26 @@ package com.jetbrains.builtInHelp import com.jetbrains.builtInHelp.search.HelpSearch +import io.netty.channel.ChannelHandlerContext +import io.netty.handler.codec.http.FullHttpRequest +import io.netty.handler.codec.http.QueryStringDecoder import org.jetbrains.annotations.NonNls @Suppress("unused") -class HelpSearchRequestHandler : HelpProcessingRequestBase() { +class HelpSearchRequestHandler : HelpRequestHandlerBase() { @NonNls override val prefix: String = "/search/" + override fun process(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): Boolean { - override fun getProcessedData(query: String, maxHits: Int): String { - return HelpSearch.search(query, maxHits) + val query = urlDecoder.parameters()["query"]?.get(0) + val maxHitsParam = urlDecoder.parameters()["maxHits"]?.get(0) + + sendData(HelpSearch.search(query, if (maxHitsParam != null) Integer.parseInt(maxHitsParam) else 100).encodeToByteArray(), + "data.json", + request, + context.channel(), + request.headers()) + + return true } } \ No newline at end of file diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpComplete.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpComplete.kt deleted file mode 100644 index 846f20f1dabd..000000000000 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpComplete.kt +++ /dev/null @@ -1,73 +0,0 @@ -// 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.jetbrains.builtInHelp.search - -import com.google.gson.Gson -import com.intellij.openapi.diagnostic.Logger -import org.apache.commons.compress.utils.IOUtils -import org.apache.lucene.analysis.standard.StandardAnalyzer -import org.apache.lucene.index.DirectoryReader -import org.apache.lucene.search.spell.LuceneDictionary -import org.apache.lucene.search.suggest.analyzing.BlendedInfixSuggester -import org.apache.lucene.store.FSDirectory -import org.jetbrains.annotations.NotNull -import java.io.FileOutputStream -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths -import org.jetbrains.annotations.NonNls - - -class HelpComplete { - - companion object { - private val resources = arrayOf("_0.cfe", "_0.cfs", "_0.si", "segments_1") - @NonNls - val PREFIX = "/search/" - @NonNls - val NOT_FOUND = "[]" - - private val analyzer: StandardAnalyzer = StandardAnalyzer() - - @NotNull - fun complete(query: String, maxHits: Int): String { - - val indexDir: Path? = Files.createTempDirectory("search-index") - var indexDirectory: FSDirectory? = null - var reader: DirectoryReader? = null - var suggester: BlendedInfixSuggester? = null - if (indexDir != null) - try { - for (resourceName in resources) { - val input = HelpSearch::class.java.getResourceAsStream( - PREFIX + resourceName) - val fos: FileOutputStream = FileOutputStream(Paths.get(indexDir.toAbsolutePath().toString(), resourceName).toFile()) - IOUtils.copy(input, fos) - fos.flush() - fos.close() - input.close() - } - indexDirectory = FSDirectory.open(indexDir) - reader = DirectoryReader.open(indexDirectory) - - suggester = BlendedInfixSuggester(indexDirectory, analyzer) - - suggester.build(LuceneDictionary(reader, "contents")) - - val completionResults = suggester.lookup(query, maxHits, false, true) - - return Gson().toJson(completionResults) - } - catch (e: Exception) { - Logger.getInstance(HelpComplete::class.java).error("Error searching help for $query", e) - } - finally { - suggester?.close() - indexDirectory?.close() - reader?.close() - for (f in indexDir.toFile().listFiles()) f.delete() - Files.delete(indexDir) - } - return NOT_FOUND - } - } -} \ No newline at end of file diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpIndexProcessor.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpIndexProcessor.kt deleted file mode 100644 index dc418dfd691d..000000000000 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpIndexProcessor.kt +++ /dev/null @@ -1,53 +0,0 @@ -// 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.jetbrains.builtInHelp.search - -import org.apache.commons.compress.utils.IOUtils -import org.apache.lucene.analysis.standard.StandardAnalyzer -import org.apache.lucene.store.FSDirectory -import org.jetbrains.annotations.NotNull -import java.io.FileOutputStream -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths -import org.jetbrains.annotations.NonNls - - -abstract class HelpIndexProcessor { - - companion object { - val resources = arrayOf("_0.cfe", "_0.cfs", "_0.si", "segments_1") - @NonNls - val STORAGE_PREFIX = "/search/" - @NonNls - val EMPTY_RESULT = "[]" - } - - val analyzer: StandardAnalyzer = StandardAnalyzer() - - fun deployIndex(): FSDirectory? { - val indexDir: Path? = Files.createTempDirectory("search-index") - var result: FSDirectory? = null - if (indexDir != null) { - for (resourceName in resources) { - val input = HelpSearch::class.java.getResourceAsStream( - STORAGE_PREFIX + resourceName) - val fos: FileOutputStream = FileOutputStream(Paths.get(indexDir.toAbsolutePath().toString(), resourceName).toFile()) - IOUtils.copy(input, fos) - fos.flush() - fos.close() - input.close() - } - result = FSDirectory.open(indexDir) - } - return result - } - - fun releaseIndex(indexDirectory: FSDirectory) { - val path = indexDirectory.directory - for (f in path.toFile().listFiles()) f.delete() - Files.delete(path) - } - - @NotNull - abstract fun process(query: String, maxResults: Int): String -} \ No newline at end of file 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 bf49b10fe593..739afa1f32c5 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 @@ -1,95 +1,153 @@ -// 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. +// Copyright 2000-2022 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.search -import com.google.gson.Gson -import com.intellij.openapi.application.ApplicationInfo +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.openapi.diagnostic.Logger +import com.intellij.util.ResourceUtil import org.apache.commons.compress.utils.IOUtils import org.apache.lucene.analysis.standard.StandardAnalyzer import org.apache.lucene.index.DirectoryReader -import org.apache.lucene.queryparser.classic.QueryParser +import org.apache.lucene.queryparser.simple.SimpleQueryParser import org.apache.lucene.search.IndexSearcher -import org.apache.lucene.search.Query import org.apache.lucene.search.TopScoreDocCollector import org.apache.lucene.search.highlight.Highlighter import org.apache.lucene.search.highlight.QueryScorer import org.apache.lucene.search.highlight.Scorer import org.apache.lucene.store.FSDirectory -import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.NotNull import java.io.FileOutputStream import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import java.util.* class HelpSearch { companion object { private val resources = arrayOf("_0.cfe", "_0.cfs", "_0.si", "segments_1") + @NonNls - val PREFIX = "/search/" - private val NOT_FOUND = "[]" + private const val NOT_FOUND = "[]" private val analyzer: StandardAnalyzer = StandardAnalyzer() @NotNull - fun search(query: String, maxHits: Int): String { + fun search(query: String?, maxHits: Int): String { - val indexDir: Path? = Files.createTempDirectory("search-index") - var indexDirectory: FSDirectory? = null - var reader: DirectoryReader? = null - if (indexDir != null) - try { + if (query != null) { + val indexDir: Path? = Files.createTempDirectory("search-index") + var indexDirectory: FSDirectory? = null + var reader: DirectoryReader? = null + if (indexDir != null) + try { - for (resourceName in resources) { - val input = HelpSearch::class.java.getResourceAsStream( - PREFIX + resourceName) - val fos = FileOutputStream(Paths.get(indexDir.toAbsolutePath().toString(), resourceName).toFile()) - IOUtils.copy(input, fos) - fos.flush() - fos.close() - input.close() + for (resourceName in resources) { + val input = ResourceUtil.getResourceAsStream(HelpSearch::class.java.classLoader, + "search", + resourceName) + val fos = + FileOutputStream(Paths.get(indexDir.toAbsolutePath().toString(), resourceName).toFile()) + IOUtils.copy(input, fos) + fos.flush() + fos.close() + input?.close() + } + + indexDirectory = FSDirectory.open(indexDir) + reader = DirectoryReader.open(indexDirectory) + + val searcher = IndexSearcher(reader) + val collector: TopScoreDocCollector = TopScoreDocCollector.create(maxHits, maxHits) + val q = SimpleQueryParser(analyzer, mapOf(Pair("contents", 1.0F), Pair("title", 1.5F))).parse(query) + searcher.search(q, collector) + val hits = collector.topDocs().scoreDocs + + val scorer: Scorer = QueryScorer(q) + val highlighter = Highlighter(scorer) + + val results = ArrayList() + for (i in hits.indices) { + val doc = searcher.doc(hits[i].doc) + val contentValue = buildString { + append(highlighter.getBestFragment( + analyzer, "contents", doc.get("contents") + )) + append("...") + } + results.add( + HelpSearchResult( + doc.get("filename"), + doc.get("title"), + "", + doc.get("title"), + i.toString(), + HelpSearchResult.SnippetResult( + HelpSearchResult.SnippetResult.Content( + contentValue, "full" + ) + ), + HelpSearchResult.HighlightedResult( + HelpSearchResult.HelpSearchResultDetails(doc.get("filename")), + HelpSearchResult.HelpSearchResultDetails(doc.get("title")), + HelpSearchResult.HelpSearchResultDetails(contentValue), + HelpSearchResult.HelpSearchResultDetails(doc.get("title")), + HelpSearchResult.HelpSearchResultDetails(doc.get("title")) + ) + ) + ) + } + val searchResults = HelpSearchResults(results) + if (searchResults.hits.isNotEmpty()) return jacksonObjectMapper().writeValueAsString(searchResults) } - - indexDirectory = FSDirectory.open(indexDir) - reader = DirectoryReader.open(indexDirectory) - ApplicationInfo.getInstance() - - val searcher = IndexSearcher(reader) - val collector: TopScoreDocCollector = TopScoreDocCollector.create(maxHits, maxHits) - - val q: Query = QueryParser("contents", analyzer).parse(query) - searcher.search(q, collector) - val hits = collector.topDocs().scoreDocs - - - val scorer: Scorer = QueryScorer(q) - val highlighter = Highlighter(scorer) - - val results = ArrayList() - for (i in hits.indices) { - val doc = searcher.doc(hits[i].doc) - results.add( - HelpSearchResult(i, doc.get("filename"), highlighter.getBestFragment( - analyzer, "contents", doc.get("contents")) + "...", - doc.get("title"), listOf("webhelp"))) + catch (e: Throwable) { + Logger.getInstance(HelpSearch::class.java).info("Error searching help for $query", e) } - - val searchResults = HelpSearchResults(results) - return if (searchResults.results.isEmpty()) NOT_FOUND else Gson().toJson(searchResults) - } - catch (e: Exception) { - Logger.getInstance(HelpSearch::class.java).error("Error searching help for $query", e) - } - finally { - indexDirectory?.close() - reader?.close() - val tempFiles = indexDir.toFile().listFiles() - tempFiles?.forEach { it.delete() } - Files.delete(indexDir) - } + finally { + indexDirectory?.close() + reader?.close() + val tempFiles = indexDir.toFile().listFiles() + tempFiles?.forEach { it.delete() } + Files.delete(indexDir) + } + } return NOT_FOUND } } -} \ No newline at end of file +} + +data class HelpSearchResult( + val url: String, + val pageTitle: String, + val breadcrumbs: String, + val mainTitle: String, + val objectID: String, + val _snippetResult: SnippetResult, + val _highlightResult: HighlightedResult +) { + data class SnippetResult(val content: Content) { + data class Content( + val value: String, + val matchLevel: String + ) + + } + + data class HelpSearchResultDetails( + val value: String, + val matchLevel: String = "full", + val fullyHighlighted: Boolean = true, + val matchedWords: List = Collections.emptyList() + ) + + data class HighlightedResult( + val url: HelpSearchResultDetails, + val pageTitle: HelpSearchResultDetails, + val metaDescription: HelpSearchResultDetails, + val mainTitle: HelpSearchResultDetails, + val headings: HelpSearchResultDetails + ) +} + +data class HelpSearchResults(var hits: List) \ No newline at end of file diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResult.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResult.kt deleted file mode 100644 index 742c3caf1a6a..000000000000 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResult.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.jetbrains.builtInHelp.search - -data class HelpSearchResult(var number: Int, var url: String, var snippet: String, var title: String, var categories: List) - - diff --git a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResults.kt b/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResults.kt deleted file mode 100644 index 4805e0fcae11..000000000000 --- a/plugins/built-in-help/src/com/jetbrains/builtInHelp/search/HelpSearchResults.kt +++ /dev/null @@ -1,4 +0,0 @@ -// 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.jetbrains.builtInHelp.search - -data class HelpSearchResults(var results: List)