Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
SMILEY4 committed Sep 11, 2024
2 parents 8faa0bf + 6c37e5a commit 90cc7d1
Show file tree
Hide file tree
Showing 29 changed files with 653 additions and 274 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kotlin.code.style=official
# project id
projectGroupId=io.github.smiley4
projectArtifactIdBase=schema-kenerator
projectVersion=1.1.1
projectVersion=1.2.0

# publishing information
projectNameBase=Schema-Kenerator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ sealed class BaseTypeData(
/**
* list of annotations on this type
*/
var annotations: MutableList<AnnotationData>
var annotations: MutableList<AnnotationData>,
/**
* Whether the type can be null
*/
var nullable: Boolean,
)


Expand All @@ -40,7 +44,8 @@ class PlaceholderTypeData(
simpleName = id.full(),
qualifiedName = id.full(),
typeParameters = mutableMapOf(),
annotations = mutableListOf()
annotations = mutableListOf(),
nullable = false
)


Expand All @@ -52,7 +57,8 @@ class WildcardTypeData : BaseTypeData(
simpleName = "*",
qualifiedName = "*",
typeParameters = mutableMapOf(),
annotations = mutableListOf()
annotations = mutableListOf(),
nullable = false
)


Expand All @@ -64,8 +70,9 @@ class PrimitiveTypeData(
simpleName: String,
qualifiedName: String,
typeParameters: MutableMap<String, TypeParameterData> = mutableMapOf(),
annotations: MutableList<AnnotationData> = mutableListOf()
) : BaseTypeData(id, simpleName, qualifiedName, typeParameters, annotations)
annotations: MutableList<AnnotationData> = mutableListOf(),
nullable: Boolean = false
) : BaseTypeData(id, simpleName, qualifiedName, typeParameters, annotations, nullable)


/**
Expand All @@ -77,6 +84,7 @@ open class ObjectTypeData(
qualifiedName: String,
typeParameters: MutableMap<String, TypeParameterData> = mutableMapOf(),
annotations: MutableList<AnnotationData> = mutableListOf(),
nullable: Boolean = false,
/**
* the list of subtypes, i.e. types that extend this type
*/
Expand All @@ -93,7 +101,7 @@ open class ObjectTypeData(
* whether the type is an inline value class
*/
var isInlineValue: Boolean = false
) : BaseTypeData(id, simpleName, qualifiedName, typeParameters, annotations)
) : BaseTypeData(id, simpleName, qualifiedName, typeParameters, annotations, nullable)


/**
Expand All @@ -108,11 +116,12 @@ class EnumTypeData(
supertypes: MutableList<TypeId> = mutableListOf(),
members: MutableList<PropertyData> = mutableListOf(),
annotations: MutableList<AnnotationData> = mutableListOf(),
nullable: Boolean = false,
/**
* the possible values of the enum
*/
var enumConstants: MutableList<String>,
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, subtypes, supertypes, members)
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, nullable, subtypes, supertypes, members)


/**
Expand All @@ -127,6 +136,7 @@ class MapTypeData(
supertypes: MutableList<TypeId> = mutableListOf(),
members: MutableList<PropertyData> = mutableListOf(),
annotations: MutableList<AnnotationData> = mutableListOf(),
nullable: Boolean = false,
/**
* the type of the key
*/
Expand All @@ -135,7 +145,7 @@ class MapTypeData(
* the type of the values
*/
var valueType: PropertyData,
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, subtypes, supertypes, members)
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, nullable, subtypes, supertypes, members)


/**
Expand All @@ -150,6 +160,7 @@ class CollectionTypeData(
supertypes: MutableList<TypeId> = mutableListOf(),
members: MutableList<PropertyData> = mutableListOf(),
annotations: MutableList<AnnotationData> = mutableListOf(),
nullable: Boolean = false,
/**
* the type of the items
*/
Expand All @@ -158,5 +169,5 @@ class CollectionTypeData(
* whether the items in the collection are unique
*/
val unique: Boolean
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, subtypes, supertypes, members)
) : ObjectTypeData(id, simpleName, qualifiedName, typeParameters, annotations, nullable, subtypes, supertypes, members)

Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package io.github.smiley4.schemakenerator.jsonschema
import io.github.smiley4.schemakenerator.core.data.BaseTypeData
import io.github.smiley4.schemakenerator.core.data.Bundle
import io.github.smiley4.schemakenerator.core.data.PropertyData
import io.github.smiley4.schemakenerator.core.data.TypeId
import io.github.smiley4.schemakenerator.jsonschema.data.CompiledJsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.JsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.RefType
import io.github.smiley4.schemakenerator.jsonschema.data.TitleType
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonNode
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaAnnotationTypeHintStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaAutoTitleStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileInlineStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileReferenceRootStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileReferenceStep
Expand All @@ -21,6 +21,8 @@ import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotati
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationTitleStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCustomizeStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaGenerationStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaTitleStep
import io.github.smiley4.schemakenerator.jsonschema.steps.TitleBuilder

