This document describes how to use Groovy builder for the PlantUML language. The document is written in AsciiDoc.
Version history
Document version | Notes | Date | Author |
---|---|---|---|
0.0.1 |
Initial Asciidoc version, updated |
2015-06-21 |
Michal Novák |
References
-
[nodebuilder] Library for creation of groovy builders with plugin support
-
[UML] http://www.uml.org/ - Unified Modeling Language
-
[PlantUML] http://plantuml.sourceforge.net - component that allows to quickly write UML diagrams.
-
[plantumlbuilder] Groovy builder for PlantUML language
Terminology
-
UML a Data Modeling Language
-
Groovy builder: builder design pattern implemented in the [groovy], with support for DSL (Domain Specific Language), see groovy builders
License
The [plantumlbuilder] is free software, licensed under MIT License.
The plantumlbuilder is free software licensed under MIT License. ----- Copyright (c) 2011-2012 Michal Novak (it.novakmi@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -----
Introduction
Note
|
This document is still work in progress. Please take a look at the examples in the templates\scripts directory
and at the tests in the tests\groovy directory to see usage of all [plantumlbuilder] features.
|
The [platnumlbuilder] represents implementation of [groovy] builder for [PlantUML] language.
Using groovy builders is a way to create tree like structures in source code. PlantUML language does not fully resemble tree like structure, in spite of this, a groovy builder can simplify UML modeling in PlantUML language (especially sequence diagrams).
The main benefits of using builder are:
-
reuse - in UML diagram and between UML diagrams
-
parametrization
-
customization of diagram language
-
direct creation of UML images from groovy script
-
taking advantage of an IDE (e.g. Intellij Idea) when creating UML diagram - text formatting, auto completion
Dependencies
To start using [plantumlbuilder] you need to have [PlantUML] jar file (plantuml.jar
) and [plantumlbuilder] jar file (plantumlbuilder-x.x.x.jar
) or sources.
For editing it is recommended to use [[http://www.jetbrains.com/idea/| Intellij Idea IDE]] (e.g. free community edition) to create UML in [groovy].
First Plantumlbuilder diagrams
The basic [plantumlbuilder] command is plant
element. See following groovy script:
// create new builder
def builder = new PlantUmlBuilder()
// plantuml element is a root element of PlantUML
builder.plantuml {
plant('A->B') // plant only puts text to the output
plant('activate B')
plant('B->C')
plant('activate C')
plant('C-->B')
plant('deactivate C')
plant('A-->B')
plant('deactivate B')
}
println builder.getText() // get PlantUML text
println ''
println 'Without @startuml/@enduml'
println builder.getText(plainPlantUml: true) // get PlantUML text without @startuml and @enduml
// use plantUML to create png file from plantuml text
SourceStringReader s = new SourceStringReader(builder.getText())
FileOutputStream file = new FileOutputStream('./example1.png')
s.generateImage(file)
file.close()
This produces following [PlantUML] output (and image file):
@startuml
A->B
activate B
B->C
activate C
C-->B
deactivate C
A-->B
deactivate B
@enduml
Without @startuml/@enduml
A->B
activate B
B->C
activate C
C-->B
deactivate C
A-->B
deactivate B
As you can see, it is possible to generate either PlantUML text enclosed in @startuml
/@enduml
(builder.getText()
) or text not being enclosed in @startuml
/@enduml
(builder.getText(plainPlantUml: true)
). The latter is useful for example if you want to add image name to the [PlantUML] text.
Next script (only <<plantumlbuilder> part shown) produces same diagram picture, but the output is differently indented.
Note
|
Note you can use builder.reset() to clear already existing content of the builder.
|
Another example with reuse (closure).
builder.reset()
final def A = 'A'
final def B = 'B'
final def C = 'C'
builder.plantuml() {
// example of block reuse
def interact = {a, b ->
plant "$a->$b"
plant "activate $b"
plant "$b-->$a"
plant "deactivate $b"
}
title 'Plantuml builder basic template - simple sequence diagram'
plant 'participant "A node" as A'
plant "participant B"
plant "participant C"
plant "$A->$B"
plant "activate $B", {
interact(B, C) //reuse
}
plant "$B-->$A"
plant "deactivate $B"
interact(C, B) //reuse
}
Following PlantUML text is created:
@startuml
title Plantuml builder basic template - simple sequence diagram
participant "A node" as A
participant B
participant C
A->B
activate B
B->C
activate C
C-->B
deactivate C
B-->A
deactivate B
C->B
activate B
B-->C
deactivate B
@enduml
Note
|
You can see the indenting of the text follows parent/child relationship of builder elements. This is useful (for more complex diagrams) to increase readability. |
Note
|
The syntax follows groovy builder syntax, and one can also use bracket, e.g.: plant("participant C") or plant("activate $B") {...
|
Advanced diagram example
The possibility to use programming language to create diagrams is not the only advantage. With Plugins, one can made custom syntax for specific diagrams or domain. Together with the [plantumlbuilder] there comes plugins for different types of UML diagrams.
Following example demonstrates how [plantumlbuilder] can be used together with PlatnUmlBuilderSeqPlugin
for sequence diagrams
parts of sequence diagram.
def u1 = 'User1'
def m1 = 'MobileA'
def m2 = 'MobileB'
def u2 = 'User2'
builder.plantuml() {
title 'Plantuml builder seq plugin template example with activation colors and boxes'
box {
actor u1
}
box "Mobile", {
participant m1
}
box("Mobile", color: "#LightBlue") {
participant m2
}
box color: "#green", {
actor u2
}
msgAd u1, to: m1, text: "Start Call", returnText: "Call finished", {
msg m1, to: m2, text: "Ring", noReturn: true
msgAd u2, to: m2, activate: "#FFBBBB", text: "PickUp", returnText: "HangUp", {
msgAd m2, to: m1, activate: "#yellow", text: "Talk"
}
}
}
Following PlantUML text is created
@startuml
title Plantuml builder seq plugin template example with activation colors and boxes
box
actor User1
end box
box "Mobile"
participant MobileA
end box
box "Mobile" #LightBlue
participant MobileB
end box
box #green
actor User2
end box
User1 -> MobileA : Start Call
activate MobileA
MobileA -> MobileB : Ring
User2 -> MobileB : PickUp
activate MobileB #FFBBBB
MobileB -> MobileA : Talk
activate MobileA #yellow
MobileA --> MobileB
deactivate MobileA
MobileB --> User2 : HangUp
deactivate MobileB
MobileA --> User1 : Call finished
deactivate MobileA
@enduml
[plantumlbuilder] language reference
Base reference
Following keywords can be used by the [plantumlbuilder].
plantuml
Represents [plantumlbuilder] root node mark (not present in PlantUML text). It is possible to pass text to be placed after @startuml
(e.g. image name).
Examples:
[plantumlbuilder] | PlantUML |
---|---|
|
N/A |
|
N/A |
plant
Text is directly copied as line to the PlantUML text. With this keyword,any PlantUML keyword can be entered by the builder.
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
autonumber |
title
, header
and footer
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
title My diagram |
|
footer My footer multiline end footer |
Note
|
Use groovy multiline string or \n to create multiline elements. Multiline elements are automatically
trimmed and indented.
|
Note
|
Use \\n in the groovy string to format one line element on the several lines
|
legend
Attributes:
pos
(optional) - left
, center
and right
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
legend My legend end legend |
|
legend right My legend multiline end legend |
Note
|
Use groovy multiline string or \n to create multiline legends. Multiline legends are automatically
trimmed and indented.
|
Note
|
Use \\n in the groovy string to format one line legend on the several lines
|
newpage
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
newpage |
|
newpage Page break |
|
newpage Page break\nmore lines |
note
Attribute: as
(optional), pos
(optional)
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
note MyNote |
|
note My note as MyNote |
|
note right : MyNote |
|
note left of A #blue a note can also be defined on several lines end note |
Note
|
Use groovy multiline string or \n to create multiline notes. Multiline notes are automatically
trimmed and indented.
|
Note
|
Use \\n in the groovy string to format one line note on the several lines
|
Plugins
Plantumlbuilder sequence plugin
See PlantUmlBuilderSeqPluginTest
for more information and examples.
Following keywords are supported (added) by the sequence plugin.
participant
, actor
, boundary
, control
, entity
and database
Attributes:
as
(optional)
color
(optional)
stereotype
(optional)
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
participant MyParticipant |
|
participant My Participant as MyParticipant |
|
participant MyParticipant #red |
|
actor MyActor |
|
actor "My Actor" as MyActor <<person>> |
Note
|
In similar way use boundary , control , entity and database
NOTE: If value contains space character (e.g. "My actor" ), it is automatically surrounded by the quotes " , unless there are surrounding quotes already
present in the value (e.g. '"My actor"' or "\"My actor\"" )
|
create
Attributes:
type
(optional) - one of participant
, actor
, boundary
, control
, entity
and database
(default is participant
)
as
(optional)
color
(optional)
stereotype
(optional)
[plantumlbuilder] | PlantUML |
---|---|
|
create MyParticipant |
|
create "My Participant" as MyParticipant |
|
create control MyParticipant #red |
|
create actor "My Actor" as MyActor <<person>> |
Note
|
If value contains space character (e.g. "My actor" ), it is automatically surrounded by the quotes " , unless there are surrounding quotes already
present in the value (e.g. '"My actor"' or "\"My actor\"" )
|
msg
Sequence diagram message.
Attributes (all optional):
-
to
(string - existingactor
,participant
, etc.) -
noReturn
(boolean) -
text
(string) -
returnText
(string) -
type
(string) -
returnType
(string) -
activate
(boolean or string - activation color) -
close
(string - "activate" or "destroy")
[plantumlbuilder] | PlantUML | Note |
---|---|---|
|
A -> A |
Create a message with self arrow. |
|
A -> B ... B --> A |
Create message from |
|
A -> B |
Create message from |
|
A -> B : call B ... B --> A |
Create message from |
|
A --> B ... B --> A |
Create message from |
|
A -> B : call B activate B ... B --> A |
Create message from |
|
A -> B : call B activate B ... B --> A deactivate B A -> B : call B activate B ... B --> A destroy B |
Create message from |
|
A -> B ... B --> A : finished |
Create message from |
|
A -> B : call B ... B -> A |
Create message from |
Note
|
Incoming and Outcoming messages are also supported with use of [ and ] . For example msg("[", to: "A") or msg("]", to: "A", text: "o2")
|
msgAd
This keyword has same meaning as the msg
keyword. In addition, it automatically adds close
attribute with the deactivate
value
(can be overwritten with the destroy
value).
msgAd("A", to: "B") {
...
}
is same as:
msg("A", to: "B", close: "deactivate") {
...
}
destroy
can be specified by adding close
attribute (in this case msg
and msgAd
are same)
msgAd("A", to: "B", close: "destroy") {
...
}
is same as:
msg("A", to: "B", close: "destroy") {
...
}
The activation color can be specified with activate
attribute:
msgAd("A", to: "B", activate: "#Green") {
...
}
is same as:
msg("A", to: "B", activate: "#Green", close: "deactivate") {
...
}
activate
Attribute: close
(optional) - specifies how to close the activation block, value can be deactivate
or destroy
Activate participant. With attribute close
it is possible to specify activate - deactivate
or activate - destroy
block.
[plantumlbuilder] | PlantUML |
---|---|
|
activate A |
|
activate A ... deactivate A |
|
activate A ... destroy A |
deactivate
and destroy
Deactivate or destroy the participant.
[plantumlbuilder] | PlantUML |
---|---|
|
deactivate A |
|
destroy A |
autonumber
Specify arrow numbering
value: numbering start (optional)
Attributes:
step
: numbering step
format
: numbering format
[plantumlbuilder] | PlantUML |
---|---|
|
autonumber |
|
autonumber 15 |
|
autonumber 40 15 |
|
autonumber "<b>[000]" |
|
autonumber 40 10 "<font color=red><b>Message 0" |
group
Create group
of given name
[plantumlbuilder] | PlantUML |
---|---|
|
group MyGroup ... end |
opt
Create opt
frame for given condition
[plantumlbuilder] | PlantUML |
---|---|
|
opt condition ... end |
alt
and else
Create alt
frame for given condition with else
[plantumlbuilder] | PlantUML |
---|---|
|
alt condition1 ... else condition2 ... end |
Note
|
else in the groovy code is inside the alt block
|
loop
Create loop
frame for given loop condition
[plantumlbuilder] | PlantUML |
---|---|
|
loop condition ... end |
break
Create break
frame
[plantumlbuilder] | PlantUML |
---|---|
|
break MyBreak ... end |
Note
|
As break is [groovy] keyword, in the builder it has to be specified as string
|
critical
Create critical
frame
[plantumlbuilder] | PlantUML |
---|---|
|
break MyCritical ... end |
ref
Create ref
frame
Attribute: over
- list of participants (mandatory)
[plantumlbuilder] | PlantUML |
---|---|
|
ref over A,B: see diagram X |
Note
|
Currently only one line ref is supported. Multiline ref has to be created with the plant keyword.
|
box
Encompass participants in the box
Attribute: color
- the color of the box
[plantumlbuilder] | PlantUML |
---|---|
|
box User actor user end box |
|
box User #LightBlue actor user end box |
hnote
and rnote
Hexagon and rectangle note for sequence diagrams.
Attribute:
pos
(mandatory)
color
Example(s):
[plantumlbuilder] | PlantUML |
---|---|
|
hnote over A : MyHNote |
|
rnote over A : MyRNote |
|
rnote over A : See\nthis diagram |
|
rnote over A #green : See\nthis diagram |
Note
|
hnote nad rnote support multiline handling just like regular note
|
Plantumlbuilder class plugin
See PlantUmlBuilderClassPluginTest
for more information and examples.
TODO
Plantumlbuilder component plugin
See PlantUmlBuilderCompPluginTest
for more information and examples.
TODO
Interface
Plantumlbuilder groovy interface
The interface consists of two parts
-
the Plantumlbuilder interface
-
the Plugin interface allowing extension of Plantumlbuilder language
- TODO
-
images/plantbuilderinterface.png
PlantUmlBuilder interface
/**
* Get PlantUML text build by the builder
* @param params map with optional name params.
* Currently supported 'plainPlantUml' - do not add '@startuml/@enduml' to the returned PlantUML text
* getText()
* getText(plainPlantUml: true)
* @return build text
*/
public String getText(params)
/**
* Reset root element of the builder.
* Use this method to start building PlantUML text from the beginning.
*/
public void reset()
/**
* Add a plugin listener.
*/
void addPlantUmlBuilderPluginListener(PlantUmlBuilderPluginListener listener)
/**
* Remove the plugin listener.
*/
void removePlantUmlBuilderPluginListener(PlantUmlBuilderPluginListener listener)
- TODO
-
See {{{cz.atlas.bubbles.it.test.plantumlbuilder.PlantUmlBuilderTest}}} for examples of the usage.
PlantUmlBuilderPluginListener interface
/**
* Builder node
*/
private class Node {
def name = '' // name of node (e.g. plant('text, at:'attrib') - name is plant)
def parent = null // parent node (or null if this is root node)
def attributes = [:] //attributes (e.g. plant('text, at:'attrib') - attributes.at == 'attrib')
def value = null //value of node (e.g. plant('text, at:'attrib') - value is text)
def children = [] //children nodes
}
//Listener interface for node or attributes
enum PluginListenerResult {
NOT_ACCEPTED, // node not accepted by the plugin
PROCESSED_STOP, // node processed by the plugin, do not process node with other plugins
PROCESSED_CONTINUE, // node processed by plugin, process node with other plugins as well
FAILED, // node processing failed
}
interface PlantUmlBuilderPluginListener {
/**
* Process given node in plugin before and after plantuml builder
* @param node builder node to process (
* @param out IndentPrinter to print PlantUML text
* @param postProcess if false, it is pre processing time, if true, it is post processing time
* @return result
* $see PluginListenerResult, Node
*/
PluginListenerResult process(final Node node, IndentPrinter out, boolean postProcess)
}
Plantuml Maven repository
The [plantumlbuilder] has been accepted by JCenter and is available in the JCenter Maven repository.
It can be automatically used with Groovy @Grab
or in the gradle
. There is no need to download and
maintain jar
files.