mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +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="StreamEx" level="project" />
|
||||||
<orderEntry type="library" name="kotlinx-collections-immutable" level="project" />
|
<orderEntry type="library" name="kotlinx-collections-immutable" level="project" />
|
||||||
<orderEntry type="module" module-name="intellij.json.split" exported="" />
|
<orderEntry type="module" module-name="intellij.json.split" exported="" />
|
||||||
|
<orderEntry type="library" name="jackson-module-kotlin" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -134,6 +134,7 @@
|
|||||||
|
|
||||||
<pluginSuggestionProvider implementation="com.jetbrains.jsonSchema.wiremock.WireMockSuggestionProvider"/>
|
<pluginSuggestionProvider implementation="com.jetbrains.jsonSchema.wiremock.WireMockSuggestionProvider"/>
|
||||||
<statistics.counterUsagesCollector implementationClass="com.jetbrains.jsonSchema.fus.JsonFeatureUsageCollector"/>
|
<statistics.counterUsagesCollector implementationClass="com.jetbrains.jsonSchema.fus.JsonFeatureUsageCollector"/>
|
||||||
|
<statistics.validation.customValidationRule implementation="com.jetbrains.jsonSchema.fus.JsonSchemaIdValidationRule"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="JavaScript">
|
<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.EventLogGroup
|
||||||
import com.intellij.internal.statistic.eventLog.events.EventField
|
import com.intellij.internal.statistic.eventLog.events.EventField
|
||||||
import com.intellij.internal.statistic.eventLog.events.EventFields
|
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.RoundedIntEventField
|
||||||
import com.intellij.internal.statistic.eventLog.events.StringEventField
|
import com.intellij.internal.statistic.eventLog.events.StringEventField
|
||||||
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
|
||||||
@@ -13,7 +12,7 @@ import org.jetbrains.annotations.ApiStatus
|
|||||||
internal object JsonFeatureUsageCollector : CounterUsagesCollector() {
|
internal object JsonFeatureUsageCollector : CounterUsagesCollector() {
|
||||||
private val jsonSchemaGroup = EventLogGroup(
|
private val jsonSchemaGroup = EventLogGroup(
|
||||||
id = "json.schema.features",
|
id = "json.schema.features",
|
||||||
version = 2,
|
version = 3,
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val jsonSchemaHighlightingSessionData =
|
internal val jsonSchemaHighlightingSessionData =
|
||||||
@@ -32,7 +31,7 @@ sealed interface JsonSchemaFusFeature {
|
|||||||
companion object {
|
companion object {
|
||||||
fun getAllRegistered(): List<EventField<*>> {
|
fun getAllRegistered(): List<EventField<*>> {
|
||||||
return listOf(
|
return listOf(
|
||||||
JsonSchemaFusRegexpFeature.entries,
|
JsonSchemaFusAllowedListFeature.entries,
|
||||||
JsonSchemaFusCountedUniqueFeature.entries,
|
JsonSchemaFusCountedUniqueFeature.entries,
|
||||||
JsonSchemaFusCountedFeature.entries
|
JsonSchemaFusCountedFeature.entries
|
||||||
).flatten()
|
).flatten()
|
||||||
@@ -41,8 +40,8 @@ sealed interface JsonSchemaFusFeature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class JsonSchemaFusRegexpFeature(override val event: StringEventField) : JsonSchemaFusFeature {
|
enum class JsonSchemaFusAllowedListFeature(override val event: StringEventField) : JsonSchemaFusFeature {
|
||||||
JsonFusSchemaId(StringValidatedByRegexpReference("schema_id", "^(https?):\\/\\/[^\\s/$.?#].[^\\s]*$", "JSON schema ID"))
|
JsonFusSchemaId(EventFields.StringValidatedByCustomRule("schema_id", JsonSchemaIdValidationRule::class.java, "JSON schema ID"))
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class JsonSchemaFusCountedUniqueFeature(override val event: RoundedIntEventField) : JsonSchemaFusFeature {
|
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.components.service
|
||||||
import com.intellij.openapi.diagnostic.thisLogger
|
import com.intellij.openapi.diagnostic.thisLogger
|
||||||
import com.intellij.psi.util.ReadActionCachedValue
|
import com.intellij.psi.util.ReadActionCachedValue
|
||||||
|
import com.jetbrains.jsonSchema.impl.JsonSchemaObject
|
||||||
import org.jetbrains.annotations.ApiStatus
|
import org.jetbrains.annotations.ApiStatus
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
@@ -42,9 +43,9 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
|||||||
return currentHighlightingSession.getCachedOrEvaluate()
|
return currentHighlightingSession.getCachedOrEvaluate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportSchemaType(schemaId: String?) {
|
fun reportSchemaType(schemaRoot: JsonSchemaObject) {
|
||||||
val currentSession = getOrComputeCurrentSession() ?: return
|
val currentSession = getOrComputeCurrentSession() ?: return
|
||||||
currentSession.schemaType = schemaId
|
currentSession.schemaType = guessBestSchemaId(schemaRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportSchemaUsageFeature(featureKind: JsonSchemaFusFeature) {
|
fun reportSchemaUsageFeature(featureKind: JsonSchemaFusFeature) {
|
||||||
@@ -64,7 +65,7 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
|||||||
.map { (feature, usagesCount) -> feature.event.with(usagesCount) }
|
.map { (feature, usagesCount) -> feature.event.with(usagesCount) }
|
||||||
val uniqueSchemasCount = JsonSchemaFusCountedUniqueFeature.UniqueRemoteUrlDownloadRequest.event.with(sessionData.requestedRemoteSchemas.size)
|
val uniqueSchemasCount = JsonSchemaFusCountedUniqueFeature.UniqueRemoteUrlDownloadRequest.event.with(sessionData.requestedRemoteSchemas.size)
|
||||||
val schemaAccessOutsideHighlightingCount = JsonSchemaFusCountedUniqueFeature.SchemaAccessWithoutReadLock.event.with(requestsOutsideHighlightingCounter.getAndSet(0))
|
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
|
val allDataAccumulated = allCountEventsDuringSession + uniqueSchemasCount + schemaAccessOutsideHighlightingCount + schemaId
|
||||||
JsonFeatureUsageCollector.jsonSchemaHighlightingSessionData.log(allDataAccumulated)
|
JsonFeatureUsageCollector.jsonSchemaHighlightingSessionData.log(allDataAccumulated)
|
||||||
@@ -74,5 +75,9 @@ class JsonSchemaHighlightingSessionStatisticsCollector {
|
|||||||
thisLogger().debug("JSON schema highlighting session statistics: $printableStatistics")
|
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) {
|
public void annotate(final @NotNull PsiElement element) {
|
||||||
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaType(myRootSchema.getId());
|
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().reportSchemaType(myRootSchema);
|
||||||
doAnnotate(element);
|
doAnnotate(element);
|
||||||
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().flushHighlightingSessionDataToFus();
|
JsonSchemaHighlightingSessionStatisticsCollector.getInstance().flushHighlightingSessionDataToFus();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user