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

io.vrap.codegen.languages.oas.model.OasModuleRenderer.kt Maven / Gradle / Ivy

package io.vrap.codegen.languages.oas.model

import com.damnhandy.uri.template.UriTemplate
import com.damnhandy.uri.template.jackson.datatype.UriTemplateSerializer
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter
import com.fasterxml.jackson.databind.ser.PropertyWriter
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter
import io.vrap.codegen.languages.extensions.EObjectExtensions
import io.vrap.codegen.languages.oas.extensions.InstanceSerializer
import io.vrap.codegen.languages.oas.extensions.ObjectInstanceSerializer
import io.vrap.rmf.codegen.io.TemplateFile
import io.vrap.rmf.codegen.rendering.FileProducer
import io.vrap.rmf.codegen.types.VrapTypeProvider
import io.vrap.rmf.raml.model.modules.Api
import io.vrap.rmf.raml.model.types.*
import io.vrap.rmf.raml.model.values.RegExp
import org.eclipse.emf.ecore.EObject
import org.eclipse.emfcloud.jackson.annotations.EcoreReferenceInfo
import org.eclipse.emfcloud.jackson.annotations.EcoreTypeInfo
import org.eclipse.emfcloud.jackson.databind.ser.EcoreReferenceSerializer
import org.eclipse.emfcloud.jackson.handlers.BaseURIHandler
import org.eclipse.emfcloud.jackson.module.EMFModule
import java.io.IOException

class OasModuleRenderer constructor(val api: Api, override val vrapTypeProvider: VrapTypeProvider) : EObjectExtensions, FileProducer {

    override fun produceFiles(): List {
        return listOf(
                oas(api)
        )
    }

    private fun oas(api: Api): TemplateFile {

        val mapper = ObjectMapper();

        val module = EMFModule();
        module.configure(EMFModule.Feature.OPTION_SERIALIZE_TYPE, false)
        val handler = BaseURIHandler()
        val typeInfo = EcoreTypeInfo()
        val referenceInfo = EcoreReferenceInfo(handler)
        val referenceSerializer = EcoreReferenceSerializer(referenceInfo, typeInfo)
//        val filters = SimpleFilterProvider().addFilter("someProps", SomePropertyFilter())

        module.typeInfo = typeInfo
        module.referenceSerializer = ReferenceSerializer(referenceSerializer);

        module.addSerializer(RegExp::class.java, RegExpSerializer())
        module.addSerializer(UriTemplate::class.java, UriTemplateSerializer())
        module.addSerializer(ObjectInstance::class.java, ObjectInstanceSerializer())
        module.addSerializer(ArrayInstance::class.java, InstanceSerializer())
        module.addSerializer(IntegerInstance::class.java, InstanceSerializer())
        module.addSerializer(BooleanInstance::class.java, InstanceSerializer())
        module.addSerializer(StringInstance::class.java, InstanceSerializer())
        module.addSerializer(NumberInstance::class.java, InstanceSerializer())
        module.addSerializer(Example::class.java, ExampleSerializer())


        module.addSerializer(NumberType::class.java, InlineTypeSerializer())

        mapper.registerModule(module)

//        var apiRaml = mapper.valueToTree(api)
//
//        apiRaml.withArray("types").toMutableList().filter { jsonNode -> jsonNode.has("inlineTypes") }.map { jsonNode -> jsonNode.toMutableList().plus(jsonNode.get("inlineTypes").flatten()) }

        return TemplateFile(relativePath = "api.json",
                content = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(api)
        )
    }
}

class ExampleSerializer : JsonSerializer() {
    override fun serialize(value: Example?, gen: JsonGenerator?, serializers: SerializerProvider?) {
        gen?.writeObject(value?.value)
    }
}

class InlineTypeSerializer : JsonSerializer() {

    override fun serialize(value: AnyType?, gen: JsonGenerator?, serializers: SerializerProvider?) {
        val eVal = value?.eClass()
        val eFeat = eVal?.eAllStructuralFeatures
        gen?.writeStartObject()
        for (con in eFeat!!) {
            if (con.name == "subTypes") {
                continue
            }
            if (con.name == "inlineTypes") {
                continue
            }
            when (val eValue = value.eGet(con)) {
                is List<*> -> {
                    if (eValue.size > 0)
                        gen?.writeObjectField(con.name, eValue)
                }
                null -> {}
                else ->
                    gen?.writeObjectField(con.name, eValue)
            }
        }
        gen?.writeEndObject()
//        when (value?.isInlineType) {
//            true -> {
//                gen?.writeString("inlineType")
//            }
//            else -> {
//                gen?.writeObject(value)
//            }
//        }
    }
}

class ReferenceSerializer (private val ecoreReferenceSerializer: JsonSerializer) : JsonSerializer() {

    override fun serialize(value: EObject?, gen: JsonGenerator?, serializers: SerializerProvider?) {
        when (value) {
            is AnyType -> {
                gen?.writeString(value.name)
            }
            is AnyAnnotationType -> {
                gen?.writeString(value.name)
            }
            else ->
                ecoreReferenceSerializer.serialize(value, gen, serializers)
        }
    }
}

class UriTemplateSerializer : JsonSerializer() {
    override fun serialize(value: UriTemplate, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeString(value.template)
    }
}

// @ToDo: correct serialization of pattern properties
class RegExpSerializer : JsonSerializer() {
    @Throws(IOException::class)
    override fun serialize(value: RegExp, gen: JsonGenerator, provider: SerializerProvider) {
        gen.writeString("/" + value.toString() + "/")
    }
}

class SomePropertyFilter : SimpleBeanPropertyFilter() {
    @Throws(Exception::class)
    override fun serializeAsField(pojo: Any, jgen: JsonGenerator, provider: SerializerProvider, writer: PropertyWriter) {
        if (include(writer)) {
            if (writer.getName().equals("subTypes")) {
                return
            }
            writer.serializeAsField(pojo, jgen, provider)
        } else if (!jgen.canOmitFields()) { // since 2.3
            writer.serializeAsOmittedField(pojo, jgen, provider)
        }
    }

    protected override fun include(writer: BeanPropertyWriter): Boolean {
        return true
    }

    protected override fun include(writer: PropertyWriter): Boolean {
        return true
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy