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

Commit 3cb4571

Browse files
committed
Merge branch '#43'
Conflicts: src/main/kotlin/io/openapiprocessor/core/writer/java/DataTypeWriter.kt src/testInt/groovy/com/github/hauner/openapi/processor/core/ProcessorPendingTest.groovy
2 parents a950c76 + 905043c commit 3cb4571

File tree

21 files changed

+299
-28
lines changed

21 files changed

+299
-28
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,13 @@ class SchemaInfo(
207207
}
208208

209209
/**
210-
* iterate over items
210+
* iterate over composed items
211211
*/
212212
fun eachItemOf(action: (info: SchemaInfo) -> Unit) {
213213
schema?.getItems()?.forEachIndexed { index, schema ->
214214
action(SchemaInfo(
215215
path = path,
216-
name = "${name}-of-${index}",
216+
name = "${name}_${itemOf()!!.capitalize()}_${index}",
217217
schema = schema,
218218
resolver = resolver
219219
))

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.openapiprocessor.core.model
1818

1919
import io.openapiprocessor.core.model.datatypes.DataType
20+
import io.openapiprocessor.core.model.datatypes.ModelDataType
2021
import io.openapiprocessor.core.model.datatypes.ObjectDataType
2122
import io.openapiprocessor.core.model.datatypes.StringEnumDataType
2223
import java.util.function.Consumer
@@ -60,6 +61,10 @@ class Api(
6061
models.getObjectDataTypes().forEach(action)
6162
}
6263

64+
fun forEachModelDataType(action: Consumer<ModelDataType>) {
65+
models.getModelDataTypes().forEach(action)
66+
}
67+
6368
fun forEachEnumDataType(action: Consumer<StringEnumDataType>) {
6469
models.getEnumDataTypes().forEach(action)
6570
}

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616

1717
package io.openapiprocessor.core.model
1818

19-
import io.openapiprocessor.core.model.datatypes.DataType
20-
import io.openapiprocessor.core.model.datatypes.MappedDataType
21-
import io.openapiprocessor.core.model.datatypes.ObjectDataType
22-
import io.openapiprocessor.core.model.datatypes.StringEnumDataType
19+
import io.openapiprocessor.core.model.datatypes.*
2320

2421
/**
2522
* Container of data types from OpenAPI '#/component/schemas'.
@@ -52,6 +49,21 @@ class DataTypes {
5249
.toList()
5350
}
5451

52+
/**
53+
* provides the *object* data types (model classes) used by the api endpoints.
54+
* For this objects the processor will create POJOs classes.
55+
*
56+
* experimental: will probably replace getObjectDataTypes().
57+
*
58+
* @return list of object data types
59+
*/
60+
fun getModelDataTypes(): Collection<ModelDataType> {
61+
return types.values
62+
.filterIsInstance<ModelDataType>()
63+
.filter { it.isModel() }
64+
.toList()
65+
}
66+
5567
/**
5668
* provides the enum data types (model classes) used by the api endpoints.
5769
* For this objects the processor will create enum classes.

src/main/kotlin/io/openapiprocessor/core/model/datatypes/ComposedObjectDataType.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ComposedObjectDataType(
3030
constraints: DataTypeConstraints? = null,
3131
deprecated: Boolean = false
3232

33-
): DataTypeBase(constraints, deprecated) {
33+
): DataTypeBase(constraints, deprecated), ModelDataType {
3434

3535
override fun getName(): String {
3636
return type
@@ -51,8 +51,27 @@ class ComposedObjectDataType(
5151
.toSet()
5252
}
5353

54+
// todo find better name
5455
override fun isComposed(): Boolean {
5556
return of != "allOf"
5657
}
5758

59+
override fun isModel(): Boolean {
60+
return of == "allOf"
61+
}
62+
63+
override fun getProperties(): Map<String, DataType> {
64+
val properties = linkedMapOf<String, DataType>()
65+
66+
if (of == "allOf") {
67+
items.forEach {
68+
if (it is ObjectDataType) {
69+
properties.putAll(it.getProperties())
70+
}
71+
}
72+
}
73+
74+
return properties
75+
}
76+
5877
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright © 2020 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.core.model.datatypes
7+
8+
interface ModelDataType: DataType {
9+
10+
fun isModel(): Boolean
11+
12+
fun getProperties(): Map<String, DataType>
13+
14+
}

src/main/kotlin/io/openapiprocessor/core/model/datatypes/ObjectDataType.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ObjectDataType(
3030
constraints: DataTypeConstraints? = null,
3131
deprecated: Boolean = false
3232

33-
): DataTypeBase(constraints, deprecated) {
33+
): DataTypeBase(constraints, deprecated), ModelDataType {
3434

3535
override fun getName(): String {
3636
return type
@@ -55,7 +55,16 @@ class ObjectDataType(
5555
return properties[name]!!
5656
}
5757

58+
@Deprecated("do not override groovys getProperties()", ReplaceWith("getProperties()"))
5859
fun getObjectProperties(): Map<String, DataType> {
60+
return getProperties()
61+
}
62+
63+
override fun isModel(): Boolean {
64+
return true
65+
}
66+
67+
override fun getProperties(): Map<String, DataType> {
5968
return properties
6069
}
6170

src/main/kotlin/io/openapiprocessor/core/writer/java/ApiWriter.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ import com.google.googlejavaformat.java.JavaFormatterOptions
2121
import io.openapiprocessor.core.converter.ApiOptions
2222
import io.openapiprocessor.core.model.Api
2323
import io.openapiprocessor.core.model.Interface
24-
import io.openapiprocessor.core.model.datatypes.ObjectDataType
2524
import io.openapiprocessor.core.model.datatypes.StringEnumDataType
2625
import io.openapiprocessor.core.misc.toURL
26+
import io.openapiprocessor.core.model.datatypes.ModelDataType
2727
import java.io.BufferedWriter
2828
import java.io.StringWriter
2929
import java.io.Writer
@@ -73,7 +73,7 @@ class ApiWriter(
7373
}
7474

7575
private fun writeObjectDataTypes(api: Api) {
76-
api.forEachObjectDataType {
76+
api.forEachModelDataType {
7777
val target = modelFolder.resolve ("${it.getName()}.java")
7878
val writer = BufferedWriter(PathWriter(target))
7979
writeDataType(writer, it)
@@ -96,7 +96,7 @@ class ApiWriter(
9696
writer.write(format(raw.toString()))
9797
}
9898

99-
private fun writeDataType(writer: Writer, dataType: ObjectDataType) {
99+
private fun writeDataType(writer: Writer, dataType: ModelDataType) {
100100
val raw = StringWriter()
101101
dataTypeWriter.write(raw, dataType)
102102
writer.write(format(raw.toString ()))

src/main/kotlin/io/openapiprocessor/core/writer/java/DataTypeWriter.kt

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package io.openapiprocessor.core.writer.java
1818

1919
import io.openapiprocessor.core.converter.ApiOptions
2020
import io.openapiprocessor.core.model.datatypes.DataType
21-
import io.openapiprocessor.core.model.datatypes.ObjectDataType
21+
import io.openapiprocessor.core.model.datatypes.ModelDataType
2222
import java.io.Writer
2323

2424
/**
@@ -33,7 +33,7 @@ class DataTypeWriter(
3333
private val validationAnnotations: BeanValidationFactory = BeanValidationFactory()
3434
) {
3535

36-
fun write(target: Writer, dataType: ObjectDataType) {
36+
fun write(target: Writer, dataType: ModelDataType) {
3737
headerWriter.write(target)
3838
target.write("package ${dataType.getPackageName()};\n\n")
3939

@@ -52,16 +52,15 @@ class DataTypeWriter(
5252

5353
target.write("public class ${dataType.getName()} {\n\n")
5454

55-
val propertyNames = dataType.getObjectProperties().keys
56-
propertyNames.forEach {
57-
val javaPropertyName = toCamelCase(it)
58-
val propDataType = dataType.getObjectProperty(it)
59-
target.write(getProp(it, javaPropertyName, propDataType, dataType.isRequired(it)))
55+
val properties = dataType.getProperties()
56+
properties.forEach { (propName, propDataType) ->
57+
val javaPropertyName = toCamelCase(propName)
58+
target.write(getProp(propName, javaPropertyName, propDataType,
59+
dataType.isRequired(propName)))
6060
}
6161

62-
propertyNames.forEach {
63-
val javaPropertyName = toCamelCase(it)
64-
val propDataType = dataType.getObjectProperty(it)
62+
properties.forEach { (propName, propDataType) ->
63+
val javaPropertyName = toCamelCase(propName)
6564
target.write(getGetter(javaPropertyName, propDataType))
6665
target.write(getSetter(javaPropertyName, propDataType))
6766
}
@@ -124,14 +123,24 @@ class DataTypeWriter(
124123
return result
125124
}
126125

127-
private fun collectImports(packageName: String, dataType: ObjectDataType): List<String> {
126+
private fun collectImports(packageName: String, dataType: ModelDataType): List<String> {
128127
val imports = mutableSetOf<String>()
129128
imports.add("com.fasterxml.jackson.annotation.JsonProperty")
130129

131130
imports.addAll(dataType.getReferencedImports())
132131

133132
if (apiOptions.beanValidation) {
134-
val propertyNames = dataType.getObjectProperties().keys
133+
val properties = dataType.getProperties()
134+
properties.forEach { (propName, propDataType) ->
135+
val javaPropertyName = toCamelCase(propName)
136+
137+
imports.addAll(validationAnnotations.collectImports(
138+
propDataType,
139+
dataType.isRequired(propName)))
140+
}
141+
142+
143+
val propertyNames = dataType.getProperties().keys
135144
propertyNames.forEach {
136145
val propDataType = dataType.getObjectProperty(it)
137146
imports.addAll(validationAnnotations.collectImports(
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright © 2020 https://github.com/openapi-processor/openapi-processor-core
3+
* PDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.openapiprocessor.core.model.datatypes
7+
8+
import io.kotest.core.spec.style.StringSpec
9+
import io.kotest.matchers.shouldBe
10+
11+
class ComposedObjectDataTypeSpec : StringSpec({
12+
13+
"loop properties of allOf objects as if it was a single object" {
14+
val composed = ComposedObjectDataType("Foo", "pkg", "allOf", listOf(
15+
ObjectDataType("Foo", "pkg", linkedMapOf(
16+
Pair("foo", StringDataType()),
17+
Pair("foobar", StringDataType())
18+
)),
19+
ObjectDataType("Bar", "pkg", linkedMapOf(
20+
Pair("bar", StringDataType()),
21+
Pair("barfoo", StringDataType())
22+
))
23+
))
24+
25+
val properties = composed.getProperties()
26+
27+
properties.keys shouldBe linkedSetOf("foo", "foobar", "bar", "barfoo")
28+
}
29+
30+
})

src/test/kotlin/io/openapiprocessor/core/writer/java/ApiWriterSpec.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ class ApiWriterSpec: StringSpec({
218218
"re-formats model sources" {
219219
val dtWriter = io.mockk.mockk<DataTypeWriter>()
220220
every { dtWriter.write(any(), any()) } answers {
221-
arg<Writer>(0).write(" class \n ${arg<ObjectDataType>(1).getName()} { }\n")
221+
arg<Writer>(0).write(" class \n ${arg<ModelDataType>(1).getName()} { }\n")
222222
}
223223

224224
val dt = DataTypes()

src/testInt/groovy/com/github/hauner/openapi/processor/core/ProcessorEndToEndTest.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class ProcessorEndToEndTest extends ProcessorTestBase {
3737
'ref-loop-array',
3838
'ref-parameter',
3939
'ref-parameter-with-primitive-mapping',
40-
'response-content-multiple-no-content'
40+
'response-content-multiple-no-content',
41+
'schema-composed-allof'
4142
]
4243

4344
@Parameterized.Parameters(name = "{0}")

src/testInt/groovy/com/github/hauner/openapi/processor/core/ProcessorPendingTest.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ import org.junit.runner.RunWith
2525
import org.junit.runners.Parameterized
2626
import spock.lang.Ignore
2727

28-
//@Ignore
28+
@Ignore
2929
@RunWith(Parameterized)
3030
class ProcessorPendingTest extends ProcessorTestBase {
3131

3232
@Parameterized.Parameters(name = "{0}")
3333
static Collection<TestSet> sources () {
3434
return [
35-
new TestSet(name: 'bean-validation', processor: new TestProcessor(), parser: ParserType.SWAGGER),
36-
new TestSet(name: 'bean-validation', processor: new TestProcessor(), parser: ParserType.OPENAPI4J)
35+
new TestSet(name: 'schema-composed-allof', processor: new TestProcessor(), parser: ParserType.SWAGGER),
36+
new TestSet(name: 'schema-composed-allof', processor: new TestProcessor(), parser: ParserType.OPENAPI4J)
3737
]
3838
}
3939

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
items:
2+
- generated/api/Api.java
3+
- generated/model/QueryResponse200.java
4+
- generated/model/QueryResponse200_AllOf_0.java
5+
- generated/model/QueryResponse200_AllOf_1.java
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* This class is auto generated by https://github.com/hauner/openapi-processor-core.
3+
* TEST ONLY.
4+
*/
5+
6+
package generated.api;
7+
8+
import annotation.Mapping;
9+
import generated.model.QueryResponse200;
10+
11+
public interface Api {
12+
13+
@Mapping("/query")
14+
QueryResponse200 getQuery();
15+
16+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* This class is auto generated by https://github.com/hauner/openapi-processor-core.
3+
* TEST ONLY.
4+
*/
5+
6+
package generated.model;
7+
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
10+
public class QueryResponse200 {
11+
12+
@JsonProperty("prop1")
13+
private String prop1;
14+
15+
@JsonProperty("prop2")
16+
private String prop2;
17+
18+
public String getProp1() {
19+
return prop1;
20+
}
21+
22+
public void setProp1(String prop1) {
23+
this.prop1 = prop1;
24+
}
25+
26+
public String getProp2() {
27+
return prop2;
28+
}
29+
30+
public void setProp2(String prop2) {
31+
this.prop2 = prop2;
32+
}
33+
34+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* This class is auto generated by https://github.com/hauner/openapi-processor-core.
3+
* TEST ONLY.
4+
*/
5+
6+
package generated.model;
7+
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
10+
public class QueryResponse200_AllOf_0 {
11+
12+
@JsonProperty("prop1")
13+
private String prop1;
14+
15+
public String getProp1() {
16+
return prop1;
17+
}
18+
19+
public void setProp1(String prop1) {
20+
this.prop1 = prop1;
21+
}
22+
23+
}

0 commit comments

Comments
 (0)