Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visibility modifier on generated code #345

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions src/main/kotlin/com/cjbooms/fabrikt/cli/CodeGenOptions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ enum class SerializationLibrary(val description: String, val serializationAnnota

override fun toString() = "`${super.toString()}` - $description"
}

enum class MemberVisibility(val description: String) {
PUBLIC("Generate models with public visibility"),
INTERNAL("Generate models with internal visibility")
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ object MutableSettings {
private lateinit var validationLibrary: ValidationLibrary
private lateinit var externalRefResolutionMode: ExternalReferencesResolutionMode
private lateinit var serializationLibrary: SerializationLibrary
private lateinit var memberVisibility: MemberVisibility

fun updateSettings(
genTypes: Set<CodeGenerationType> = emptySet(),
Expand All @@ -27,6 +28,7 @@ object MutableSettings {
validationLibrary: ValidationLibrary = ValidationLibrary.JAVAX_VALIDATION,
externalRefResolutionMode: ExternalReferencesResolutionMode = ExternalReferencesResolutionMode.TARGETED,
serializationLibrary: SerializationLibrary = SerializationLibrary.JACKSON,
generatedMemberVisibility: MemberVisibility = MemberVisibility.PUBLIC
) {
this.generationTypes = genTypes.toMutableSet()
this.controllerOptions = controllerOptions.toMutableSet()
Expand All @@ -39,11 +41,12 @@ object MutableSettings {
this.validationLibrary = validationLibrary
this.externalRefResolutionMode = externalRefResolutionMode
this.serializationLibrary = serializationLibrary
this.memberVisibility = generatedMemberVisibility
}

fun addOption(option: ModelCodeGenOptionType) = modelOptions.add(option)
fun addOption(override: CodeGenTypeOverride) = typeOverrides.add(override)

fun addOption(visibility: MemberVisibility) { memberVisibility = visibility }
fun generationTypes() = this.generationTypes.toSet()
fun controllerOptions() = this.controllerOptions.toSet()
fun controllerTarget() = this.controllerTarget
Expand All @@ -55,4 +58,5 @@ object MutableSettings {
fun validationLibrary() = this.validationLibrary
fun externalRefResolutionMode() = this.externalRefResolutionMode
fun serializationLibrary() = this.serializationLibrary
fun memberVisibility() = this.memberVisibility
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cjbooms.fabrikt.generators

import com.cjbooms.fabrikt.cli.MemberVisibility
import com.cjbooms.fabrikt.generators.TypeFactory.maybeMakeMapValueNullable
import com.cjbooms.fabrikt.generators.model.JacksonMetadata
import com.cjbooms.fabrikt.model.SerializationAnnotations
Expand Down Expand Up @@ -43,6 +44,7 @@ object PropertyUtils {
classSettings: ClassSettings = ClassSettings(ClassSettings.PolymorphyType.NONE),
validationAnnotations: ValidationAnnotations = JavaxValidationAnnotations,
serializationAnnotations: SerializationAnnotations = JacksonAnnotations,
memberVisibility: MemberVisibility
) {
if (this.typeInfo is KotlinTypeInfo.UntypedObject && !serializationAnnotations.supportsAdditionalProperties)
throw UnsupportedOperationException("Untyped objects not supported by selected serialization library (${this.oasKey}: ${this.schema})")
Expand Down Expand Up @@ -169,6 +171,10 @@ object PropertyUtils {
}
}

if (memberVisibility == MemberVisibility.INTERNAL) {
property.addModifiers(KModifier.INTERNAL)
}

classBuilder.addProperty(property.build())
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.cjbooms.fabrikt.generators.model

import com.cjbooms.fabrikt.cli.ExternalReferencesResolutionMode
import com.cjbooms.fabrikt.cli.MemberVisibility
import com.cjbooms.fabrikt.cli.ModelCodeGenOptionType
import com.cjbooms.fabrikt.cli.ModelCodeGenOptionType.SEALED_INTERFACES_FOR_ONE_OF
import com.cjbooms.fabrikt.configurations.Packages
Expand Down Expand Up @@ -76,6 +77,7 @@ class ModelGenerator(
private val validationAnnotations: ValidationAnnotations = MutableSettings.validationLibrary().annotations
private val serializationAnnotations: SerializationAnnotations = MutableSettings.serializationLibrary().serializationAnnotations
private val externalRefResolutionMode: ExternalReferencesResolutionMode = MutableSettings.externalRefResolutionMode()
private val memberVisibility = MutableSettings.memberVisibility()

companion object {
fun toModelType(basePackage: String, typeInfo: KotlinTypeInfo, isNullable: Boolean = false): TypeName {
Expand Down Expand Up @@ -400,6 +402,7 @@ class ModelGenerator(
.addQuarkusReflectionAnnotation()
.addMicronautIntrospectedAnnotation()
.addMicronautReflectionAnnotation()
.addVisibility()

enum.entries.forEach {
val enumConstantBuilder = TypeSpec.anonymousClassBuilder()
Expand All @@ -412,6 +415,7 @@ class ModelGenerator(
}

val valuePropSpecBuilder = PropertySpec.builder("value", String::class).initializer("value")
.addVisibility()
serializationAnnotations.addEnumPropertyAnnotation(valuePropSpecBuilder)
classBuilder.addProperty(valuePropSpecBuilder.build())

Expand All @@ -425,10 +429,12 @@ class ModelGenerator(
.addFunction(
FunSpec.builder("fromValue")
.addParameter(ParameterSpec.builder("value", String::class).build())
.addVisibility()
.returns(enumType.copy(nullable = true))
.addStatement("return mapping[value]")
.build(),
)
.addVisibility()
.build()

return classBuilder.addType(companion).build()
Expand Down Expand Up @@ -469,6 +475,8 @@ class ModelGenerator(
.addMicronautIntrospectedAnnotation()
.addMicronautReflectionAnnotation()
.addCompanionObject()
.addVisibility()

for (oneOfInterface in oneOfInterfaces) {
classBuilder
.addSuperinterface(generatedType(packages.base, ModelNameRegistry.getOrRegister(oneOfInterface)))
Expand Down Expand Up @@ -570,6 +578,7 @@ class ModelGenerator(
.addQuarkusReflectionAnnotation()
.addMicronautIntrospectedAnnotation()
.addMicronautReflectionAnnotation()
.addVisibility()

return interfaceBuilder.build()
}
Expand Down Expand Up @@ -720,6 +729,7 @@ class ModelGenerator(
classSettings = classType,
validationAnnotations = validationAnnotations,
serializationAnnotations = serializationAnnotations,
memberVisibility = memberVisibility
)
}
if (constructorBuilder.parameters.isNotEmpty() && classBuilder.modifiers.isEmpty()) {
Expand Down Expand Up @@ -786,6 +796,14 @@ class ModelGenerator(
return this
}

private fun TypeSpec.Builder.addVisibility(): TypeSpec.Builder {
if (memberVisibility == MemberVisibility.INTERNAL) {
this.addModifiers(KModifier.INTERNAL)
}

return this
}

private fun TypeSpec.Builder.addOptionalAnnotation(
optionType: ModelCodeGenOptionType,
type: ClassName,
Expand All @@ -804,4 +822,26 @@ class ModelGenerator(
ExternalReferencesResolutionMode.TARGETED -> this.filter { apiSchema -> externalReferences.value.contains(apiSchema.name) }
else -> this
}

private fun PropertySpec.Builder.addVisibility(): PropertySpec.Builder {
when (memberVisibility) {
MemberVisibility.PUBLIC -> this.addModifiers(KModifier.PUBLIC)
MemberVisibility.INTERNAL -> this.addModifiers(KModifier.INTERNAL)
}

return this
}

private fun FunSpec.Builder.addVisibility(): FunSpec.Builder {
when (memberVisibility) {
MemberVisibility.PUBLIC -> this.addModifiers(KModifier.PUBLIC)
MemberVisibility.INTERNAL -> this.addModifiers(KModifier.INTERNAL)
}

return this
}

}



Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.cjbooms.fabrikt.generators
import com.beust.jcommander.ParameterException
import com.cjbooms.fabrikt.cli.CodeGenTypeOverride
import com.cjbooms.fabrikt.cli.CodeGenerationType
import com.cjbooms.fabrikt.cli.MemberVisibility
import com.cjbooms.fabrikt.cli.ModelCodeGenOptionType
import com.cjbooms.fabrikt.cli.ValidationLibrary
import com.cjbooms.fabrikt.configurations.Packages
Expand Down Expand Up @@ -67,6 +68,7 @@ class ModelGeneratorTest {
"oneOfMarkerInterface",
"byteArrayStream",
"untypedObject",
"internalVisibility"
)

@BeforeEach
Expand All @@ -89,7 +91,7 @@ class ModelGeneratorTest {
if (testCaseName == "instantDateTime") {
MutableSettings.addOption(CodeGenTypeOverride.DATETIME_AS_INSTANT)
}
if (testCaseName == "discriminatedOneOf" || testCaseName == "oneOfMarkerInterface") {
if (testCaseName == "discriminatedOneOf" || testCaseName == "oneOfMarkerInterface" || testCaseName == "internalVisibility") {
MutableSettings.addOption(ModelCodeGenOptionType.SEALED_INTERFACES_FOR_ONE_OF)
}
if (testCaseName == "mapExamplesNonNullValues") {
Expand All @@ -98,6 +100,9 @@ class ModelGeneratorTest {
if (testCaseName == "byteArrayStream") {
MutableSettings.addOption(CodeGenTypeOverride.BYTEARRAY_AS_INPUTSTREAM)
}
if (testCaseName == "internalVisibility") {
MutableSettings.addOption(MemberVisibility.INTERNAL)
}
val basePackage = "examples.${testCaseName.replace("/", ".")}"
val apiLocation = javaClass.getResource("/examples/$testCaseName/api.yaml")!!
val sourceApi = SourceApi(apiLocation.readText(), baseDir = Paths.get(apiLocation.toURI()))
Expand Down
70 changes: 70 additions & 0 deletions src/test/resources/examples/internalVisibility/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
openapi: 3.0.0
info:
paths:
/some:
post:
operationId: sendSomeObject
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/SomeObj"
responses:
200:
content:
application/json:
schema:
$ref: "#/components/schemas/SomeObj"
get:
operationId: getSomeObject
responses:
200:
description: Success response
content:
application/json:
schema:
$ref: "#/components/schemas/SomeObj"

components:
schemas:
SomeObj:
type: object
required:
- state
properties:
state:
$ref: "#/components/schemas/State"
State:
oneOf:
- $ref: "#/components/schemas/StateA"
- $ref: "#/components/schemas/StateB"
discriminator:
propertyName: status
mapping:
a: "#/components/schemas/StateA"
b: "#/components/schemas/StateB"
Status:
type: string
enum:
- a
- b
StateA:
type: object
required:
- status
properties:
status:
$ref: "#/components/schemas/Status"
StateB:
type: object
required:
- status
- mode
properties:
status:
$ref: "#/components/schemas/Status"
mode:
type: string
enum:
- mode1
- mode2
Empty file.
Empty file.
13 changes: 13 additions & 0 deletions src/test/resources/examples/internalVisibility/models/SomeObj.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonProperty
import javax.validation.Valid
import javax.validation.constraints.NotNull

internal class SomeObj(
@param:JsonProperty("state")
@get:JsonProperty("state")
@get:NotNull
@get:Valid
internal val state: State,
)
14 changes: 14 additions & 0 deletions src/test/resources/examples/internalVisibility/models/State.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonSubTypes
import com.fasterxml.jackson.`annotation`.JsonTypeInfo

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "status",
visible = true,
)
@JsonSubTypes(JsonSubTypes.Type(value = StateA::class, name = "a"),JsonSubTypes.Type(value =
StateB::class, name = "b"))
internal sealed interface State
11 changes: 11 additions & 0 deletions src/test/resources/examples/internalVisibility/models/StateA.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonProperty
import javax.validation.constraints.NotNull

internal class StateA(
@get:JsonProperty("status")
@get:NotNull
@param:JsonProperty("status")
internal val status: Status = Status.A,
) : State
14 changes: 14 additions & 0 deletions src/test/resources/examples/internalVisibility/models/StateB.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonProperty
import javax.validation.constraints.NotNull

internal class StateB(
@get:JsonProperty("mode")
@get:NotNull
internal val mode: StateBMode,
@get:JsonProperty("status")
@get:NotNull
@param:JsonProperty("status")
internal val status: Status = Status.B,
) : State
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonValue
import kotlin.String
import kotlin.collections.Map

internal enum class StateBMode(
@JsonValue
internal val `value`: String,
) {
MODE1("mode1"),
MODE2("mode2"),
;

internal companion object {
private val mapping: Map<String, StateBMode> = entries.associateBy(StateBMode::value)

internal fun fromValue(`value`: String): StateBMode? = mapping[value]
}
}
20 changes: 20 additions & 0 deletions src/test/resources/examples/internalVisibility/models/Status.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package examples.internalVisibility.models

import com.fasterxml.jackson.`annotation`.JsonValue
import kotlin.String
import kotlin.collections.Map

internal enum class Status(
@JsonValue
internal val `value`: String,
) {
A("a"),
B("b"),
;

internal companion object {
private val mapping: Map<String, Status> = entries.associateBy(Status::value)

internal fun fromValue(`value`: String): Status? = mapping[value]
}
}
Loading