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

io.vrap.codegen.languages.javalang.client.builder.predicates.JavaExpansionPredicateRenderer.kt Maven / Gradle / Ivy

package io.vrap.codegen.languages.javalang.client.builder.predicates;

import com.google.common.collect.Lists
import io.vrap.codegen.languages.extensions.hasSubtypes
import io.vrap.codegen.languages.extensions.isPatternProperty
import io.vrap.codegen.languages.extensions.namedSubTypes
import io.vrap.codegen.languages.java.base.extensions.*
import io.vrap.rmf.codegen.firstLowerCase
import io.vrap.rmf.codegen.firstUpperCase
import io.vrap.rmf.codegen.io.TemplateFile
import io.vrap.rmf.codegen.rendering.ObjectTypeRenderer
import io.vrap.rmf.codegen.rendering.utils.escapeAll
import io.vrap.rmf.codegen.rendering.utils.keepAngleIndent
import io.vrap.rmf.codegen.rendering.utils.keepIndentation
import io.vrap.rmf.codegen.types.*
import io.vrap.rmf.raml.model.types.*
import io.vrap.rmf.raml.model.types.Annotation
import io.vrap.rmf.raml.model.util.StringCaseFormat
import java.time.LocalDate
import java.time.LocalTime
import java.time.ZonedDateTime
import javax.lang.model.SourceVersion

class JavaExpansionPredicateRenderer constructor(val basePackageName: String, override val vrapTypeProvider: VrapTypeProvider) : JavaObjectTypeExtensions,
    JavaEObjectTypeExtensions, ObjectTypeRenderer {

    override fun render(type: ObjectType): TemplateFile {
        val vrapType = vrapTypeProvider.doSwitch(type).toJavaVType() as VrapObjectType

        val implements = listOf("ExpansionDsl")
            .plus(
                when (val ex = type.getAnnotation("java-expansion-implements") ) {
                    is Annotation -> {
                        (ex.value as StringInstance).value.escapeAll()
                    }
                    else -> null
                }
            )
            .filterNotNull()

        val content = """
            |package ${vrapType.`package`.predicatePackage()};
            |
            |import com.commercetools.api.predicates.expansion.ExpansionDsl;
            |
            |import static com.commercetools.api.predicates.expansion.ExpansionUtil.appendOne;
            |
            |import java.util.Collections;
            |import java.util.List;
            |
            |${if (type.markDeprecated()) """
            |@Deprecated""" else ""}
            |public class ${vrapType.builderDslName()} ${if (implements.isNotEmpty()) { "implements ${implements.joinToString(separator = ", ")}" } else ""} {
            |
            |    private final List path;
            |    
            |    private ${vrapType.builderDslName()}(final List path) {
            |        this.path = path;
            |    }
            |
            |    public static ${vrapType.builderDslName()} of() {
            |        return new ${vrapType.builderDslName()}(Collections.emptyList());
            |    }
            |
            |    public static ${vrapType.builderDslName()} of(final List path) {
            |        return new ${vrapType.builderDslName()}(path);
            |    }
            |    
            |    @Override
            |    public List getPath() {
            |        return path;
            |    }
            |
            |    <<${type.allProperties.asSequence()
                    .filterNot { it.deprecated() }
                    .filterNot { it.type.isScalar() }
                    .filter { it.type.isExpandable() || (it.type is ArrayType && (it.type as ArrayType).items.isExpandable()) }
                    .joinToString("\n") { it.toBuilderDsl(type) }}>>
            |}
        """.trimMargin().keepAngleIndent()

        return TemplateFile(
            relativePath = "${vrapType.`package`.predicatePackage()}.${vrapType.builderDslName()}".replace(".", "/") + ".java",
            content = content
        )
    }

    private fun String.predicatePackage() : String {
        return this.replace(".models.", ".predicates.expansion.")
    }

    private fun Property.toBuilderDsl(type: ObjectType) : String {
        val vrapType = type.toVrapType()
        val propType = this.type.toVrapType()

        return propType.toBuilderDsl(this.name, this);
    }

    private fun VrapType.toBuilderDsl(propertyName: String, property: Property) : String {
        var methodName = propertyName
        if(SourceVersion.isKeyword(methodName)) {
            methodName = "_$methodName"
        }

        if (property.isPatternProperty()) {
            if (this.fullClassName() == "java.lang.Object") {
                return """
                    |public ${basePackageName.toJavaPackage()}.predicates.expansion.ObjectExpansionDsl withName(final String name) {
                    |   return ${basePackageName.toJavaPackage()}.predicates.expansion.ObjectExpansionDsl.of(appendOne(path, name));
                    |}
                    """.trimMargin()
            }
            return """
                |public ${(this as VrapObjectType).builderDslName(true)} withName(final String name) {
                |    return ${this.builderDslName(true)}.of(appendOne(path, name));
                |}
            """.trimMargin()
        }
        if (this is VrapArrayType) {
            return """
                |public ${this.builderDslName(true)} $methodName() {
                |    return ${this.builderDslName(true)}.of(appendOne(path, "$propertyName[*]"));
                |}
                |public ${this.builderDslName(true)} $methodName(long index) {
                |    return ${this.builderDslName(true)}.of(appendOne(path, "$propertyName[" + index + "]"));
                |}
            """.trimMargin()
        }
        if (this.fullClassName() == "java.lang.Object") {
            return """
            |public ${basePackageName.toJavaPackage()}.predicates.expansion.ObjectExpansionDsl $methodName() {
            |   return ${basePackageName.toJavaPackage()}.predicates.expansion.ObjectExpansionDsl.of(appendOne(path, "$propertyName"));
            |}
            """.trimMargin()
        }

        return """
            |public ${(this as VrapObjectType).builderDslName(true)} $methodName() {
            |   return ${this.builderDslName(true)}.of(appendOne(path, "$propertyName"));
            |}
        """.trimMargin()
    }

    private fun VrapArrayType.builderDslName(fqcn: Boolean = false) : String {
        return "${if (fqcn) this.itemType.fullClassName().predicatePackage() else this.itemType.simpleName()}ExpansionBuilderDsl"
    }

    private fun VrapObjectType.builderDslName(fqcn: Boolean = false) : String {
        return "${if (fqcn) this.fullClassName().predicatePackage() else this.simpleName()}ExpansionBuilderDsl"
    }

    private fun ObjectType.markDeprecated() : Boolean {
        val anno = this.getAnnotation("markDeprecated")
        return (anno != null && (anno.value as BooleanInstance).value)
    }

    private fun AnyType.isAnyType(): Boolean {
        return this.isScalar().not() && this !is ObjectType && this !is ArrayType && this !is UnionType && this !is IntersectionType && this !is NilType
    }

    private fun AnyType.isScalar(): Boolean {
        return when (this) {
            is StringType -> true
            is IntegerType -> true
            is NumberType -> true
            is BooleanType -> true
            is DateTimeType -> true
            is DateOnlyType -> true
            is DateTimeOnlyType -> true
            is TimeOnlyType -> true
            is ArrayType -> this.items == null || this.items.isScalar()
            else -> false
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy