@@ -2,17 +2,14 @@ package com.mapk.kmapper
2
2
3
3
import com.mapk.annotations.KGetterAlias
4
4
import com.mapk.annotations.KGetterIgnore
5
- import com.mapk.core.ArgumentBucket
5
+ import com.mapk.core.ArgumentAdaptor
6
6
import com.mapk.core.KFunctionForCall
7
- import com.mapk.core.getAliasOrName
8
- import com.mapk.core.isUseDefaultArgument
9
7
import com.mapk.core.toKConstructor
10
8
import java.lang.reflect.Method
11
9
import java.util.concurrent.ConcurrentHashMap
12
10
import java.util.concurrent.ConcurrentMap
13
11
import kotlin.reflect.KClass
14
12
import kotlin.reflect.KFunction
15
- import kotlin.reflect.KParameter
16
13
import kotlin.reflect.KVisibility
17
14
import kotlin.reflect.full.memberProperties
18
15
import kotlin.reflect.jvm.javaGetter
@@ -22,28 +19,26 @@ class KMapper<T : Any> private constructor(
22
19
parameterNameConverter : (String ) -> String
23
20
) {
24
21
constructor (function: KFunction <T >, parameterNameConverter: (String ) -> String = { it }) : this (
25
- KFunctionForCall (function), parameterNameConverter
22
+ KFunctionForCall (function, parameterNameConverter ), parameterNameConverter
26
23
)
27
24
28
25
constructor (clazz: KClass <T >, parameterNameConverter: (String ) -> String = { it }) : this (
29
- clazz.toKConstructor(), parameterNameConverter
26
+ clazz.toKConstructor(parameterNameConverter ), parameterNameConverter
30
27
)
31
28
32
- private val parameterMap: Map <String , ParameterForMap <* >> = function.parameters
33
- .filter { it.kind != KParameter .Kind .INSTANCE && ! it.isUseDefaultArgument() }
34
- .associate {
35
- (parameterNameConverter(it.getAliasOrName()!! )) to ParameterForMap .newInstance(it, parameterNameConverter)
36
- }
29
+ private val parameterMap: Map <String , ParameterForMap <* >> = function.requiredParameters.associate {
30
+ it.name to ParameterForMap (it, parameterNameConverter)
31
+ }
37
32
38
33
private val getCache: ConcurrentMap <KClass <* >, List <ArgumentBinder >> = ConcurrentHashMap ()
39
34
40
- private fun bindArguments (argumentBucket : ArgumentBucket , src : Any ) {
35
+ private fun bindArguments (argumentAdaptor : ArgumentAdaptor , src : Any ) {
41
36
val clazz = src::class
42
37
43
38
// キャッシュヒットしたら登録した内容に沿って取得処理を行う
44
39
getCache[clazz]?.let { getters ->
45
40
// 取得対象フィールドは十分絞り込んでいると考えられるため、終了判定は行わない
46
- getters.forEach { it.bindArgument(src, argumentBucket ) }
41
+ getters.forEach { it.bindArgument(src, argumentAdaptor ) }
47
42
return
48
43
}
49
44
@@ -68,73 +63,75 @@ class KMapper<T : Any> private constructor(
68
63
69
64
val binder = ArgumentBinder (param, javaGetter)
70
65
71
- binder.bindArgument(src, argumentBucket )
66
+ binder.bindArgument(src, argumentAdaptor )
72
67
tempBinderArrayList.add(binder)
73
68
// キャッシュの整合性を保つため、ここでは終了判定を行わない
74
69
}
75
70
}
76
71
getCache.putIfAbsent(clazz, tempBinderArrayList)
77
72
}
78
73
79
- private fun bindArguments (argumentBucket : ArgumentBucket , src : Map <* , * >) {
74
+ private fun bindArguments (argumentAdaptor : ArgumentAdaptor , src : Map <* , * >) {
80
75
src.forEach { (key, value) ->
81
76
parameterMap[key]?.let { param ->
82
77
// 取得した内容がnullでなければ適切にmapする
83
- argumentBucket .putIfAbsent(param.param , value?.let { param.mapObject(value) })
78
+ argumentAdaptor .putIfAbsent(param.name , value?.let { param.mapObject(value) })
84
79
// 終了判定
85
- if (argumentBucket.isInitialized ) return
80
+ if (argumentAdaptor.isFullInitialized() ) return
86
81
}
87
82
}
88
83
}
89
84
90
- private fun bindArguments (argumentBucket : ArgumentBucket , srcPair : Pair <* , * >) {
91
- parameterMap[srcPair.first.toString()]?.let {
92
- argumentBucket.putIfAbsent(it.param, srcPair.second?.let { value -> it.mapObject(value) })
85
+ private fun bindArguments (argumentAdaptor : ArgumentAdaptor , srcPair : Pair <* , * >) {
86
+ val key = srcPair.first.toString()
87
+
88
+ parameterMap[key]?.let {
89
+ argumentAdaptor.putIfAbsent(key, srcPair.second?.let { value -> it.mapObject(value) })
93
90
}
94
91
}
95
92
96
93
fun map (srcMap : Map <String , Any ?>): T {
97
- val bucket : ArgumentBucket = function.getArgumentBucket ()
98
- bindArguments(bucket , srcMap)
94
+ val adaptor : ArgumentAdaptor = function.getArgumentAdaptor ()
95
+ bindArguments(adaptor , srcMap)
99
96
100
- return function.call(bucket )
97
+ return function.call(adaptor )
101
98
}
102
99
103
100
fun map (srcPair : Pair <String , Any ?>): T {
104
- val bucket : ArgumentBucket = function.getArgumentBucket ()
105
- bindArguments(bucket , srcPair)
101
+ val adaptor : ArgumentAdaptor = function.getArgumentAdaptor ()
102
+ bindArguments(adaptor , srcPair)
106
103
107
- return function.call(bucket )
104
+ return function.call(adaptor )
108
105
}
109
106
110
107
fun map (src : Any ): T {
111
- val bucket : ArgumentBucket = function.getArgumentBucket ()
112
- bindArguments(bucket , src)
108
+ val adaptor : ArgumentAdaptor = function.getArgumentAdaptor ()
109
+ bindArguments(adaptor , src)
113
110
114
- return function.call(bucket )
111
+ return function.call(adaptor )
115
112
}
116
113
117
114
fun map (vararg args : Any ): T {
118
- val bucket : ArgumentBucket = function.getArgumentBucket ()
115
+ val adaptor : ArgumentAdaptor = function.getArgumentAdaptor ()
119
116
120
117
listOf (* args).forEach { arg ->
121
118
when (arg) {
122
- is Map <* , * > -> bindArguments(bucket , arg)
123
- is Pair <* , * > -> bindArguments(bucket , arg)
124
- else -> bindArguments(bucket , arg)
119
+ is Map <* , * > -> bindArguments(adaptor , arg)
120
+ is Pair <* , * > -> bindArguments(adaptor , arg)
121
+ else -> bindArguments(adaptor , arg)
125
122
}
126
123
}
127
124
128
- return function.call(bucket )
125
+ return function.call(adaptor )
129
126
}
130
127
}
131
128
132
129
private class ArgumentBinder (private val param : ParameterForMap <* >, private val javaGetter : Method ) {
133
- fun bindArgument (src : Any , bucket : ArgumentBucket ) {
130
+ fun bindArgument (src : Any , adaptor : ArgumentAdaptor ) {
134
131
// 初期化済みであれば高コストな取得処理は行わない
135
- if (! bucket.containsKey (param.param )) {
132
+ if (! adaptor.isInitialized (param.name )) {
136
133
// javaGetterを呼び出す方が高速
137
- bucket .putIfAbsent(param.param , javaGetter.invoke(src)?.let { param.mapObject(it) })
134
+ adaptor .putIfAbsent(param.name , javaGetter.invoke(src)?.let { param.mapObject(it) })
138
135
}
139
136
}
140
137
}
0 commit comments