Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create BaseModels for Schemas #88

Merged
merged 2 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object EntityFactory {
) as EntityHolder
}

fun createBaseModelHolder(
fun createWrapperBaseModelHolder(
sourceModel: ISourceModel,
allWrapperPaths: List<String>
): BaseModelHolder {
Expand All @@ -53,6 +53,19 @@ object EntityFactory {
) as BaseModelHolder
}

fun createSchemaBaseModelHolder(
sourceModel: ISourceModel,
allSchemaClassPaths: List<String>
): BaseModelHolder {
return create(
sourceModel,
BaseModelHolder(sourceModel),
allSchemaClassPaths,
emptyMap(),
SCHEMA_SUB_ENTITY_SUFFIX
) as BaseModelHolder
}

fun createChildEntityHolder(
sourceModel: ISourceModel,
allWrapperPaths: List<String>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class ModelWorkSet(

private val schemaModels: MutableMap<String, SchemaClassHolder> = HashMap()

private val baseModels: MutableMap<String, BaseModelHolder> = HashMap()
private val wrapperBaseModels: MutableMap<String, BaseModelHolder> = HashMap()

private val schemaBaseModels: MutableMap<String, BaseModelHolder> = HashMap()

private val typeConverterModels: MutableMap<String, TypeConverterHolder> = HashMap()

Expand Down Expand Up @@ -66,21 +68,27 @@ class ModelWorkSet(

override fun loadModels(logger: Logger, env: ProcessingEnvironment) {
val allWrapperPaths = allWrapperElements.map { element -> element.toString() }
val allSchemaClassPaths = allSchemaClassElements.map { element -> element.toString() }

for (element in allBaseModelElements) {
val baseModel =
EntityFactory.createBaseModelHolder(SourceModel(element), allWrapperPaths)
baseModels[element.toString()] = baseModel
val wrapperBaseModel = EntityFactory.createWrapperBaseModelHolder(SourceModel(element), allWrapperPaths)
wrapperBaseModels[element.toString()] = wrapperBaseModel

val schemaBaseModel = EntityFactory.createSchemaBaseModelHolder(SourceModel(element), allSchemaClassPaths)
schemaBaseModels[element.toString()] = schemaBaseModel
}

// we can resolve the based on chain when all base models are parsed.
for (baseModel in baseModels.values) {
EntityFactory.addBasedOn(baseModel.sourceElement, baseModels, baseModel)
for (baseModel in wrapperBaseModels.values) {
EntityFactory.addBasedOn(baseModel.sourceElement, wrapperBaseModels, baseModel)
}

for (baseModel in schemaBaseModels.values) {
EntityFactory.addBasedOn(baseModel.sourceElement, schemaBaseModels, baseModel)
}

for (element in allEntityElements) {
val entityModel =
EntityFactory.createEntityHolder(SourceModel(element), allWrapperPaths, baseModels)
val entityModel = EntityFactory.createEntityHolder(SourceModel(element), allWrapperPaths, wrapperBaseModels)
entityModels[element.toString()] = entityModel

entityModel.reducesModels.forEach {
Expand All @@ -90,7 +98,7 @@ class ModelWorkSet(
it
),
allWrapperPaths,
baseModels
wrapperBaseModels
)
reduced.isReduced = true
entityModels[reduced.entitySimpleName] = reduced
Expand All @@ -101,7 +109,7 @@ class ModelWorkSet(
val wrapperModel = EntityFactory.createChildEntityHolder(
SourceModel(element),
allWrapperPaths,
baseModels
wrapperBaseModels
)
wrapperModels[element.toString()] = wrapperModel

Expand All @@ -112,19 +120,18 @@ class ModelWorkSet(
it
),
allWrapperPaths,
baseModels
wrapperBaseModels
)
reduced.isReduced = true
entityModels[reduced.entitySimpleName] = reduced
}
}

val allSchemaClassPaths = allSchemaClassElements.map { element -> element.toString() }
for (element in allSchemaClassElements) {
val schemaModel = EntityFactory.createSchemaEntityHolder(
SourceModel(element),
allSchemaClassPaths,
baseModels
schemaBaseModels
)
schemaModels[element.toString()] = schemaModel
}
Expand All @@ -145,7 +152,6 @@ class ModelWorkSet(

ModelValidation(
logger,
baseModels,
wrapperModels,
entityModels,
typeConverterModels.values.toList(),
Expand All @@ -166,7 +172,7 @@ class ModelWorkSet(
get() = schemaModels.keys.toList()

val bases: List<BaseModelHolder>
get() = baseModels.values.toList()
get() = wrapperBaseModels.values.toList()

val typeConverters: List<TypeConverterHolder>
get() = typeConverterModels.values.toList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.schwarz.crystalprocessor.generation.model.TypeConverterObjectGenerati
import com.schwarz.crystalprocessor.generation.model.WrapperGeneration
import com.schwarz.crystalprocessor.meta.SchemaGenerator
import com.schwarz.crystalprocessor.model.entity.BaseEntityHolder
import com.schwarz.crystalprocessor.model.entity.SchemaClassHolder
import com.schwarz.crystalprocessor.model.typeconverter.TypeConverterHolderForEntityGeneration
import com.schwarz.crystalprocessor.processing.Worker
import com.squareup.kotlinpoet.FileSpec
Expand Down Expand Up @@ -78,7 +79,7 @@ class ModelWorker(override val logger: Logger, override val codeGenerator: CodeG
WrapperGeneration().generateModel(it, useSuspend, typeConvertersByConvertedClass)
}

process(workSet.schemas, generatedInterfaces, useSuspend, typeConvertersByConvertedClass) {
process(workSet.schemas) {
SchemaGeneration().generateModel(it, workSet.schemaClassPaths, typeConvertersByConvertedClass)
}

Expand All @@ -87,15 +88,8 @@ class ModelWorker(override val logger: Logger, override val codeGenerator: CodeG
schemaGenerator?.generate()
}

private fun <T : BaseEntityHolder> process(
models: List<T>,
generatedInterfaces: MutableSet<String>,
useSuspend: Boolean,
typeConvertersByConvertedClass: Map<TypeName, TypeConverterHolderForEntityGeneration>,
generate: (T) -> FileSpec
) {
for (model in models) {
generateInterface(generatedInterfaces, model, useSuspend, typeConvertersByConvertedClass)
private fun process(schemaModels: List<SchemaClassHolder>, generate: (SchemaClassHolder) -> FileSpec) {
for (model in schemaModels) {
documentationGenerator?.addEntitySegments(model)
schemaGenerator?.addEntity(model)
entityRelationshipGenerator?.addEntityNodes(model)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.schwarz.crystalprocessor.validation.model

import com.schwarz.crystalapi.Reduce
import com.schwarz.crystalapi.TypeConverter
import com.schwarz.crystalapi.deprecated.DeprecatedField
import com.schwarz.crystalprocessor.Logger
import com.schwarz.crystalprocessor.model.entity.BaseEntityHolder
import com.schwarz.crystalprocessor.model.entity.BaseModelHolder
import com.schwarz.crystalprocessor.model.entity.EntityHolder
import com.schwarz.crystalprocessor.model.entity.WrapperEntityHolder
import com.schwarz.crystalapi.Reduce
import com.schwarz.crystalapi.TypeConverter
import com.schwarz.crystalapi.deprecated.DeprecatedField
import com.schwarz.crystalprocessor.model.typeconverter.ImportedTypeConverterHolder
import com.schwarz.crystalprocessor.model.typeconverter.TypeConverterHolder
import com.schwarz.crystalprocessor.model.typeconverter.TypeConverterHolderForEntityGeneration
Expand All @@ -17,7 +16,6 @@ import com.squareup.kotlinpoet.ParameterizedTypeName

class ModelValidation(
val logger: Logger,
val baseModels: MutableMap<String, BaseModelHolder>,
val wrapperModels: MutableMap<String, WrapperEntityHolder>,
val entityModels: MutableMap<String, EntityHolder>,
val typeConverterModels: List<TypeConverterHolder>,
Expand Down Expand Up @@ -197,7 +195,10 @@ class ModelValidation(
private fun validateTypeConversions() {
typeConverterModels.forEach {
if (!nonConvertibleClassesTypeNames.contains(it.mapClassTypeName)) {
logger.error("Invalid map type ${it.mapClassTypeName} found in TypeConverter ${it.classTypeName}. Should be one of $nonConvertibleClassesTypeNames", null)
logger.error(
"Invalid map type ${it.mapClassTypeName} found in TypeConverter ${it.classTypeName}. Should be one of $nonConvertibleClassesTypeNames",
null
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,59 @@ class CouchbaseBaseBinderProcessorKotlinTest {
Assert.assertEquals(expected, actual)
}

@Test
fun testKotlinSchemaGenerationWithBasedOn() {
val expected = File("src/test/resources/ExpectedSubSchema.txt").readLines()
val testObject = SourceFile.kotlin(
"TestObject.kt",
PACKAGE_HEADER +
"import com.schwarz.crystalapi.Fields\n" +
"import com.schwarz.crystalapi.Field\n" +
"import com.schwarz.crystalapi.MapWrapper\n" +
"import com.schwarz.crystalapi.SchemaClass\n" +
"@MapWrapper\n" +
"@SchemaClass\n" +
"@Fields(\n" +
"Field(name = \"type\", type = String::class, defaultValue = \"test\", readonly = true)\n" +
")\n" +
"open class TestObject"
)
val base = SourceFile.kotlin(
"Base.kt",
PACKAGE_HEADER +
"import com.schwarz.crystalapi.BaseModel\n" +
"import com.schwarz.crystalapi.Fields\n" +
"import com.schwarz.crystalapi.Field\n" +
"@BaseModel\n" +
"@Fields(\n" +
"Field(name = \"someObject\", type = TestObject::class)\n" +
")\n" +
"open class Base"
)
val sub = SourceFile.kotlin(
"Sub.kt",
PACKAGE_HEADER +
"import com.kaufland.testModels.TestObject\n" +
"import com.schwarz.crystalapi.BasedOn\n" +
"import com.schwarz.crystalapi.Field\n" +
"import com.schwarz.crystalapi.Fields\n" +
"import com.schwarz.crystalapi.SchemaClass\n" +
"import java.time.OffsetDateTime\n" +
"@SchemaClass\n" +
"@BasedOn(Base::class)\n" +
"@Fields(\n" +
"Field(name = \"type\", type = String::class, defaultValue = \"sub\", readonly = true)\n" +
")\n" +
"class Sub"
)
val compilation = compileKotlin(base, testObject, sub)

val actual = compilation.generatedFiles.find { it.name == "SubSchema.kt" }!!.readLines()

Assert.assertEquals(KotlinCompilation.ExitCode.OK, compilation.exitCode)
Assert.assertEquals(expected, actual)
}

@Test
fun testKotlinPrivateGeneration() {
val subEntity = SourceFile.kotlin(
Expand Down
26 changes: 26 additions & 0 deletions crystal-map-processor/src/test/resources/ExpectedSubSchema.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// DO NOT EDIT THIS FILE.
// Generated using Crystal-Map
//
// Do not edit this class!!!!.
//
package com.kaufland.testModels

import com.schwarz.crystalapi.schema.CMJsonField
import com.schwarz.crystalapi.schema.CMObjectField
import com.schwarz.crystalapi.schema.Schema
import kotlin.String

public open class SubSchema(
path: String = "",
) : Schema {
public val DEFAULT_TYPE: String = "sub"

public val type: CMJsonField<String> = CMJsonField("type", path)

public val someObject: CMObjectField<TestObjectSchema> = CMObjectField(
com.kaufland.testModels.TestObjectSchema(if (path.isBlank()) "someObject" else
"$path.someObject"),
"someObject",
path,
)
}
Loading