Skip to content

Commit 53006cc

Browse files
author
Sigmund Marius Nilssen
committed
Merge branch 'master' into security-scheme-generation-test
2 parents cf7e58f + dd1438a commit 53006cc

File tree

8 files changed

+71
-46
lines changed

8 files changed

+71
-46
lines changed
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,45 @@
11
package com.papsign.ktor.openapigen.modules
22

33
import java.util.*
4+
import kotlin.collections.ArrayList
45
import kotlin.collections.LinkedHashSet
5-
import kotlin.reflect.KClass
66
import kotlin.reflect.KType
7-
import kotlin.reflect.full.starProjectedType
8-
import kotlin.reflect.full.superclasses
9-
10-
class CachingModuleProvider: ModuleProvider<CachingModuleProvider> {
11-
12-
@Synchronized
13-
override fun ofType(type: KType): Collection<Any> {
14-
return modules[type]?.toList() ?: listOf()
7+
import kotlin.reflect.full.isSubtypeOf
8+
import kotlin.reflect.full.isSupertypeOf
9+
10+
class CachingModuleProvider(previous: Iterable<Pair<KType, OpenAPIModule>> = listOf()) : ModuleProvider<CachingModuleProvider> {
11+
12+
private val modules: MutableList<Pair<KType, OpenAPIModule>> = Collections.synchronizedList( synchronized(previous) { previous.toMutableList() } )
13+
14+
override fun ofType(type: KType): Collection<OpenAPIModule> {
15+
val set = LinkedHashSet<OpenAPIModule>()
16+
synchronized(modules) {
17+
modules.filter {
18+
it.first.isSubtypeOf(type)
19+
}
20+
}.forEach {
21+
set.remove(it.second)
22+
set.add(it.second)
23+
}
24+
return set
1525
}
1626

17-
@Synchronized
1827
override fun registerModule(module: OpenAPIModule, type: KType) {
19-
registerModuleForClass(type, module)
2028
if (module is DependentModule) {
21-
module.handlers.forEach { registerModule(it, it::class.starProjectedType) }
29+
module.handlers.forEach { (depType, depModule) ->
30+
if (synchronized(modules) { modules.find { it.second == depModule } } == null) {
31+
registerModule(depModule, depType)
32+
}
33+
}
2234
}
35+
modules.add(type to module)
2336
}
2437

25-
@Synchronized
2638
override fun unRegisterModule(module: OpenAPIModule) {
27-
modules.values.forEach { it.remove(module) }
28-
}
29-
30-
@Synchronized
31-
private fun registerModuleForClass(type: KType, module: OpenAPIModule) {
32-
val lst = modules.getOrPut(type) {LinkedHashSet()}
33-
lst.remove(module)
34-
lst.add(module)
35-
(type.classifier as KClass<*>).supertypes.forEach {
36-
registerModuleForClass(it, module)
37-
}
39+
synchronized(modules) { modules.removeIf { it.second == module } }
3840
}
3941

40-
private val modules = HashMap<KType, LinkedHashSet<OpenAPIModule>>()
41-
42-
@Synchronized
4342
override fun child(): CachingModuleProvider {
44-
val new = CachingModuleProvider()
45-
modules.forEach { (t: KType, u) ->
46-
new.modules[t] = LinkedHashSet(u)
47-
}
48-
return new
43+
return CachingModuleProvider(modules)
4944
}
5045
}
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
package com.papsign.ktor.openapigen.modules
22

3+
import com.papsign.ktor.openapigen.getKType
4+
import kotlin.reflect.KType
5+
36
interface DependentModule {
4-
val handlers: Collection<OpenAPIModule>
5-
}
7+
val handlers: Collection<Pair<KType, OpenAPIModule>>
8+
9+
companion object {
10+
inline fun <reified T: OpenAPIModule> handler(handler: T): Pair<KType, T> {
11+
return getKType<T>() to handler
12+
}
13+
}
14+
}

src/main/kotlin/com/papsign/ktor/openapigen/modules/providers/AuthProvider.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ package com.papsign.ktor.openapigen.modules.providers
33
import com.papsign.ktor.openapigen.model.Described
44
import com.papsign.ktor.openapigen.model.security.SecuritySchemeModel
55
import com.papsign.ktor.openapigen.modules.DependentModule
6+
import com.papsign.ktor.openapigen.modules.DependentModule.Companion.handler
67
import com.papsign.ktor.openapigen.modules.OpenAPIModule
78
import com.papsign.ktor.openapigen.modules.handlers.AuthHandler
89
import com.papsign.ktor.openapigen.route.path.auth.OpenAPIAuthenticatedRoute
910
import com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute
1011
import io.ktor.application.ApplicationCall
1112
import io.ktor.util.pipeline.PipelineContext
13+
import kotlin.reflect.KType
1214

1315
interface AuthProvider<TAuth>: OpenAPIModule, DependentModule {
1416
suspend fun getAuth(pipeline: PipelineContext<Unit, ApplicationCall>): TAuth
1517
fun apply(route: NormalOpenAPIRoute): OpenAPIAuthenticatedRoute<TAuth>
1618
val security: Iterable<Iterable<Security<*>>>
17-
override val handlers: Collection<OpenAPIModule>
18-
get() = listOf(AuthHandler)
19+
override val handlers: Collection<Pair<KType, OpenAPIModule>>
20+
get() = listOf(handler(AuthHandler))
1921

2022
data class Security<TScope>(val scheme: SecuritySchemeModel<TScope>, val requirements: List<TScope>) where TScope: Enum<TScope>, TScope: Described
2123
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package com.papsign.ktor.openapigen.modules.providers
22

3+
import com.papsign.ktor.openapigen.getKType
34
import com.papsign.ktor.openapigen.modules.DependentModule
5+
import com.papsign.ktor.openapigen.modules.DependentModule.Companion.handler
46
import com.papsign.ktor.openapigen.modules.OpenAPIModule
57
import com.papsign.ktor.openapigen.modules.handlers.RouteHandler
68
import io.ktor.http.HttpMethod
9+
import kotlin.reflect.KType
710

811
interface MethodProvider : OpenAPIModule, DependentModule {
912
val method: HttpMethod
10-
override val handlers: Collection<OpenAPIModule>
11-
get() = listOf(RouteHandler)
12-
}
13+
override val handlers: Collection<Pair<KType, OpenAPIModule>>
14+
get() = listOf(handler(RouteHandler))
15+
}
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package com.papsign.ktor.openapigen.modules.providers
22

33
import com.papsign.ktor.openapigen.APITag
4+
import com.papsign.ktor.openapigen.getKType
45
import com.papsign.ktor.openapigen.modules.DependentModule
6+
import com.papsign.ktor.openapigen.modules.DependentModule.Companion.handler
57
import com.papsign.ktor.openapigen.modules.OpenAPIModule
68
import com.papsign.ktor.openapigen.modules.RouteOpenAPIModule
79
import com.papsign.ktor.openapigen.modules.handlers.TagHandlerModule
10+
import kotlin.reflect.KType
811

912
interface TagProviderModule: RouteOpenAPIModule, DependentModule {
1013
val tags: Collection<APITag>
11-
override val handlers: Collection<OpenAPIModule>
12-
get() = listOf(TagHandlerModule)
14+
override val handlers: Collection<Pair<KType, OpenAPIModule>>
15+
get() = listOf(handler(TagHandlerModule))
1316
}

src/main/kotlin/com/papsign/ktor/openapigen/modules/providers/ThrowInfoProvider.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package com.papsign.ktor.openapigen.modules.providers
22

33
import com.papsign.ktor.openapigen.APIException
44
import com.papsign.ktor.openapigen.modules.DependentModule
5+
import com.papsign.ktor.openapigen.modules.DependentModule.Companion.handler
56
import com.papsign.ktor.openapigen.modules.OpenAPIModule
67
import com.papsign.ktor.openapigen.modules.handlers.ThrowOperationHandler
8+
import kotlin.reflect.KType
79

810
interface ThrowInfoProvider: OpenAPIModule, DependentModule {
911
val exceptions: List<APIException<*, *>>
10-
override val handlers: Collection<OpenAPIModule>
11-
get() = listOf(ThrowOperationHandler)
12+
override val handlers: Collection<Pair<KType, OpenAPIModule>>
13+
get() = listOf(handler(ThrowOperationHandler))
1214
}

src/main/kotlin/com/papsign/ktor/openapigen/route/Functions.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.papsign.ktor.openapigen.route
33
import com.papsign.ktor.openapigen.APITag
44
import com.papsign.ktor.openapigen.annotations.Path
55
import com.papsign.ktor.openapigen.content.type.ContentTypeProvider
6+
import com.papsign.ktor.openapigen.getKType
67
import com.papsign.ktor.openapigen.modules.handlers.RequestHandlerModule
78
import com.papsign.ktor.openapigen.modules.handlers.ResponseHandlerModule
89
import com.papsign.ktor.openapigen.modules.registerModule
@@ -13,7 +14,11 @@ import io.ktor.routing.HttpMethodRouteSelector
1314
import io.ktor.routing.createRouteFromPath
1415
import io.ktor.util.pipeline.ContextDsl
1516
import kotlin.reflect.KType
17+
import kotlin.reflect.KTypeProjection
18+
import kotlin.reflect.KVariance
19+
import kotlin.reflect.full.createType
1620
import kotlin.reflect.full.findAnnotation
21+
import kotlin.reflect.full.starProjectedType
1722
import kotlin.reflect.jvm.jvmErasure
1823
import kotlin.reflect.typeOf
1924

@@ -141,13 +146,15 @@ internal fun <TParams : Any, TResponse : Any, TRequest : Any, TRoute : OpenAPIRo
141146
RequestHandlerModule.create(
142147
bType,
143148
exampleRequest
144-
)
149+
),
150+
RequestHandlerModule::class.createType(listOf(KTypeProjection(KVariance.INVARIANT, bType)))
145151
)
146152
provider.registerModule(
147153
ResponseHandlerModule.create(
148154
rType,
149155
exampleResponse
150-
)
156+
),
157+
ResponseHandlerModule::class.createType(listOf(KTypeProjection(KVariance.INVARIANT, rType)))
151158
)
152159
if (path != null) {
153160
provider.registerModule(PathProviderModule(path.path))

src/main/kotlin/com/papsign/ktor/openapigen/route/OpenAPIRoute.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.papsign.ktor.openapigen.modules.ofType
1111
import com.papsign.ktor.openapigen.modules.openapi.HandlerModule
1212
import com.papsign.ktor.openapigen.modules.registerModule
1313
import com.papsign.ktor.openapigen.openAPIGen
14+
import com.papsign.ktor.openapigen.parameters.handlers.ParameterHandler
1415
import com.papsign.ktor.openapigen.parameters.util.buildParameterHandler
1516
import com.papsign.ktor.openapigen.route.response.Responder
1617
import com.papsign.ktor.openapigen.validation.ValidationHandler
@@ -24,6 +25,9 @@ import io.ktor.routing.application
2425
import io.ktor.routing.contentType
2526
import io.ktor.util.pipeline.PipelineContext
2627
import kotlin.reflect.KType
28+
import kotlin.reflect.KTypeProjection
29+
import kotlin.reflect.KVariance
30+
import kotlin.reflect.full.createType
2731

2832
abstract class OpenAPIRoute<T : OpenAPIRoute<T>>(val ktorRoute: Route, val provider: CachingModuleProvider) {
2933
private val log = classLogger()
@@ -37,7 +41,7 @@ abstract class OpenAPIRoute<T : OpenAPIRoute<T>>(val ktorRoute: Route, val provi
3741
pass: suspend OpenAPIRoute<*>.(pipeline: PipelineContext<Unit, ApplicationCall>, responder: Responder, P, B) -> Unit
3842
) {
3943
val parameterHandler = buildParameterHandler<P>(paramsType)
40-
provider.registerModule(parameterHandler)
44+
provider.registerModule(parameterHandler, ParameterHandler::class.createType(listOf(KTypeProjection(KVariance.INVARIANT, paramsType))))
4145

4246
val apiGen = ktorRoute.application.openAPIGen
4347
provider.ofType<HandlerModule>().forEach {

0 commit comments

Comments
 (0)