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

com.ossuminc.riddl.diagrams.mermaid.EntityRelationshipDiagram.scala Maven / Gradle / Ivy

The newest version!
package com.ossuminc.riddl.diagrams.mermaid

import com.ossuminc.riddl.language.AST.*
import com.ossuminc.riddl.passes.resolve.ReferenceMap

import scala.scalajs.js.annotation.*

@JSExportTopLevel("EntityRelationshipDiagram")
class EntityRelationshipDiagram(refMap: ReferenceMap) {

  private def makeTypeName(
    pid: PathIdentifier,
    parent: Parent
  ): String = {
    refMap.definitionOf[Definition](pid, parent) match {
      case None => s"unresolved path: ${pid.format}"
      case Some(definition: Definition) => definition.id.format
    }
  }

  private def makeTypeName(
    typeEx: TypeExpression,
    parent: Parent
  ): String = {
    val name = typeEx match {
      case AliasedTypeExpression(_, _, pid)      => makeTypeName(pid, parent)
      case EntityReferenceTypeExpression(_, pid) => makeTypeName(pid, parent)
      case UniqueId(_, pid)                      => makeTypeName(pid, parent)
      case Alternation(_, of) =>
        of.map(ate => makeTypeName(ate.pathId, parent))
          .mkString("-")
      case _: Mapping                        => "Mapping"
      case _: Aggregation                    => "Aggregation"
      case _: AggregateUseCaseTypeExpression => "Message"
      case _                                 => typeEx.format
    }
    name.replace(" ", "-")
  }

  private def makeERDRelationship(
    from: String,
    to: Field,
    parent: Parent
  ): String = {
    val typeName = makeTypeName(to.typeEx, parent)
    if typeName.nonEmpty then
      val connector = to.typeEx match
        case _: OneOrMore                     => from + " ||--|{ " + typeName
        case _: ZeroOrMore                    => from + " ||--o{ " + typeName
        case _: Optional                      => from + " ||--o| " + typeName
        case _: AliasedTypeExpression         => from + " ||--|| " + typeName
        case _: EntityReferenceTypeExpression => from + " ||--|| " + typeName
        case _: UniqueId                      => from + " ||--|| " + typeName
        case _ => ""
      connector + " : references"
    else typeName
  }

  def generate(
    name: String,
    fields: Seq[Field],
    parent: Parent
  ): Seq[String] = {

    val typ: Seq[String] = s"$name {" +: fields.map { f =>
      val typeName = makeTypeName(f.typeEx, parent)
      val fieldName = f.id.format.replace(" ", "-")
      val comment = "\"" + f.briefString + "\""
      s"  $typeName $fieldName $comment"
    } :+ "}"

    val relationships: Seq[String] = fields
      .map(makeERDRelationship(name, _, parent))
      .filter(_.nonEmpty)

    Seq("erDiagram") ++ typ ++ relationships
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy