[kotlin] support collection format multi (#5792)

* [kotlin] support collectionFormat:multi

Adds "multi" support to collections.

Also changes generic lists (List<T>) to arrays. Generic lists and nested
lists can be problematic and require customized json factories. The
previous implement appeared to work because the results in the test were
LinkedHashMap with count greather than 0. The functional test has been
updated to force serialization and verify the results.

* [kotlin] Regenerate sample

* [kotlin] Update model test for Array changes
This commit is contained in:
Jim Schubert
2017-06-09 03:40:18 -04:00
committed by wing328
parent 2d008be181
commit dabf01c3fa
17 changed files with 120 additions and 92 deletions

View File

@@ -125,16 +125,16 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
typeMapping.put("date-time", "java.time.LocalDateTime");
typeMapping.put("date", "java.time.LocalDateTime");
typeMapping.put("file", "java.io.File");
typeMapping.put("array", "kotlin.collections.List");
typeMapping.put("list", "kotlin.collections.List");
typeMapping.put("array", "kotlin.Array");
typeMapping.put("list", "kotlin.Array");
typeMapping.put("map", "kotlin.collections.Map");
typeMapping.put("object", "kotlin.Any");
typeMapping.put("binary", "kotlin.Array<kotlin.Byte>");
typeMapping.put("Date", "java.time.LocalDateTime");
typeMapping.put("DateTime", "java.time.LocalDateTime");
instantiationTypes.put("array", "listOf");
instantiationTypes.put("list", "listOf");
instantiationTypes.put("array", "arrayOf");
instantiationTypes.put("list", "arrayOf");
instantiationTypes.put("map", "mapOf");
importMapping = new HashMap<String, String>();
@@ -241,6 +241,7 @@ public class KotlinClientCodegen extends DefaultCodegen implements CodegenConfig
final String infrastructureFolder = (sourceFolder + File.separator + packageName + File.separator + "infrastructure").replace(".", "/");
supportingFiles.add(new SupportingFile("infrastructure/ApiClient.kt.mustache", infrastructureFolder, "ApiClient.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiAbstractions.kt.mustache", infrastructureFolder, "ApiAbstractions.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApiInfrastructureResponse.kt.mustache", infrastructureFolder, "ApiInfrastructureResponse.kt"));
supportingFiles.add(new SupportingFile("infrastructure/ApplicationDelegates.kt.mustache", infrastructureFolder, "ApplicationDelegates.kt"));
supportingFiles.add(new SupportingFile("infrastructure/RequestConfig.kt.mustache", infrastructureFolder, "RequestConfig.kt"));

View File

@@ -19,7 +19,7 @@ class {{classname}}(basePath: kotlin.String = "{{{basePath}}}") : ApiClient(base
@Suppress("UNCHECKED_CAST"){{/returnType}}
fun {{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Unit{{/returnType}} {
val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to "${{paramName}}"{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}}
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = {{^hasQueryParams}}mapOf(){{/hasQueryParams}}{{#hasQueryParams}}mapOf({{#queryParams}}"{{paramName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{paramName}}{{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/queryParams}}){{/hasQueryParams}}
val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mapOf(){{/hasQueryParams}}{{#hasQueryParams}}mapOf({{#queryParams}}"{{paramName}}" to {{#isContainer}}toMultiValue({{paramName}}.toList(), "{{collectionFormat}}"){{/isContainer}}{{^isContainer}}listOf("${{paramName}}"){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/queryParams}}){{/hasQueryParams}}
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = {{^headerParams}}mapOf({{#hasFormParams}}"Content-Type" to "multipart/form-data"{{/hasFormParams}}){{/headerParams}}{{#headerParams}}mapOf("{{paramName}}" to {{#isContainer}}{{paramName}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{paramName}}{{/isContainer}}){{/headerParams}}
val localVariableConfig = RequestConfig(
RequestMethod.{{httpMethod}},
@@ -43,13 +43,5 @@ class {{classname}}(basePath: kotlin.String = "{{{basePath}}}") : ApiClient(base
}
{{/operation}}
private fun collectionDelimiter(collectionFormat: kotlin.String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
}
{{/operations}}

View File

@@ -0,0 +1,20 @@
package {{packageName}}.infrastructure
typealias MultiValueMap = Map<String,List<String>>
fun collectionDelimiter(collectionFormat: String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" }
fun <T: Any?> toMultiValue(items: List<T>, collectionFormat: String, map: (item: Any?) -> String = defaultMultiValueConverter): List<String> {
return when(collectionFormat) {
"multi" -> items.map(map)
else -> listOf(items.map(map).joinToString(separator = collectionDelimiter(collectionFormat)))
}
}

View File

@@ -60,7 +60,11 @@ open class ApiClient(val baseUrl: String) {
var urlBuilder = httpUrl.newBuilder()
.addPathSegments(requestConfig.path.trimStart('/'))
requestConfig.query.forEach { k, v -> urlBuilder = urlBuilder.addQueryParameter(k,v) }
requestConfig.query.forEach { k, v ->
v.forEach { queryValue ->
urlBuilder = urlBuilder.addQueryParameter(k,queryValue)
}
}
val url = urlBuilder.build()
val headers = requestConfig.headers + defaultHeaders
@@ -73,6 +77,7 @@ open class ApiClient(val baseUrl: String) {
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
}
// TODO: support multiple contentType,accept options here.
val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase()
val accept = (headers[Accept] as String).substringBefore(";").toLowerCase()

View File

@@ -5,9 +5,11 @@ package {{packageName}}.infrastructure
* 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(
val method: RequestMethod,
val path: String,
val headers: Map<String, String> = mapOf(),
val query: Map<String, String> = mapOf())
val query: Map<String, List<String>> = mapOf())

View File

@@ -104,10 +104,10 @@ public class KotlinClientCodegenModelTest {
Assert.assertEquals(property.baseName, "examples");
Assert.assertEquals(property.getter, "getExamples");
Assert.assertEquals(property.setter, "setExamples");
Assert.assertEquals(property.datatype, "kotlin.collections.List<kotlin.String>");
Assert.assertEquals(property.datatype, "kotlin.Array<kotlin.String>");
Assert.assertEquals(property.name, "examples");
Assert.assertEquals(property.defaultValue, "null");
Assert.assertEquals(property.baseType, "kotlin.collections.List");
Assert.assertEquals(property.baseType, "kotlin.Array");
Assert.assertEquals(property.containerType, "array");
Assert.assertFalse(property.required);
Assert.assertTrue(property.isContainer);

View File

@@ -7,8 +7,8 @@ Name | Type | Description | Notes
**id** | **kotlin.Long** | | [optional]
**category** | [**Category**](Category.md) | | [optional]
**name** | **kotlin.String** | |
**photoUrls** | **kotlin.collections.List&lt;kotlin.String&gt;** | |
**tags** | [**kotlin.collections.List&lt;Tag&gt;**](Tag.md) | | [optional]
**photoUrls** | **kotlin.Array&lt;kotlin.String&gt;** | |
**tags** | [**kotlin.Array&lt;Tag&gt;**](Tag.md) | | [optional]
**status** | [**inline**](#StatusEnum) | pet status in the store | [optional]

View File

@@ -110,7 +110,7 @@ null (empty response body)
<a name="findPetsByStatus"></a>
# **findPetsByStatus**
> kotlin.collections.List&lt;Pet&gt; findPetsByStatus(status)
> kotlin.Array&lt;Pet&gt; findPetsByStatus(status)
Finds Pets by status
@@ -123,9 +123,9 @@ Multiple status values can be provided with comma separated strings
//import io.swagger.client.models.*
val apiInstance = PetApi()
val status : kotlin.collections.List<kotlin.String> = // kotlin.collections.List<kotlin.String> | Status values that need to be considered for filter
val status : kotlin.Array<kotlin.String> = // kotlin.Array<kotlin.String> | Status values that need to be considered for filter
try {
val result : kotlin.collections.List<Pet> = apiInstance.findPetsByStatus(status)
val result : kotlin.Array<Pet> = apiInstance.findPetsByStatus(status)
println(result)
} catch (e: ClientException) {
println("4xx response calling PetApi#findPetsByStatus")
@@ -140,11 +140,11 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**status** | [**kotlin.collections.List&lt;kotlin.String&gt;**](kotlin.String.md)| Status values that need to be considered for filter | [enum: available, pending, sold]
**status** | [**kotlin.Array&lt;kotlin.String&gt;**](kotlin.String.md)| Status values that need to be considered for filter | [enum: available, pending, sold]
### Return type
[**kotlin.collections.List&lt;Pet&gt;**](Pet.md)
[**kotlin.Array&lt;Pet&gt;**](Pet.md)
### Authorization
@@ -157,7 +157,7 @@ Name | Type | Description | Notes
<a name="findPetsByTags"></a>
# **findPetsByTags**
> kotlin.collections.List&lt;Pet&gt; findPetsByTags(tags)
> kotlin.Array&lt;Pet&gt; findPetsByTags(tags)
Finds Pets by tags
@@ -170,9 +170,9 @@ Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3
//import io.swagger.client.models.*
val apiInstance = PetApi()
val tags : kotlin.collections.List<kotlin.String> = // kotlin.collections.List<kotlin.String> | Tags to filter by
val tags : kotlin.Array<kotlin.String> = // kotlin.Array<kotlin.String> | Tags to filter by
try {
val result : kotlin.collections.List<Pet> = apiInstance.findPetsByTags(tags)
val result : kotlin.Array<Pet> = apiInstance.findPetsByTags(tags)
println(result)
} catch (e: ClientException) {
println("4xx response calling PetApi#findPetsByTags")
@@ -187,11 +187,11 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**tags** | [**kotlin.collections.List&lt;kotlin.String&gt;**](kotlin.String.md)| Tags to filter by |
**tags** | [**kotlin.Array&lt;kotlin.String&gt;**](kotlin.String.md)| Tags to filter by |
### Return type
[**kotlin.collections.List&lt;Pet&gt;**](Pet.md)
[**kotlin.Array&lt;Pet&gt;**](Pet.md)
### Authorization

View File

@@ -75,7 +75,7 @@ Creates list of users with given input array
//import io.swagger.client.models.*
val apiInstance = UserApi()
val body : kotlin.collections.List<User> = // kotlin.collections.List<User> | List of user object
val body : kotlin.Array<User> = // kotlin.Array<User> | List of user object
try {
apiInstance.createUsersWithArrayInput(body)
} catch (e: ClientException) {
@@ -91,7 +91,7 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | [**kotlin.collections.List&lt;User&gt;**](User.md)| List of user object |
**body** | [**kotlin.Array&lt;User&gt;**](User.md)| List of user object |
### Return type
@@ -121,7 +121,7 @@ Creates list of users with given input array
//import io.swagger.client.models.*
val apiInstance = UserApi()
val body : kotlin.collections.List<User> = // kotlin.collections.List<User> | List of user object
val body : kotlin.Array<User> = // kotlin.Array<User> | List of user object
try {
apiInstance.createUsersWithListInput(body)
} catch (e: ClientException) {
@@ -137,7 +137,7 @@ try {
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**body** | [**kotlin.collections.List&lt;User&gt;**](User.md)| List of user object |
**body** | [**kotlin.Array&lt;User&gt;**](User.md)| List of user object |
### Return type

View File

@@ -26,7 +26,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
*/
fun addPet(body: Pet) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -58,7 +58,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
*/
fun deletePet(petId: kotlin.Long, apiKey: kotlin.String) : Unit {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("apiKey" to apiKey)
val localVariableConfig = RequestConfig(
RequestMethod.DELETE,
@@ -85,12 +85,12 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter
* @return kotlin.collections.List<Pet>
* @return kotlin.Array<Pet>
*/
@Suppress("UNCHECKED_CAST")
fun findPetsByStatus(status: kotlin.collections.List<kotlin.String>) : kotlin.collections.List<Pet> {
fun findPetsByStatus(status: kotlin.Array<kotlin.String>) : kotlin.Array<Pet> {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("status" to status.joinToString(separator = collectionDelimiter("csv")))
val localVariableQuery: MultiValueMap = mapOf("status" to toMultiValue(status.toList(), "csv"))
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -98,13 +98,13 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
query = localVariableQuery,
headers = localVariableHeaders
)
val response = request<kotlin.collections.List<Pet>>(
val response = request<kotlin.Array<Pet>>(
localVariableConfig,
localVariableBody
)
return when (response.responseType) {
ResponseType.Success -> (response as Success<*>).data as kotlin.collections.List<Pet>
ResponseType.Success -> (response as Success<*>).data as kotlin.Array<Pet>
ResponseType.Informational -> TODO()
ResponseType.Redirection -> TODO()
ResponseType.ClientError -> throw ClientException((response as ClientError<*>).body as? String ?: "Client error")
@@ -117,12 +117,12 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by
* @return kotlin.collections.List<Pet>
* @return kotlin.Array<Pet>
*/
@Suppress("UNCHECKED_CAST")
fun findPetsByTags(tags: kotlin.collections.List<kotlin.String>) : kotlin.collections.List<Pet> {
fun findPetsByTags(tags: kotlin.Array<kotlin.String>) : kotlin.Array<Pet> {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("tags" to tags.joinToString(separator = collectionDelimiter("csv")))
val localVariableQuery: MultiValueMap = mapOf("tags" to toMultiValue(tags.toList(), "csv"))
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -130,13 +130,13 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
query = localVariableQuery,
headers = localVariableHeaders
)
val response = request<kotlin.collections.List<Pet>>(
val response = request<kotlin.Array<Pet>>(
localVariableConfig,
localVariableBody
)
return when (response.responseType) {
ResponseType.Success -> (response as Success<*>).data as kotlin.collections.List<Pet>
ResponseType.Success -> (response as Success<*>).data as kotlin.Array<Pet>
ResponseType.Informational -> TODO()
ResponseType.Redirection -> TODO()
ResponseType.ClientError -> throw ClientException((response as ClientError<*>).body as? String ?: "Client error")
@@ -154,7 +154,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
@Suppress("UNCHECKED_CAST")
fun getPetById(petId: kotlin.Long) : Pet {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -185,7 +185,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
*/
fun updatePet(body: Pet) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.PUT,
@@ -218,7 +218,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
*/
fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String, status: kotlin.String) : Unit {
val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("Content-Type" to "multipart/form-data")
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -252,7 +252,7 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
@Suppress("UNCHECKED_CAST")
fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String, file: java.io.File) : ApiResponse {
val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("Content-Type" to "multipart/form-data")
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -275,12 +275,4 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
}
}
private fun collectionDelimiter(collectionFormat: kotlin.String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
}

View File

@@ -25,7 +25,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC
*/
fun deleteOrder(orderId: kotlin.String) : Unit {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.DELETE,
@@ -56,7 +56,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC
@Suppress("UNCHECKED_CAST")
fun getInventory() : kotlin.collections.Map<kotlin.String, kotlin.Int> {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -88,7 +88,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC
@Suppress("UNCHECKED_CAST")
fun getOrderById(orderId: kotlin.Long) : Order {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -120,7 +120,7 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC
@Suppress("UNCHECKED_CAST")
fun placeOrder(body: Order) : Order {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -143,12 +143,4 @@ class StoreApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiC
}
}
private fun collectionDelimiter(collectionFormat: kotlin.String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
}

View File

@@ -25,7 +25,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
*/
fun createUser(body: User) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -54,9 +54,9 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
* @param body List of user object
* @return void
*/
fun createUsersWithArrayInput(body: kotlin.collections.List<User>) : Unit {
fun createUsersWithArrayInput(body: kotlin.Array<User>) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -85,9 +85,9 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
* @param body List of user object
* @return void
*/
fun createUsersWithListInput(body: kotlin.collections.List<User>) : Unit {
fun createUsersWithListInput(body: kotlin.Array<User>) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.POST,
@@ -118,7 +118,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
*/
fun deleteUser(username: kotlin.String) : Unit {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.DELETE,
@@ -150,7 +150,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
@Suppress("UNCHECKED_CAST")
fun getUserByName(username: kotlin.String) : User {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -183,7 +183,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
@Suppress("UNCHECKED_CAST")
fun loginUser(username: kotlin.String, password: kotlin.String) : kotlin.String {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("username" to username, "password" to password)
val localVariableQuery: MultiValueMap = mapOf("username" to listOf("$username"), "password" to listOf("$password"))
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -213,7 +213,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
*/
fun logoutUser() : Unit {
val localVariableBody: kotlin.Any? = null
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.GET,
@@ -245,7 +245,7 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
*/
fun updateUser(username: kotlin.String, body: User) : Unit {
val localVariableBody: kotlin.Any? = body
val localVariableQuery: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableQuery: MultiValueMap = mapOf()
val localVariableHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf()
val localVariableConfig = RequestConfig(
RequestMethod.PUT,
@@ -268,12 +268,4 @@ class UserApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCl
}
}
private fun collectionDelimiter(collectionFormat: kotlin.String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
}

View File

@@ -0,0 +1,20 @@
package io.swagger.client.infrastructure
typealias MultiValueMap = Map<String,List<String>>
fun collectionDelimiter(collectionFormat: String) = when(collectionFormat) {
"csv" -> ","
"tsv" -> "\t"
"pipes" -> "|"
"ssv" -> " "
else -> ""
}
val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" }
fun <T: Any?> toMultiValue(items: List<T>, collectionFormat: String, map: (item: Any?) -> String = defaultMultiValueConverter): List<String> {
return when(collectionFormat) {
"multi" -> items.map(map)
else -> listOf(items.map(map).joinToString(separator = collectionDelimiter(collectionFormat)))
}
}

View File

@@ -60,7 +60,11 @@ open class ApiClient(val baseUrl: String) {
var urlBuilder = httpUrl.newBuilder()
.addPathSegments(requestConfig.path.trimStart('/'))
requestConfig.query.forEach { k, v -> urlBuilder = urlBuilder.addQueryParameter(k,v) }
requestConfig.query.forEach { k, v ->
v.forEach { queryValue ->
urlBuilder = urlBuilder.addQueryParameter(k,queryValue)
}
}
val url = urlBuilder.build()
val headers = requestConfig.headers + defaultHeaders
@@ -73,6 +77,7 @@ open class ApiClient(val baseUrl: String) {
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
}
// TODO: support multiple contentType,accept options here.
val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase()
val accept = (headers[Accept] as String).substringBefore(";").toLowerCase()

View File

@@ -5,9 +5,11 @@ package io.swagger.client.infrastructure
* 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(
val method: RequestMethod,
val path: String,
val headers: Map<String, String> = mapOf(),
val query: Map<String, String> = mapOf())
val query: Map<String, List<String>> = mapOf())

View File

@@ -25,10 +25,10 @@ import io.swagger.client.models.Tag
*/
data class Pet (
val name: kotlin.String,
val photoUrls: kotlin.collections.List<kotlin.String>,
val photoUrls: kotlin.Array<kotlin.String>,
val id: kotlin.Long? = null,
val category: Category? = null,
val tags: kotlin.collections.List<Tag>? = null,
val tags: kotlin.Array<Tag>? = null,
/* pet status in the store */
val status: Pet.Status? = null
) {

View File

@@ -2,16 +2,21 @@ package io.swagger.client.functional
import io.kotlintest.matchers.should
import io.kotlintest.matchers.beGreaterThan
import io.kotlintest.matchers.shouldEqual
import io.kotlintest.specs.ShouldSpec
import io.swagger.client.apis.PetApi
import io.swagger.client.models.Pet
class EvaluateTest : ShouldSpec() {
init {
should("query against pet statuses") {
val api = PetApi()
val results = api.findPetsByStatus(listOf("sold"))
val results = api.findPetsByStatus(arrayOf("sold"))
results.size should beGreaterThan(1)
// Pet is lazily deserialized here. Need to iterate to verify all "sold" statuses.
results.all { it.status == Pet.Status.sold } shouldEqual true
}
// TODO: Handle default (200) response