forked from loafle/openapi-generator-original
[Kotlin] enumPropertyNaming UPPERCASE should separate words with _ (#4062)
* [Kotlin] enumPropertyNaming UPPERCASE should separate words with _ * Add unit cases for issue 4062 Co-authored-by: William Cheng <wing328hk@gmail.com>
This commit is contained in:
parent
376e419d0b
commit
69b8831cbe
34
bin/kotlin-uppercase-enum.sh
Executable file
34
bin/kotlin-uppercase-enum.sh
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
echo "# START SCRIPT: $SCRIPT"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=$(ls -ld "$SCRIPT")
|
||||||
|
link=$(expr "$ls" : '.*-> \(.*\)$')
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=$(dirname "$SCRIPT")/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=$(dirname "$SCRIPT")/..
|
||||||
|
APP_DIR=$(cd "${APP_DIR}"; pwd)
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn -B clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="generate -t modules/openapi-generator/src/main/resources/kotlin-client -i modules/openapi-generator/src/test/resources/3_0/issue-4062.yaml -g kotlin --artifact-id kotlin-uppercase-enum --additional-properties enumPropertyNaming=UPPERCASE -o samples/client/petstore/kotlin-uppercase-enum $@"
|
||||||
|
|
||||||
|
java ${JAVA_OPTS} -jar ${executable} ${ags}
|
||||||
|
|
||||||
|
cp CI/samples.ci/client/petstore/kotlin-uppercase-enum/pom.xml samples/client/petstore/kotlin-uppercase-enum/pom.xml
|
@ -530,7 +530,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
|
|||||||
modified = underscore(modified);
|
modified = underscore(modified);
|
||||||
break;
|
break;
|
||||||
case UPPERCASE:
|
case UPPERCASE:
|
||||||
modified = modified.toUpperCase(Locale.ROOT);
|
modified = underscore(modified).toUpperCase(Locale.ROOT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
servers:
|
||||||
|
- url: 'http://petstore.swagger.io/v2'
|
||||||
|
info:
|
||||||
|
description: Test for issue 4062
|
||||||
|
version: 1.0.0
|
||||||
|
title: OpenAPI Petstore
|
||||||
|
license:
|
||||||
|
name: Apache-2.0
|
||||||
|
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
|
||||||
|
paths:
|
||||||
|
/enum:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- enum
|
||||||
|
summary: Get enums
|
||||||
|
description: ''
|
||||||
|
operationId: getEnum
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/PetEnum'
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
PetEnum:
|
||||||
|
type: string
|
||||||
|
description: An enum with complex-ish naming
|
||||||
|
enum:
|
||||||
|
- myFirstValue
|
||||||
|
- MY_SECOND_VALUE
|
@ -0,0 +1,23 @@
|
|||||||
|
# OpenAPI Generator Ignore
|
||||||
|
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
@ -0,0 +1 @@
|
|||||||
|
4.2.0-SNAPSHOT
|
50
samples/client/petstore/kotlin-uppercase-enum/README.md
Normal file
50
samples/client/petstore/kotlin-uppercase-enum/README.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# org.openapitools.client - Kotlin client library for OpenAPI Petstore
|
||||||
|
|
||||||
|
## Requires
|
||||||
|
|
||||||
|
* Kotlin 1.3.41
|
||||||
|
* Gradle 4.9
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
First, create the gradle wrapper script:
|
||||||
|
|
||||||
|
```
|
||||||
|
gradle wrapper
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew check assemble
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs all tests and packages the library.
|
||||||
|
|
||||||
|
## Features/Implementation Notes
|
||||||
|
|
||||||
|
* Supports JSON inputs/outputs, File inputs, and Form inputs.
|
||||||
|
* Supports collection formats for query parameters: csv, tsv, ssv, pipes.
|
||||||
|
* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions.
|
||||||
|
* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets.
|
||||||
|
|
||||||
|
<a name="documentation-for-api-endpoints"></a>
|
||||||
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
All URIs are relative to *http://petstore.swagger.io/v2*
|
||||||
|
|
||||||
|
Class | Method | HTTP request | Description
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
*EnumApi* | [**getEnum**](docs/EnumApi.md#getenum) | **GET** /enum | Get enums
|
||||||
|
|
||||||
|
|
||||||
|
<a name="documentation-for-models"></a>
|
||||||
|
## Documentation for Models
|
||||||
|
|
||||||
|
- [org.openapitools.client.models.PetEnum](docs/PetEnum.md)
|
||||||
|
|
||||||
|
|
||||||
|
<a name="documentation-for-authorization"></a>
|
||||||
|
## Documentation for Authorization
|
||||||
|
|
||||||
|
All endpoints do not require authorization.
|
37
samples/client/petstore/kotlin-uppercase-enum/build.gradle
Normal file
37
samples/client/petstore/kotlin-uppercase-enum/build.gradle
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
group 'org.openapitools'
|
||||||
|
version '1.0.0'
|
||||||
|
|
||||||
|
wrapper {
|
||||||
|
gradleVersion = '4.9'
|
||||||
|
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.3.41'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
|
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||||
|
compile "com.squareup.moshi:moshi-kotlin:1.8.0"
|
||||||
|
compile "com.squareup.moshi:moshi-adapters:1.8.0"
|
||||||
|
compile "com.squareup.okhttp3:okhttp:4.0.1"
|
||||||
|
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0"
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
# EnumApi
|
||||||
|
|
||||||
|
All URIs are relative to *http://petstore.swagger.io/v2*
|
||||||
|
|
||||||
|
Method | HTTP request | Description
|
||||||
|
------------- | ------------- | -------------
|
||||||
|
[**getEnum**](EnumApi.md#getEnum) | **GET** /enum | Get enums
|
||||||
|
|
||||||
|
|
||||||
|
<a name="getEnum"></a>
|
||||||
|
# **getEnum**
|
||||||
|
> PetEnum getEnum()
|
||||||
|
|
||||||
|
Get enums
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```kotlin
|
||||||
|
// Import classes:
|
||||||
|
//import org.openapitools.client.infrastructure.*
|
||||||
|
//import org.openapitools.client.models.*
|
||||||
|
|
||||||
|
val apiInstance = EnumApi()
|
||||||
|
try {
|
||||||
|
val result : PetEnum = apiInstance.getEnum()
|
||||||
|
println(result)
|
||||||
|
} catch (e: ClientException) {
|
||||||
|
println("4xx response calling EnumApi#getEnum")
|
||||||
|
e.printStackTrace()
|
||||||
|
} catch (e: ServerException) {
|
||||||
|
println("5xx response calling EnumApi#getEnum")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
This endpoint does not need any parameter.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**PetEnum**](PetEnum.md)
|
||||||
|
|
||||||
|
### Authorization
|
||||||
|
|
||||||
|
No authorization required
|
||||||
|
|
||||||
|
### HTTP request headers
|
||||||
|
|
||||||
|
- **Content-Type**: Not defined
|
||||||
|
- **Accept**: application/json
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
# PetEnum
|
||||||
|
|
||||||
|
## Enum
|
||||||
|
|
||||||
|
|
||||||
|
* `MY_FIRST_VALUE` (value: `"myFirstValue"`)
|
||||||
|
|
||||||
|
* `MY_SECOND_VALUE` (value: `"MY_SECOND_VALUE"`)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
rootProject.name = 'kotlin-uppercase-enum'
|
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* Test for issue 4062
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
package org.openapitools.client.apis
|
||||||
|
|
||||||
|
import org.openapitools.client.models.PetEnum
|
||||||
|
|
||||||
|
import org.openapitools.client.infrastructure.ApiClient
|
||||||
|
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.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 EnumApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiClient(basePath) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get enums
|
||||||
|
*
|
||||||
|
* @return PetEnum
|
||||||
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun getEnum() : PetEnum {
|
||||||
|
val localVariableBody: kotlin.Any? = null
|
||||||
|
val localVariableQuery: MultiValueMap = mapOf()
|
||||||
|
val localVariableHeaders: MutableMap<String, String> = mutableMapOf()
|
||||||
|
val localVariableConfig = RequestConfig(
|
||||||
|
RequestMethod.GET,
|
||||||
|
"/enum",
|
||||||
|
query = localVariableQuery,
|
||||||
|
headers = localVariableHeaders
|
||||||
|
)
|
||||||
|
val response = request<PetEnum>(
|
||||||
|
localVariableConfig,
|
||||||
|
localVariableBody
|
||||||
|
)
|
||||||
|
|
||||||
|
return when (response.responseType) {
|
||||||
|
ResponseType.Success -> (response as Success<*>).data as PetEnum
|
||||||
|
ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.")
|
||||||
|
ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.")
|
||||||
|
ResponseType.ClientError -> throw ClientException((response as ClientError<*>).body as? String ?: "Client error")
|
||||||
|
ResponseType.ServerError -> throw ServerException((response as ServerError<*>).message ?: "Server error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.openapitools.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: 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,153 @@
|
|||||||
|
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 java.io.File
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val client: OkHttpClient by lazy {
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val builder: OkHttpClient.Builder = OkHttpClient.Builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
|
||||||
|
when {
|
||||||
|
content is File -> content.asRequestBody(
|
||||||
|
mediaType.toMediaTypeOrNull()
|
||||||
|
)
|
||||||
|
mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
|
||||||
|
FormBody.Builder().apply {
|
||||||
|
// content's type *must* be Map<String, Any>
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(content as Map<String,String>).forEach { (key, value) ->
|
||||||
|
add(key, value)
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
mediaType == JsonMediaType -> Serializer.moshi.adapter(T::class.java).toJson(content).toRequestBody(
|
||||||
|
mediaType.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.")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected inline fun <reified T: Any?> responseBody(body: ResponseBody?, mediaType: String? = JsonMediaType): T? {
|
||||||
|
if(body == null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val bodyContent = body.string()
|
||||||
|
if (bodyContent.isEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return when(mediaType) {
|
||||||
|
JsonMediaType -> Serializer.moshi.adapter(T::class.java).fromJson(bodyContent)
|
||||||
|
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected inline fun <reified T: Any?> request(requestConfig: RequestConfig, body : Any? = null): ApiInfrastructureResponse<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] ?: "" == "") {
|
||||||
|
throw kotlin.IllegalStateException("Missing Content-Type header. This is required.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if(headers[Accept] ?: "" == "") {
|
||||||
|
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: support multiple contentType options here.
|
||||||
|
val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase()
|
||||||
|
|
||||||
|
val request = when (requestConfig.method) {
|
||||||
|
RequestMethod.DELETE -> Request.Builder().url(url).delete()
|
||||||
|
RequestMethod.GET -> Request.Builder().url(url)
|
||||||
|
RequestMethod.HEAD -> Request.Builder().url(url).head()
|
||||||
|
RequestMethod.PATCH -> Request.Builder().url(url).patch(requestBody(body, contentType))
|
||||||
|
RequestMethod.PUT -> Request.Builder().url(url).put(requestBody(body, contentType))
|
||||||
|
RequestMethod.POST -> Request.Builder().url(url).post(requestBody(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(";")?.toLowerCase()
|
||||||
|
|
||||||
|
// TODO: handle specific mapping types. e.g. Map<int, Class<?>>
|
||||||
|
when {
|
||||||
|
response.isRedirect -> return Redirection(
|
||||||
|
response.code,
|
||||||
|
response.headers.toMultimap()
|
||||||
|
)
|
||||||
|
response.isInformational -> return Informational(
|
||||||
|
response.message,
|
||||||
|
response.code,
|
||||||
|
response.headers.toMultimap()
|
||||||
|
)
|
||||||
|
response.isSuccessful -> return Success(
|
||||||
|
responseBody(response.body, accept),
|
||||||
|
response.code,
|
||||||
|
response.headers.toMultimap()
|
||||||
|
)
|
||||||
|
response.isClientError -> return ClientError(
|
||||||
|
response.body?.string(),
|
||||||
|
response.code,
|
||||||
|
response.headers.toMultimap()
|
||||||
|
)
|
||||||
|
else -> return ServerError(
|
||||||
|
null,
|
||||||
|
response.body?.string(),
|
||||||
|
response.code,
|
||||||
|
response.headers.toMultimap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package org.openapitools.client.infrastructure
|
||||||
|
|
||||||
|
enum class ResponseType {
|
||||||
|
Success, Informational, Redirection, ClientError, ServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ApiInfrastructureResponse<T>(val responseType: ResponseType) {
|
||||||
|
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()
|
||||||
|
): ApiInfrastructureResponse<T>(ResponseType.Success)
|
||||||
|
|
||||||
|
class Informational<T>(
|
||||||
|
val statusText: String,
|
||||||
|
override val statusCode: Int = -1,
|
||||||
|
override val headers: Map<String, List<String>> = mapOf()
|
||||||
|
) : ApiInfrastructureResponse<T>(ResponseType.Informational)
|
||||||
|
|
||||||
|
class Redirection<T>(
|
||||||
|
override val statusCode: Int = -1,
|
||||||
|
override val headers: Map<String, List<String>> = mapOf()
|
||||||
|
) : ApiInfrastructureResponse<T>(ResponseType.Redirection)
|
||||||
|
|
||||||
|
class ClientError<T>(
|
||||||
|
val body: Any? = null,
|
||||||
|
override val statusCode: Int = -1,
|
||||||
|
override val headers: Map<String, List<String>> = mapOf()
|
||||||
|
) : ApiInfrastructureResponse<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>>
|
||||||
|
): ApiInfrastructureResponse<T>(ResponseType.ServerError)
|
@ -0,0 +1,29 @@
|
|||||||
|
package org.openapitools.client.infrastructure
|
||||||
|
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
object ApplicationDelegates {
|
||||||
|
/**
|
||||||
|
* Provides a property delegate, allowing the property to be set once and only once.
|
||||||
|
*
|
||||||
|
* If unset (no default value), a get on the property will throw [IllegalStateException].
|
||||||
|
*/
|
||||||
|
fun <T> setOnce(defaultValue: T? = null) : ReadWriteProperty<Any?, T> = SetOnce(defaultValue)
|
||||||
|
|
||||||
|
private class SetOnce<T>(defaultValue: T? = null) : ReadWriteProperty<Any?, T> {
|
||||||
|
private var isSet = false
|
||||||
|
private var value: T? = defaultValue
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return value ?: throw IllegalStateException("${property.name} not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = synchronized(this) {
|
||||||
|
if (!isSet) {
|
||||||
|
this.value = value
|
||||||
|
isSet = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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,42 @@
|
|||||||
|
@file:Suppress("unused")
|
||||||
|
package org.openapitools.client.infrastructure
|
||||||
|
|
||||||
|
import java.lang.RuntimeException
|
||||||
|
|
||||||
|
open class ClientException : RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an [ClientException] with no detail message.
|
||||||
|
*/
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an [ClientException] with the specified detail message.
|
||||||
|
|
||||||
|
* @param message the detail message.
|
||||||
|
*/
|
||||||
|
constructor(message: kotlin.String) : super(message)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val serialVersionUID: Long = 123L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class ServerException : RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an [ServerException] with no detail message.
|
||||||
|
*/
|
||||||
|
constructor() : super()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an [ServerException] with the specified detail message.
|
||||||
|
|
||||||
|
* @param message the detail message.
|
||||||
|
*/
|
||||||
|
constructor(message: kotlin.String) : super(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,16 @@
|
|||||||
|
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(
|
||||||
|
val method: RequestMethod,
|
||||||
|
val path: String,
|
||||||
|
val headers: MutableMap<String, String> = mutableMapOf(),
|
||||||
|
val query: Map<String, List<String>> = mapOf()
|
||||||
|
)
|
@ -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,23 @@
|
|||||||
|
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
|
||||||
|
*/
|
||||||
|
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,18 @@
|
|||||||
|
package org.openapitools.client.infrastructure
|
||||||
|
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
|
||||||
|
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
object Serializer {
|
||||||
|
@JvmStatic
|
||||||
|
val moshi: Moshi = Moshi.Builder()
|
||||||
|
.add(Date::class.java, Rfc3339DateJsonAdapter().nullSafe())
|
||||||
|
.add(LocalDateTimeAdapter())
|
||||||
|
.add(LocalDateAdapter())
|
||||||
|
.add(UUIDAdapter())
|
||||||
|
.add(ByteArrayAdapter())
|
||||||
|
.add(KotlinJsonAdapterFactory())
|
||||||
|
.build()
|
||||||
|
}
|
@ -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.fromString(s)
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* Test for issue 4062
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
package org.openapitools.client.models
|
||||||
|
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum with complex-ish naming
|
||||||
|
* Values: MY_FIRST_VALUE,MY_SECOND_VALUE
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum class PetEnum(val value: kotlin.String){
|
||||||
|
|
||||||
|
|
||||||
|
@Json(name = "myFirstValue")
|
||||||
|
MY_FIRST_VALUE("myFirstValue"),
|
||||||
|
|
||||||
|
|
||||||
|
@Json(name = "MY_SECOND_VALUE")
|
||||||
|
MY_SECOND_VALUE("MY_SECOND_VALUE");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user