Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import com.papsign.ktor.openapigen.*
import com.papsign.ktor.openapigen.classLogger
import kotlin.reflect.*
import kotlin.reflect.full.*
import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.jvmErasure
import kotlin.reflect.jvm.*


/**
Expand Down Expand Up @@ -139,7 +138,7 @@ class ValidationHandler private constructor(
} else {
val appropriateConstructor = type.jvmErasure.constructors.find {
it.parameters.size == 1 && it.parameters[0].type.isSubtypeOf(iterableType)
} ?: error("Unsupported Iterable type $type, must have a constructor that takes an iterable");
} ?: error("Unsupported Iterable type $type, must have a constructor that takes an iterable")
when {
handler.isUseful() && shouldTransform -> {
transformFun = { t: Any? ->
Expand Down Expand Up @@ -208,8 +207,7 @@ class ValidationHandler private constructor(
}
else -> {
val handled = type.memberProperties.mapNotNull { prop ->
val validator =
build(prop)
val validator = build(prop)
if (validator.isUseful()) {
prop.source.javaField.also {
if (it == null) {
Expand All @@ -236,15 +234,25 @@ class ValidationHandler private constructor(
handled.isNotEmpty() -> {
transformFun = { t: Any? ->
if (t != null) {
val copy = t.javaClass.kotlin.memberFunctions.find { it.name == "copy" }
val copyParams = copy?.instanceParameter?.let { mutableMapOf<KParameter, Any?>(it to t) }
handled.forEach { (handler, field) ->
// TODO convert this to canAccess and only change status if false
val accessible = field.isAccessible
field.isAccessible = true
field.set(t, handler.handle(field.get(t)))
field.isAccessible = accessible
val getter = field.kotlinProperty?.javaGetter
if (copy != null && copyParams != null && getter != null) {
val param = copy.parameters.first { it.name == field.name }
copyParams[param] = handler.handle(getter(t))
} else {
// TODO convert this to canAccess and only change status if false
val accessible = field.isAccessible
field.isAccessible = true
field.set(t, handler.handle(field.get(t)))
field.isAccessible = accessible
}
}
}
t
if (copy != null && copyParams != null) {
copy.callBy(copyParams)
} else t
} else t
}
}
shouldTransform -> {
Expand Down
55 changes: 55 additions & 0 deletions src/test/kotlin/TestServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.papsign.ktor.openapigen.annotations.type.string.length.Length
import com.papsign.ktor.openapigen.annotations.type.string.length.MaxLength
import com.papsign.ktor.openapigen.annotations.type.string.length.MinLength
import com.papsign.ktor.openapigen.annotations.type.string.pattern.RegularExpression
import com.papsign.ktor.openapigen.annotations.type.string.trim.Trim
import com.papsign.ktor.openapigen.interop.withAPI
import com.papsign.ktor.openapigen.model.Described
import com.papsign.ktor.openapigen.model.server.ServerModel
Expand Down Expand Up @@ -319,6 +320,12 @@ object TestServer {
}
}
}

route("employees") {
get<FilterQuery, FilterQuery> { params ->
respond(params)
}
}
}
}.start(true)
}
Expand Down Expand Up @@ -412,4 +419,52 @@ object TestServer {
data class InstantResponse(val instant: Instant)
data class LocalTimeResponse(val time: LocalTime?)
data class OffsetTimeResponse(val time: OffsetTime?)

data class FilterQuery(
@QueryParam("Vendor Code") @Trim
val vendorCode: String? = null,
@QueryParam("Organization") @Trim
val organization: String? = null,
@QueryParam("startDate")
val startDate: LocalDate? = null,
@QueryParam("endDate")
val endDate: LocalDate? = null,
@QueryParam("tenant") @Trim
val tenant: String? = null,
@QueryParam("manager") @Trim
val manager: String? = null,
@QueryParam("performer") @Trim
val performer: String? = null,
@QueryParam("condition") @Trim
val condition: String? = null,
@QueryParam("onlyNew")
val onlyNew: Boolean? = null,
@QueryParam("name") @Trim
val name: String? = null,
@QueryParam("minQuantity") @Min(0)
val minQuantity: Int? = null,
@QueryParam("maxQuantity") @Min(0)
val maxQuantity: Int? = null,
@QueryParam("minCost") @Min(0)
val minCost: Int? = null,
@QueryParam("maxCost") @Min(0)
val maxCost: Int? = null,
@QueryParam("inStock")
val inStock: Boolean? = null,
@QueryParam("active")
val active: Boolean? = null,

@QueryParam("employeeName") @Trim
val employeeName: String? = null,

@QueryParam("sortToken")
@StringExample("fullName") @Trim
val sortToken: String? = null,
@QueryParam("pageSize")
@Min(1)
val pageSize: Int? = null,
@QueryParam("page")
@Min(0)
val page: Long? = 0
)
}