Skip to content
Merged
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The library has springdoc-openapi as a provided dependency,
thus users of the library have to include that dependency in their projects:
- for springdoc-openapi 1.x versions `1.6.7` up to `1.7.0` (including) of
`"org.springdoc" % "springdoc-openapi-webmvc-core"` are supported
- for springdoc-openapi 2.x versions `2.0.0` up to `2.3.0` (including) of
- for springdoc-openapi 2.x versions `2.0.0` up to `2.8.9` (including) of
`"org.springdoc" % "springdoc-openapi-starter-webmvc-api"` are supported

### Add library dependency to SBT/Maven
Expand Down
2 changes: 1 addition & 1 deletion examples/springdoc-openapi-scala-2/simple/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ lazy val root = (project in file("."))
.settings(
libraryDependencies ++= Seq(
"za.co.absa" %% "springdoc-openapi-scala-2" % `springdoc-openapi-scala-2-version`,
"org.springdoc" % "springdoc-openapi-starter-webmvc-api" % "2.3.0",
"org.springdoc" % "springdoc-openapi-starter-webmvc-api" % "2.8.9",
"org.springframework.boot" % "spring-boot-starter-web" % "3.2.0",
"org.playframework" %% "play-json" % "3.0.1"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package za.co.absa.springdocopenapiscala

import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.media.{Discriminator, Schema}
import io.swagger.v3.oas.models.media.{ArraySchema, BooleanSchema, Discriminator, IntegerSchema, NumberSchema, ObjectSchema, Schema, StringSchema, UUIDSchema}

import java.time.{Instant, LocalDate, LocalDateTime, LocalTime, ZonedDateTime}
import java.util.UUID
Expand All @@ -27,6 +27,7 @@ import scala.reflect.runtime.universe._
import OpenAPIModelRegistration._

import java.sql.Timestamp
import scala.collection.Seq

class OpenAPIModelRegistration(
components: Components,
Expand Down Expand Up @@ -69,7 +70,7 @@ class OpenAPIModelRegistration(
handleType(tpe)
}

private case class OpenAPISimpleType(tpe: String, format: Option[String] = None)
private case class OpenAPISimpleType(schema: Schema[_], format: Option[String] = None, _type: Option[String] = None)

@tailrec
private def handleType(tpe: Type): Schema[_] = {
Expand All @@ -96,8 +97,7 @@ class OpenAPIModelRegistration(

private def handleCaseType(tpe: Type): Schema[_] = {
val name = tpe.typeSymbol.name.toString.trim
val schema = new Schema
schema.setType("object")
val schema = new ObjectSchema
val fields = tpe.decls.collect {
case field: TermSymbol if field.isVal => field
}
Expand All @@ -114,17 +114,15 @@ class OpenAPIModelRegistration(

private def handleMap(keyType: Type, valueType: Type): Schema[_] = keyType match {
case _ if keyType <:< typeOf[String] =>
val schema = new Schema
schema.setType("object")
val schema = new ObjectSchema
schema.setAdditionalProperties(handleType(valueType))
schema
case _ => throw new IllegalArgumentException("In OpenAPI 3.0.x Map must have String key type.")
}

private def handleSeqLike(tpe: Type): Schema[_] = {
val schema = new Schema
val schema = new ArraySchema
val innerSchema = handleType(tpe.typeArgs.head)
schema.setType("array")
schema.setItems(innerSchema)
schema
}
Expand All @@ -139,8 +137,7 @@ class OpenAPIModelRegistration(
val enumValues = parentObjectType.members.filter(isSymbolEnumerationValue)
val enumValuesAsStrings = enumValues.map(_.name.toString.trim)

val schema = new Schema[String]
schema.setType("string")
val schema = new StringSchema
schema.setEnum(enumValuesAsStrings.toList.asJava)
schema
}
Expand Down Expand Up @@ -224,33 +221,39 @@ class OpenAPIModelRegistration(
}

private def handleSimpleType(tpe: Type): Schema[_] = {
val schema = new Schema
val OpenAPISimpleType(terminalTpe, format) = getOpenAPISimpleType(tpe)
schema.setType(terminalTpe)
format.foreach(f => schema.setFormat(f))
schema
val simpleType = getOpenAPISimpleType(tpe)
simpleType.format.foreach(simpleType.schema.setFormat)
simpleType._type.foreach(simpleType.schema.setType)
simpleType.schema
}

private def getOpenAPISimpleType(tpe: Type): OpenAPISimpleType = tpe.dealias match {
case t if t =:= typeOf[Byte] => OpenAPISimpleType("integer", Some("int32"))
case t if t =:= typeOf[Short] => OpenAPISimpleType("integer", Some("int32"))
case t if t =:= typeOf[Int] => OpenAPISimpleType("integer", Some("int32"))
case t if t =:= typeOf[Long] => OpenAPISimpleType("integer", Some("int64"))
case t if t =:= typeOf[Float] => OpenAPISimpleType("number", Some("float"))
case t if t =:= typeOf[Double] => OpenAPISimpleType("number", Some("double"))
case t if t =:= typeOf[Char] => OpenAPISimpleType("string")
case t if t =:= typeOf[String] => OpenAPISimpleType("string")
case t if t =:= typeOf[UUID] => OpenAPISimpleType("string", Some("uuid"))
case t if t =:= typeOf[Boolean] => OpenAPISimpleType("boolean")
case t if t =:= typeOf[Unit] => OpenAPISimpleType("null")
case t if t =:= typeOf[ZonedDateTime] => OpenAPISimpleType("string", Some("date-time"))
case t if t =:= typeOf[Instant] => OpenAPISimpleType("string", Some("date-time"))
case t if t =:= typeOf[LocalDateTime] => OpenAPISimpleType("string", Some("date-time"))
case t if t =:= typeOf[LocalDate] => OpenAPISimpleType("string", Some("date"))
case t if t =:= typeOf[LocalTime] => OpenAPISimpleType("string", Some("time"))
case t if t =:= typeOf[Timestamp] => OpenAPISimpleType("string", Some("date-time"))
case t if t =:= typeOf[BigDecimal] => OpenAPISimpleType("number")
case t if t =:= typeOf[BigInt] => OpenAPISimpleType("integer")
case t if t =:= typeOf[Byte] || t =:= typeOf[Short] || t =:= typeOf[Int] =>
OpenAPISimpleType(new IntegerSchema())
case t if t =:= typeOf[Long] =>
OpenAPISimpleType(new IntegerSchema(), Some("int64"))
case t if t =:= typeOf[Float] =>
OpenAPISimpleType(new NumberSchema(), Some("float"))
case t if t =:= typeOf[Double] =>
OpenAPISimpleType(new NumberSchema(), Some("double"))
case t if t =:= typeOf[Char] || t =:= typeOf[String] =>
OpenAPISimpleType(new StringSchema())
case t if t =:= typeOf[UUID] =>
OpenAPISimpleType(new UUIDSchema())
case t if t =:= typeOf[Boolean] =>
OpenAPISimpleType(new BooleanSchema())
case t if t =:= typeOf[Unit] =>
OpenAPISimpleType(new Schema, None, Some("null"))
case t if t =:= typeOf[ZonedDateTime] || t =:= typeOf[Instant] || t =:= typeOf[LocalDateTime] || t =:= typeOf[Timestamp] =>
OpenAPISimpleType(new StringSchema(), Some("date-time"))
case t if t =:= typeOf[LocalDate] =>
OpenAPISimpleType(new StringSchema(), Some("date"))
case t if t =:= typeOf[LocalTime] =>
OpenAPISimpleType(new StringSchema(), Some("time"))
case t if t =:= typeOf[BigDecimal] =>
OpenAPISimpleType(new NumberSchema())
case t if t =:= typeOf[BigInt] =>
OpenAPISimpleType(new IntegerSchema(), Some(null))
}

private def registerAsReference(name: String, schema: Schema[_]): Schema[_] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package za.co.absa.springdocopenapiscala

import io.swagger.v3.oas.models.Components
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.media.{IntegerSchema, Schema}
import org.scalatest
import org.scalatest.flatspec.AnyFlatSpec

Expand Down Expand Up @@ -281,7 +281,7 @@ class OpenAPIModelRegistrationSpec extends AnyFlatSpec {
assertAdditionalPropertiesAreAsExpected(
actualSchemas,
"Maps.a",
(new Schema).`type`("integer").format("int32")
new IntegerSchema()
)
assertTypeAndFormatAreAsExpected(actualSchemas, "Maps.b", "object")
assertAdditionalPropertiesAreAsExpected(
Expand Down
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object Dependencies {

def springdocOpenapi(majorVersion: Int): String = majorVersion match {
case 1 => "[1.6.7,1.7.0]"
case 2 => "[2.0.0,2.3.0]"
case 2 => "[2.0.0,2.8.9]"
}
}

Expand Down