[json] IJPL-160634 Fix accidentally broken json schema mapping persisting

Historically, we store enum's string representation inside the json mappings state. In turn, the string is assembled from a message bundle line used in several places across the project. Changing this line broke the deserialization process.

To preserve backward compatibility, we intentionally continue using the same approach, but provide a converter capable of reading the schema version tag both in new and in old formats

GitOrigin-RevId: 8813740318ede3c9bc5656ee46c847059760e3c5
This commit is contained in:
Nikita Katkov
2024-09-11 14:26:56 +02:00
committed by intellij-monorepo-bot
parent 1a8311c0e0
commit e1c5798abc
3 changed files with 49 additions and 0 deletions

View File

@@ -141,6 +141,7 @@ qualified.name.qualified=qualified name
qualified.name.pointer=JSON pointer
schema.of.version=JSON Schema {0}
schema.of.version.deprecated=JSON Schema version {0}
schema.configuration.error.empty.file.path=Empty file path matches nothing
schema.configuration.error.empty.pattern=Empty pattern matches nothing

View File

@@ -17,12 +17,14 @@ import com.intellij.util.PatternUtil;
import com.intellij.util.SmartList;
import com.intellij.util.concurrency.SynchronizedClearableLazy;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.OptionTag;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.util.xmlb.annotations.Transient;
import com.jetbrains.jsonSchema.ide.JsonSchemaService;
import com.jetbrains.jsonSchema.impl.JsonSchemaVersion;
import com.jetbrains.jsonSchema.impl.light.legacy.JsonSchemaObjectReadingUtils;
import com.jetbrains.jsonSchema.remote.JsonFileResolver;
import com.jetbrains.jsonSchema.settings.mappings.JsonSchemaVersionConverter;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,6 +46,7 @@ public final class UserDefinedJsonSchemaConfiguration {
private @Nls String name;
private @Nullable @Nls String generatedName;
public String relativePathToSchema;
@OptionTag(converter = JsonSchemaVersionConverter.class)
public @NotNull JsonSchemaVersion schemaVersion = JsonSchemaVersion.SCHEMA_4;
public boolean applicationDefined;
public List<Item> patterns = new SmartList<>();

View File

@@ -0,0 +1,45 @@
// 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.settings.mappings
import com.intellij.json.JsonBundle
import com.intellij.util.xmlb.Converter
import com.jetbrains.jsonSchema.impl.JsonSchemaVersion
// This converter exists because a long time ago the JsonSchemaVersion class was directly used in the UI state persisting,
// and the version's identity was computed simply by calling toString() method.
// Important pitfall here is that the toString() method uses language-dependent values from the message bundle,
// so it's crucial to restore values using the same bundle messages as before :(
internal class JsonSchemaVersionConverter : Converter<JsonSchemaVersion?>() {
override fun fromString(value: String): JsonSchemaVersion? {
return findSuitableVersion(value)
}
override fun toString(value: JsonSchemaVersion?): String? {
return value?.toString()
}
private fun findSuitableVersion(effectiveSerialisedValue: String): JsonSchemaVersion {
return JsonSchemaVersion.entries.asSequence()
.firstOrNull { version -> canBeSerializedInto(version, effectiveSerialisedValue) }
?: JsonSchemaVersion.SCHEMA_4
}
private fun canBeSerializedInto(version: JsonSchemaVersion, effectiveSerialisedValue: String): Boolean {
return getPossibleSerializedValues(version).any { it == effectiveSerialisedValue }
}
private fun getPossibleSerializedValues(version: JsonSchemaVersion): Sequence<String> {
val versionNumber = when (version) {
JsonSchemaVersion.SCHEMA_4 -> 4
JsonSchemaVersion.SCHEMA_6 -> 6
JsonSchemaVersion.SCHEMA_7 -> 7
JsonSchemaVersion.SCHEMA_2019_09 -> 201909
JsonSchemaVersion.SCHEMA_2020_12 -> 202012
else -> 4
}
return sequenceOf(
JsonBundle.message("schema.of.version", versionNumber),
JsonBundle.message("schema.of.version.deprecated", versionNumber)
)
}
}