Skip to content

Commit e4625c4

Browse files
committed
refactor: refactor FieldMetadata
1 parent 6a01bdc commit e4625c4

14 files changed

+110
-139
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,87 @@
11
package team.yi.rsql.querydsl
22

3-
import com.querydsl.codegen.*
4-
import com.querydsl.codegen.utils.model.TypeCategory
5-
import com.querydsl.core.types.dsl.*
6-
import java.lang.reflect.*
3+
import com.querydsl.codegen.EntityType
4+
import team.yi.rsql.querydsl.util.RsqlUtil
5+
import java.lang.reflect.Field
76

8-
@Suppress("MemberVisibilityCanBePrivate")
97
class FieldMetadata {
10-
val type: Class<*>?
11-
var fieldSelector: String? = null
12-
private set
13-
var fieldSelectorIndex: Int? = null
14-
private set
15-
var field: Field? = null
16-
private set
17-
var parameterizedType: Class<*>? = null
18-
private set
19-
var collection: Boolean? = null
20-
private set
21-
var entityType: EntityType? = null
22-
private set
23-
var pathType: Class<*>? = null
24-
private set
25-
var parent: FieldMetadata? = null
26-
private set
27-
val collectionType: Class<*>?
28-
get() = parameterizedType ?: type
8+
val parent: FieldMetadata?
9+
val field: Field?
10+
val fieldSelector: String?
11+
val clazz: Class<*>?
12+
val parameterizedType: Class<*>?
13+
val entityType: EntityType?
2914

3015
constructor(type: Class<*>, parent: FieldMetadata?) {
31-
this.type = type
16+
this.fieldSelector = null
3217
this.parent = parent
18+
this.field = null
19+
this.clazz = type
20+
this.parameterizedType = null
21+
this.entityType = null
3322
}
3423

3524
constructor(fieldSelector: String, parent: FieldMetadata) {
3625
this.fieldSelector = fieldSelector
37-
this.fieldSelectorIndex = parseFieldSelector(fieldSelector)
3826
this.parent = parent
3927
this.field = getField(parent, fieldSelector)
40-
this.type = getClass(this.field)
41-
this.entityType = getEntityType(parameterizedType ?: type)
42-
this.pathType = getPathType(entityType)
28+
this.clazz = this.field?.type
29+
this.parameterizedType = RsqlUtil.getParameterizedType(this.field)
30+
this.entityType = RsqlUtil.getEntityType(parameterizedType ?: clazz)
4331
}
4432

4533
constructor(fieldSelector: String, rootClass: Class<*>) {
4634
this.fieldSelector = fieldSelector
47-
this.fieldSelectorIndex = parseFieldSelector(fieldSelector)
35+
this.parent = null
4836
this.field = getField(rootClass, fieldSelector, this)
49-
this.type = getClass(this.field)
50-
this.entityType = getEntityType(parameterizedType ?: type)
51-
this.pathType = getPathType(entityType)
52-
}
53-
54-
private fun parseFieldSelector(fieldSelector: String): Int? {
55-
return getListIndex(fieldSelector)?.also { this.fieldSelector = removeListIndex(fieldSelector) }
56-
}
57-
58-
private fun getClass(field: Field?): Class<*>? {
59-
return field?.let {
60-
if (List::class.java.isAssignableFrom(it.type) || Set::class.java.isAssignableFrom(it.type)) {
61-
this.collection = true
62-
63-
val listType = it.genericType as ParameterizedType
64-
65-
this.parameterizedType = listType.actualTypeArguments[0] as Class<*>
66-
}
67-
68-
return it.type
69-
}
37+
this.clazz = this.field?.type
38+
this.parameterizedType = RsqlUtil.getParameterizedType(this.field)
39+
this.entityType = RsqlUtil.getEntityType(parameterizedType ?: clazz)
7040
}
7141

7242
companion object {
73-
fun getEntityType(entityClass: Class<*>?): EntityType? = entityClass?.let { TypeFactory().getEntityType(it) }
74-
75-
fun getPathType(entityType: EntityType?): Class<*> {
76-
return when (entityType?.originalCategory) {
77-
TypeCategory.COMPARABLE -> ComparablePath::class.java
78-
TypeCategory.ENUM -> EnumPath::class.java
79-
TypeCategory.DATE -> DatePath::class.java
80-
TypeCategory.DATETIME -> DateTimePath::class.java
81-
TypeCategory.TIME -> TimePath::class.java
82-
TypeCategory.NUMERIC -> NumberPath::class.java
83-
TypeCategory.STRING -> StringPath::class.java
84-
TypeCategory.BOOLEAN -> BooleanPath::class.java
85-
else -> EntityPathBase::class.java
86-
}
87-
}
88-
89-
fun getField(fieldMetadata: FieldMetadata, fieldName: String): Field? {
90-
val clazz = fieldMetadata.parameterizedType ?: fieldMetadata.type
43+
private fun getField(fieldMetadata: FieldMetadata, fieldName: String): Field? {
44+
val clazz = fieldMetadata.parameterizedType ?: fieldMetadata.clazz
9145

9246
return this.getField(clazz, fieldName, fieldMetadata)
9347
}
9448

95-
fun getField(clazz: Class<*>?, fieldName: String, fieldMetadata: FieldMetadata): Field? {
49+
private fun getField(clazz: Class<*>?, fieldName: String, fieldMetadata: FieldMetadata): Field? {
9650
return clazz?.let {
9751
try {
9852
it.getDeclaredField(fieldName)
99-
} catch (nsf: NoSuchFieldException) {
53+
} catch (_: NoSuchFieldException) {
10054
return if (it.superclass == null) null else getField(it.superclass, fieldName, fieldMetadata)
10155
}
10256
}
10357
}
10458

105-
private fun getListIndex(fieldSelector: String): Int? {
106-
val startIndex = fieldSelector.indexOf('[')
107-
val endIndex = fieldSelector.indexOf(']')
59+
@JvmStatic
60+
fun parseFieldSelector(rootClass: Class<*>, fieldSelector: String?): List<FieldMetadata> {
61+
var field = fieldSelector
10862

109-
return if (startIndex == -1 || endIndex == -1) null else fieldSelector.substring(startIndex + 1, endIndex).toInt()
110-
}
63+
field?.let {
64+
if (it.startsWith("f{")) {
65+
val declares = it.substring(1).trim('{', '}').split('`')
66+
67+
field = declares[2]
68+
}
69+
}
11170

112-
private fun removeListIndex(fieldSelector: String): String {
113-
val stringBuilder = StringBuilder(fieldSelector)
114-
val startIndex = fieldSelector.indexOf('[')
115-
val endIndex = fieldSelector.indexOf(']')
71+
val nestedFields = field?.split(".").orEmpty()
72+
val fieldMetadataList = mutableListOf<FieldMetadata>()
11673

117-
return when {
118-
startIndex == -1 || endIndex == -1 -> fieldSelector
119-
else -> stringBuilder.replace(startIndex, endIndex + 1, "").toString()
74+
for (i in nestedFields.indices) {
75+
val fieldMetadata: FieldMetadata = if (i == 0) {
76+
FieldMetadata(nestedFields[i], rootClass)
77+
} else {
78+
FieldMetadata(nestedFields[i], fieldMetadataList[i - 1])
79+
}
80+
81+
fieldMetadataList.add(fieldMetadata)
12082
}
83+
84+
return fieldMetadataList
12185
}
12286
}
12387
}

src/main/kotlin/team/yi/rsql/querydsl/PredicateBuilder.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import cz.jirutka.rsql.parser.ast.ComparisonNode
77
import team.yi.rsql.querydsl.exception.TypeNotSupportedException
88
import team.yi.rsql.querydsl.handler.FieldTypeHandler
99
import team.yi.rsql.querydsl.operator.RsqlOperator
10-
import team.yi.rsql.querydsl.util.RsqlUtil
1110

1211
class PredicateBuilder<E>(private val rsqlConfig: RsqlConfig<E>) {
1312
@Throws(TypeNotSupportedException::class)
1413
fun getExpression(rootPath: PathBuilder<E>, comparisonNode: ComparisonNode, operator: RsqlOperator): BooleanExpression? {
1514
val rootClass = rootPath.type
1615
val interceptor = rsqlConfig.nodeInterceptors.find { it.supports(rootClass, comparisonNode, operator) }
1716
val node = if (interceptor == null) comparisonNode else interceptor.visit(rootClass, comparisonNode, operator, rsqlConfig.nodesFactory) ?: return null
18-
val fieldMetadataList = RsqlUtil.parseFieldSelector(rootClass, node.selector)
17+
val fieldMetadataList = FieldMetadata.parseFieldSelector(rootClass, node.selector)
1918
val processedPaths = mutableListOf<Expression<*>>()
2019
var typeHandler: FieldTypeHandler<E>? = null
2120

src/main/kotlin/team/yi/rsql/querydsl/QuerydslRsql.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class QuerydslRsql<E> private constructor(builder: Builder<E>) {
114114
val sorts = RsqlUtil.parseSortExpression(sortString)
115115

116116
for (sortSelect in sorts.keys) {
117-
val sortPath = getSortPath(fromPath, RsqlUtil.parseFieldSelector(fromPath.type, sortSelect))
117+
val sortPath = getSortPath(fromPath, FieldMetadata.parseFieldSelector(fromPath.type, sortSelect))
118118
val path = sortPath as? Path<Comparable<*>>
119119
val order = OrderSpecifier(sorts[sortSelect], path)
120120

src/main/kotlin/team/yi/rsql/querydsl/RsqlConfig.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class RsqlConfig<E> private constructor(builder: Builder<E>) {
5858

5959
@Suppress("UNCHECKED_CAST")
6060
fun getFieldTypeHandler(node: ComparisonNode, fieldMetadata: FieldMetadata): FieldTypeHandler<E> {
61-
return getFieldTypeHandler(fieldMetadata.type, node, RsqlOperator(node.operator.symbol), fieldMetadata)
61+
return getFieldTypeHandler(fieldMetadata.clazz, node, RsqlOperator(node.operator.symbol), fieldMetadata)
6262
}
6363

6464
@Suppress("UNCHECKED_CAST")
@@ -79,7 +79,7 @@ class RsqlConfig<E> private constructor(builder: Builder<E>) {
7979

8080
@Suppress("UNCHECKED_CAST")
8181
fun getSortFieldTypeHandler(fieldMetadata: FieldMetadata): SortFieldTypeHandler<E> {
82-
val type = fieldMetadata.type
82+
val type = fieldMetadata.clazz
8383

8484
for (typeHandler in sortFieldTypeHandlers) {
8585
val handler = typeHandler.getDeclaredConstructor(

src/main/kotlin/team/yi/rsql/querydsl/RsqlNodeInterceptor.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package team.yi.rsql.querydsl
22

33
import cz.jirutka.rsql.parser.UnknownOperatorException
4-
import cz.jirutka.rsql.parser.ast.*
4+
import cz.jirutka.rsql.parser.ast.ComparisonNode
5+
import cz.jirutka.rsql.parser.ast.NodesFactory
56
import team.yi.rsql.querydsl.operator.RsqlOperator
67

78
@FunctionalInterface

src/main/kotlin/team/yi/rsql/querydsl/handler/CharacterFieldTypeHandler.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class CharacterFieldTypeHandler<E>(
2626
}
2727

2828
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
29-
return Expressions.path(fieldMetadata.type, parentPath as Path<*>?, fieldMetadata.fieldSelector)
29+
return Expressions.path(fieldMetadata.clazz, parentPath as Path<*>?, fieldMetadata.fieldSelector)
3030
}
3131

3232
override fun getValue(values: List<String?>, rootPath: Path<*>, fm: FieldMetadata?): Collection<Expression<out Any?>?>? {

src/main/kotlin/team/yi/rsql/querydsl/handler/CollectionFieldTypeHandler.kt

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import team.yi.rsql.querydsl.FieldMetadata
1111
import team.yi.rsql.querydsl.RsqlConfig
1212
import team.yi.rsql.querydsl.exception.TypeNotSupportedException
1313
import team.yi.rsql.querydsl.operator.RsqlOperator
14+
import team.yi.rsql.querydsl.util.RsqlUtil
1415

1516
@Suppress("UNCHECKED_CAST")
1617
open class CollectionFieldTypeHandler<E>(
@@ -19,28 +20,27 @@ open class CollectionFieldTypeHandler<E>(
1920
override val fieldMetadata: FieldMetadata,
2021
override val rsqlConfig: RsqlConfig<E>,
2122
) : SimpleFieldTypeHandler<E>(node, operator, fieldMetadata, rsqlConfig) {
23+
private val collectionType: Class<*>?
24+
get() = fieldMetadata.parameterizedType ?: fieldMetadata.clazz
25+
2226
override fun supports(type: Class<*>?): Boolean {
2327
return if (type == null) false else DefaultTypeSystem().isCollectionType(type)
2428
}
2529

2630
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
27-
return fieldMetadata.pathType?.let {
28-
val queryType = it as Class<SimpleExpression<E>>
29-
val listMetadata = PathMetadataFactory.forProperty(parentPath as Path<*>?, fieldMetadata.fieldSelector)
30-
val collectionPath = Expressions.collectionPath(fieldMetadata.collectionType as Class<E>, queryType, listMetadata)
31+
val queryType = RsqlUtil.getPathType(fieldMetadata.entityType) as? Class<SimpleExpression<E>> ?: return null
32+
val listMetadata = PathMetadataFactory.forProperty(parentPath as Path<*>?, fieldMetadata.fieldSelector)
33+
val collectionPath = Expressions.collectionPath(collectionType as Class<E>, queryType, listMetadata)
3134

32-
return collectionPath.any() as Path<*>
33-
}
35+
return collectionPath.any() as Path<*>
3436
}
3537

3638
override fun getValue(values: List<String?>, rootPath: Path<*>, fm: FieldMetadata?): Collection<Expression<out Any?>?>? {
3739
if (values.isEmpty()) return null
3840

3941
val fieldMetadata = fm ?: this.fieldMetadata
4042

41-
if (fieldMetadata.parameterizedType == null) return null
42-
43-
fieldMetadata.collectionType?.let {
43+
collectionType?.let {
4444
val fmd = FieldMetadata(it, fieldMetadata)
4545

4646
try {

src/main/kotlin/team/yi/rsql/querydsl/handler/DateTimeFieldTypeHandler.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class DateTimeFieldTypeHandler<E : Comparable<E>>(
1818
) : TemporalFieldTypeHandler<E>(node, operator, fieldMetadata, rsqlConfig) {
1919
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
2020
return Expressions.dateTimePath(
21-
fieldMetadata.type as Class<out Comparable<*>?>,
21+
fieldMetadata.clazz as Class<out Comparable<*>?>,
2222
parentPath as Path<*>?,
2323
fieldMetadata.fieldSelector
2424
)

src/main/kotlin/team/yi/rsql/querydsl/handler/DefaultSortFieldTypeHandler.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class DefaultSortFieldTypeHandler<E>(
1111
override fun supports(type: Class<*>?): Boolean = true
1212

1313
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
14-
return Expressions.path(fieldMetadata.type, parentPath as Path<*>?, fieldMetadata.fieldSelector)
14+
return Expressions.path(fieldMetadata.clazz, parentPath as Path<*>?, fieldMetadata.fieldSelector)
1515
}
1616
}

src/main/kotlin/team/yi/rsql/querydsl/handler/EnumFieldTypeHandler.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class EnumFieldTypeHandler<E : Enum<E>>(
2626
}
2727

2828
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
29-
val type = fieldMetadata.type as? Class<out E>
29+
val type = fieldMetadata.clazz as? Class<out E>
3030

3131
return Expressions.enumPath(type, parentPath as Path<*>?, fieldMetadata.fieldSelector)
3232
}
@@ -35,7 +35,7 @@ class EnumFieldTypeHandler<E : Enum<E>>(
3535
if (values.isEmpty()) return null
3636

3737
return values
38-
.map { if (it.isNullOrBlank()) null else Expressions.asEnum(java.lang.Enum.valueOf(fieldMetadata.type as Class<E>, it)) }
38+
.map { if (it.isNullOrBlank()) null else Expressions.asEnum(java.lang.Enum.valueOf(fieldMetadata.clazz as Class<E>, it)) }
3939
.toList()
4040
}
4141
}

src/main/kotlin/team/yi/rsql/querydsl/handler/NumberFieldTypeHandler.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class NumberFieldTypeHandler<E>(
3838
}
3939

4040
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
41-
return Expressions.numberPath(fieldMetadata.type as Class<E>, parentPath as Path<*>?, fieldMetadata.fieldSelector)
41+
return Expressions.numberPath(fieldMetadata.clazz as Class<E>, parentPath as Path<*>?, fieldMetadata.fieldSelector)
4242
}
4343

4444
override fun getValue(values: List<String?>, rootPath: Path<*>, fm: FieldMetadata?): Collection<Expression<out Any?>?>? {
@@ -57,7 +57,7 @@ class NumberFieldTypeHandler<E>(
5757

5858
val number = NumberUtils.createNumber(value)
5959

60-
return MathUtils.cast(number, fieldMetadata.type as Class<out E?>)
60+
return MathUtils.cast(number, fieldMetadata.clazz as Class<out E?>)
6161
}
6262

6363
override fun getExpression(path: Expression<*>?, values: Collection<Expression<out Any?>?>?, fm: FieldMetadata?): BooleanExpression? {

src/main/kotlin/team/yi/rsql/querydsl/handler/SimpleFieldTypeHandler.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ open class SimpleFieldTypeHandler<E>(
2626
}
2727

2828
override fun getPath(parentPath: Expression<*>?): Expression<*>? {
29-
return Expressions.path(fieldMetadata.type, parentPath as Path<*>?, fieldMetadata.fieldSelector)
29+
return Expressions.path(fieldMetadata.clazz, parentPath as Path<*>?, fieldMetadata.fieldSelector)
3030
}
3131

3232
override fun getValue(values: List<String?>, rootPath: Path<*>, fm: FieldMetadata?): Collection<Expression<out Any?>?>? {

src/main/kotlin/team/yi/rsql/querydsl/operator/Operator.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package team.yi.rsql.querydsl.operator
22

3-
import java.util.*
4-
53
@Suppress("SpellCheckingInspection")
64
enum class Operator(vararg val rsqlOperator: String) {
75
ISNULL("=isnull=", "=isNull="),
@@ -43,7 +41,7 @@ enum class Operator(vararg val rsqlOperator: String) {
4341
AFTER("=after=");
4442

4543
companion object {
46-
val lookup: MutableMap<String, Operator> = HashMap()
44+
val lookup = mutableMapOf<String, Operator>()
4745

4846
operator fun get(operator: String): Operator? = lookup[operator]
4947

0 commit comments

Comments
 (0)