Sharing a huge and complicated set of data model classes (POJOs) across multiple applications can be painful. That set of tools greatly reduces a lot of boilerplate code.
What you need is to describe an interface of data class. Annotation processing will make the rest of it:
-
Generate mutable interface;
-
Generate default
data class
implementation; -
Generate DSL function for
data class
initialization.
Don’t forget to add kapt plugin to build.gradle
:
plugins {
id 'kotlin-kapt'
}
Add a custom repository and model
dependencies:
repositories {
mavenCentral()
maven {
url 'https://packages.eraga.net/repository/eraga-public-maven-releases/'
}
}
dependencies {
compileOnly "net.eraga.tools.model:model-annotations:1.1.0"
kapt "net.eraga.tools.model:model-processor:1.1.0"
}
Describe your POJO as kotlin interface
@ImplementModel(implSuffix = "Data")
interface Category {
val id: Int
val weight: Int
val name: String
}
Run ./gradlew build
and you will get following kapt output in
your build/generated
folder:
import java.io.Serializable
import kotlin.Int
import kotlin.String
import kotlin.Unit
interface CategoryMutableModel : Category {
override var id: Int
override var weight: Int
override var name: String
}
data class CategoryData(
override var id: Int = 0,
override var weight: Int = 0,
override var name: String = ""
) : CategoryMutableModel, Serializable
fun categoryData(init: CategoryData.() -> Unit): Category {
val instance = CategoryData()
instance.init()
return instance
}
Example DSL to create an object of Category
type.
val animals = categoryData {
name = "Animals"
id = 1
weight = 10
}
class OtherCategory(
override val id: Int,
override val weight: Int,
override val name: String,
var parent: Category) : Category {
}
fun main(args: Array<String>) {
val animals = categoryData {
name = "Animals"
id = 1
weight = 10
}
val otherCategory = OtherCategory(1, 1, "Tigers", parent = animals)
}
interface WithAnyId {
val id: Any
}
interface WithStringId : WithAnyId {
override val id: String
}
interface WithUUId : WithAnyId {
@ConstructorInitializer(value = "UUID.randomUUID()")
override val id: UUID
@ConstructorInitializer(value = "LocalDateTime.now()")
val dateTime: LocalDateTime
/**
* Chosen by fair roll of dice, don't override in implementations
*/
@PreventOverride
val randomNumber: Long
get() = 4
}