Skip to content
This repository was archived by the owner on Mar 16, 2025. It is now read-only.
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 @@ -155,13 +155,20 @@ class DataTypeConverter(
}

private fun createObjectDataType(schemaInfo: SchemaInfo, dataTypes: DataTypes): DataType {
val properties = LinkedHashMap<String, DataType>()
val properties = LinkedHashMap<String, PropertyDataType>()
schemaInfo.eachProperty { propName: String, propSchemaInfo: SchemaInfo ->
var propDataType = convert(propSchemaInfo, dataTypes)

if (propSchemaInfo.getNullable()) {
propDataType = nullWrapper.wrap(propDataType, schemaInfo)
}

propDataType = PropertyDataType(
propSchemaInfo.readOnly,
propSchemaInfo.writeOnly,
propDataType
)

properties[propName] = propDataType
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class SchemaInfo(
* schema.
*
* The swagger parser (resolve option) creates schemas for intermediate $refs where the name is
* based on the filename. This breaks code generation because the original/public name of the
* based on the filename. It breaks code generation because the original/public name of the
* schema is lost.
*/
private var refName: Boolean = false
Expand Down Expand Up @@ -219,6 +219,12 @@ class SchemaInfo(
val pattern: String?
get() = schema?.pattern

val readOnly: Boolean
get() = schema?.readOnly ?: false

val writeOnly: Boolean
get() = schema?.writeOnly ?: false

/**
* iterate over properties
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ class DataTypeCollector(
is StringEnumDataType -> {
dataTypes.addRef(dataType.getName())
}
is PropertyDataType -> {
collect(dataType.dataType)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface DataType {
}

/**
* The "package" of this type without [typeName].
* The "package" of this type without [getTypeName].
*/
fun getPackageName(): String

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
package io.openapiprocessor.core.model.datatypes

/**
* Null(able) data type wrapper. Assumes a single generic parameter.
* Null(able) data type wrapper, i.e. [org.openapitools.jackson.nullable.JsonNullable]. Assumes a
* single generic parameter.
*/
class NullDataType(
private val name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ open class ObjectDataType(
private val name: DataTypeName,
private val pkg: String,
/** linked map to preserve order */
private val properties: LinkedHashMap<String, DataType> = linkedMapOf(),
private val properties: LinkedHashMap<String, PropertyDataType> = linkedMapOf(),
override val constraints: DataTypeConstraints? = null,
override val deprecated: Boolean = false,
override val documentation: Documentation? = null
Expand Down Expand Up @@ -44,15 +44,15 @@ open class ObjectDataType(
.toSet()
}

fun addObjectProperty(name: String, type: DataType) {
fun addObjectProperty(name: String, type: PropertyDataType) {
properties[name] = type
}

fun getObjectProperty(name: String): DataType {
fun getObjectProperty(name: String): PropertyDataType {
return properties[name]!!
}

fun getProperties(): Map<String, DataType> {
fun getProperties(): Map<String, PropertyDataType> {
return properties
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2021 https://github.com/openapi-processor/openapi-processor-core
* PDX-License-Identifier: Apache-2.0
*/

package io.openapiprocessor.core.model.datatypes

import io.openapiprocessor.core.model.Documentation

/**
* schema "properties" data type wrapper. readOnly/writeOnly may be different on each use of the
* same schema as a property in another schema.
*/
open class PropertyDataType(
val readOnly: Boolean,
val writeOnly: Boolean,
val dataType: DataType
): DataType {

override fun getName(): String {
return dataType.getName()
}

override fun getTypeName(): String {
return dataType.getTypeName()
}

override fun getPackageName(): String {
return dataType.getPackageName()
}

override fun getImports(): Set<String> {
return dataType.getImports()
}

override val referencedImports: Set<String>
get() = dataType.referencedImports

override val constraints: DataTypeConstraints?
get() = dataType.constraints

override val deprecated: Boolean
get() = dataType.deprecated

override val documentation: Documentation?
get() = dataType.documentation

}

2 changes: 2 additions & 0 deletions src/main/kotlin/io/openapiprocessor/core/parser/Schema.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ interface Schema {

val pattern: String?

val readOnly: Boolean
val writeOnly: Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,10 @@ class Schema(val schema: O4jSchema) : ParserSchema {
override val pattern: String?
get() = schema.pattern

override val readOnly: Boolean
get() = schema.readOnly ?: false

override val writeOnly: Boolean
get() = schema.writeOnly ?: false

}
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,10 @@ class Schema(private val schema: SwaggerSchema<*>): ParserSchema {
override val pattern: String?
get() = schema.pattern

override val readOnly: Boolean
get() = schema.readOnly ?: false

override val writeOnly: Boolean
get() = schema.writeOnly ?: false

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.openapiprocessor.core.converter.ApiOptions
import io.openapiprocessor.core.model.datatypes.DataType
import io.openapiprocessor.core.model.datatypes.ModelDataType
import io.openapiprocessor.core.model.datatypes.NullDataType
import io.openapiprocessor.core.model.datatypes.PropertyDataType
import io.openapiprocessor.core.support.capitalizeFirstChar
import java.io.Writer

Expand Down Expand Up @@ -56,7 +57,7 @@ class DataTypeWriter(

dataType.forEach { propName, propDataType ->
val javaPropertyName = toCamelCase(propName)
target.write(getProp(propName, javaPropertyName, propDataType,
target.write(getProp(propName, javaPropertyName, propDataType as PropertyDataType,
dataType.isRequired(propName)))
}

Expand All @@ -70,8 +71,10 @@ class DataTypeWriter(
}

private fun getProp(
propertyName: String, javaPropertyName: String,
propDataType: DataType, required: Boolean): String {
propertyName: String,
javaPropertyName: String,
propDataType: PropertyDataType,
required: Boolean): String {

var result = ""

Expand All @@ -83,26 +86,52 @@ class DataTypeWriter(

var propTypeName = propDataType.getTypeName()
if(apiOptions.beanValidation) {
val info = validationAnnotations.validate(propDataType, required)
val info = validationAnnotations.validate(propDataType.dataType, required)
val prop = info.prop
prop.annotations.forEach {
result += " ${it}\n"
}
propTypeName = prop.dataTypeValue
}

result += " @JsonProperty(\"$propertyName\")\n"
result += " ${getPropertyAnnotation(propertyName, propDataType)}\n"
result += " private $propTypeName $javaPropertyName"

// null may have an init value
if (propDataType is NullDataType && propDataType.init != null) {
result += " = ${propDataType.init}"
// null (JsonNullable) may have an init value
val dataType = propDataType.dataType
if (dataType is NullDataType && dataType.init != null) {
result += " = ${dataType.init}"
}

result += ";\n\n"
return result
}

private fun getPropertyAnnotation(propertyName: String, propDataType: PropertyDataType): String {
val access = getAccess(propDataType)

var result = "@JsonProperty("
if (access != null) {
result += "value = \"$propertyName\", access = JsonProperty.Access.${access.value}"
} else {
result += "\"$propertyName\""
}

result += ")"
return result
}

private fun getAccess(propDataType: PropertyDataType): PropertyAccess? {
if (!propDataType.readOnly && !propDataType.writeOnly)
return null

return when {
propDataType.readOnly -> PropertyAccess("READ_ONLY")
propDataType.writeOnly -> PropertyAccess("WRITE_ONLY")
else -> throw IllegalStateException()
}
}

private fun getGetter(propertyName: String, propDataType: DataType): String {
var result = ""
result += ifDeprecated(propDataType)
Expand Down Expand Up @@ -156,9 +185,8 @@ class DataTypeWriter(
imports.addAll(prop.imports)

dataType.forEach { propName, propDataType ->
val propInfo = validationAnnotations.validate(
propDataType, dataType.isRequired(propName))

val target = getTarget(propDataType)
val propInfo = validationAnnotations.validate(target, dataType.isRequired(propName))
val propProp = propInfo.prop
imports.addAll(propProp.imports)
}
Expand All @@ -169,4 +197,13 @@ class DataTypeWriter(
.sorted()
}

private fun getTarget(dataType: DataType): DataType {
if (dataType is PropertyDataType)
return dataType.dataType

return dataType
}

}

class PropertyAccess(val value: String)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.openapiprocessor.core.framework.Framework
import io.openapiprocessor.core.model.datatypes.LazyDataType
import io.openapiprocessor.core.converter.ApiOptions
import io.openapiprocessor.core.model.datatypes.ObjectDataType
import io.openapiprocessor.core.model.datatypes.PropertyDataType
import spock.lang.Specification

import static com.github.hauner.openapi.core.test.OpenApiParser.parse
Expand Down Expand Up @@ -66,9 +67,11 @@ components:
def itf = api.interfaces.first ()
def ep = itf.endpoints.first ()
def rp = ep.getFirstResponse ('200')
def rt = rp.responseType
def sf = rt.properties.self
def rt = rp.responseType as ObjectDataType
def pt = rt.properties.self
def sf = pt.dataType
rt instanceof ObjectDataType
pt instanceof PropertyDataType
sf instanceof LazyDataType
sf.name == 'Self'
sf.packageName == 'io.openapiprocessor.generated.model'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class DataTypeConverterSpec extends Specification {
def bar = dt.find ('Bar') as ObjectDataType
bar.properties['val'].name == 'String'
def foo = dt.find ('Foo') as ObjectDataType
foo.properties['bar'] == bar
foo.properties['bar'].dataType == bar
}

void "converts simple array schema to Array[]" () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,13 @@ class TestSchema implements Schema {
[]
}

@Override
boolean getReadOnly () {
return false
}

@Override
boolean getWriteOnly () {
return false
}
}
Loading