Skip to content

Commit

Permalink
refactor(render): separate property and class introspector
Browse files Browse the repository at this point in the history
  • Loading branch information
jbl428 committed Nov 9, 2023
1 parent 3a2fbc7 commit 9de2e4a
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlIntrospectorModifier
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlRenderIntrospector
import com.linecorp.kotlinjdsl.render.jpql.introspector.impl.JakartaJpqlIntrospector
import com.linecorp.kotlinjdsl.render.jpql.introspector.impl.JavaxJpqlIntrospector
import com.linecorp.kotlinjdsl.render.jpql.introspector.impl.KotlinStyleJpqlPropertyIntrospector
import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlRenderSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializer
import com.linecorp.kotlinjdsl.render.jpql.serializer.JpqlSerializerModifier
Expand Down Expand Up @@ -246,6 +247,8 @@ private class DefaultModule : JpqlRenderModule {
context.appendIntrospector(JakartaJpqlIntrospector())
}

context.appendIntrospector(KotlinStyleJpqlPropertyIntrospector())

context.addAllSerializer(
JpqlAliasedExpressionSerializer(),
JpqlAndSerializer(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.linecorp.kotlinjdsl.render.jpql.introspector

import com.linecorp.kotlinjdsl.SinceJdsl
import kotlin.reflect.KCallable

/**
* Abstract class to get the entity information by introspecting KClass.
*/
@SinceJdsl("3.1.0")
abstract class JpqlEntityIntrospector : JpqlIntrospector {
override fun introspect(property: KCallable<*>): JpqlPropertyDescription? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.linecorp.kotlinjdsl.render.jpql.introspector

import com.linecorp.kotlinjdsl.SinceJdsl
import kotlin.reflect.KClass

/**
* Abstract class to get the entity information by introspecting KCallable.
*/
@SinceJdsl("3.1.0")
abstract class JpqlPropertyIntrospector : JpqlIntrospector {
override fun introspect(type: KClass<*>): JpqlEntityDescription? = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@ package com.linecorp.kotlinjdsl.render.jpql.introspector.impl

import com.linecorp.kotlinjdsl.Internal
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlEntityDescription
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlIntrospector
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlPropertyDescription
import kotlin.reflect.KCallable
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlEntityIntrospector
import kotlin.reflect.KClass
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotations

/**
* Introspector that introspects KClass and KCallable using [jakarta.persistence.Entity].
* Introspector that introspects KClass using [jakarta.persistence.Entity].
*/
@Internal
class JakartaJpqlIntrospector : JpqlIntrospector {
class JakartaJpqlIntrospector : JpqlEntityIntrospector() {
override fun introspect(type: KClass<*>): JpqlEntityDescription? {
val entity = type.findAnnotations(jakarta.persistence.Entity::class).firstOrNull()

Expand All @@ -24,21 +20,6 @@ class JakartaJpqlIntrospector : JpqlIntrospector {
null
}
}

override fun introspect(property: KCallable<*>): JpqlPropertyDescription? {
return when (property) {
is KProperty1<*, *> -> JpqlProperty(property.name)
is KFunction1<*, *> -> JpqlProperty(resolvePropertyName(property))
else -> null
}
}

private fun resolvePropertyName(getter: KFunction1<*, *>): String =
if (getter.name.startsWith("is")) {
getter.name
} else {
getter.name.removePrefix("get").replaceFirstChar { it.lowercase() }
}
}

private data class JakartaEntity(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@ package com.linecorp.kotlinjdsl.render.jpql.introspector.impl

import com.linecorp.kotlinjdsl.Internal
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlEntityDescription
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlIntrospector
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlPropertyDescription
import kotlin.reflect.KCallable
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlEntityIntrospector
import kotlin.reflect.KClass
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotations

/**
* Introspector that introspects KClass and KCallable using [javax.persistence.Entity].
* Introspector that introspects KClass using [javax.persistence.Entity].
*/
@Internal
class JavaxJpqlIntrospector : JpqlIntrospector {
class JavaxJpqlIntrospector : JpqlEntityIntrospector() {
override fun introspect(type: KClass<*>): JpqlEntityDescription? {
val entity = type.findAnnotations(javax.persistence.Entity::class).firstOrNull()

Expand All @@ -24,21 +20,6 @@ class JavaxJpqlIntrospector : JpqlIntrospector {
null
}
}

override fun introspect(property: KCallable<*>): JpqlPropertyDescription? {
return when (property) {
is KProperty1<*, *> -> JpqlProperty(property.name)
is KFunction1<*, *> -> JpqlProperty(resolvePropertyName(property))
else -> null
}
}

private fun resolvePropertyName(getter: KFunction1<*, *>): String =
if (getter.name.startsWith("is")) {
getter.name
} else {
getter.name.removePrefix("get").replaceFirstChar { it.lowercase() }
}
}

private data class JavaxEntity(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.linecorp.kotlinjdsl.render.jpql.introspector.impl

import com.linecorp.kotlinjdsl.Internal
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlPropertyDescription
import com.linecorp.kotlinjdsl.render.jpql.introspector.JpqlPropertyIntrospector
import kotlin.reflect.KCallable
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty1

/**
* Introspector that introspects a property name in KCallable using Kotlin style.
*/
@Internal
class KotlinStyleJpqlPropertyIntrospector : JpqlPropertyIntrospector() {
override fun introspect(property: KCallable<*>): JpqlPropertyDescription? {
return when (property) {
is KProperty1<*, *> -> KotlinStyleProperty(property.name)
is KFunction1<*, *> -> KotlinStyleProperty(resolvePropertyName(property))
else -> null
}
}

private fun resolvePropertyName(getter: KFunction1<*, *>): String =
if (getter.name.startsWith("is")) {
getter.name
} else {
getter.name.removePrefix("get").replaceFirstChar { it.lowercase() }
}
}

private data class KotlinStyleProperty(
override val name: String,
) : JpqlPropertyDescription
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.linecorp.kotlinjdsl.render.jpql.introspector.impl

import io.mockk.mockkClass
import org.assertj.core.api.WithAssertions
import org.junit.jupiter.api.Test
import kotlin.reflect.KProperty0

class JakartaJpqlIntrospectorTest : WithAssertions {
private val sut = JakartaJpqlIntrospector()
Expand All @@ -13,7 +11,7 @@ class JakartaJpqlIntrospectorTest : WithAssertions {
}

@Test
fun `introspect(type) returns name of entity annotation, when entity annotation has name`() {
fun `introspect() returns name of entity annotation, when entity annotation has name`() {
// given
val type = EntityClass1::class

Expand All @@ -25,7 +23,7 @@ class JakartaJpqlIntrospectorTest : WithAssertions {
}

@Test
fun `introspect(type) returns name of class, when entity annotation does not have name`() {
fun `introspect() returns name of class, when entity annotation does not have name`() {
// given
val type = EntityClass2::class

Expand All @@ -37,7 +35,7 @@ class JakartaJpqlIntrospectorTest : WithAssertions {
}

@Test
fun `introspect(type) returns null, when there is no entity annotation`() {
fun `introspect() returns null, when there is no entity annotation`() {
// given
val type = NonEntityCLass1::class

Expand All @@ -48,76 +46,8 @@ class JakartaJpqlIntrospectorTest : WithAssertions {
assertThat(actual?.name).isNull()
}

@Test
fun `introspect(property) returns property name, when property is KProperty1`() {
// given
val property = EntityClass1::property1

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("property1")
}

@Test
fun `introspect(property) returns property name with prefix removed, when getter name starts with get`() {
// given
val property = EntityClass1::getProperty2

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("property2")
}

@Test
fun `introspect(property) returns property name as is, when getter name starts with is`() {
// given
val property = EntityClass1::isProperty3

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("isProperty3")
}

@Test
fun `introspect(property) returns property name as is, when getter name does not start with get or is`() {
// given
val property = EntityClass1::someProperty

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("someProperty")
}

@Test
fun `introspect(property) returns null, when property is not KProperty1 or KFunction1`() {
// given
val property = mockkClass(KProperty0::class)

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isNull()
}

@jakarta.persistence.Entity(name = ENTITY_NAME_1)
private open class EntityClass1 {
val property1: Long = 0

fun getProperty2(): Long = 100

fun isProperty3(): Boolean = true

fun someProperty(): String = "someProperty"
}
private open class EntityClass1

@jakarta.persistence.Entity
private open class EntityClass2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.linecorp.kotlinjdsl.render.jpql.introspector.impl

import io.mockk.mockkClass
import org.assertj.core.api.WithAssertions
import org.junit.jupiter.api.Test
import kotlin.reflect.KProperty0

class JavaxJpqlIntrospectorTest : WithAssertions {
private val sut = JavaxJpqlIntrospector()
Expand All @@ -13,7 +11,7 @@ class JavaxJpqlIntrospectorTest : WithAssertions {
}

@Test
fun `introspect(type) returns name of entity annotation, when entity annotation has name`() {
fun `introspect() returns name of entity annotation, when entity annotation has name`() {
// given
val type = EntityClass1::class

Expand Down Expand Up @@ -48,76 +46,8 @@ class JavaxJpqlIntrospectorTest : WithAssertions {
assertThat(actual?.name).isNull()
}

@Test
fun `introspect(property) returns property name, when property is KProperty1`() {
// given
val property = EntityClass1::property1

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("property1")
}

@Test
fun `introspect(property) returns property name with prefix removed, when getter name starts with get`() {
// given
val property = EntityClass1::getProperty2

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("property2")
}

@Test
fun `introspect(property) returns property name as is, when getter name starts with is`() {
// given
val property = EntityClass1::isProperty3

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("isProperty3")
}

@Test
fun `introspect(property) returns property name as is, when getter name does not start with get or is`() {
// given
val property = EntityClass1::someProperty

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isEqualTo("someProperty")
}

@Test
fun `introspect(property) returns null, when property is not KProperty1 or KFunction1`() {
// given
val property = mockkClass(KProperty0::class)

// when
val actual = sut.introspect(property)

// then
assertThat(actual?.name).isNull()
}

@javax.persistence.Entity(name = ENTITY_NAME_1)
private open class EntityClass1 {
val property1: Long = 0

fun getProperty2(): Long = 100

fun isProperty3(): Boolean = true

fun someProperty(): String = "someProperty"
}
private open class EntityClass1

@javax.persistence.Entity
private open class EntityClass2
Expand Down
Loading

0 comments on commit 9de2e4a

Please sign in to comment.