enum class OptionalHandling {
REQUIRED,
Expand Down Expand Up @@ -54,10 +56,32 @@ fun Bundle<BaseTypeData>.generateJsonSchema(configBlock: JsonSchemaGenerationSte


/**
* See [JsonSchemaAutoTitleStep]
* See [JsonSchemaTitleStep]
*/
@Deprecated("Was renamed", ReplaceWith("withTitle"))
fun Bundle<JsonSchema>.withAutoTitle(type: TitleType = TitleType.FULL): Bundle<JsonSchema> {
return JsonSchemaAutoTitleStep(type).process(this)
return withTitle(type)
}


/**
* See [JsonSchemaTitleStep]
*/
fun Bundle<JsonSchema>.withTitle(type: TitleType = TitleType.FULL): Bundle<JsonSchema> {
return withTitle(
when (type) {
TitleType.FULL -> TitleBuilder.BUILDER_FULL
TitleType.SIMPLE -> TitleBuilder.BUILDER_SIMPLE
}
)
}


/**
* See [JsonSchemaTitleStep]
*/
fun Bundle<JsonSchema>.withTitle(builder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String): Bundle<JsonSchema> {
return JsonSchemaTitleStep(builder).process(this)
}


Expand Down Expand Up @@ -97,15 +121,43 @@ fun Bundle<JsonSchema>.compileInlining(): CompiledJsonSchema {
* See [JsonSchemaCompileReferenceStep]
*/
fun Bundle<JsonSchema>.compileReferencing(pathType: RefType = RefType.FULL): CompiledJsonSchema {
return JsonSchemaCompileReferenceStep(pathType).compile(this)
return compileReferencing(
when (pathType) {
RefType.FULL -> TitleBuilder.BUILDER_FULL
RefType.SIMPLE -> TitleBuilder.BUILDER_SIMPLE
}
)
}


/**
* See [JsonSchemaCompileReferenceStep]
*/
fun Bundle<JsonSchema>.compileReferencing(builder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String): CompiledJsonSchema {
return JsonSchemaCompileReferenceStep(builder).compile(this)
}


/**
* See [JsonSchemaCompileReferenceRootStep]
*/
fun Bundle<JsonSchema>.compileReferencingRoot(pathType: RefType = RefType.FULL): CompiledJsonSchema {
return JsonSchemaCompileReferenceRootStep(pathType).compile(this)
return compileReferencingRoot(
when (pathType) {
RefType.FULL -> TitleBuilder.BUILDER_FULL
RefType.SIMPLE -> TitleBuilder.BUILDER_SIMPLE
}
)
}


/**
* See [JsonSchemaCompileReferenceRootStep]
*/
fun Bundle<JsonSchema>.compileReferencingRoot(
builder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String
): CompiledJsonSchema {
return JsonSchemaCompileReferenceRootStep(builder).compile(this)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package io.github.smiley4.schemakenerator.jsonschema.steps

import io.github.smiley4.schemakenerator.core.data.BaseTypeData
import io.github.smiley4.schemakenerator.core.data.Bundle
import io.github.smiley4.schemakenerator.core.data.TypeId
import io.github.smiley4.schemakenerator.jsonschema.data.CompiledJsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.JsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.RefType
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileUtils.getRefPath
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileUtils.shouldReference

/**
* Resolves references in prepared json-schemas by collecting them in the definitions-section and referencing them.
* @param pathType how to reference the type, i.e. which name to use
* @param pathBuilder builds the path to reference the type, i.e. which "name" to use
*/
class JsonSchemaCompileReferenceRootStep(private val pathType: RefType = RefType.FULL) {
class JsonSchemaCompileReferenceRootStep(private val pathBuilder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String) {

private val schemaUtils = JsonSchemaUtils()

Expand All @@ -20,9 +20,9 @@ class JsonSchemaCompileReferenceRootStep(private val pathType: RefType = RefType
* Put referenced schemas into definitions and reference them
*/
fun compile(bundle: Bundle<JsonSchema>): CompiledJsonSchema {
val result = JsonSchemaCompileReferenceStep(pathType).compile(bundle)
val result = JsonSchemaCompileReferenceStep(pathBuilder).compile(bundle)
if (shouldReference(result.json)) {
val refPath = getRefPath(pathType, result.typeData, bundle.buildTypeDataMap())
val refPath = pathBuilder(result.typeData, bundle.buildTypeDataMap())
return CompiledJsonSchema(
typeData = result.typeData,
json = schemaUtils.referenceSchema(refPath, true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,22 @@ import io.github.smiley4.schemakenerator.core.data.TypeId
import io.github.smiley4.schemakenerator.core.data.flatten
import io.github.smiley4.schemakenerator.jsonschema.data.CompiledJsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.JsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.RefType
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonNode
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonObject
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonTextValue
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.obj
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileUtils.getRefPath
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileUtils.resolveReferences
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileUtils.shouldReference

/**
* Resolves references in prepared json-schemas by collecting them in the definitions-section and referencing them.
* @param pathType how to reference the type, i.e. which name to use
* @param pathBuilder builds the path to reference the type, i.e. which "name" to use
*/
class JsonSchemaCompileReferenceStep(private val pathType: RefType = RefType.FULL) {
class JsonSchemaCompileReferenceStep(private val pathBuilder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String) {

private val schemaUtils = JsonSchemaUtils()


/**
* Put referenced schemas into definitions and reference them
*/
Expand Down Expand Up @@ -52,10 +51,10 @@ class JsonSchemaCompileReferenceStep(private val pathType: RefType = RefType.FUL
val referencedSchema = schemaList.find(referencedId)
return if (referencedSchema != null) {
if (shouldReference(referencedSchema.json)) {
val refPath = getRefPath(pathType, referencedSchema.typeData, typeDataMap)
if(!definitions.containsKey(refPath)) {
val refPath = pathBuilder(referencedSchema.typeData, typeDataMap)
if (!definitions.containsKey(refPath)) {
definitions[refPath] = placeholder() // break out of infinite loops
definitions[refPath] = resolveReferences(referencedSchema.json) { resolve(it, schemaList, typeDataMap, definitions)}
definitions[refPath] = resolveReferences(referencedSchema.json) { resolve(it, schemaList, typeDataMap, definitions) }
}
schemaUtils.referenceSchema(refPath, true)
} else {
Expand All @@ -73,7 +72,7 @@ class JsonSchemaCompileReferenceStep(private val pathType: RefType = RefType.FUL
}
}

private fun placeholder() = obj { }
private fun placeholder() = obj { }

private fun Collection<JsonSchema>.find(id: TypeId): JsonSchema? {
return this.find { it.typeData.id == id }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package io.github.smiley4.schemakenerator.jsonschema.steps

import io.github.smiley4.schemakenerator.core.data.BaseTypeData
import io.github.smiley4.schemakenerator.core.data.TypeId
import io.github.smiley4.schemakenerator.jsonschema.data.RefType
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonArray
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonNode
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonObject
Expand Down Expand Up @@ -78,23 +75,4 @@ object JsonSchemaCompileUtils {
return false
}


fun getRefPath(pathType: RefType, typeData: BaseTypeData, typeDataMap: Map<TypeId, BaseTypeData>): String {
return when (pathType) {
RefType.FULL -> typeData.qualifiedName
RefType.SIMPLE -> typeData.simpleName
}.let {
if (typeData.typeParameters.isNotEmpty()) {
val paramString = typeData.typeParameters
.map { (_, param) -> getRefPath(pathType, typeDataMap[param.type]!!, typeDataMap) }
.joinToString(",")
"$it<$paramString>"
} else {
it
}
}.let {
it + (typeData.id.additionalId?.let { a -> "#$a" } ?: "")
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import io.github.smiley4.schemakenerator.core.data.BaseTypeData
import io.github.smiley4.schemakenerator.core.data.Bundle
import io.github.smiley4.schemakenerator.core.data.TypeId
import io.github.smiley4.schemakenerator.jsonschema.data.JsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.TitleType
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonObject
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonTextValue

/**
* Adds an automatically determined title to schemas.
* @param type the type of the title
* @param titleBuilder the builder for the title
*/
class JsonSchemaAutoTitleStep(val type: TitleType = TitleType.FULL) {
class JsonSchemaTitleStep(private val titleBuilder: (type: BaseTypeData, types: Map<TypeId, BaseTypeData>) -> String) {

fun process(bundle: Bundle<JsonSchema>): Bundle<JsonSchema> {
val typeDataMap = bundle.buildTypeDataMap()
Expand All @@ -24,25 +23,7 @@ class JsonSchemaAutoTitleStep(val type: TitleType = TitleType.FULL) {

private fun process(schema: JsonSchema, typeDataMap: Map<TypeId, BaseTypeData>) {
if (schema.json is JsonObject && schema.json.properties["title"] == null) {
schema.json.properties["title"] = JsonTextValue(determineTitle(schema.typeData, typeDataMap))
}
}

private fun determineTitle(typeData: BaseTypeData, typeDataMap: Map<TypeId, BaseTypeData>): String {
return when (type) {
TitleType.FULL -> typeData.qualifiedName
TitleType.SIMPLE -> typeData.simpleName
}.let {
if (typeData.typeParameters.isNotEmpty()) {
val paramString = typeData.typeParameters
.map { (_, param) -> determineTitle(typeDataMap[param.type]!!, typeDataMap) }
.joinToString(",")
"$it<$paramString>"
} else {
it
}
}.let {
it + (typeData.id.additionalId?.let { a -> "#$a" } ?: "")
schema.json.properties["title"] = JsonTextValue(titleBuilder(schema.typeData, typeDataMap))
}
}

Expand Down
Loading

0 comments on commit 90cc7d1

Please sign in to comment.