Info generator structure

This commit is contained in:
slon565 2023-08-09 13:11:07 +04:00
parent 0686dd7c93
commit 71d16dd569
4 changed files with 117 additions and 0 deletions

View file

@ -16,6 +16,7 @@ java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") }
maven { url = uri("https://jitpack.io") }
}
val exposedVersion = "0.41.1"
@ -54,10 +55,19 @@ dependencies {
implementation("io.github.microutils:kotlin-logging-jvm:$loggingVersion")
implementation("org.postgresql:postgresql:$postgresVersion")
implementation("nl.devhaan:KotlinPoetDSL:0.1.1")
//testImplementation("org.springframework.security:spring-security-test:$securityTestVersion")
testImplementation("org.springframework.boot:spring-boot-starter-test:$springBootVersion")
}
sourceSets {
main {
java.srcDirs(File("C:\\Users\\Andrey\\IdeaProjects\\sicamp-helper\\build\\generated\\source"))
kotlin.srcDirs(File("C:\\Users\\Andrey\\IdeaProjects\\sicamp-helper\\build\\generated\\source"))
}
}
configurations.all {
resolutionStrategy {
eachDependency {

View file

@ -4,11 +4,15 @@ import org.jetbrains.exposed.dao.LongEntity
import org.jetbrains.exposed.dao.LongEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import ru.sicamp.sicamphelper.db.table.Rooms
import ru.sicamp.sicamphelper.generator.Info
class Room(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<Room>(Rooms)
@Info
var name by Rooms.name
@Info
var type by Rooms.type
@Info
var description by Rooms.description
}

View file

@ -6,20 +6,28 @@ import org.jetbrains.exposed.dao.id.EntityID
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
import ru.sicamp.sicamphelper.db.table.Users
import ru.sicamp.sicamphelper.generator.Info
import java.time.LocalDateTime
class User(id: EntityID<Long>) : LongEntity(id), UserDetails {
companion object : LongEntityClass<User>(Users)
@Info
var login by Users.login
@Info
var name by Users.name
var supervisor by User optionalReferencedOn Users.supervisor
var _password by Users.password
@Info
var tgId by Users.tgId
@Info
var tgUsername by Users.tgUsername
@Info
var role by Users.role
var group by Group referencedOn Users.group
@Info
var sex by Users.sex
@Info
var age by Users.age
var locked by Users.locked
var enabled by Users.enabled

View file

@ -0,0 +1,95 @@
package ru.sicamp.sicamphelper.generator
import com.squareup.kotlinpoet.asTypeName
import mu.KLogging
import nl.devhaan.kotlinpoetdsl.classes.clazz
import nl.devhaan.kotlinpoetdsl.constructorBuilder.buildConstructor
import nl.devhaan.kotlinpoetdsl.constructorBuilder.constructor
import nl.devhaan.kotlinpoetdsl.constructorBuilder.thiz
import nl.devhaan.kotlinpoetdsl.files.file
import nl.devhaan.kotlinpoetdsl.of
import nl.devhaan.kotlinpoetdsl.packaged
import nl.devhaan.kotlinpoetdsl.public
import nl.devhaan.kotlinpoetdsl.valOf
import ru.sicamp.sicamphelper.db.entity.Room
import ru.sicamp.sicamphelper.db.entity.User
import java.io.File
import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties
class InfoGenerator {
fun <T : Any> generateInfo(kClass: KClass<T>) {
val className = "${kClass.simpleName}Info"
logger.info("Beginning generating $className")
val file = File("C:\\Users\\Andrey\\IdeaProjects\\sicamp-helper\\build\\generated\\source")
file(GENERATED_PACKAGE, className) {
val constructorParameters = kClass.infoVariables()
val secondaryConstructor = buildConstructor {
val entityName = "entity"
constructor(entityName of kClass).thiz(
*constructorParameters.map {
"$entityName.${it.name}"
}.toTypedArray()
) {}
}
logger.info("Found ${constructorParameters.size} parameters")
clazz(className, *constructorParameters.toTypedArray()) {
public.constructor(secondaryConstructor)
}.packaged(GENERATED_PACKAGE)
}.writeTo(file)
}
private fun KClass<*>.infoPropertiesWithAnnotations() = memberProperties.mapNotNull { property ->
property.annotations.firstOrNull { it is Info }?.let { annotation ->
property to annotation
}
}.also { logger.info("Found ${it.size} properties") }
private fun KClass<*>.infoVariables() = infoPropertiesWithAnnotations()
.map { (property, annotation) ->
logger.info("Getting type for ${property.name}")
val typeName = property.returnType.asTypeName()
property.name.valOf(
if (annotation is Info) {
if (property.returnType.isMarkedNullable) {
typeName.asNullable()
} else {
typeName
}
} else {
error("Annotation $annotation is not of type Info")
}
)
}
companion object : KLogging() {
const val GENERATED_PACKAGE = "ru.sicamp.helper.generated"
}
}
@Target(AnnotationTarget.CLASS)
annotation class GeneratorTarget
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class Info
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class Dto
@GeneratorTarget
class A(
@Info
val a: String? = "a",
@Info
val c: String = "c",
@Dto
val b: String = "b"
)
fun main() {
InfoGenerator().generateInfo(User::class)
InfoGenerator().generateInfo(Room::class)
}