Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
cleaning up header writer
renaming SpriteRegistry.kt to SpriteLibrary.kt
  • Loading branch information
chriskn committed Nov 29, 2024
1 parent 13c8f29 commit e3242f7
Show file tree
Hide file tree
Showing 77 changed files with 37,395 additions and 502 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.github.chriskn.structurizrextension.api.icons

import com.github.chriskn.structurizrextension.api.view.sprite.PlantUmlSprite
import java.net.MalformedURLException
import java.net.URI
import java.net.URL
Expand Down Expand Up @@ -55,7 +54,7 @@ object IconRegistry {
/**
* @return The file name of an icon with the given name (case-insensitive) or null if no icon with the given name exists.
*/
@Deprecated("use spriteForName instead")
@Deprecated("use sprite API instead")
internal fun iconFileNameFor(name: String?): String? {
return if (name == null || !exists(name)) {
null
Expand All @@ -68,22 +67,6 @@ object IconRegistry {
}
}

/**
* @param name the name of the sprite
* @return the PumlSprite for a given name or null if no sprites exists
*/
internal fun spriteForName(name: String?): PlantUmlSprite? {
if (name == null || !exists(name)) {
return null
}
val url = iconNameToIconUrl[name.lowercase()]
val iconFileName = iconFileNameFor(name)
if (url == null || iconFileName == null) {
return null
}
return PlantUmlSprite(name = iconFileName, path = url.toString())
}

internal fun reset() {
iconNameToIconUrl.clear()
iconNameToIconUrl.putAll(commonIcons.mapValues { URI(it.value).toURL() })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Component
import com.structurizr.model.Container
import com.structurizr.model.StaticStructureElement
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Element
import com.structurizr.model.InteractionStyle

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Container
import com.structurizr.model.DeploymentElement
import com.structurizr.model.DeploymentNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Container
import com.structurizr.model.DeploymentElement
import com.structurizr.model.DeploymentNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.github.chriskn.structurizrextension.internal.export.view.style.spriteFromJson
import com.github.chriskn.structurizrextension.internal.export.view.style.toJson
import com.structurizr.model.ModelItem
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.Container
import com.structurizr.model.Location
import com.structurizr.model.SoftwareSystem
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.chriskn.structurizrextension.api.model

import com.github.chriskn.structurizrextension.api.icons.IconRegistry
import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import com.structurizr.model.InteractionStyle
import com.structurizr.model.Person
import com.structurizr.model.StaticStructureElement
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.github.chriskn.structurizrextension.api.view.sprite.library

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.ImageSprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.PlantUmlSprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite
import java.net.URI
import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.toPath

/**
* Sprite library
*
* Library offering sprites from different [SpriteSet]s associated by their name.
*
* Allows to load json SpriteSets from URLs.
*/
object SpriteLibrary {

private const val DEFAULT_SPRITES_FOLDER = "/sprites/"

private val spritesByName: MutableMap<String, Sprite> = mutableMapOf()

private val defaultSpriteSetPaths = this.javaClass.getResource(DEFAULT_SPRITES_FOLDER)
?.toURI()
?.toPath()
?.listDirectoryEntries()
.orEmpty()

init {
defaultSpriteSetPaths.map { spriteSetPath ->
loadSpriteSet(spriteSetPath.toUri())
}
}

/**
* Get Sprite by name
*
* @param name the name of the sprite.
* @return the sprite with the given name
*
* @throws IllegalArgumentException if sprite with name does not exist
*/
fun spriteByName(name: String): Sprite {
val lowercaseName = name.lowercase()
return spritesByName[lowercaseName]
?: throw IllegalArgumentException(
"No sprite found for name $lowercaseName. Possible matches: [${
findSpriteByNameContaining(Regex(lowercaseName))
.map { it.name }
.joinToString(", ")
}]"
)
}

/**
* Get Sprite by name or null
*
* @param name the name of the sprite.
* @return the sprite with the given name or null if no sprite with name exists
*/
fun spriteByNameOrNull(name: String): Sprite? {
val lowercaseName = name.lowercase()
return spritesByName[lowercaseName]
}

/**
* Find Sprite by name containing regex
*
* @param nameRegex the regex applied to all sprite names
* @return all sprites with name containing nameRegex
*/
fun findSpriteByNameContaining(nameRegex: Regex): List<Sprite> = spritesByName
.filter { it.key.contains(nameRegex) }
.values
.toList()

/**
* Load sprite set
*
* Loads a [SpriteSet] json from the given URL and adds the contained sprites to the library
*
* @param spriteSetJsonUri URI pointing to [SpriteSet] json file
* @return the loaded SpriteSet
*/
fun loadSpriteSet(spriteSetJsonUri: URI): SpriteSet {
val spriteSet = jacksonObjectMapper().readValue(spriteSetJsonUri.toURL(), SpriteSet::class.java)
val configuredSprites = spriteSet.sprites.map { sprite ->
configureSprite(sprite, spriteSet)
}.toSet()
addSpritesByName(configuredSprites)
return spriteSet.copy(sprites = configuredSprites)
}

private fun addSpritesByName(sprites: Set<Sprite>) {
val spritesWithName = sprites.filter { it.name != null }
spritesByName.putAll(spritesWithName.associateBy { it.name!!.lowercase() })
}

private fun configureSprite(
sprite: Sprite,
spriteSet: SpriteSet,
) = when (sprite) {
is PlantUmlSprite -> sprite.copy(
additionalIncludes = spriteSet.additionalIncludes.orEmpty() + sprite.additionalIncludes.orEmpty(),
additionalDefinitions = spriteSet.additionalDefinitions.orEmpty() + sprite.additionalDefinitions.orEmpty()
)

is ImageSprite -> sprite.copy(
additionalDefinitions = spriteSet.additionalDefinitions.orEmpty() + sprite.additionalDefinitions.orEmpty()
)

else -> sprite
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.github.chriskn.structurizrextension.api.view.sprite.registry
package com.github.chriskn.structurizrextension.api.view.sprite.library

import com.github.chriskn.structurizrextension.api.view.sprite.Sprite
import com.github.chriskn.structurizrextension.api.view.sprite.sprites.Sprite

/**
* SpriteSet
*
* Used to describe a set of sprites as json and load it via [SpriteRegistry]
* Used to describe a set of sprites as json and load it via [SpriteLibrary]
*
* @property name name of the SpriteSet. Should describe the contained sprites
* @property source optional url or other pointer to the original source of the sprites contained
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.github.chriskn.structurizrextension.api.view.sprite
package com.github.chriskn.structurizrextension.api.view.sprite.sprites

import java.net.URI

private val fileInUriRegex = "[^/\\\\&?]+\\.\\w{3,4}(?=([?&].*\$|\$))".toRegex()

/**
* Image sprite
*
Expand All @@ -14,24 +12,27 @@ private val fileInUriRegex = "[^/\\\\&?]+\\.\\w{3,4}(?=([?&].*\$|\$))".toRegex()
* @property scale the image scale. Must be greater zero. 1.0 is default
* @property additionalDefinitions each will be written as !define <additionalDefinition> in the output file.
* Can be used to define named urls. The names then can be used in the url
*
* @constructor Create Image sprite
*/
data class ImageSprite(
val url: String,
val scale: Double? = null,
override val name: String? = null,
val additionalDefinitions: List<String>? = null,
val additionalDefinitions: Set<String>? = null,
) : Sprite(name, scale) {

init {
validateImageUrl(url)
}

private fun validateImageUrl(urlString: String) {
require(urlString.isNotBlank()) {
"URL cannot be blank"
}
val uri = URI(urlString)
val mathResult = fileInUriRegex.find(uri.schemeSpecificPart)
val fileWithEnding = mathResult?.groupValues?.first()
require(fileWithEnding?.contains(".") == true) {
val fileWithEnding = uri.normalize().schemeSpecificPart.split("/").lastOrNull()
require(fileWithEnding != null && fileWithEnding.matches(Regex(".+\\.\\w{3,4}"))) {
"Image URI must point to a file"
}
require(uri.scheme == "img") { "Image URI must use img scheme" }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.chriskn.structurizrextension.api.view.sprite
package com.github.chriskn.structurizrextension.api.view.sprite.sprites

import com.fasterxml.jackson.annotation.JsonIgnore
import com.github.chriskn.structurizrextension.internal.view.style.toValidColor
Expand All @@ -12,6 +12,7 @@ import com.github.chriskn.structurizrextension.internal.view.style.toValidColor
* @property name the name of the icon starting with '&'. See [Open Iconic sprites](https://plantuml.com/de/openiconic)
* @property color the color of the icon. Must be a valid hex code or a named color (e.g. "green")
* @property scale the scale of the icon
*
* @constructor Create Open iconic sprite
*/
data class OpenIconicSprite(
Expand All @@ -24,7 +25,8 @@ data class OpenIconicSprite(
internal val colorValidated: String? = color?.let { toValidColor(color) }

init {
require(name.isNotBlank()) { "Icon name must not be blank" }
require(name.startsWith("&")) { "Icon name must start with '&' but was $name" }
require(
name.startsWith("&") && name.length > 1
) { "Icon name must start with '&' followed by a name but was $name" }
}
}
Loading

0 comments on commit e3242f7

Please sign in to comment.