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

dev.fuelyour.vertxkuickstartcore.tools.SwaggerMerger.kt Maven / Gradle / Ivy

package dev.fuelyour.vertxkuickstartcore.tools

import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.parser.OpenAPIV3Parser
import io.vertx.ext.web.api.contract.openapi3.impl.OpenApi3Utils
import org.apache.commons.collections4.ListUtils
import org.reflections.Reflections
import org.reflections.scanners.ResourcesScanner

/**
 * Merge multiple swagger documents into one. This allows swagger documents to be broken down into manageable pieces,
 * and merged back together for final documentation generation.
 */
object SwaggerMerger {

    fun mergeAllInDirectory(path: String): OpenAPI? =
        findSwaggerFilesInPath(path)
            .map { loadSwagger("/$it") }
            .fold(null as OpenAPI?) { s1, s2 ->
                s1?.merge(s2) ?: s2
            }

    private fun findSwaggerFilesInPath(path: String): Set =
        Reflections(path, ResourcesScanner())
            .getResources { it?.endsWith(".yaml") ?: false }

    private fun loadSwagger(filename: String): OpenAPI =
        OpenAPIV3Parser()
            .readLocation(filename, null, OpenApi3Utils.getParseOptions())
            .openAPI

    private fun OpenAPI.merge(new: OpenAPI): OpenAPI {
        servers = combineLists(servers, new.servers)
        security = combineLists(security, new.security)
        tags = combineLists(tags, new.tags)
        new.paths?.forEach { it -> paths.addPathItem(it.key, it.value) }
        extensions = combineMaps(extensions, new.extensions)
        components.merge(new.components)
        if (info == null)
            info = new.info
        return this
    }

    private fun Components.merge(other: Components) {
        schemas = combineMaps(schemas, other.schemas)
        responses = combineMaps(responses, other.responses)
        parameters = combineMaps(parameters, other.parameters)
        examples = combineMaps(examples, other.examples)
        requestBodies = combineMaps(requestBodies, other.requestBodies)
        headers = combineMaps(headers, other.headers)
        securitySchemes = combineMaps(securitySchemes, other.securitySchemes)
        links = combineMaps(links, other.links)
        callbacks = combineMaps(callbacks, other.callbacks)
        extensions = combineMaps(extensions, other.extensions)
    }

    private fun  combineLists(list1: List?, list2: List?): List? {
        val combined = ListUtils.union(
            list1 ?: listOf(),
            list2 ?: listOf()
        )
        return if (combined.isEmpty()) null else combined
    }

    private fun  combineMaps(
        map1: MutableMap?,
        map2: MutableMap?
    ): MutableMap? {
        return when {
            map1 == null -> map2
            map2 == null -> map1
            else -> {
                val combined = linkedMapOf()
                combined.putAll(map1)
                combined.putAll(map2)
                combined
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy