Skip to content

Commit 855e6f9

Browse files
authored
🐛 fix JsonSchema type error when refer to non-object definitions (#368)
1 parent c9f36bc commit 855e6f9

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

src/main/kotlin/wu/seal/jsontokotlin/utils/classgenerator/DataClassGeneratorByJSONSchema.kt

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,8 @@ class DataClassGeneratorByJSONSchema(private val rootClassName: String, private
5656
isRequired: Boolean,
5757
includeConst: Boolean = true
5858
): Property {
59-
val typeClass = if (jsonProp.typeString == "array") {
60-
val innerProperty = resolveProperty(
61-
jsonProp.items
62-
?: throw IllegalArgumentException("Array `items` must be defined (property: $propertyName)"),
63-
propertyName,
64-
false
65-
)
66-
GenericListClass(generic = innerProperty.typeObject)
67-
} else {
68-
val (jsonClassName, realDef) = getRealDefinition(jsonProp)
69-
resolveTypeClass(realDef.typeString, jsonClassName, realDef, propertyName)
70-
}
59+
val (jsonClassName, realDef) = getRealDefinition(jsonProp)
60+
val typeClass = resolveTypeClass(realDef.typeString, jsonClassName, realDef, propertyName)
7161
val value = if (isRequired || !jsonProp.isTypeNullable) getDefaultValue(typeClass.name) else null
7262
return Property(
7363
originName = propertyName,
@@ -89,6 +79,15 @@ class DataClassGeneratorByJSONSchema(private val rootClassName: String, private
8979
): KotlinClass {
9080
val simpleName = jsonClassName ?: propertyName.capitalize()
9181
return when {
82+
realDefJsonType == "array" -> {
83+
val innerProperty = resolveProperty(
84+
realDef.items
85+
?: throw IllegalArgumentException("Array `items` must be defined (property: $propertyName)"),
86+
propertyName,
87+
false
88+
)
89+
GenericListClass(generic = innerProperty.typeObject)
90+
}
9291
checkEnum && realDef.enum != null -> resolveEnumClass(realDef, simpleName)
9392
checkSealed && realDef.anyOf != null -> resolveSealedClass(realDef, simpleName)
9493
realDefJsonType != null && (jsonClassName != null || realDefJsonType == "object") -> generateClass(
@@ -204,11 +203,13 @@ class DataClassGeneratorByJSONSchema(private val rootClassName: String, private
204203
/** resolves `ref`, `oneOf` and `allOf` then returns a real property definition */
205204
private fun getRealDefinition(def: PropertyDef): Pair<String? /* ClassName */, PropertyDef> {
206205
return when {
206+
(def.typeString != null && def.typeString != "object") -> Pair(null, def)
207207
(def.properties != null) -> Pair(def.tryGetClassName(), def)
208-
(def.ref != null) -> Pair(
209-
def.tryGetClassName(),
210-
getRealDefinition(jsonSchema.resolveDefinition(def.ref)).second
211-
)
208+
(def.ref != null) -> {
209+
val (cls, pd) = getRealDefinition(jsonSchema.resolveDefinition(def.ref))
210+
val className = if (pd.typeString != "object" && pd.enum.isNullOrEmpty()) cls else def.tryGetClassName()
211+
Pair(className, pd)
212+
}
212213
(def.oneOf != null) -> getRealDefinition(def.oneOf.firstOrNull { it.typeString != "null" }
213214
?: def.oneOf.first())
214215
(def.allOf != null) -> {

src/test/kotlin/wu/seal/jsontokotlin/JsonSchemaGeneratorTest.kt

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ enum class LogEventType(val value: Int) {
10761076
/**
10771077
* Gets a collection JsonConverter that will be used during serialization.
10781078
*/
1079-
val Converters: JsonConverterCollection?,
1079+
val Converters: List<JsonConverter>?,
10801080
/**
10811081
* Gets or sets the contract resolver used by the serializer whenserializing .NET objects to JSON and vice versa.
10821082
*/
@@ -1131,11 +1131,17 @@ enum class LogEventType(val value: Int) {
11311131
val CheckAdditionalContent: Boolean
11321132
)
11331133
1134+
/**
1135+
* Used to resolve references when serializing and deserializing JSON by the JsonSerializer.
1136+
*/
1137+
class IReferenceResolver
11341138
1139+
class SerializationBinder
11351140
1136-
1137-
1138-
1141+
/**
1142+
* Allows users to control class loading and mandate what class to load.
1143+
*/
1144+
class ISerializationBinder
11391145
11401146
/**
11411147
* Represents a trace writer.
@@ -1147,7 +1153,7 @@ enum class LogEventType(val value: Int) {
11471153
val LevelFilter: TraceLevel?
11481154
)
11491155
1150-
1156+
class IEqualityComparer
11511157
11521158
/**
11531159
* Specifies type name handling options for the JsonSerializer.
@@ -1266,9 +1272,24 @@ enum class LogEventType(val value: Int) {
12661272
Ignore(2);
12671273
}
12681274
1275+
/**
1276+
* Converts an object to and from JSON.
1277+
*/
1278+
data class JsonConverter(
1279+
/**
1280+
* Gets a value indicating whether this JsonConverter can read JSON.
1281+
*/
1282+
val CanRead: Boolean,
1283+
/**
1284+
* Gets a value indicating whether this JsonConverter can write JSON.
1285+
*/
1286+
val CanWrite: Boolean
1287+
)
12691288
1270-
1271-
1289+
/**
1290+
* Used by JsonSerializer to resolve a JsonContract for a given Type.
1291+
*/
1292+
class IContractResolver
12721293
12731294
data class StreamingContext(
12741295
val State: StreamingContextStates?,

src/test/kotlin/wu/seal/jsontokotlin/TestIssue329.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,17 @@ class TestIssue329 {
9898
) {
9999
data class Target(
100100
@SerializedName("A")
101-
val a: Aa = Aa(),
101+
val a: String = "",
102102
@SerializedName("B")
103103
val b: Bb = Bb()
104104
) {
105105
data class Bb(
106106
@SerializedName("Bba")
107-
val bba: Aa = Aa(),
107+
val bba: String = "",
108108
@SerializedName("Bbb")
109-
val bbb: Aa = Aa(),
109+
val bbb: String = "",
110110
@SerializedName("Bbc")
111-
val bbc: Aa = Aa()
111+
val bbc: String = ""
112112
)
113113
}
114114
}

0 commit comments

Comments
 (0)