All Downloads are FREE. Search and download functionalities are using the official Maven repository.

camundala.helper.openApi.BpmnCreator.scala Maven / Gradle / Ivy

There is a newer version: 1.30.23
Show newest version
package camundala.helper.openApi

import io.swagger.v3.oas.models.OpenAPI

import scala.jdk.CollectionConverters.*

case class BpmnCreator()(using config: OpenApiConfig):

  def create(openAPI: OpenAPI): ApiDefinition =
    val superClass: BpmnSuperClass =
      BpmnSuperClassCreator(openAPI.getInfo, Option(openAPI.getExternalDocs)).create
    val bpmnClasses =
      BpmnClassesCreator(openAPI.getPaths.asScala.toMap).create
    val serviceClasses =
      ServiceClassesCreator(openAPI.getComponents.getSchemas.asScala.toMap).create
    val examples = examplesFrom(bpmnClasses)
    val examplesAll = extractExamples(serviceClasses, examples)
    val updatedServiceClasses = setDefaultValues(serviceClasses, examplesAll)
    ApiDefinition(
      superClass,
      updatedServiceClasses,
      bpmnClasses
    )
  end create

  private def examplesFrom(bpmnClasses: Seq[BpmnServiceObject]): Map[String, Json] =
    bpmnClasses
      .flatMap: c =>
        def ex(field: Option[ConstrField]) = field.flatMap: in =>
          in.example.map(in.tpeName -> _)

        Seq(ex(c.in), ex(c.out)).flatten
      .toMap

  private def extractExamples(
      serviceClasses: Seq[IsFieldType],
      examples: Map[String, Json]
  ): Map[String, Json] =
    val serviceClassMap: Map[String, IsFieldType] = serviceClasses.map(c => c.className -> c).toMap
    serviceClasses.foldLeft(Map.empty[String, Json]):
      case result -> (serviceClass: BpmnClass) if examples.contains(serviceClass.className) =>
        println(s"Example for: ${serviceClass.className}")
        result ++ extractExample(serviceClass, serviceClassMap, examples(serviceClass.className))
      case result -> (serviceClass: BpmnEnum) => // not supported yet
        println(s"Example not supported for: ${serviceClass.className}")
        result
      case result -> other =>
        println(s"No Example for: ${other.className}")
        result
  end extractExamples

  private def extractExample(
      serviceClass: BpmnClass,
      serviceClassMap: Map[String, IsFieldType],
      example: Json
  ): Map[String, Json] =
    val cursor = example.deepDropNullValues.hcursor
    val cursor2 = if example.isArray then cursor.downArray.downN(0) else cursor
    val exMap = serviceClass.fields
      .map: field =>
        cursor2.downField(field.name).focus
          .flatMap:
            case j if j.isArray =>
              j.hcursor.downArray.downN(0).focus
            case j => Some(j)
          .filter:
            _.isObject
          .flatMap: j =>
            serviceClassMap.get(field.tpeName)
              .map:
                case c: BpmnClass =>
                  println(s"Sub Example for: ${c.name}")
                  extractExample(c, serviceClassMap, j)
                case e: BpmnEnum => // not supported yet
                  println(s"Sub Example not supported for: ${e.name}")
                  Map(field.tpeName -> j)
      .collect:
        case Some(m) => m
      .foldLeft(Map.empty[String, Json]): (result, ex) =>
        result ++ ex

    exMap + (serviceClass.name -> example)
  end extractExample

  private def setDefaultValues(
      serviceClasses: Seq[IsFieldType],
      examples: Map[String, Json]
  ): Seq[IsFieldType] =
    serviceClasses.foldLeft(Seq.empty[IsFieldType]):
      case result -> (serviceClass: BpmnClass) =>
        val fields: Option[Seq[ConstrField]] = examples.get(serviceClass.className)
          .map: json =>
            val cursor = json.deepDropNullValues.hcursor
            serviceClass.fields
              .map: field =>
                val defaultValue = cursor.downField(field.name).focus
                  .map:
                    case j if j.isObject =>
                      field.tpeName + "()"
                    case j if j.isArray =>
                      j.asArray
                        .map:
                          _.map:
                            case j2 if j2.isObject =>
                              field.tpeName + "()"
                            case j2 if j2.isArray =>
                              s"Seq.empty[${field.tpeName}] // Seq(Seq()) should not happen"
                            case elem =>
                              elem.toString
                          .mkString(", ")
                        .getOrElse(s"Seq.empty[${field.tpeName}]")
                    case value =>
                      value.toString
                field.withDefaultValueAsStr(defaultValue)
        // println(s"EX: ${ex}")

        result :+ fields.map(f => serviceClass.withFields(f)).getOrElse(serviceClass)
      case result -> serviceClass =>
        result :+ serviceClass
  end setDefaultValues

  private def extractExample(key: String, example: Json): Seq[(String, Json)] =
    val cursor = example.deepDropNullValues
      .hcursor
    val subExamples: Seq[(String, Json)] =
      cursor.keys.view.toSeq.flatten
        .map: k =>
          cursor.downField(k)
        .map: f =>
          f.key
            .flatMap: k =>
              f.focus.map(k -> _)
        .collect:
          case Some(k -> v) if v.isObject =>
            extractExample(k, v)
        .flatten
    subExamples :+ key -> example
  end extractExample
end BpmnCreator




© 2015 - 2024 Weber Informatics LLC | Privacy Policy