mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-06 00:26:08 +00:00
[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,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.openapitools.client">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<application />
|
||||
</manifest>
|
||||
@@ -0,0 +1,198 @@
|
||||
package org.openapitools.client.apis
|
||||
|
||||
import android.content.Context
|
||||
import com.android.volley.DefaultRetryPolicy
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.RequestQueue
|
||||
import com.android.volley.Response
|
||||
import com.android.volley.toolbox.BaseHttpStack
|
||||
import com.android.volley.toolbox.Volley
|
||||
import java.util.*;
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import com.google.gson.reflect.TypeToken
|
||||
|
||||
import org.openapitools.client.request.IRequestFactory
|
||||
import org.openapitools.client.request.RequestFactory
|
||||
import org.openapitools.client.infrastructure.CollectionFormats.*
|
||||
|
||||
|
||||
/*
|
||||
* If you wish to use a custom http stack with your client you
|
||||
* can pass that to the request queue like:
|
||||
* Volley.newRequestQueue(context.applicationContext, myCustomHttpStack)
|
||||
*/
|
||||
class DefaultApi (
|
||||
private val context: Context,
|
||||
private val requestQueue: Lazy<RequestQueue> = lazy(initializer = {
|
||||
Volley.newRequestQueue(context.applicationContext)
|
||||
}),
|
||||
private val requestFactory: IRequestFactory = RequestFactory(),
|
||||
private val basePath: String = "http://localhost",
|
||||
private val postProcessors :List <(Request<*>) -> Unit> = listOf()) {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
suspend 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 body: Any? = null
|
||||
// verify the required parameter 'pi0' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(pi0)
|
||||
// verify the required parameter 'pi1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(pi1)
|
||||
// verify the required parameter 'pn0' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(pn0)
|
||||
// verify the required parameter 'pn1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(pn1)
|
||||
// verify the required parameter 'qi1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(qi1)
|
||||
// verify the required parameter 'qi3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(qi3)
|
||||
// verify the required parameter 'qn1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(qn1)
|
||||
// verify the required parameter 'qn3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(qn3)
|
||||
// verify the required parameter 'hi1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(hi1)
|
||||
// verify the required parameter 'hi3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(hi3)
|
||||
// verify the required parameter 'hn1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(hn1)
|
||||
// verify the required parameter 'hn3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(hn3)
|
||||
// verify the required parameter 'fi1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(fi1)
|
||||
// verify the required parameter 'fi3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(fi3)
|
||||
// verify the required parameter 'fn1' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(fn1)
|
||||
// verify the required parameter 'fn3' is set
|
||||
// This is probably taken care of by non-null types anyway
|
||||
requireNotNull(fn3)
|
||||
|
||||
val contentTypes : Array<String> = arrayOf("multipart/form-data")
|
||||
val contentType: String = if (contentTypes.isNotEmpty()) { contentTypes.first() } else { "application/json" }
|
||||
|
||||
// Do some work or avoid some work based on what we know about the model,
|
||||
// before we delegate to a pluggable request factory template
|
||||
// The request factory template contains only pure code and no templates
|
||||
// to make it easy to override with your own.
|
||||
|
||||
// create path and map variables
|
||||
val path = "/test".replace("{" + "pi0" + "}", IRequestFactory.escapeString(pi0.toString())).replace("{" + "pi1" + "}", IRequestFactory.escapeString(pi1.toString())).replace("{" + "pn0" + "}", IRequestFactory.escapeString(pn0.toString())).replace("{" + "pn1" + "}", IRequestFactory.escapeString(pn1.toString()));
|
||||
|
||||
// form params
|
||||
val formParams = mapOf<String, String>(
|
||||
"fi0" to IRequestFactory.parameterToString(fi0),
|
||||
"fi1" to IRequestFactory.parameterToString(fi1),
|
||||
"fi2" to IRequestFactory.parameterToString(fi2),
|
||||
"fi3" to IRequestFactory.parameterToString(fi3),
|
||||
"fn0" to IRequestFactory.parameterToString(fn0),
|
||||
"fn1" to IRequestFactory.parameterToString(fn1),
|
||||
"fn2" to IRequestFactory.parameterToString(fn2),
|
||||
"fn3" to IRequestFactory.parameterToString(fn3),
|
||||
)
|
||||
|
||||
|
||||
// TODO: Cater for allowing empty values
|
||||
// TODO, if its apikey auth, then add the header names here and the hardcoded auth key
|
||||
// Only support hard coded apikey in query param auth for when we do this first path
|
||||
val queryParams = mapOf<String, String>(
|
||||
"qi0" to IRequestFactory.parameterToString(qi0),
|
||||
"qi1" to IRequestFactory.parameterToString(qi1),
|
||||
"qi2" to IRequestFactory.parameterToString(qi2),
|
||||
"qi3" to IRequestFactory.parameterToString(qi3),
|
||||
"qn0" to IRequestFactory.parameterToString(qn0),
|
||||
"qn1" to IRequestFactory.parameterToString(qn1),
|
||||
"qn2" to IRequestFactory.parameterToString(qn2),
|
||||
"qn3" to IRequestFactory.parameterToString(qn3),
|
||||
).filter { it.value.isNotEmpty() }
|
||||
|
||||
val headerParams: Map<String, String> = mapOf(
|
||||
"hi0" to IRequestFactory.parameterToString(hi0),
|
||||
"hi1" to IRequestFactory.parameterToString(hi1),
|
||||
"hi2" to IRequestFactory.parameterToString(hi2),
|
||||
"hi3" to IRequestFactory.parameterToString(hi3),
|
||||
"hn0" to IRequestFactory.parameterToString(hn0),
|
||||
"hn1" to IRequestFactory.parameterToString(hn1),
|
||||
"hn2" to IRequestFactory.parameterToString(hn2),
|
||||
"hn3" to IRequestFactory.parameterToString(hn3),
|
||||
)
|
||||
|
||||
return suspendCoroutine { continuation ->
|
||||
val responseListener = Response.Listener<Unit> { response ->
|
||||
continuation.resume(response)
|
||||
}
|
||||
|
||||
val errorListener = Response.ErrorListener { error ->
|
||||
continuation.resumeWithException(error)
|
||||
}
|
||||
|
||||
val responseType = object : TypeToken<Unit>() {}.type
|
||||
|
||||
// Call the correct request builder based on whether we have a return type or a body.
|
||||
// All other switching on types must be done in code inside the builder
|
||||
val request: Request<Unit> = requestFactory.build(
|
||||
Request.Method.POST,
|
||||
"$basePath$path",
|
||||
body,
|
||||
headerParams,
|
||||
queryParams,
|
||||
formParams,
|
||||
contentType,
|
||||
responseType,
|
||||
responseListener,
|
||||
errorListener)
|
||||
|
||||
postProcessors.forEach{ it.invoke(request)}
|
||||
|
||||
requestQueue.value.add(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.google.gson.stream.JsonToken.NULL
|
||||
import java.io.IOException
|
||||
|
||||
class ByteArrayAdapter : TypeAdapter<ByteArray>() {
|
||||
@Throws(IOException::class)
|
||||
override fun write(out: JsonWriter?, value: ByteArray?) {
|
||||
if (value == null) {
|
||||
out?.nullValue()
|
||||
} else {
|
||||
out?.value(String(value))
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(out: JsonReader?): ByteArray? {
|
||||
out ?: return null
|
||||
|
||||
when (out.peek()) {
|
||||
NULL -> {
|
||||
out.nextNull()
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
return out.nextString().toByteArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
class CollectionFormats {
|
||||
|
||||
open class CSVParams {
|
||||
|
||||
var params: List<String>
|
||||
|
||||
constructor(params: List<String>) {
|
||||
this.params = params
|
||||
}
|
||||
|
||||
constructor(vararg params: String) {
|
||||
this.params = listOf(*params)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return params.joinToString(",")
|
||||
}
|
||||
}
|
||||
|
||||
open class SSVParams : CSVParams {
|
||||
|
||||
constructor(params: List<String>) : super(params)
|
||||
|
||||
constructor(vararg params: String) : super(*params)
|
||||
|
||||
override fun toString(): String {
|
||||
return params.joinToString(" ")
|
||||
}
|
||||
}
|
||||
|
||||
class TSVParams : CSVParams {
|
||||
|
||||
constructor(params: List<String>) : super(params)
|
||||
|
||||
constructor(vararg params: String) : super(*params)
|
||||
|
||||
override fun toString(): String {
|
||||
return params.joinToString("\t")
|
||||
}
|
||||
}
|
||||
|
||||
class PIPESParams : CSVParams {
|
||||
|
||||
constructor(params: List<String>) : super(params)
|
||||
|
||||
constructor(vararg params: String) : super(*params)
|
||||
|
||||
override fun toString(): String {
|
||||
return params.joinToString("|")
|
||||
}
|
||||
}
|
||||
|
||||
class SPACEParams : SSVParams()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* 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.infrastructure
|
||||
|
||||
import org.openapitools.client.models.room.*
|
||||
|
||||
// TODO ITransformForStorage
|
||||
interface ITransformForStorage<T> {
|
||||
fun toRoomModel(): T
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.google.gson.stream.JsonToken.NULL
|
||||
import java.io.IOException
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateAdapter(private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE) : TypeAdapter<LocalDate>() {
|
||||
@Throws(IOException::class)
|
||||
override fun write(out: JsonWriter?, value: LocalDate?) {
|
||||
if (value == null) {
|
||||
out?.nullValue()
|
||||
} else {
|
||||
out?.value(formatter.format(value))
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(out: JsonReader?): LocalDate? {
|
||||
out ?: return null
|
||||
|
||||
when (out.peek()) {
|
||||
NULL -> {
|
||||
out.nextNull()
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
return LocalDate.parse(out.nextString(), formatter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.google.gson.stream.JsonToken.NULL
|
||||
import java.io.IOException
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateTimeAdapter(private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME) : TypeAdapter<LocalDateTime>() {
|
||||
@Throws(IOException::class)
|
||||
override fun write(out: JsonWriter?, value: LocalDateTime?) {
|
||||
if (value == null) {
|
||||
out?.nullValue()
|
||||
} else {
|
||||
out?.value(formatter.format(value))
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(out: JsonReader?): LocalDateTime? {
|
||||
out ?: return null
|
||||
|
||||
when (out.peek()) {
|
||||
NULL -> {
|
||||
out.nextNull()
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
return LocalDateTime.parse(out.nextString(), formatter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import com.google.gson.stream.JsonToken.NULL
|
||||
import java.io.IOException
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class OffsetDateTimeAdapter(private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME) : TypeAdapter<OffsetDateTime>() {
|
||||
@Throws(IOException::class)
|
||||
override fun write(out: JsonWriter?, value: OffsetDateTime?) {
|
||||
if (value == null) {
|
||||
out?.nullValue()
|
||||
} else {
|
||||
out?.value(formatter.format(value))
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(out: JsonReader?): OffsetDateTime? {
|
||||
out ?: return null
|
||||
|
||||
when (out.peek()) {
|
||||
NULL -> {
|
||||
out.nextNull()
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
return OffsetDateTime.parse(out.nextString(), formatter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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.google.gson.annotations.SerializedName
|
||||
import org.openapitools.client.models.room.ApaRoomModel
|
||||
import org.openapitools.client.infrastructure.ITransformForStorage
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param i0
|
||||
* @param n0
|
||||
* @param i1
|
||||
* @param n1
|
||||
*/
|
||||
|
||||
data class Apa (
|
||||
|
||||
@SerializedName("i0")
|
||||
val i0: kotlin.Int,
|
||||
|
||||
@SerializedName("n0")
|
||||
val n0: java.math.BigDecimal,
|
||||
|
||||
@SerializedName("i1")
|
||||
val i1: kotlin.Int? = null,
|
||||
|
||||
@SerializedName("n1")
|
||||
val n1: java.math.BigDecimal? = null
|
||||
|
||||
): ITransformForStorage<ApaRoomModel> {
|
||||
companion object { }
|
||||
override fun toRoomModel(): ApaRoomModel =
|
||||
ApaRoomModel(roomTableId = 0,
|
||||
i0 = this.i0,
|
||||
n0 = this.n0,
|
||||
i1 = this.i1,
|
||||
n1 = this.n1,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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.room
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import org.openapitools.client.models.*
|
||||
|
||||
|
||||
@Entity(tableName = "Apa")
|
||||
/**
|
||||
* Room model for
|
||||
* @param i0
|
||||
* @param n0
|
||||
* @param i1
|
||||
* @param n1
|
||||
*/
|
||||
data class ApaRoomModel (
|
||||
@PrimaryKey(autoGenerate = true) var roomTableId: Int,
|
||||
|
||||
var i0: kotlin.Int,
|
||||
var n0: java.math.BigDecimal,
|
||||
var i1: kotlin.Int? = null,
|
||||
var n1: java.math.BigDecimal? = null,
|
||||
|
||||
) {
|
||||
|
||||
companion object { }
|
||||
|
||||
fun toApiModel(): Apa = Apa(
|
||||
i0 = this.i0,
|
||||
n0 = this.n0,
|
||||
i1 = this.i1,
|
||||
n1 = this.n1,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package org.openapitools.client.request
|
||||
|
||||
import com.android.volley.NetworkResponse
|
||||
import com.android.volley.ParseError
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.Response
|
||||
import com.android.volley.toolbox.HttpHeaderParser
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.nio.charset.Charset
|
||||
import java.net.HttpURLConnection
|
||||
import java.lang.reflect.Type
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
import org.openapitools.client.infrastructure.OffsetDateTimeAdapter
|
||||
import org.openapitools.client.infrastructure.LocalDateTimeAdapter
|
||||
import org.openapitools.client.infrastructure.LocalDateAdapter
|
||||
import org.openapitools.client.infrastructure.ByteArrayAdapter
|
||||
|
||||
class GsonRequest<T>(
|
||||
method: Int,
|
||||
url: String,
|
||||
private val body: Any?,
|
||||
private val headers: Map<String, String>?,
|
||||
private val params: MutableMap<String, String>?,
|
||||
private val contentTypeForBody: String?,
|
||||
private val encodingForParams: String?,
|
||||
private val gsonAdapters: Map<Type, Any>?,
|
||||
private val type: Type,
|
||||
private val listener: Response.Listener<T>,
|
||||
errorListener: Response.ErrorListener
|
||||
) : Request<T>(method, url, errorListener) {
|
||||
|
||||
val gsonBuilder: GsonBuilder = GsonBuilder()
|
||||
.registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter())
|
||||
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter())
|
||||
.registerTypeAdapter(LocalDate::class.java, LocalDateAdapter())
|
||||
.registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter())
|
||||
.apply {
|
||||
gsonAdapters?.forEach {
|
||||
this.registerTypeAdapter(it.key, it.value)
|
||||
}
|
||||
}
|
||||
|
||||
val gson: Gson by lazy {
|
||||
gsonBuilder.create()
|
||||
}
|
||||
|
||||
private var response: NetworkResponse? = null
|
||||
|
||||
override fun deliverResponse(response: T?) {
|
||||
listener.onResponse(response)
|
||||
}
|
||||
|
||||
override fun getParams(): MutableMap<String, String>? = params ?: super.getParams()
|
||||
|
||||
override fun getBodyContentType(): String = contentTypeForBody ?: super.getBodyContentType()
|
||||
|
||||
override fun getParamsEncoding(): String = encodingForParams ?: super.getParamsEncoding()
|
||||
|
||||
override fun getHeaders(): MutableMap<String, String> {
|
||||
val combined = HashMap<String, String>()
|
||||
combined.putAll(super.getHeaders())
|
||||
if (headers != null) {
|
||||
combined.putAll(headers)
|
||||
}
|
||||
return combined
|
||||
}
|
||||
|
||||
override fun getBody(): ByteArray? {
|
||||
if (body != null) {
|
||||
return gson.toJson(body).toByteArray(Charsets.UTF_8)
|
||||
}
|
||||
return super.getBody()
|
||||
}
|
||||
|
||||
override fun parseNetworkResponse(response: NetworkResponse?): Response<T> {
|
||||
return try {
|
||||
this.response = copyTo(response)
|
||||
val json = String(
|
||||
response?.data ?: ByteArray(0),
|
||||
Charset.forName(HttpHeaderParser.parseCharset(response?.headers))
|
||||
)
|
||||
Response.success(
|
||||
gson.fromJson<T>(json, type),
|
||||
HttpHeaderParser.parseCacheHeaders(response)
|
||||
)
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
Response.error(ParseError(e))
|
||||
} catch (e: JsonSyntaxException) {
|
||||
Response.error(ParseError(e))
|
||||
}
|
||||
}
|
||||
|
||||
private fun copyTo(response: NetworkResponse?): NetworkResponse {
|
||||
return if (response != null) {
|
||||
NetworkResponse(
|
||||
response.statusCode,
|
||||
response.data,
|
||||
response.notModified,
|
||||
response.networkTimeMs,
|
||||
response.allHeaders
|
||||
)
|
||||
} else {
|
||||
// Return an empty response.
|
||||
NetworkResponse(
|
||||
HttpURLConnection.HTTP_BAD_METHOD,
|
||||
ByteArray(0),
|
||||
false,
|
||||
0,
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.openapitools.client.request
|
||||
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.Response
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.lang.reflect.Type
|
||||
import java.net.URLEncoder
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.LocalDate
|
||||
|
||||
|
||||
interface IRequestFactory {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* ISO 8601 date time format.
|
||||
* @see https://en.wikipedia.org/wiki/ISO_8601
|
||||
*/
|
||||
fun formatDateTime(datetime: OffsetDateTime) = DateTimeFormatter.ISO_INSTANT.format(datetime)
|
||||
fun formatDate(date: LocalDate) = DateTimeFormatter.ISO_LOCAL_DATE.format(date)
|
||||
|
||||
fun escapeString(str: String): String {
|
||||
return try {
|
||||
URLEncoder.encode(str, "UTF-8")
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
str
|
||||
}
|
||||
}
|
||||
|
||||
fun parameterToString(param: Any?) =
|
||||
when (param) {
|
||||
null -> ""
|
||||
is OffsetDateTime -> formatDateTime(param)
|
||||
is Collection<*> -> {
|
||||
val b = StringBuilder()
|
||||
for (o in param) {
|
||||
if (b.isNotEmpty()) {
|
||||
b.append(",")
|
||||
}
|
||||
b.append(o.toString())
|
||||
}
|
||||
b.toString()
|
||||
}
|
||||
else -> param.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun <T> build(
|
||||
method: Int,
|
||||
url : String,
|
||||
body: Any?,
|
||||
headers: Map<String, String>?,
|
||||
queryParams: Map<String, String>?,
|
||||
formParams: Map<String, String>?,
|
||||
contentTypeForBody: String?,
|
||||
type: Type,
|
||||
responseListener: Response.Listener<T>,
|
||||
errorListener: Response.ErrorListener): Request<T>
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// Knowing the details of an operation it will produce a call to a Volley Request constructor
|
||||
package org.openapitools.client.request
|
||||
|
||||
|
||||
import com.android.volley.Request
|
||||
import com.android.volley.Response
|
||||
import org.openapitools.client.request.IRequestFactory.Companion.escapeString
|
||||
import java.lang.reflect.Type
|
||||
import java.util.Locale
|
||||
import java.util.UUID
|
||||
|
||||
class RequestFactory(private val headerFactories : List<() -> Map<String, String>> = listOf(), private val postProcessors :List <(Request<*>) -> Unit> = listOf(), private val gsonAdapters: Map<Type, Any> = mapOf()): IRequestFactory {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T> build(
|
||||
method: Int,
|
||||
url: String,
|
||||
body: Any?,
|
||||
headers: Map<String, String>?,
|
||||
queryParams: Map<String, String>?,
|
||||
formParams: Map<String, String>?,
|
||||
contentTypeForBody: String?,
|
||||
type: Type,
|
||||
responseListener: Response.Listener<T>,
|
||||
errorListener: Response.ErrorListener
|
||||
): Request<T> {
|
||||
val afterMarketHeaders = (headers?.toMutableMap() ?: mutableMapOf())
|
||||
// Factory built and aftermarket
|
||||
// Merge the after market headers on top of the base ones in case we are overriding per call auth
|
||||
val allHeaders = headerFactories.fold(afterMarketHeaders) { acc, factory -> (acc + factory.invoke()).toMutableMap() }
|
||||
|
||||
// If we decide to support auth parameters in the url, then you will reference them by supplying a url string
|
||||
// with known variable name refernces in the string. We will then apply
|
||||
val updatedUrl = if (!queryParams.isNullOrEmpty()) {
|
||||
queryParams.asSequence().fold("$url?") {acc, param ->
|
||||
"$acc${escapeString(param.key)}=${escapeString(param.value)}&"
|
||||
}.trimEnd('&')
|
||||
} else {
|
||||
url
|
||||
}
|
||||
|
||||
val request = GsonRequest(
|
||||
method,
|
||||
updatedUrl,
|
||||
body,
|
||||
allHeaders,
|
||||
formParams?.toMutableMap(),
|
||||
contentTypeForBody,
|
||||
null,
|
||||
gsonAdapters,
|
||||
type,
|
||||
responseListener,
|
||||
errorListener)
|
||||
|
||||
postProcessors.forEach{ it.invoke(request)}
|
||||
|
||||
return request
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user