Skip to content
This repository was archived by the owner on Mar 16, 2025. It is now read-only.

Commit 789b971

Browse files
committed
Merge branch 'response-type-handling'
# Conflicts: # src/main/kotlin/io/openapiprocessor/core/writer/java/InterfaceWriter.kt # src/main/kotlin/io/openapiprocessor/core/writer/java/MethodWriter.kt
2 parents ce249c8 + e608a88 commit 789b971

37 files changed

Lines changed: 977 additions & 164 deletions

File tree

src/main/kotlin/io/openapiprocessor/core/converter/ApiOptions.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package io.openapiprocessor.core.converter
77

88
import io.openapiprocessor.core.converter.mapping.Mapping
9+
import io.openapiprocessor.core.converter.mapping.ResultStyleOptionMapping
10+
import io.openapiprocessor.core.processor.mapping.v2.ResultStyle
911
import io.openapiprocessor.core.support.Empty
1012

1113
/**
@@ -68,3 +70,20 @@ class ApiOptions {
6870
}
6971

7072
}
73+
74+
/**
75+
* get (global) result style option mapping value if set, otherwise [ResultStyle.SUCCESS].
76+
*
77+
* this is a shortcut to avoid the dependency on the
78+
* [io.openapiprocessor.core.converter.mapping.MappingFinder] for this *simple* case.
79+
*/
80+
val ApiOptions.resultStyle: ResultStyle
81+
get() {
82+
val matches = typeMappings
83+
.filterIsInstance(ResultStyleOptionMapping::class.java)
84+
85+
if (matches.isEmpty())
86+
return ResultStyle.SUCCESS
87+
88+
return matches.first().value
89+
}

src/main/kotlin/io/openapiprocessor/core/converter/mapping/MappingFinder.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package io.openapiprocessor.core.converter.mapping
88
import io.openapiprocessor.core.converter.SchemaInfo
99
import io.openapiprocessor.core.converter.mapping.matcher.*
1010
import io.openapiprocessor.core.model.HttpMethod
11+
import io.openapiprocessor.core.processor.mapping.v2.ResultStyle
1112

