forked from loafle/openapi-generator-original
[BUG][Kotlin-client] Handling default values of parameters (#12255)
* Bugfix Kotlin-client: Handling default values of parameters * Adding object
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* Demo
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* Please note:
|
||||
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* Do not edit this file manually.
|
||||
*/
|
||||
|
||||
@file:Suppress(
|
||||
"ArrayInDataClass",
|
||||
"EnumEntryName",
|
||||
"RemoveRedundantQualifierName",
|
||||
"UnusedImport"
|
||||
)
|
||||
|
||||
package org.openapitools.client.apis
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
import org.openapitools.client.infrastructure.ApiClient
|
||||
import org.openapitools.client.infrastructure.ApiResponse
|
||||
import org.openapitools.client.infrastructure.ClientException
|
||||
import org.openapitools.client.infrastructure.ClientError
|
||||
import org.openapitools.client.infrastructure.ServerException
|
||||
import org.openapitools.client.infrastructure.ServerError
|
||||
import org.openapitools.client.infrastructure.MultiValueMap
|
||||
import org.openapitools.client.infrastructure.PartConfig
|
||||
import org.openapitools.client.infrastructure.RequestConfig
|
||||
import org.openapitools.client.infrastructure.RequestMethod
|
||||
import org.openapitools.client.infrastructure.ResponseType
|
||||
import org.openapitools.client.infrastructure.Success
|
||||
import org.openapitools.client.infrastructure.toMultiValue
|
||||
|
||||
class DefaultApi(basePath: kotlin.String = defaultBasePath) : ApiClient(basePath) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
val defaultBasePath: String by lazy {
|
||||
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests default values
|
||||
* Tests default values of different parameters
|
||||
* @param pi0 (default to 10)
|
||||
* @param pi1
|
||||
* @param pn0 (default to 10.0)
|
||||
* @param pn1
|
||||
* @param qi0 (optional, default to 10)
|
||||
* @param qi1 (default to 71)
|
||||
* @param qi2 (optional)
|
||||
* @param qi3
|
||||
* @param qn0 (optional, default to 10.0)
|
||||
* @param qn1 (default to 71.0)
|
||||
* @param qn2 (optional)
|
||||
* @param qn3
|
||||
* @param hi0 (optional, default to 10)
|
||||
* @param hi1 (default to 71)
|
||||
* @param hi2 (optional)
|
||||
* @param hi3
|
||||
* @param hn0 (optional, default to 10.0)
|
||||
* @param hn1 (default to 71.0)
|
||||
* @param hn2 (optional)
|
||||
* @param hn3
|
||||
* @param fi0 (optional, default to 10)
|
||||
* @param fi1 (default to 71)
|
||||
* @param fi2 (optional)
|
||||
* @param fi3
|
||||
* @param fn0 (optional, default to 10.0)
|
||||
* @param fn1 (default to 71.0)
|
||||
* @param fn2 (optional)
|
||||
* @param fn3
|
||||
* @return void
|
||||
* @throws IllegalStateException If the request is not correctly configured
|
||||
* @throws IOException Rethrows the OkHttp execute method exception
|
||||
* @throws UnsupportedOperationException If the API returns an informational or redirection response
|
||||
* @throws ClientException If the API returns a client error response
|
||||
* @throws ServerException If the API returns a server error response
|
||||
*/
|
||||
@Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class)
|
||||
fun test(pi0: kotlin.Int = 10, pi1: kotlin.Int, pn0: java.math.BigDecimal = java.math.BigDecimal("10.0"), pn1: java.math.BigDecimal, qi0: kotlin.Int? = 10, qi1: kotlin.Int = 71, qi2: kotlin.Int? = null, qi3: kotlin.Int, qn0: java.math.BigDecimal? = java.math.BigDecimal("10.0"), qn1: java.math.BigDecimal = java.math.BigDecimal("71.0"), qn2: java.math.BigDecimal? = null, qn3: java.math.BigDecimal, hi0: kotlin.Int? = 10, hi1: kotlin.Int = 71, hi2: kotlin.Int? = null, hi3: kotlin.Int, hn0: java.math.BigDecimal? = java.math.BigDecimal("10.0"), hn1: java.math.BigDecimal = java.math.BigDecimal("71.0"), hn2: java.math.BigDecimal? = null, hn3: java.math.BigDecimal, fi0: kotlin.Int? = 10, fi1: kotlin.Int = 71, fi2: kotlin.Int? = null, fi3: kotlin.Int, fn0: java.math.BigDecimal? = java.math.BigDecimal("10.0"), fn1: java.math.BigDecimal = java.math.BigDecimal("71.0"), fn2: java.math.BigDecimal? = null, fn3: java.math.BigDecimal) : Unit {
|
||||
val localVarResponse = testWithHttpInfo(pi0 = pi0, pi1 = pi1, pn0 = pn0, pn1 = pn1, qi0 = qi0, qi1 = qi1, qi2 = qi2, qi3 = qi3, qn0 = qn0, qn1 = qn1, qn2 = qn2, qn3 = qn3, hi0 = hi0, hi1 = hi1, hi2 = hi2, hi3 = hi3, hn0 = hn0, hn1 = hn1, hn2 = hn2, hn3 = hn3, fi0 = fi0, fi1 = fi1, fi2 = fi2, fi3 = fi3, fn0 = fn0, fn1 = fn1, fn2 = fn2, fn3 = fn3)
|
||||
|
||||
return when (localVarResponse.responseType) {
|
||||
ResponseType.Success -> Unit
|
||||
ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.")
|
||||
ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.")
|
||||
ResponseType.ClientError -> {
|
||||
val localVarError = localVarResponse as ClientError<*>
|
||||
throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
|
||||
}
|
||||
ResponseType.ServerError -> {
|
||||
val localVarError = localVarResponse as ServerError<*>
|
||||
throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests default values
|
||||
* Tests default values of different parameters
|
||||
* @param pi0 (default to 10)
|
||||
* @param pi1
|
||||
* @param pn0 (default to 10.0)
|
||||
* @param pn1
|
||||
* @param qi0 (optional, default to 10)
|
||||
* @param qi1 (default to 71)
|
||||
* @param qi2 (optional)
|
||||
* @param qi3
|
||||
* @param qn0 (optional, default to 10.0)
|
||||
* @param qn1 (default to 71.0)
|
||||
* @param qn2 (optional)
|
||||
* @param qn3
|
||||
* @param hi0 (optional, default to 10)
|
||||
* @param hi1 (default to 71)
|
||||
* @param hi2 (optional)
|
||||
* @param hi3
|
||||
* @param hn0 (optional, default to 10.0)
|
||||
* @param hn1 (default to 71.0)
|
||||
* @param hn2 (optional)
|
||||
* @param hn3
|
||||
* @param fi0 (optional, default to 10)
|
||||
* @param fi1 (default to 71)
|
||||
* @param fi2 (optional)
|
||||
* @param fi3
|
||||
* @param fn0 (optional, default to 10.0)
|
||||
* @param fn1 (default to 71.0)
|
||||
* @param fn2 (optional)
|
||||
* @param fn3
|
||||
* @return ApiResponse<Unit?>
|
||||
* @throws IllegalStateException If the request is not correctly configured
|
||||
* @throws IOException Rethrows the OkHttp execute method exception
|
||||
*/
|
||||
@Throws(IllegalStateException::class, IOException::class)
|
||||
fun testWithHttpInfo(pi0: kotlin.Int, pi1: kotlin.Int, pn0: java.math.BigDecimal, pn1: java.math.BigDecimal, qi0: kotlin.Int?, qi1: kotlin.Int, qi2: kotlin.Int?, qi3: kotlin.Int, qn0: java.math.BigDecimal?, qn1: java.math.BigDecimal, qn2: java.math.BigDecimal?, qn3: java.math.BigDecimal, hi0: kotlin.Int?, hi1: kotlin.Int, hi2: kotlin.Int?, hi3: kotlin.Int, hn0: java.math.BigDecimal?, hn1: java.math.BigDecimal, hn2: java.math.BigDecimal?, hn3: java.math.BigDecimal, fi0: kotlin.Int?, fi1: kotlin.Int, fi2: kotlin.Int?, fi3: kotlin.Int, fn0: java.math.BigDecimal?, fn1: java.math.BigDecimal, fn2: java.math.BigDecimal?, fn3: java.math.BigDecimal) : ApiResponse<Unit?> {
|
||||
val localVariableConfig = testRequestConfig(pi0 = pi0, pi1 = pi1, pn0 = pn0, pn1 = pn1, qi0 = qi0, qi1 = qi1, qi2 = qi2, qi3 = qi3, qn0 = qn0, qn1 = qn1, qn2 = qn2, qn3 = qn3, hi0 = hi0, hi1 = hi1, hi2 = hi2, hi3 = hi3, hn0 = hn0, hn1 = hn1, hn2 = hn2, hn3 = hn3, fi0 = fi0, fi1 = fi1, fi2 = fi2, fi3 = fi3, fn0 = fn0, fn1 = fn1, fn2 = fn2, fn3 = fn3)
|
||||
|
||||
return request<Map<String, PartConfig<*>>, Unit>(
|
||||
localVariableConfig
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* To obtain the request config of the operation test
|
||||
*
|
||||
* @param pi0 (default to 10)
|
||||
* @param pi1
|
||||
* @param pn0 (default to 10.0)
|
||||
* @param pn1
|
||||
* @param qi0 (optional, default to 10)
|
||||
* @param qi1 (default to 71)
|
||||
* @param qi2 (optional)
|
||||
* @param qi3
|
||||
* @param qn0 (optional, default to 10.0)
|
||||
* @param qn1 (default to 71.0)
|
||||
* @param qn2 (optional)
|
||||
* @param qn3
|
||||
* @param hi0 (optional, default to 10)
|
||||
* @param hi1 (default to 71)
|
||||
* @param hi2 (optional)
|
||||
* @param hi3
|
||||
* @param hn0 (optional, default to 10.0)
|
||||
* @param hn1 (default to 71.0)
|
||||
* @param hn2 (optional)
|
||||
* @param hn3
|
||||
* @param fi0 (optional, default to 10)
|
||||
* @param fi1 (default to 71)
|
||||
* @param fi2 (optional)
|
||||
* @param fi3
|
||||
* @param fn0 (optional, default to 10.0)
|
||||
* @param fn1 (default to 71.0)
|
||||
* @param fn2 (optional)
|
||||
* @param fn3
|
||||
* @return RequestConfig
|
||||
*/
|
||||
fun testRequestConfig(pi0: kotlin.Int, pi1: kotlin.Int, pn0: java.math.BigDecimal, pn1: java.math.BigDecimal, qi0: kotlin.Int?, qi1: kotlin.Int, qi2: kotlin.Int?, qi3: kotlin.Int, qn0: java.math.BigDecimal?, qn1: java.math.BigDecimal, qn2: java.math.BigDecimal?, qn3: java.math.BigDecimal, hi0: kotlin.Int?, hi1: kotlin.Int, hi2: kotlin.Int?, hi3: kotlin.Int, hn0: java.math.BigDecimal?, hn1: java.math.BigDecimal, hn2: java.math.BigDecimal?, hn3: java.math.BigDecimal, fi0: kotlin.Int?, fi1: kotlin.Int, fi2: kotlin.Int?, fi3: kotlin.Int, fn0: java.math.BigDecimal?, fn1: java.math.BigDecimal, fn2: java.math.BigDecimal?, fn3: java.math.BigDecimal) : RequestConfig<Map<String, PartConfig<*>>> {
|
||||
val localVariableBody = mapOf(
|
||||
"fi0" to PartConfig(body = fi0, headers = mutableMapOf()),
|
||||
"fi1" to PartConfig(body = fi1, headers = mutableMapOf()),
|
||||
"fi2" to PartConfig(body = fi2, headers = mutableMapOf()),
|
||||
"fi3" to PartConfig(body = fi3, headers = mutableMapOf()),
|
||||
"fn0" to PartConfig(body = fn0, headers = mutableMapOf()),
|
||||
"fn1" to PartConfig(body = fn1, headers = mutableMapOf()),
|
||||
"fn2" to PartConfig(body = fn2, headers = mutableMapOf()),
|
||||
"fn3" to PartConfig(body = fn3, headers = mutableMapOf()),)
|
||||
val localVariableQuery: MultiValueMap = mutableMapOf<kotlin.String, kotlin.collections.List<kotlin.String>>()
|
||||
.apply {
|
||||
if (qi0 != null) {
|
||||
put("qi0", listOf(qi0.toString()))
|
||||
}
|
||||
put("qi1", listOf(qi1.toString()))
|
||||
if (qi2 != null) {
|
||||
put("qi2", listOf(qi2.toString()))
|
||||
}
|
||||
put("qi3", listOf(qi3.toString()))
|
||||
if (qn0 != null) {
|
||||
put("qn0", listOf(qn0.toString()))
|
||||
}
|
||||
put("qn1", listOf(qn1.toString()))
|
||||
if (qn2 != null) {
|
||||
put("qn2", listOf(qn2.toString()))
|
||||
}
|
||||
put("qn3", listOf(qn3.toString()))
|
||||
}
|
||||
val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
|
||||
hi0?.apply { localVariableHeaders["hi0"] = this.toString() }
|
||||
hi1.apply { localVariableHeaders["hi1"] = this.toString() }
|
||||
hi2?.apply { localVariableHeaders["hi2"] = this.toString() }
|
||||
hi3.apply { localVariableHeaders["hi3"] = this.toString() }
|
||||
hn0?.apply { localVariableHeaders["hn0"] = this.toString() }
|
||||
hn1.apply { localVariableHeaders["hn1"] = this.toString() }
|
||||
hn2?.apply { localVariableHeaders["hn2"] = this.toString() }
|
||||
hn3.apply { localVariableHeaders["hn3"] = this.toString() }
|
||||
|
||||
return RequestConfig(
|
||||
method = RequestMethod.POST,
|
||||
path = "/test".replace("{"+"pi0"+"}", "$pi0").replace("{"+"pi1"+"}", "$pi1").replace("{"+"pn0"+"}", "$pn0").replace("{"+"pn1"+"}", "$pn1"),
|
||||
query = localVariableQuery,
|
||||
headers = localVariableHeaders,
|
||||
body = localVariableBody
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
typealias MultiValueMap = MutableMap<String,List<String>>
|
||||
|
||||
fun collectionDelimiter(collectionFormat: String) = when(collectionFormat) {
|
||||
"csv" -> ","
|
||||
"tsv" -> "\t"
|
||||
"pipe" -> "|"
|
||||
"space" -> " "
|
||||
else -> ""
|
||||
}
|
||||
|
||||
val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" }
|
||||
|
||||
fun <T : Any?> toMultiValue(items: Array<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter)
|
||||
= toMultiValue(items.asIterable(), collectionFormat, map)
|
||||
|
||||
fun <T : Any?> toMultiValue(items: Iterable<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter): List<String> {
|
||||
return when(collectionFormat) {
|
||||
"multi" -> items.map(map)
|
||||
else -> listOf(items.joinToString(separator = collectionDelimiter(collectionFormat), transform = map))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.Request
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Headers.Companion.toHeaders
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.Call
|
||||
import okhttp3.Callback
|
||||
import okhttp3.Response
|
||||
import okhttp3.internal.EMPTY_REQUEST
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
import java.net.URLConnection
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.OffsetTime
|
||||
import java.util.Locale
|
||||
import com.squareup.moshi.adapter
|
||||
|
||||
open class ApiClient(val baseUrl: String) {
|
||||
companion object {
|
||||
protected const val ContentType = "Content-Type"
|
||||
protected const val Accept = "Accept"
|
||||
protected const val Authorization = "Authorization"
|
||||
protected const val JsonMediaType = "application/json"
|
||||
protected const val FormDataMediaType = "multipart/form-data"
|
||||
protected const val FormUrlEncMediaType = "application/x-www-form-urlencoded"
|
||||
protected const val XmlMediaType = "application/xml"
|
||||
|
||||
val apiKey: MutableMap<String, String> = mutableMapOf()
|
||||
val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
|
||||
var username: String? = null
|
||||
var password: String? = null
|
||||
var accessToken: String? = null
|
||||
const val baseUrlKey = "org.openapitools.client.baseUrl"
|
||||
|
||||
@JvmStatic
|
||||
val client: OkHttpClient by lazy {
|
||||
builder.build()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess Content-Type header from the given file (defaults to "application/octet-stream").
|
||||
*
|
||||
* @param file The given file
|
||||
* @return The guessed Content-Type
|
||||
*/
|
||||
protected fun guessContentTypeFromFile(file: File): String {
|
||||
val contentType = URLConnection.guessContentTypeFromName(file.name)
|
||||
return contentType ?: "application/octet-stream"
|
||||
}
|
||||
|
||||
protected inline fun <reified T> requestBody(content: T, mediaType: String?): RequestBody =
|
||||
when {
|
||||
mediaType == FormDataMediaType ->
|
||||
MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.apply {
|
||||
// content's type *must* be Map<String, PartConfig<*>>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(content as Map<String, PartConfig<*>>).forEach { (name, part) ->
|
||||
val contentType = part.headers.remove("Content-Type")
|
||||
val bodies = if (part.body is Iterable<*>) part.body else listOf(part.body)
|
||||
bodies.forEach { body ->
|
||||
val headers = part.headers.toMutableMap() +
|
||||
("Content-Disposition" to "form-data; name=\"$name\"" + if (body is File) "; filename=\"${body.name}\"" else "")
|
||||
addPart(headers.toHeaders(),
|
||||
requestSingleBody(body, contentType))
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
else -> requestSingleBody(content, mediaType)
|
||||
}
|
||||
|
||||
protected inline fun <reified T> requestSingleBody(content: T, mediaType: String?): RequestBody =
|
||||
when {
|
||||
content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull())
|
||||
mediaType == FormUrlEncMediaType -> {
|
||||
FormBody.Builder().apply {
|
||||
// content's type *must* be Map<String, PartConfig<*>>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(content as Map<String, PartConfig<*>>).forEach { (name, part) ->
|
||||
add(name, parameterToString(part.body))
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
mediaType == null || mediaType.startsWith("application/") && mediaType.endsWith("json") ->
|
||||
if (content == null) {
|
||||
EMPTY_REQUEST
|
||||
} else {
|
||||
Serializer.moshi.adapter(T::class.java).toJson(content)
|
||||
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
|
||||
}
|
||||
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
|
||||
// TODO: this should be extended with other serializers
|
||||
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body and File body.")
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? {
|
||||
if(body == null) {
|
||||
return null
|
||||
}
|
||||
if (T::class.java == File::class.java) {
|
||||
// return tempfile
|
||||
// Attention: if you are developing an android app that supports API Level 25 and bellow, please check flag supportAndroidApiLevel25AndBelow in https://openapi-generator.tech/docs/generators/kotlin#config-options
|
||||
val f = java.nio.file.Files.createTempFile("tmp.org.openapitools.client", null).toFile()
|
||||
f.deleteOnExit()
|
||||
body.byteStream().use { java.nio.file.Files.copy(it, f.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING) }
|
||||
return f as T
|
||||
}
|
||||
val bodyContent = body.string()
|
||||
if (bodyContent.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
return when {
|
||||
mediaType==null || (mediaType.startsWith("application/") && mediaType.endsWith("json")) ->
|
||||
Serializer.moshi.adapter<T>().fromJson(bodyContent)
|
||||
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected inline fun <reified I, reified T: Any?> request(requestConfig: RequestConfig<I>): ApiResponse<T?> {
|
||||
val httpUrl = baseUrl.toHttpUrlOrNull() ?: throw IllegalStateException("baseUrl is invalid.")
|
||||
|
||||
val url = httpUrl.newBuilder()
|
||||
.addPathSegments(requestConfig.path.trimStart('/'))
|
||||
.apply {
|
||||
requestConfig.query.forEach { query ->
|
||||
query.value.forEach { queryValue ->
|
||||
addQueryParameter(query.key, queryValue)
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
|
||||
// take content-type/accept from spec or set to default (application/json) if not defined
|
||||
if (requestConfig.headers[ContentType].isNullOrEmpty()) {
|
||||
requestConfig.headers[ContentType] = JsonMediaType
|
||||
}
|
||||
if (requestConfig.headers[Accept].isNullOrEmpty()) {
|
||||
requestConfig.headers[Accept] = JsonMediaType
|
||||
}
|
||||
val headers = requestConfig.headers
|
||||
|
||||
if(headers[ContentType].isNullOrEmpty()) {
|
||||
throw kotlin.IllegalStateException("Missing Content-Type header. This is required.")
|
||||
}
|
||||
|
||||
if(headers[Accept].isNullOrEmpty()) {
|
||||
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
|
||||
}
|
||||
|
||||
// TODO: support multiple contentType options here.
|
||||
val contentType = (headers[ContentType] as String).substringBefore(";").lowercase(Locale.getDefault())
|
||||
|
||||
val request = when (requestConfig.method) {
|
||||
RequestMethod.DELETE -> Request.Builder().url(url).delete(requestBody(requestConfig.body, contentType))
|
||||
RequestMethod.GET -> Request.Builder().url(url)
|
||||
RequestMethod.HEAD -> Request.Builder().url(url).head()
|
||||
RequestMethod.PATCH -> Request.Builder().url(url).patch(requestBody(requestConfig.body, contentType))
|
||||
RequestMethod.PUT -> Request.Builder().url(url).put(requestBody(requestConfig.body, contentType))
|
||||
RequestMethod.POST -> Request.Builder().url(url).post(requestBody(requestConfig.body, contentType))
|
||||
RequestMethod.OPTIONS -> Request.Builder().url(url).method("OPTIONS", null)
|
||||
}.apply {
|
||||
headers.forEach { header -> addHeader(header.key, header.value) }
|
||||
}.build()
|
||||
|
||||
val response = client.newCall(request).execute()
|
||||
|
||||
val accept = response.header(ContentType)?.substringBefore(";")?.lowercase(Locale.getDefault())
|
||||
|
||||
// TODO: handle specific mapping types. e.g. Map<int, Class<?>>
|
||||
return when {
|
||||
response.isRedirect -> Redirection(
|
||||
response.code,
|
||||
response.headers.toMultimap()
|
||||
)
|
||||
response.isInformational -> Informational(
|
||||
response.message,
|
||||
response.code,
|
||||
response.headers.toMultimap()
|
||||
)
|
||||
response.isSuccessful -> Success(
|
||||
responseBody(response.body, accept),
|
||||
response.code,
|
||||
response.headers.toMultimap()
|
||||
)
|
||||
response.isClientError -> ClientError(
|
||||
response.message,
|
||||
response.body?.string(),
|
||||
response.code,
|
||||
response.headers.toMultimap()
|
||||
)
|
||||
else -> ServerError(
|
||||
response.message,
|
||||
response.body?.string(),
|
||||
response.code,
|
||||
response.headers.toMultimap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun parameterToString(value: Any?): String = when (value) {
|
||||
null -> ""
|
||||
is Array<*> -> toMultiValue(value, "csv").toString()
|
||||
is Iterable<*> -> toMultiValue(value, "csv").toString()
|
||||
is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime ->
|
||||
parseDateToQueryString(value)
|
||||
else -> value.toString()
|
||||
}
|
||||
|
||||
protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
|
||||
/*
|
||||
.replace("\"", "") converts the json object string to an actual string for the query parameter.
|
||||
The moshi or gson adapter allows a more generic solution instead of trying to use a native
|
||||
formatter. It also easily allows to provide a simple way to define a custom date format pattern
|
||||
inside a gson/moshi adapter.
|
||||
*/
|
||||
return Serializer.moshi.adapter(T::class.java).toJson(value).replace("\"", "")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
enum class ResponseType {
|
||||
Success, Informational, Redirection, ClientError, ServerError
|
||||
}
|
||||
|
||||
interface Response
|
||||
|
||||
abstract class ApiResponse<T>(val responseType: ResponseType): Response {
|
||||
abstract val statusCode: Int
|
||||
abstract val headers: Map<String,List<String>>
|
||||
}
|
||||
|
||||
class Success<T>(
|
||||
val data: T,
|
||||
override val statusCode: Int = -1,
|
||||
override val headers: Map<String, List<String>> = mapOf()
|
||||
): ApiResponse<T>(ResponseType.Success)
|
||||
|
||||
class Informational<T>(
|
||||
val statusText: String,
|
||||
override val statusCode: Int = -1,
|
||||
override val headers: Map<String, List<String>> = mapOf()
|
||||
) : ApiResponse<T>(ResponseType.Informational)
|
||||
|
||||
class Redirection<T>(
|
||||
override val statusCode: Int = -1,
|
||||
override val headers: Map<String, List<String>> = mapOf()
|
||||
) : ApiResponse<T>(ResponseType.Redirection)
|
||||
|
||||
class ClientError<T>(
|
||||
val message: String? = null,
|
||||
val body: Any? = null,
|
||||
override val statusCode: Int = -1,
|
||||
override val headers: Map<String, List<String>> = mapOf()
|
||||
) : ApiResponse<T>(ResponseType.ClientError)
|
||||
|
||||
class ServerError<T>(
|
||||
val message: String? = null,
|
||||
val body: Any? = null,
|
||||
override val statusCode: Int = -1,
|
||||
override val headers: Map<String, List<String>>
|
||||
): ApiResponse<T>(ResponseType.ServerError)
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.math.BigDecimal
|
||||
|
||||
class BigDecimalAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: BigDecimal): String {
|
||||
return value.toPlainString()
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): BigDecimal {
|
||||
return BigDecimal(value)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.math.BigInteger
|
||||
|
||||
class BigIntegerAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: BigInteger): String {
|
||||
return value.toString()
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): BigInteger {
|
||||
return BigInteger(value)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
|
||||
class ByteArrayAdapter {
|
||||
@ToJson
|
||||
fun toJson(data: ByteArray): String = String(data)
|
||||
|
||||
@FromJson
|
||||
fun fromJson(data: String): ByteArray = data.toByteArray()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
@file:Suppress("unused")
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import java.lang.RuntimeException
|
||||
|
||||
open class ClientException(message: kotlin.String? = null, val statusCode: Int = -1, val response: Response? = null) : RuntimeException(message) {
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 123L
|
||||
}
|
||||
}
|
||||
|
||||
open class ServerException(message: kotlin.String? = null, val statusCode: Int = -1, val response: Response? = null) : RuntimeException(message) {
|
||||
|
||||
companion object {
|
||||
private const val serialVersionUID: Long = 456L
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: LocalDate): String {
|
||||
return DateTimeFormatter.ISO_LOCAL_DATE.format(value)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): LocalDate {
|
||||
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateTimeAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: LocalDateTime): String {
|
||||
return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): LocalDateTime {
|
||||
return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class OffsetDateTimeAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: OffsetDateTime): String {
|
||||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(value)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): OffsetDateTime {
|
||||
return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
/**
|
||||
* Defines a config object for a given part of a multi-part request.
|
||||
* NOTE: Headers is a Map<String,String> because rfc2616 defines
|
||||
* multi-valued headers as csv-only.
|
||||
*/
|
||||
data class PartConfig<T>(
|
||||
val headers: MutableMap<String, String> = mutableMapOf(),
|
||||
val body: T? = null
|
||||
)
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
/**
|
||||
* Defines a config object for a given request.
|
||||
* NOTE: This object doesn't include 'body' because it
|
||||
* allows for caching of the constructed object
|
||||
* for many request definitions.
|
||||
* NOTE: Headers is a Map<String,String> because rfc2616 defines
|
||||
* multi-valued headers as csv-only.
|
||||
*/
|
||||
data class RequestConfig<T>(
|
||||
val method: RequestMethod,
|
||||
val path: String,
|
||||
val headers: MutableMap<String, String> = mutableMapOf(),
|
||||
val query: MutableMap<String, List<String>> = mutableMapOf(),
|
||||
val body: T? = null
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
/**
|
||||
* Provides enumerated HTTP verbs
|
||||
*/
|
||||
enum class RequestMethod {
|
||||
GET, DELETE, HEAD, OPTIONS, PATCH, POST, PUT
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import okhttp3.Response
|
||||
|
||||
/**
|
||||
* Provides an extension to evaluation whether the response is a 1xx code
|
||||
*/
|
||||
val Response.isInformational : Boolean get() = this.code in 100..199
|
||||
|
||||
/**
|
||||
* Provides an extension to evaluation whether the response is a 3xx code
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
|
||||
val Response.isRedirect : Boolean get() = this.code in 300..399
|
||||
|
||||
/**
|
||||
* Provides an extension to evaluation whether the response is a 4xx code
|
||||
*/
|
||||
val Response.isClientError : Boolean get() = this.code in 400..499
|
||||
|
||||
/**
|
||||
* Provides an extension to evaluation whether the response is a 5xx (Standard) through 999 (non-standard) code
|
||||
*/
|
||||
val Response.isServerError : Boolean get() = this.code in 500..999
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
|
||||
object Serializer {
|
||||
@JvmStatic
|
||||
val moshiBuilder: Moshi.Builder = Moshi.Builder()
|
||||
.add(OffsetDateTimeAdapter())
|
||||
.add(LocalDateTimeAdapter())
|
||||
.add(LocalDateAdapter())
|
||||
.add(UUIDAdapter())
|
||||
.add(ByteArrayAdapter())
|
||||
.add(URIAdapter())
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.add(BigDecimalAdapter())
|
||||
.add(BigIntegerAdapter())
|
||||
|
||||
@JvmStatic
|
||||
val moshi: Moshi by lazy {
|
||||
moshiBuilder.build()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.net.URI
|
||||
|
||||
class URIAdapter {
|
||||
@ToJson
|
||||
fun toJson(uri: URI) = uri.toString()
|
||||
|
||||
@FromJson
|
||||
fun fromJson(s: String): URI = URI.create(s)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.util.UUID
|
||||
|
||||
class UUIDAdapter {
|
||||
@ToJson
|
||||
fun toJson(uuid: UUID) = uuid.toString()
|
||||
|
||||
@FromJson
|
||||
fun fromJson(s: String): UUID = UUID.fromString(s)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Demo
|
||||
*
|
||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* Please note:
|
||||
* This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* Do not edit this file manually.
|
||||
*/
|
||||
|
||||
@file:Suppress(
|
||||
"ArrayInDataClass",
|
||||
"EnumEntryName",
|
||||
"RemoveRedundantQualifierName",
|
||||
"UnusedImport"
|
||||
)
|
||||
|
||||
package org.openapitools.client.models
|
||||
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param i0
|
||||
* @param n0
|
||||
* @param i1
|
||||
* @param n1
|
||||
*/
|
||||
|
||||
data class Apa (
|
||||
|
||||
@Json(name = "i0")
|
||||
val i0: kotlin.Int,
|
||||
|
||||
@Json(name = "n0")
|
||||
val n0: java.math.BigDecimal,
|
||||
|
||||
@Json(name = "i1")
|
||||
val i1: kotlin.Int? = null,
|
||||
|
||||
@Json(name = "n1")
|
||||
val n1: java.math.BigDecimal? = null
|
||||
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user