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 @@ -125,16 +125,16 @@ public KotlinClientCodegen() {
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>();
Expand Down Expand Up @@ -241,6 +241,7 @@ public void processOpts() {
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"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}},
Expand All @@ -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}}
Original file line number Diff line number Diff line change
@@ -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)))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ public void arrayPropertyTest() {
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);
Expand Down
4 changes: 2 additions & 2 deletions samples/client/petstore/kotlin/docs/Pet.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]


Expand Down
20 changes: 10 additions & 10 deletions samples/client/petstore/kotlin/docs/PetApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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")
Expand All @@ -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

Expand All @@ -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

Expand All @@ -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")
Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions samples/client/petstore/kotlin/docs/UserApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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

Expand Down Expand Up @@ -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) {
Expand All @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -85,26 +85,26 @@ 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,
"/pet/findByStatus",
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")
Expand All @@ -117,26 +117,26 @@ 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,
"/pet/findByTags",
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")
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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 -> ""
}
}
Loading