mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 06:59:44 +07:00
[json] IJ-CR-149952 Prefer allowed values list instead of regexp-based schemaId reporting
(cherry picked from commit 047b36e55b16ec4721f882c879dbb9e415511849) IJ-CR-149952 GitOrigin-RevId: 6bf17ed7a46cc07e38aad2e3e403ce9315d4b29f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f651b9272e
commit
883722fe8e
@@ -32,5 +32,6 @@
|
||||
<orderEntry type="library" name="StreamEx" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-collections-immutable" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.json.split" exported="" />
|
||||
<orderEntry type="library" name="jackson-module-kotlin" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -134,6 +134,7 @@
|
||||
|
||||
<pluginSuggestionProvider implementation="com.jetbrains.jsonSchema.wiremock.WireMockSuggestionProvider"/>
|
||||
<statistics.counterUsagesCollector implementationClass="com.jetbrains.jsonSchema.fus.JsonFeatureUsageCollector"/>
|
||||
<statistics.validation.customValidationRule implementation="com.jetbrains.jsonSchema.fus.JsonSchemaIdValidationRule"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="JavaScript">
|
||||
|
||||
@@ -4,7 +4,6 @@ package com.jetbrains.jsonSchema.fus
|
||||
import com.intellij.internal.statistic.eventLog.EventLogGroup
|
||||
import com.intellij.internal.statistic.eventLog.events.EventField
|
||||
import com.intellij.internal.statistic.eventLog.events.EventFields
|
||||
import com.intellij.internal.statistic.eventLog.events.EventFields.StringValidatedByRegexpReference
|
||||
import com.intellij.internal.statistic.eventLog.events.RoundedIntEventField
|
||||
import com.intellij.internal.statistic.eventLog.events.StringEventField
|
||||
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
||||
@@ -13,7 +12,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
internal object JsonFeatureUsageCollector : CounterUsagesCollector() {
|
||||
private val jsonSchemaGroup = EventLogGroup(
|
||||
id = "json.schema.features",
|
||||
version = 2,
|
||||
version = 3,
|
||||
)
|
||||
|
||||
internal val jsonSchemaHighlightingSessionData =
|
||||
@@ -32,7 +31,7 @@ sealed interface JsonSchemaFusFeature {
|
||||
companion object {
|
||||
fun getAllRegistered(): List<EventField<*>> {
|
||||
return listOf(
|
||||
JsonSchemaFusRegexpFeature.entries,
|
||||
JsonSchemaFusAllowedListFeature.entries,
|
||||
JsonSchemaFusCountedUniqueFeature.entries,
|
||||
JsonSchemaFusCountedFeature.entries
|
||||
).flatten()
|
||||
@@ -41,8 +40,8 @@ sealed interface JsonSchemaFusFeature {
|
||||
}
|
||||
}
|
||||
|
||||
enum class JsonSchemaFusRegexpFeature(override val event: StringEventField) : JsonSchemaFusFeature {
|
||||
JsonFusSchemaId(StringValidatedByRegexpReference("schema_id", "^(https?):\\/\\/[^\\s/$.?#].[^\\s]*$", "JSON schema ID"))
|
||||
enum class JsonSchemaFusAllowedListFeature(override val event: StringEventField) : JsonSchemaFusFeature {
|
||||
JsonFusSchemaId(EventFields.StringValidatedByCustomRule("schema_id", JsonSchemaIdValidationRule::class.java, "JSON schema ID"))
|
||||
}
|
||||
|
||||
enum class JsonSchemaFusCountedUniqueFeature(override val event: RoundedIntEventField) : JsonSchemaFusFeature {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.psi.util.ReadActionCachedValue
|
||||
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
@@ -42,9 +43,9 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
||||
return currentHighlightingSession.getCachedOrEvaluate()
|
||||
}
|
||||
|
||||
fun reportSchemaType(schemaId: String?) {
|
||||
fun reportSchemaType(schemaRoot: JsonSchemaObject) {
|
||||
val currentSession = getOrComputeCurrentSession() ?: return
|
||||
currentSession.schemaType = schemaId
|
||||
currentSession.schemaType = guessBestSchemaId(schemaRoot)
|
||||
}
|
||||
|
||||
fun reportSchemaUsageFeature(featureKind: JsonSchemaFusFeature) {
|
||||
@@ -64,7 +65,7 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
||||
.map { (feature, usagesCount) -> feature.event.with(usagesCount) }
|
||||
val uniqueSchemasCount = JsonSchemaFusCountedUniqueFeature.UniqueRemoteUrlDownloadRequest.event.with(sessionData.requestedRemoteSchemas.size)
|
||||
val schemaAccessOutsideHighlightingCount = JsonSchemaFusCountedUniqueFeature.SchemaAccessWithoutReadLock.event.with(requestsOutsideHighlightingCounter.getAndSet(0))
|
||||
val schemaId = JsonSchemaFusRegexpFeature.JsonFusSchemaId.event.with(sessionData.schemaType)
|
||||
val schemaId = JsonSchemaFusAllowedListFeature.JsonFusSchemaId.event.with(sessionData.schemaType)
|
||||
|
||||
val allDataAccumulated = allCountEventsDuringSession + uniqueSchemasCount + schemaAccessOutsideHighlightingCount + schemaId
|
||||
JsonFeatureUsageCollector.jsonSchemaHighlightingSessionData.log(allDataAccumulated)
|
||||
@@ -74,5 +75,9 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
||||
thisLogger().debug("JSON schema highlighting session statistics: $printableStatistics")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun guessBestSchemaId(schemaRoot: JsonSchemaObject): String? {
|
||||
val rawSchemaIdentifier = schemaRoot.id ?: schemaRoot.rawFile?.name
|
||||
return rawSchemaIdentifier?.replace("http://", "https://")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.jsonSchema.fus
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||
import com.fasterxml.jackson.core.JsonFactory
|
||||
import com.fasterxml.jackson.core.StreamReadFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.intellij.internal.statistic.eventLog.validator.ValidationResultType
|
||||
import com.intellij.internal.statistic.eventLog.validator.rules.EventContext
|
||||
import com.intellij.internal.statistic.eventLog.validator.rules.impl.CustomValidationRule
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* All known schema ids and names downloaded from https://schemastore.org/api/json/catalog.json
|
||||
* The list is quite big, so it is extracted to a separate resource file and must be loaded outside EDT to prevent possible freezes.
|
||||
*/
|
||||
internal class JsonSchemaIdValidationRule : CustomValidationRule() {
|
||||
override fun getRuleId(): String = "json_schema_id_rule"
|
||||
|
||||
override fun doValidate(data: String, context: EventContext): ValidationResultType {
|
||||
return if (AllowListHolder.allowedNames.contains(data)) ValidationResultType.ACCEPTED else ValidationResultType.REJECTED
|
||||
}
|
||||
|
||||
object AllowListHolder {
|
||||
val allowedNames: Set<String> by lazy {
|
||||
deserialiseBundledAllowedSchemaIds()
|
||||
}
|
||||
|
||||
fun deserialiseBundledAllowedSchemaIds(): Set<String> {
|
||||
val bundledDataStream =
|
||||
try {
|
||||
JsonSchemaIdValidationRule::class.java.getResourceAsStream("KnownSchemaIdentifiers.json").use { stream ->
|
||||
val objectMapper = ObjectMapper(
|
||||
JsonFactory.builder().enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION).build()
|
||||
)
|
||||
objectMapper.readValue<ArrayList<KnownJsonSchemaIdentity>>(
|
||||
stream,
|
||||
objectMapper.typeFactory.constructCollectionType(ArrayList::class.java, KnownJsonSchemaIdentity::class.java)
|
||||
)
|
||||
}
|
||||
}
|
||||
catch (exception: IOException) {
|
||||
thisLogger().warn("Failed to load bundled allowed schema identifiers", exception)
|
||||
return emptySet()
|
||||
}
|
||||
return bundledDataStream
|
||||
.asSequence()
|
||||
.flatMap { sequenceOf(it.url, it.fileName).filterNotNull() }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class KnownJsonSchemaIdentity(val url: String? = null, val fileName: String? = null)
|
||||
}
|
||||
}
|
||||
|
||||
3825
json/src/com/jetbrains/jsonSchema/fus/KnownSchemaIdentifiers.json
Normal file
3825
json/src/com/jetbrains/jsonSchema/fus/KnownSchemaIdentifiers.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -59,7 +59,7 @@ public final class JsonSchemaComplianceChecker {
|
||||
}
|
||||
|
||||
public void annotate(final @NotNull PsiElement element) {
|
||||
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaType(myRootSchema.getId());
|
||||
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaType(myRootSchema);
|
||||
doAnnotate(element);
|
||||
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().flushHighlightingSessionDataToFus();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user