All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.javalin.plugin.openapi.external.KotlinOpenApiDsl.kt Maven / Gradle / Ivy

There is a newer version: 6.2.0
Show newest version
package io.javalin.plugin.openapi.external

import io.swagger.v3.core.converter.ModelConverters
import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.examples.Example
import io.swagger.v3.oas.models.media.ArraySchema
import io.swagger.v3.oas.models.media.BooleanSchema
import io.swagger.v3.oas.models.media.Content
import io.swagger.v3.oas.models.media.DateSchema
import io.swagger.v3.oas.models.media.DateTimeSchema
import io.swagger.v3.oas.models.media.IntegerSchema
import io.swagger.v3.oas.models.media.MapSchema
import io.swagger.v3.oas.models.media.MediaType
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.media.StringSchema
import io.swagger.v3.oas.models.parameters.Parameter
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime
import java.util.*

// The original functions are in https://github.com/derveloper/kotlin-openapi3-dsl/blob/master/src/main/kotlin/cc/vileda/openapi/dsl/OpenApiDsl.kt
// I needed to create a copy of all the inline functions, as it is not possible to call kotlin inline function from java code

internal fun  Components.schema(clazz: Class) {
    schema(clazz) {}
}

internal fun  Components.schema(clazz: Class, init: Schema<*>.() -> Unit) {
    if (schemas == null) {
        schemas = mutableMapOf()
    }
    val schema = findSchema(clazz)
    schema?.main?.init()
    schema?.all?.forEach { (key, schema) ->
        schemas[key] = schema
    }
}

internal fun  Parameter.schema(clazz: Class, init: Schema<*>.() -> Unit) {
    schema = findSchema(clazz)?.main
    schema.init()
}

internal fun  Parameter.schema(clazz: Class) {
    schema = findSchema(clazz)?.main
}

internal fun  mediaType(clazz: Class): MediaType {
    val mediaType = MediaType()
    val modelSchema = findSchema(clazz)?.main
    mediaType.schema = modelSchema
    return mediaType
}

/**
 * This helper is not in the original library.
 * Because it is not possible to create a list instance of an unknown type we need a separate method for that.
 */
internal fun mediaTypeOfList(): MediaType {
    val mediaType = MediaType()
    val modelSchema = ArraySchema()
    mediaType.schema = modelSchema
    return mediaType
}

internal fun  mediaTypeRef(clazz: Class): MediaType {
    val mediaType = MediaType()
    mediaType.schema = Schema()
    mediaType.schema.`$ref` = clazz.simpleName
    return mediaType
}

internal fun  Content.mediaTypeRef(clazz: Class, name: String) {
    val mediaType = mediaTypeRef(clazz)
    addMediaType(name, mediaType)
}

internal fun  Content.mediaType(clazz: Class, name: String) {
    val mediaType = mediaType(clazz)
    addMediaType(name, mediaType)
}

internal fun  Content.mediaTypeArrayOfRef(clazz: Class, name: String) {
    val mediaTypeArray = mediaTypeOfList()
    val mediaTypeObj = mediaTypeRef(clazz)
    (mediaTypeArray.schema as ArraySchema).items(mediaTypeObj.schema)
    addMediaType(name, mediaTypeArray)
}

internal fun  Content.mediaTypeArrayOf(clazz: Class, name: String) {
    val mediaTypeArray = mediaTypeOfList()
    val mediaTypeObj = mediaType(clazz)
    (mediaTypeArray.schema as ArraySchema).items(mediaTypeObj.schema)
    addMediaType(name, mediaTypeArray)
}

internal data class FindSchemaResponse(
        /** The main schema that is requested */
        val main: Schema<*>,
        /** All schemas that are used by the main schema */
        val all: Map> = mapOf()
)

internal fun  findSchema(clazz: Class): FindSchemaResponse? {
    getEnumSchema(clazz)?.let {
        return FindSchemaResponse(it)
    }
    return when (clazz) {
        String::class.java -> FindSchemaResponse(StringSchema())
        Boolean::class.java -> FindSchemaResponse(BooleanSchema())
        java.lang.Boolean::class.java -> FindSchemaResponse(BooleanSchema())
        Int::class.java -> FindSchemaResponse(IntegerSchema())
        Integer::class.java -> FindSchemaResponse(IntegerSchema())
        List::class.java -> FindSchemaResponse(ArraySchema())
        Map::class.java -> FindSchemaResponse(MapSchema())
        Long::class.java -> FindSchemaResponse(IntegerSchema().format("int64"))
        BigDecimal::class.java -> FindSchemaResponse(IntegerSchema().format(""))
        Date::class.java -> FindSchemaResponse(DateSchema())
        LocalDate::class.java -> FindSchemaResponse(DateSchema())
        LocalDateTime::class.java -> FindSchemaResponse(DateTimeSchema())
        /* BEGIN Custom classes */
        ByteArray::class.java -> FindSchemaResponse(StringSchema().format("binary"))
        /* END Custom classes */
        else -> {
            val schemas = ModelConverters.getInstance().readAll(clazz)
            schemas[clazz.simpleName]?.let { FindSchemaResponse(it, schemas) }
        }
    }
}

internal fun  getEnumSchema(clazz: Class): Schema<*>? {
    val values = clazz.enumConstants ?: return null

    val schema = StringSchema()
    for (enumVal in values) {
        schema.addEnumItem(enumVal.toString())
    }
    return schema
}


internal fun  MediaType.example(clazz: Class, value: T, init: Example.() -> Unit) {
    if (examples == null) {
        examples = mutableMapOf()
    }

    val example = Example()
    example.value = value
    example.init()
    examples[clazz.simpleName] = example
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy