camundala.camunda.model.scala Maven / Gradle / Ivy
package camundala
package camunda
import camundala.bpmn.*
import camundala.domain.*
case class Bpmn(path: Path, processes: BpmnProcess*)
case class BpmnProcess(
process: Process[?, ?, ?],
elements: Seq[BpmnInOut[?, ?]] = Seq.empty
):
lazy val id: String = process.id
def withElements(
elements: (InOut[?, ?, ?] | BpmnInOut[?, ?])*
): BpmnProcess =
this.copy(elements = elements.map {
case inOut: InOut[?, ?, ?] => BpmnInOut(inOut.asInstanceOf[InOut[Product, Product, ?]])
case bpmnInOut: BpmnInOut[?, ?] => bpmnInOut
})
end BpmnProcess
object BpmnProcess:
given Conversion[InOut[?, ?, ?], BpmnInOut[?, ?]] = BpmnInOut(_)
case class BpmnInOut[
In <: Product,
Out <: Product
](
inOut: InOut[In, Out, ?],
outMappers: Seq[PathMapper] = Seq.empty,
inMappers: Seq[PathMapper] = Seq.empty
):
lazy val id: String = inOut.id
def withOutMapper(pathMapper: PathMapper): BpmnInOut[In, Out] =
copy(outMappers = outMappers :+ pathMapper)
def withInMapper(pathMapper: PathMapper): BpmnInOut[In, Out] =
copy(inMappers = inMappers :+ pathMapper)
end BpmnInOut
case class PathMapper(
varName: String,
varType: MapType,
path: List[PathEntry]
):
// flag if it can be matched with a simple Expression:
// ${myObj.prop("myField").stringValue()}
// this is possible if there are only PathElems in the path.
lazy val isInOutMapper: Boolean =
path.forall(_.isInstanceOf[PathEntry.PathElem])
def printGroovy(): String =
toMappingEntries
.map(_.printGroovy())
.mkString("\n.")
def printExpression(): String =
toMappingEntries
.map(_.name) match
case Nil => throwErr("The Path is empty - It must have more than one element!")
case x :: Nil => throwErr(s"The Path is '$x' - It must have more than one element!")
case x :: xs =>
s"$${" + x + xs.mkString(".prop(\"", "\").prop(\"", s"\")${varType.expr}") + "}"
def toMappingEntries: List[MappingEntry] =
val head = path.headOption match
case Some(PathEntry.PathElem(n)) =>
MappingEntry.ValueElem(n)
case other =>
throwErr("The Path must start")
path.tail.foldLeft(List[MappingEntry](head)) {
case result -> PathEntry.PathElem(n) =>
result :+ MappingEntry.ValueElem(n)
case result -> PathEntry.OptionalPath =>
result.init :+ MappingEntry.OptionalElem(result.last.name)
}
end toMappingEntries
end PathMapper
enum PathEntry:
case OptionalPath
case PathElem(name: String)
enum MapType(val expr: String):
case Boolean extends MapType(".boolValue()")
case Int extends MapType(".numberValue()")
case Long extends MapType(".numberValue()")
case Double extends MapType(".numberValue()")
case String extends MapType(".stringValue()")
case Json extends MapType("")
end MapType
object MapType:
def apply(className: String): MapType =
className match
case n if n.contains("Boolean") => MapType.Boolean
case n if n.contains("Int") => MapType.Int
case n if n.contains("Long") => MapType.Long
case n if n.contains("Float") => MapType.Double
case n if n.contains("Double") => MapType.Double
case n if n.contains("String") => MapType.String
case n => MapType.Json
end MapType
sealed trait MappingEntry:
def name: String
def printGroovy(): String
object MappingEntry:
case class OptionalElem(name: String) extends MappingEntry:
def printGroovy(): String = s"$name?"
case class SeqElem(name: String) extends MappingEntry:
def printGroovy(): String = "SeqElem"
case class ValueElem(name: String) extends MappingEntry:
def printGroovy(): String = name
end MappingEntry