1213
/**
1314
* find mappings of a given schema info in the type mapping list.
@@ -127,6 +128,21 @@ class MappingFinder(private val typeMappings: List<Mapping> = emptyList()) {
127128
return matches.first() as ResultTypeMapping
128129
}
129130

131+
/**
132+
* get (global) result style option mapping value.
133+
*
134+
* @return the [ResultStyle] if set, otherwise null.
135+
*/
136+
fun findResultStyleMapping(): ResultStyle? {
137+
val matches = typeMappings
138+
.filterIsInstance(ResultStyleOptionMapping::class.java)
139+
140+
if (matches.isEmpty())
141+
return null
142+
143+
return matches.first().value
144+
}
145+
130146
/**
131147
* find (endpoint) "single" type mappings.
132148
*
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright 2021 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.core.converter.mapping
7+
8+
/**
9+
* allows to handle simple name/value options in the mappings configuration.
10+
*/
11+
open class OptionMapping<T>(val name: String, val value: T): Mapping {
12+
13+
override fun getChildMappings(): List<Mapping> {
14+
return listOf(this)
15+
}
16+
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright 2021 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.core.converter.mapping
7+
8+
import io.openapiprocessor.core.processor.mapping.v2.ResultStyle
9+
10+
class ResultStyleOptionMapping(resultStyle: ResultStyle):
11+
OptionMapping<ResultStyle>("resultStyle", resultStyle)

src/main/kotlin/io/openapiprocessor/core/model/EndpointResponse.kt

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package io.openapiprocessor.core.model
77

88
import io.openapiprocessor.core.model.datatypes.AnyOneOfObjectDataType
99
import io.openapiprocessor.core.model.datatypes.ResultDataType
10+
import io.openapiprocessor.core.processor.mapping.v2.ResultStyle
1011

1112
/**
1213
* The responses that can be returned by an endpoint method for one (successful) response.
@@ -29,18 +30,36 @@ class EndpointResponse(
2930
get() = main.contentType
3031

3132
/**
32-
* provides the response type.
33+
* provides the response type based on the requested style.
3334
*
34-
* If the endpoint has multiple responses and there is no result data type the response type
35-
* is `Object`. If the response has a result data type the response type is `ResultDataType<?>`.
35+
* [ResultStyle.SUCCESS]
36+
* - response type is the single success response type regardless of the number of available
37+
* error responses.
38+
*
39+
* [ResultStyle.ALL]
40+
* - If the endpoint has multiple responses the response type is `Object`. If the response is
41+
* wrapped by a result data type (i.e. wrapper) the response type is `ResultDataType<?>`.
42+
* - If the endpoint has only a success response type it is used as the response type.
43+
*
44+
* @param style required style
45+
* @return the response data type in the requested style
46+
*/
47+
fun getResponseType(style: ResultStyle): String {
48+
if (isAnyOneOfResponse())
49+
return getMultiResponseTypeName()
50+
51+
if (style == ResultStyle.ALL && errors.isNotEmpty())
52+
return getMultiResponseTypeName()
53+
54+
return getSingleResponseTypeName()
55+
}
56+
57+
/**
58+
* test only: provides the response type.
3659
*/
3760
val responseType: String
3861
get() {
39-
return if (hasMultipleResponses()) {
40-
getMultiResponseTypeName()
41-
} else {
42-
getSingleResponseTypeName()
43-
}
62+
return getResponseType(ResultStyle.SUCCESS)
4463
}
4564

4665
val description: String?
@@ -49,16 +68,19 @@ class EndpointResponse(
4968
/**
5069
* provides the imports required for {@link #getResponseType()}.
5170
*
71+
* @param style required style
5272
* @return list of imports
5373
*/
54-
val responseImports: Set<String>
55-
get() {
56-
return if (hasMultipleResponses()) {
57-
getImportsMulti()
58-
} else {
59-
getImportsSingle()
60-
}
61-
}
74+
75+
fun getResponseImports(style: ResultStyle): Set<String> {
76+
if (isAnyOneOfResponse())
77+
return getImportsMulti()
78+
79+
if (style == ResultStyle.ALL && errors.isNotEmpty())
80+
return getImportsMulti()
81+
82+
return getImportsSingle()
83+
}
6284

6385
/**
6486
* returns a list with all content types.
@@ -76,14 +98,8 @@ class EndpointResponse(
7698
return result
7799
}
78100

79-
/**
80-
* if this response has multiple types.
81-
*/
82-
private fun hasMultipleResponses(): Boolean {
83-
if (main.responseType is AnyOneOfObjectDataType) {
84-
return true
85-
}
86-
return errors.isNotEmpty()
101+
private fun isAnyOneOfResponse(): Boolean {
102+
return main.responseType is AnyOneOfObjectDataType
87103
}
88104

89105
/**
@@ -109,14 +125,7 @@ class EndpointResponse(
109125
}
110126

111127
private fun getImportsSingle(): Set<String> {
112-
val imports = mutableSetOf<String>()
113-
114-
imports.addAll (main.imports)
115-
errors.forEach {
116-
imports.addAll (it.imports)
117-
}
118-
119-
return imports
128+
return main.imports
120129
}
121130

122131
}

src/main/kotlin/io/openapiprocessor/core/processor/MappingConverter.kt

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
/*
2-
* Copyright 2019-2020 the original authors
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
2+
* Copyright 2019 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
154
*/
165

176
package io.openapiprocessor.core.processor
@@ -26,8 +15,6 @@ import io.openapiprocessor.core.processor.mapping.v2.Mapping as MappingV2
2615
/**
2716
* Converter for the type mapping from the mapping yaml. It converts the type mapping information
2817
* into the format used by [io.openapiprocessor.core.converter.DataTypeConverter].
29-
*
30-
* @author Martin Hauner
3118
*/
3219
class MappingConverter {
3320

src/main/kotlin/io/openapiprocessor/core/processor/MappingReader.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.openapiprocessor.core.processor
77

88
import com.fasterxml.jackson.databind.DeserializationFeature
9+
import com.fasterxml.jackson.databind.MapperFeature
910
import com.fasterxml.jackson.databind.ObjectMapper
1011
import com.fasterxml.jackson.databind.PropertyNamingStrategies
1112
import com.fasterxml.jackson.databind.module.SimpleModule
@@ -84,10 +85,11 @@ class MappingReader(private val validator: MappingValidator = MappingValidator()
8485
.nullIsSameAsDefault (true)
8586
.build ()
8687

87-
return ObjectMapper (YAMLFactory ())
88-
.configure (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
89-
.setPropertyNamingStrategy (PropertyNamingStrategies.KEBAB_CASE)
90-
.registerModules (kotlinModule, module)
88+
return ObjectMapper(YAMLFactory())
89+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
90+
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true)
91+
.setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE)
92+
.registerModules(kotlinModule, module)
9193
}
9294

9395
private fun createV1Parser(): ObjectMapper {

src/main/kotlin/io/openapiprocessor/core/processor/mapping/v2/Map.kt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,12 @@
11
/*
2-
* Copyright 2020 the original authors
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
2+
* Copyright 2020 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
154
*/
165

176
package io.openapiprocessor.core.processor.mapping.v2
187

198
/**
209
* the "map:" entry in the mapping yaml
21-
*
22-
* @author Martin Hauner
2310
*/
2411
data class Map(
2512

@@ -28,6 +15,11 @@ data class Map(
2815
*/
2916
val result: String? = null,
3017

18+
/**
19+
* controller method return type, eg. **success** response or **all** responses
20+
*/
21+
val resultStyle: ResultStyle? = null,
22+
3123
/**
3224
* single mapping, e.g. Mono<>
3325
*/
@@ -38,6 +30,11 @@ data class Map(
3830
*/
3931
val multi: String? = null,
4032

33+
/**
34+
* controller method response
35+
*/
36+
val responseType: ResponseType? = ResponseType.ALL,
37+
4138
/**
4239
* null wrapper, e.g. JsonNullable<>
4340
*/

src/main/kotlin/io/openapiprocessor/core/processor/mapping/v2/MappingConverter.kt

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
/*
2-
* Copyright 2020 the original authors
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
2+
* Copyright 2020 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
154
*/
165

176
package io.openapiprocessor.core.processor.mapping.v2
@@ -30,8 +19,6 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker
3019
/**
3120
* Converter for the type mapping from the mapping yaml. It converts the type mapping information
3221
* into the format used by [io.openapiprocessor.core.converter.DataTypeConverter].
33-
*
34-
* @author Martin Hauner
3522
*/
3623
class MappingConverter(val mapping: MappingV2) {
3724
companion object {
@@ -47,6 +34,10 @@ class MappingConverter(val mapping: MappingV2) {
4734
result.add(convertResult(mapping.map.result))
4835
}
4936

37+
if(mapping.map.resultStyle != null) {
38+
result.add(convertResultStyleOption(mapping.map.resultStyle))
39+
}
40+
5041
if(mapping.map.single != null) {
5142
result.add(convertType("single" , mapping.map.single))
5243
}
@@ -79,6 +70,10 @@ class MappingConverter(val mapping: MappingV2) {
7970
return result
8071
}
8172

73+
private fun convertResultStyleOption(value: ResultStyle): Mapping {
74+
return ResultStyleOptionMapping(value)
75+
}
76+
8277
private fun convertResult (result: String): Mapping {
8378
return ResultTypeMapping(result)
8479
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright 2021 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.core.processor.mapping.v2
7+
8+
enum class ResponseType(val kind: String) {
9+
ALL("all"),
10+
SUCCESS("success")
11+
}

0 commit comments

Comments
 (0)