Skip to content

Commit

Permalink
Supported Jackson (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
nulls authored Jul 26, 2023
2 parents c1fadf2 + 00b1e92 commit 8907c9f
Show file tree
Hide file tree
Showing 43 changed files with 619 additions and 127 deletions.
27 changes: 18 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ repositories {
}

kotlin {
jvm()
jvm {
withJava()
compilations.all {
kotlinOptions.run {
jvmTarget = "1.8"
}
}
}
linuxX64()
mingwX64()
macosX64()
sourceSets {
@Suppress("UNUSED_VARIABLE")
val commonMain by getting {
dependencies {
api(libs.kotlinx.serialization.json)
Expand All @@ -29,19 +35,22 @@ kotlin {
implementation(libs.jetbrains.annotations)
}
}
val commonNonJvmMain by creating {
dependsOn(commonMain)
}
listOf(
"linuxX64",
"mingwX64",
"macosX64",
).forEach { nonJvmTarget ->
getByName("${nonJvmTarget}Main").dependsOn(commonNonJvmMain)
}
@Suppress("UNUSED_VARIABLE")
val jvmMain by getting {
dependencies {
api(libs.jackson.annotations)
api(libs.jackson.databind)
}
}
@Suppress("UNUSED_VARIABLE")
val jvmTest by getting {
dependencies {
implementation(libs.jackson.module.kotlin)
implementation(libs.jackson.datatype.jsr310)
}
}
}
}
178 changes: 166 additions & 12 deletions src/commonMain/kotlin/com/saveourtool/osv4k/OsvSchema.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package com.saveourtool.osv4k

import com.saveourtool.osv4k.annotations.Access
import com.saveourtool.osv4k.annotations.JsonProperty
import com.saveourtool.osv4k.annotations.JsonSerialize
import com.saveourtool.osv4k.jackson.*
import com.saveourtool.osv4k.utils.LocalDateTimeRfc3339Serializer
import kotlinx.datetime.LocalDateTime
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
import kotlinx.serialization.json.JsonObject

typealias RawOsvSchema = OsvSchema<JsonObject, JsonObject, JsonObject, JsonObject>
Expand All @@ -16,80 +13,212 @@ typealias RawOsvSchema = OsvSchema<JsonObject, JsonObject, JsonObject, JsonObjec
* A schema for describing a vulnerability in an open source package.
*/
@Serializable
data class OsvSchema<D, A_D, A_E, A_R_D> (
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class OsvSchema<D, A_D, A_E, A_R_D>(
@SerialName("schema_version")
@JsonProperty(value = "schema_version", namespace = "", required = true, index = -1, defaultValue = "", access = Access.AUTO)
@get:JsonProperty(value = "schema_version", namespace = "", required = false, index = -1, defaultValue = "1.0.0", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "schema_version", namespace = "", required = false, index = -1, defaultValue = "1.0.0", access = JsonPropertyAccess.AUTO)
// TODO: add validation to SemVer or re-use library for it
val schemaVersion: String = "1.0.0",

@JsonProperty(value = "id", namespace = "", required = true, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val id: String,
@Serializable(with = LocalDateTimeRfc3339Serializer::class)
@JsonSerialize(
using = LocalDateTimeRfc3339JacksonSerializer::class,
contentUsing = JsonSerializerNone::class,
keyUsing = JsonSerializerNone::class,
nullsUsing = JsonSerializerNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
typing = JsonSerializeTyping.DEFAULT_TYPING,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
include = JsonSerializeInclusion.DEFAULT_INCLUSION,
)
@JsonDeserialize(
using = LocalDateTimeRfc3339JacksonDeserializer::class,
contentUsing = JsonDeserializerNone::class,
keyUsing = KeyDeserializerNone::class,
builder = JavaVoid::class,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
)
@JsonProperty(value = "modified", namespace = "", required = true, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val modified: LocalDateTime,

@Serializable(with = LocalDateTimeRfc3339Serializer::class)
@JsonSerialize(
using = LocalDateTimeRfc3339JacksonSerializer::class,
contentUsing = JsonSerializerNone::class,
keyUsing = JsonSerializerNone::class,
nullsUsing = JsonSerializerNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
typing = JsonSerializeTyping.DEFAULT_TYPING,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
include = JsonSerializeInclusion.DEFAULT_INCLUSION,
)
@JsonDeserialize(
using = LocalDateTimeRfc3339JacksonDeserializer::class,
contentUsing = JsonDeserializerNone::class,
keyUsing = KeyDeserializerNone::class,
builder = JavaVoid::class,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
)
@JsonProperty(value = "published", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val published: LocalDateTime? = null,
@Serializable(with = LocalDateTimeRfc3339Serializer::class)
@JsonSerialize(using = )
@JsonSerialize(
using = LocalDateTimeRfc3339JacksonSerializer::class,
contentUsing = JsonSerializerNone::class,
keyUsing = JsonSerializerNone::class,
nullsUsing = JsonSerializerNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
typing = JsonSerializeTyping.DEFAULT_TYPING,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
include = JsonSerializeInclusion.DEFAULT_INCLUSION,
)
@JsonDeserialize(
using = LocalDateTimeRfc3339JacksonDeserializer::class,
contentUsing = JsonDeserializerNone::class,
keyUsing = KeyDeserializerNone::class,
builder = JavaVoid::class,
converter = ConverterNone::class,
contentConverter = ConverterNone::class,
`as` = JavaVoid::class,
keyAs = JavaVoid::class,
contentAs = JavaVoid::class,
)
@JsonProperty(value = "withdrawn", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val withdrawn: LocalDateTime? = null,

@JsonProperty(value = "aliases", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val aliases: List<String>? = null,
@JsonProperty(value = "related", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val related: List<String>? = null,
@JsonProperty(value = "summary", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val summary: String? = null,
@JsonProperty(value = "details", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val details: String? = null,
@JsonProperty(value = "severity", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val severity: List<Severity>? = null,
@JsonProperty(value = "affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val affected: List<Affected<A_D, A_E, A_R_D>>? = null,
@JsonProperty(value = "references", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val references: List<Reference>? = null,
@JsonProperty(value = "credits", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val credits: List<Credit>? = null,
@SerialName("database_specific")
@JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = Access.AUTO)
@get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val databaseSpecific: D? = null,
)

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Affected<D, E, R_D> (
@JsonProperty(value = "package", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val `package`: Package? = null,

@JsonProperty(value = "severity", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val severity: List<Severity>? = null,
@JsonProperty(value = "ranges", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val ranges: List<Range<R_D>>? = null,
@JsonProperty(value = "versions", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val versions: List<String>? = null,

@SerialName("ecosystem_specific")
@JsonProperty(value = "ecosystem_specific", namespace = "", required = false, index = -1, defaultValue = "", access = Access.AUTO)
@get:JsonProperty(value = "ecosystem_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "ecosystem_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val ecosystemSpecific: E? = null,
@SerialName("database_specific")
@JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = Access.AUTO)
@get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val databaseSpecific: D? = null,
)

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Package (
@JsonProperty(value = "ecosystem", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val ecosystem: String,
@JsonProperty(value = "name", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val name: String,
@JsonProperty(value = "purl", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val purl: String? = null
)

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Range<D> (
@JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val type: RangeType,
@JsonProperty(value = "repo", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val repo: String? = null,
@JsonProperty(value = "events", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val events: List<Event>,
// TODO: do
@SerialName("database_specific")
@get:JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "database_specific", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val databaseSpecific: D? = null,
)

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Event (
@JsonProperty(value = "introduced", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val introduced: String? = null,
@JsonProperty(value = "fixed", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val fixed: String? = null,

@SerialName("last_affected")
@get:JsonProperty(value = "last_affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
@JsonProperty(value = "last_affected", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val lastAffected: String? = null,

@JsonProperty(value = "limit", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val limit: String? = null
)

//@Serializable
enum class RangeType {
ECOSYSTEM,
GIT,
Expand All @@ -98,8 +227,16 @@ enum class RangeType {
}

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Severity (
@JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val type: SeverityType,
@JsonProperty(value = "score", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val score: String
)

Expand All @@ -110,9 +247,18 @@ enum class SeverityType {
}

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Credit (
@JsonProperty(value = "name", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val name: String,
@JsonProperty(value = "contact", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val contact: List<String>? = null,
@JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val type: CreditType? = null
)

Expand All @@ -131,8 +277,16 @@ enum class CreditType {
}

@Serializable
@JsonInclude(
value = JsonIncludeType.NON_NULL,
content = JsonIncludeType.ALWAYS,
valueFilter = JavaVoid::class,
contentFilter = JavaVoid::class,
)
data class Reference (
@JsonProperty(value = "type", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val type: ReferenceType,
@JsonProperty(value = "url", namespace = "", required = false, index = -1, defaultValue = "", access = JsonPropertyAccess.AUTO)
val url: String
)

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.saveourtool.osv4k.jackson

expect interface Converter<IN, OUT>
expect abstract class ConverterNone : Converter<Any, Any>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.saveourtool.osv4k.jackson

expect class JavaVoid
10 changes: 10 additions & 0 deletions src/commonMain/kotlin/com/saveourtool/osv4k/jackson/JsonCreator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.saveourtool.osv4k.jackson

expect annotation class JsonCreator(
val mode: JsonCreatorMode,
)
expect enum class JsonCreatorMode {
DEFAULT,
PROPERTIES,
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.saveourtool.osv4k.jackson

import kotlin.reflect.KClass

expect annotation class JsonDeserialize(
val using: KClass<out JsonDeserializer<out Any>>,
val contentUsing: KClass<out JsonDeserializer<out Any>>,
val keyUsing: KClass<out KeyDeserializer>,
val builder: KClass<*>,
val converter: KClass<out Converter<Any, Any>>,
val contentConverter: KClass<out Converter<Any, Any>>,
val `as`: KClass<*>,
val keyAs: KClass<*>,
val contentAs: KClass<*>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.saveourtool.osv4k.jackson

expect abstract class JsonDeserializer<T>

expect abstract class JsonDeserializerNone: JsonDeserializer<Any>
Loading

0 comments on commit 8907c9f

Please sign in to comment.