Skip to content

Commit

Permalink
Fix for strcuturizr compatibility issues (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskn committed Aug 4, 2024
1 parent f69a44f commit 20d534d
Show file tree
Hide file tree
Showing 16 changed files with 399 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@ import com.structurizr.model.Person
import com.structurizr.model.SoftwareSystem

private const val LOCATION_PROPERTY = "c4location"
private val defaultLocation = Location.Unspecified

var SoftwareSystem.c4Location: Location
/**
* Returns the [Location] of the SoftwareSystem.
*/
get() = Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
get() = if (this.properties.containsKey(LOCATION_PROPERTY)) {
Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
} else {
defaultLocation
}

/**
* Sets the [Location] of the SoftwareSystem.
Expand All @@ -24,7 +29,11 @@ var Container.c4Location: Location
/**
* Returns the [Location] of the container.
*/
get() = Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
get() = if (this.properties.containsKey(LOCATION_PROPERTY)) {
Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
} else {
defaultLocation
}

/**
* Sets the [Location] of the container.
Expand All @@ -37,7 +46,11 @@ var Person.c4Location: Location
/**
* Returns the [Location] of the Component.
*/
get() = Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
get() = if (this.properties.containsKey(LOCATION_PROPERTY)) {
Location.valueOf(this.properties.getValue(LOCATION_PROPERTY))
} else {
defaultLocation
}

/**
* Sets the [Location] of the Component.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ internal class DynamicViewExporter(
containerGroups.forEach { (container, components) ->
val system = container.softwareSystem
if (hierarchy.containsKey(system)) {
hierarchy[system] = hierarchy[system]!!.plus(container to components).toMutableMap()
hierarchy[system] = hierarchy.getValue(system).plus(container to components).toMutableMap()
} else {
hierarchy[system] = mutableMapOf(container to components)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,61 @@ import com.structurizr.view.SystemContextView
import com.structurizr.view.SystemLandscapeView

internal class SystemViewExporter(
private val c4PlantUMLExporter: ExtendedC4PlantUMLExporter
private val c4PlantUMLExporter: ExtendedC4PlantUMLExporter,
) {

fun exportLandscapeView(view: SystemLandscapeView): Diagram {
val writer = IndentingWriter()
c4PlantUMLExporter.writeHeader(view, writer)

val elementsInView = view.elements.sortedBy { idOf(it.element) }

val systemsAndPersonsInEnterprise = if (view.showEnterpriseBoundary) {
writeElementsInEnterprise(view, writer)
} else {
emptyList()
}

writeElementsOutsideEnterprise(
elementsOutsideEnterprise = elementsInView - systemsAndPersonsInEnterprise.toSet(),
view,
writer
)
val showEnterpriseBoundary = view.showEnterpriseBoundary
writeElements(view, writer, showEnterpriseBoundary)

c4PlantUMLExporter.writeRelationships(view, writer)
c4PlantUMLExporter.writeFooter(view, writer)
return c4PlantUMLExporter.createDiagram(view, writer.toString())
}

internal fun exportContextView(view: SystemContextView): Diagram {
fun exportContextView(view: SystemContextView): Diagram {
val writer = IndentingWriter()
c4PlantUMLExporter.writeHeader(view, writer)

val elementsInView = view.elements.sortedBy { idOf(it.element) }

val systemsAndPersonsInEnterprise = if (view.showEnterpriseBoundary) {
writeElementsInEnterprise(view, writer)
} else {
emptyList()
}

writeElementsOutsideEnterprise(
elementsOutsideEnterprise = elementsInView - systemsAndPersonsInEnterprise.toSet(),
view,
writer
)
val showEnterpriseBoundary = view.showEnterpriseBoundary
writeElements(view, writer, showEnterpriseBoundary)

c4PlantUMLExporter.writeRelationships(view, writer)
c4PlantUMLExporter.writeFooter(view, writer)

return c4PlantUMLExporter.createDiagram(view, writer.toString())
}

private fun writeElements(
view: StaticView,
writer: IndentingWriter,
showEnterpriseBoundary: Boolean,
) {
val elementsInView = view.elements.sortedBy { idOf(it.element) }
val systemsAndPersonsInEnterprise = systemsAndPersonsInEnterprise(view)
if (showEnterpriseBoundary && systemsAndPersonsInEnterprise.isNotEmpty()) {
writeElementsInEnterprise(view, writer, systemsAndPersonsInEnterprise)
writeElementsOutsideEnterprise(
elementsOutsideEnterprise = elementsInView - systemsAndPersonsInEnterprise.toSet(),
view,
writer
)
} else {
writeElementsOutsideEnterprise(
elementsOutsideEnterprise = elementsInView,
view,
writer
)
}
}

private fun writeElementsOutsideEnterprise(
elementsOutsideEnterprise: List<ElementView>,
view: StaticView,
writer: IndentingWriter
writer: IndentingWriter,
) {
for (elementView in elementsOutsideEnterprise) {
c4PlantUMLExporter.writeElement(view, elementView.element, writer)
Expand All @@ -82,19 +83,18 @@ internal class SystemViewExporter(

private fun writeElementsInEnterprise(
view: StaticView,
writer: IndentingWriter
): List<ElementView> {
val systemsAndPersonsInEnterprise = systemsInEnterprise(view)
val enterpriseName = view.model.enterpriseName ?: ""
writer: IndentingWriter,
systemsAndPersonsInEnterprise: List<ElementView>,
) {
val enterpriseName = view.model.enterpriseName.orEmpty()
c4PlantUMLExporter.startEnterpriseBoundary(view, enterpriseName, writer)
for (elementView in systemsAndPersonsInEnterprise) {
c4PlantUMLExporter.writeElement(view, elementView.element, writer)
}
c4PlantUMLExporter.endEnterpriseBoundary(view, writer)
return systemsAndPersonsInEnterprise
}

private fun systemsInEnterprise(view: ModelView): List<ElementView> =
private fun systemsAndPersonsInEnterprise(view: ModelView): List<ElementView> =
view.elements
.filter {
val element = it.element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,8 @@ internal object BoundaryWriter {
}

private fun DeploymentNode.toMacro() =
"""Node(${idOf(this)}, "$name", "${technology ?: ""}", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
"""Node(${idOf(this)}, "$name", "${technology.orEmpty()}", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""

private fun determineBoundaryEndSymbol(view: View): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,44 +67,32 @@ internal class ElementWriter(
}

private fun InfrastructureNode.toMacro() =
"""Node(${idOf(this)}, "$name", "${technology ?: ""}", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
"""Node(${idOf(this)}, "$name", "${technology.orEmpty()}", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""

private fun SoftwareSystem.toMacro(id: String) =
"""System${this.c4Type?.c4Type ?: ""}${this.c4Location.toPlantUmlString()}($id, "$name", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
"""System${this.c4Type?.c4Type.orEmpty()}${this.c4Location.toPlantUmlString()}($id, "$name", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""

private fun Container.toMacro(id: String): String =
"""Container${this.c4Type?.c4Type ?: ""}${this.c4Location.toPlantUmlString()}($id, "$name", "$technology", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
"""Container${this.c4Type?.c4Type.orEmpty()}${this.c4Location.toPlantUmlString()}($id, "$name", "$technology", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""

private fun Person.toMacro(): String {
val externalMarker = this.c4Location.toPlantUmlString()
return """Person$externalMarker(${idOf(this)}, "$name", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
return """Person$externalMarker(${idOf(this)}, "$name", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""
}

private fun Component.toMacro(): String {
return """Component${this.c4Type?.c4Type ?: ""}(${
idOf(
this
)
}, "$name", "$technology", "${description ?: ""}", "${
IconRegistry.iconFileNameFor(
icon
) ?: ""
return """Component${this.c4Type?.c4Type.orEmpty()}(${
idOf(this)
}, "$name", "${technology.orEmpty()}", "${description.orEmpty()}", "${
IconRegistry.iconFileNameFor(icon).orEmpty()
}"${linkString(link)})"""
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ import com.structurizr.model.ModelItem
internal object PropertyWriter {

fun writeProperties(item: ModelItem, writer: IndentingWriter) {
if (item.c4Properties == null) {
return
}
val headers = item.c4Properties!!.header
val c4Properties = item.c4Properties ?: return
val headers = c4Properties.header
if (!headers.isNullOrEmpty()) {
writer.writeLine("""SetPropertyHeader(${headers.joinToString(", ") { """"$it"""" }})""")
} else {
writer.writeLine("""WithoutPropertyHeader()""")
}
val values = item.c4Properties?.values ?: listOf()
val values = c4Properties.values
values.forEach { row ->
writer.writeLine("""AddProperty(${row.joinToString(", ") { value -> """"$value"""" }})""")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ internal class RelationshipWriter(
if (relationship.technology != null) {
relationshipBuilder.append(""", "${relationship.technology}"""")
}
val sprite = IconRegistry.iconFileNameFor(relationship.icon ?: "")
val sprite = IconRegistry.iconFileNameFor(relationship.icon.orEmpty())
if (!sprite.isNullOrBlank()) {
relationshipBuilder.append(""", ${'$'}sprite=$sprite""")
}
Expand Down Expand Up @@ -123,7 +123,7 @@ internal class RelationshipWriter(
relationshipBuilder.append(""", ${'$'}techn="${relationship.technology}"""")
}

val sprite = IconRegistry.iconFileNameFor(relationship.icon ?: "")
val sprite = IconRegistry.iconFileNameFor(relationship.icon.orEmpty())
if (!sprite.isNullOrBlank()) {
relationshipBuilder.append(""", ${'$'}sprite="$sprite"""")
}
Expand Down
Loading

0 comments on commit 20d534d

Please sign in to comment.