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

io.vrap.codegen.languages.csharp.extensions.CsharpVrapExtensions.kt Maven / Gradle / Ivy

Go to download

RAML API client code generators based on the REST Modeling Framework. https://github.com/vrapio/rest-modeling-framework

There is a newer version: 1.0.0-20241120142200
Show newest version
package io.vrap.codegen.languages.csharp.extensions

import com.damnhandy.uri.template.Expression
import com.damnhandy.uri.template.UriTemplate
import com.google.common.collect.Lists
import io.vrap.rmf.codegen.types.*
import io.vrap.rmf.raml.model.util.StringCaseFormat
import com.hypertino.inflector.English
import io.vrap.rmf.raml.model.resources.Method
import io.vrap.rmf.raml.model.resources.Resource
import io.vrap.rmf.raml.model.responses.Body
import io.vrap.rmf.raml.model.types.*
import java.util.*

fun VrapType.simpleName(): String {
    return when (this) {
        is VrapScalarType -> this.scalarType
        is VrapDateTimeType -> this.simpleClassName
        is VrapEnumType -> "I"+this.simpleClassName
        is VrapObjectType -> if(this.simpleClassName == "Date" || this.simpleClassName == "DateTime" || this.simpleClassName == "TimeSpan" || this.simpleClassName == "Object") this.simpleClassName else "I${this.simpleClassName}"
        is VrapAnyType -> this.baseType
        is VrapArrayType -> """IList\<${this.itemType.simpleName()}\>"""
        is VrapNilType -> throw IllegalStateException("$this has no simple class name.")
    }
}

fun VrapType.toCsharpVType(): VrapType {
    return when (this) {
        is VrapObjectType -> {
            VrapObjectType(`package` = this.`package`.toCsharpPackage(), simpleClassName = this.simpleClassName)
        }
        is VrapEnumType -> {
            VrapEnumType(`package` = this.`package`.toCsharpPackage(), simpleClassName = this.simpleClassName)
        }
        is VrapArrayType -> {
            VrapArrayType(this.itemType.toCsharpVType())
        }
        else -> {
            this
        }

    }
}

fun VrapType.csharpPackage(): String {
    var packageName = ""
    if (this is VrapObjectType) packageName = this.`package`
    else if (this is VrapEnumType) packageName = this.`package`

    if(!packageName.isNullOrEmpty())
        packageName = packageName.toCsharpPackage()
    return packageName
}
//need refactor
fun VrapType.requestBuildersPackage(resourceNamePlural: String): String {
    var cPackage = this.csharpPackage().replace("Clients","Client")
    return if(resourceNamePlural.isNullOrEmpty()) "$cPackage.RequestBuilders" else "$cPackage.RequestBuilders.$resourceNamePlural"
}

/**
 * Returns package "commercetools.API/models/Order" as csharp namespace, example "commercetools.API.Models.Orders"
 * Don't appply camelCase to commercetools
 */
fun String.toCsharpPackage():String{
    if(!this.contains("/"))
        return this
    var packageAsList = this.split("/")
    var first = packageAsList.first()
    var domainTypeAsPlural = packageAsList.last().singularize().pluralize()
    packageAsList = packageAsList.dropLast(1).plus(domainTypeAsPlural)

    return packageAsList.takeLast(maxOf(packageAsList.size, 1)).joinToString(".")
    {
        s -> if(s == first) {
        return@joinToString s
        } else return@joinToString StringCaseFormat.UPPER_CAMEL_CASE.apply(s)
    }
}

/**
 * Returns physical path of the file should be generated like "commercetools/API/models/Orders/OrderDraft.cs"
 */
fun VrapType.csharpClassRelativePath(isInterface: Boolean = false): String {
    var packageName = "";
    var simpleClassName = ""

    if (this is VrapObjectType) {
        packageName = this.`package`
        simpleClassName = this.simpleClassName
    } else if (this is VrapEnumType) {
        packageName = this.`package`
        simpleClassName = this.simpleClassName
    }

    var namespaceDir = packageName.toNamespaceDir()
    var fileName = if (isInterface) "I${simpleClassName}" else "${simpleClassName}"

    return "${namespaceDir}.${fileName}".replace(".", "/") + ".cs"
}

/**
 * Package example "commercetools.API/models/Order"
 * Returns physical path of the file should be generated like "commercetools/API/Models/Orders"
 */
fun String.toNamespaceDir():String{
    if(!this.contains("/"))
        return this

    var packageAsList = this.split("/")
    var domainTypeAsPlural = packageAsList.last().singularize().pluralize()
    packageAsList = packageAsList.dropLast(1).plus(domainTypeAsPlural)
    return packageAsList.joinToString("/") { s -> StringCaseFormat.UPPER_CAMEL_CASE.apply(s) }.lowerCamelCase()
}

fun String.pluralize(): String {
    val typesToExcluded = arrayOf("common", "me", "graphql")
    if(typesToExcluded.contains(this.lowercase(Locale.getDefault())))
        return this
   return English.plural(this)
}

fun String.singularize(): String {
    return English.singular(this)
}

fun AnyType.isNullableScalar(): Boolean {
    return when (this) {
        is IntegerType -> true
        is NumberType -> true
        is BooleanType -> true
        is DateTimeType -> true
        is DateOnlyType -> true
        is DateTimeOnlyType -> true
        is TimeOnlyType -> true
        is StringType -> false
        is ArrayType -> false
        else -> false
    }
}

fun Resource.resourcePathList(): List {
    val path = Lists.newArrayList()
    if (this.fullUri.template == "/") {
        return path
    }
    path.add(this)
    var t = this.eContainer()
    while (t is Resource) {
        val template = t.fullUri.template
        if (template != "/") {
            path.add(t)
        }
        t = t.eContainer()
    }
    return Lists.reverse(path)
}
fun UriTemplate.paramValues(): List {
    return this.components.filterIsInstance().flatMap { expression -> expression.varSpecs.map { varSpec -> varSpec.variableName  } }
}

fun Method.firstBody(): Body? = this.bodies.stream().findFirst().orElse(null)

fun QueryParameter.methodName(): String {
    val anno = this.getAnnotation("placeholderParam", true)

    if (anno != null) {
        val o = anno.value as ObjectInstance
        val paramName = o.value.stream().filter { propertyValue -> propertyValue.name == "paramName" }.findFirst().orElse(null).value as StringInstance
        return "With" + StringCaseFormat.UPPER_CAMEL_CASE.apply(paramName.value)
    }
    return "With" + StringCaseFormat.UPPER_CAMEL_CASE.apply(this.name.replace(".", "-"))
}

fun Property.deprecated() : Boolean {
    val anno = this.getAnnotation("deprecated")
    if (anno != null) {
        return (anno.value as BooleanInstance).value
    }
    val typeAnno = this.type.getAnnotation("deprecated")
    return (typeAnno != null && (typeAnno.value as BooleanInstance).value)
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy