Link map key to an entity that hasn't been defined yet in a PlantUML object diagram

33 views Asked by At

When defining a map in a PlantUML object diagram, is it possible to link a key within a map to another map that hasn't been defined yet?

Understandably, the following code yields a "No such entity Map2" error if the indicated line is uncommented:

@startuml

' Maps can contain two types of keys:
' Value keys have a value within the map; they use a "=>" arrow.
' Link keys point to another entity in the diagram (outside the map); they use a "*->" arrow.
' The two types of keys are rendered differently.

map Map1 {
  SomeKey => SomeValue
' If the next line is uncommented, diagram generation fails with a "No such entity Map2" error.
'  OtherMap *-> Map2
}

map Map2 {
  SomeKey => SomeValue
  OtherMap *-> Map1
}

@enduml

This isn't a problem with other entity types because they can be defined before links between them are specified. Here's an example using objects:

@startuml

object Obj1
object Obj2

' Adding links between objects after they've been defined.
Obj1 -> Obj2
Obj2 -> Obj1

' Adding fields to objects after they've been defined.
Obj1 : field = value
Obj1 : Any string can go here
Obj2 : field : value
Obj2 : No particular syntax

@enduml

As far as I can tell, this isn't possible with link keys in maps: a map's definition must include all its keys (it's not possible to add keys to an existing map) and the type of each key (value vs. link) is permanently set when the map is defined. It's possible to link an existing empty value key to another entity after the map containing that key has been defined, but the key is still rendered as a value key, not a link key (see the last example in this question).

Here are a couple ways I tried to add a key to an existing map (with that key linking to another map):

@startuml

map Map1 {
  SomeKey => SomeValue
}

map Map2 {
  SomeKey => SomeValue
  Map1 *-> Map1
}

map Map3 {
  SomeKey => SomeValue
  Map1 *-> Map1
}

' Trying to add a key named "Map3" to Map2 that links to Map3.

' Attempt 1
' Adds an arrow from Map2 to Map3. No "Map3" key is added.
'Map2::Map3 -> Map3

' Attempt 2
' Adds an arrow pointing from Map2 to Map3. The arrow starts with a diamond. No "Map3" key is added.
'Map2::Map3 *-> Map3


@enduml

The answer here suggests starting with an empty value key and then later adding a link. This almost works: the existing key can be linked to the entity, but is still rendered as a value key (not a link key) with an empty value:

@startuml

map Map1 {
  SomeKey => SomeValue
}

' Note the new "Map3" value key with no value.
' Trying to define an empty link key results in an error.
map Map2 {
  SomeKey => SomeValue
  Map1 *-> Map1
  Map3 =>
}

map Map3 {
  SomeKey => SomeValue
  Map1 *-> Map1
}

' Trying to link the existing "Map3" key in Map2 to Map3.

' Attempt 1
' Close, but there's still an empty value next to the "Map3" key in Map2.
'Map2::Map3 -> Map3

' Attempt 2
' Adds an arrow pointing from Map2's "Map3" key to Map3. The arrow starts with a diamond.
' There's still an empty value next to the "Map3" key in Map2.
'Map2::Map3 *-> Map3


@enduml

Accordingly, it seems like adding or updating a properly-rendered link key to a map after the map containing the key has been defined isn't possible in PlantUML at present, but I'm hoping there may be a solution I've missed.

0

There are 0 answers