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

cc.unitmesh.processor.api.swagger.Swagger3Processor.kt Maven / Gradle / Ivy

package cc.unitmesh.processor.api.swagger

import cc.unitmesh.processor.api.base.*
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.Operation
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.responses.ApiResponse
import io.swagger.v3.parser.OpenAPIV3Parser
import java.io.File

class Swagger3Processor(private val api: OpenAPI) : ApiProcessor {
    private val apiSchemaMutableMap = api.components?.schemas

    override fun convertApi(): List {
        if (api.paths == null) return listOf()
        val allItems = mutableListOf()

        api.paths.forEach { (path, pathItem) ->
            pathItem.readOperationsMap().forEach { (method, operation) ->
                val apiItem = ApiItem(
                    path = path,
                    method = method.toString(),
                    description = operation.description?.replace("\n", " ") ?: "",
                    operationId = operation.operationId ?: "",
                    tags = operation.tags ?: listOf(),
                    request = convertRequest(operation),
                    response = convertResponses(operation),
                )

                allItems.add(apiItem)
            }
        }

        // group by tag
        val apiDetailsByTag = allItems.groupBy { it.tags.firstOrNull() ?: "" }
        return apiDetailsByTag.map { (tag, apiItems) ->
            ApiCollection(tag, "", apiItems)
        }
    }

    private fun convertResponses(operation: Operation): List {
        return operation.responses?.map {
            // use regex to get the status code
            val regex = Regex("([0-9]+)")
            val code = regex.find(it.key)?.value?.toInt() ?: 0
            val responseBody = handleResponse(it.value) ?: listOf()
            Response(code, responseBody)
        } ?: listOf()
    }

    private fun handleResponse(response: ApiResponse): List? {
        val content = response.content?.values
        val refName = content?.firstOrNull()?.schema?.`$ref`
        if (refName != null) {
            return getFromSchemaRef(refName)
        }

        val schema = content?.firstOrNull()?.schema
        if (schema != null) {
            return getFromSchemaItem(schema)
        }

        return null
    }

    private fun getFromSchemaItem(schema: Schema) =
        schema.properties?.map { (name, schema) ->
            Parameter(
                name = name,
                type = schema.type ?: "",
            )
        }

    private fun getFromSchemaRef(refName: String): List? {
        val name = refName.split("/").last()
        val schema = apiSchemaMutableMap?.get(name)
        return schema?.properties?.map { (name, schema) ->
            Parameter(
                name = name,
                type = schema.type ?: "",
            )
        }
    }

    private fun convertRequest(operation: Operation): Request {
        val parameters = operation.parameters?.map {
            Parameter(
                name = it.name ?: "",
                type = it.schema?.type ?: "",
            )
        }

        val request = operation.requestBody?.content?.values?.flatMap { content ->
            content.schema?.properties?.map { (name, schema) ->
                Parameter(
                    name = name,
                    type = schema.type ?: "",
                )
            } ?: listOf()
        } ?: listOf()

        return Request(parameters ?: listOf(), request)
    }

    companion object {
        val logger = org.slf4j.LoggerFactory.getLogger(Swagger3Processor::class.java)!!

        fun fromFile(file: File): OpenAPI? {
            try {
                return OpenAPIV3Parser().read(file.absolutePath)
            } catch (e: Exception) {
                logger.error("parse swagger file failed: ${file.absolutePath}")
                e.printStackTrace()
            }

            return null
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy