PlantUML-compatible grammar for structural models#

A B-UML model can also be generated from a class model built with PlantUML . All you need is to provide the textual model (PlantUML) and our T2M transformation will produce the B-UML based model, including the source code to build the model, in case you want to modify any part of your model that is not possible with PlantUML.

Let’s see an example with the classic library model. The textual model written in PlantUML is shown below.

 1@startuml
 2class Library {
 3+ name: str
 4+ address: str
 5}
 6
 7class Book {
 8+ title: str
 9+ pages: int
10+ release: date
11}
12
13class Author {
14+ name: str
15+ email: str 
16}
17
18Book "*" -- "1..*" Author: writtenBy
19Library "1" -- "*" Book: has
20@enduml

And the diagram produced by PlantUML is as follows.

Library model

Save the PlantUML textual model in a file, e.g. library.plantuml. (.txt extension is also allowed)

Then, load and process the model using our grammar and apply the transformation to obtain the B-UML based model.

# Import methods and classes
from besser.BUML.notations.structuralPlantUML import plantuml_to_buml
from besser.BUML.metamodel.structural import DomainModel

# PlantUML to B-UML model
library_buml: DomainModel = plantuml_to_buml(plantUML_model_path='library.plantuml')

Note

The model_path parameter contains the path and name of the .plantuml model to be transformed

library_buml is the BUML model containing the domain specification. You can look up the classes, attributes, relationships, etc. For example, the following is the way to get the class names.

# Print class names
for cls in library_buml.get_classes():
    print(cls.name)

You should get output like this:

Library
Book
Author

Warning

Although the PlantUML notation allows the definition of unnamed associations, for the BESSER platform it is necessary that all associations have a unique name.

BUML model source code#

When you run this PlantUML to BUML transformation, the file buml/buml_model.py will be created with the python code of your BUML model definition. You could directly reuse this code to make quick modifications to your model. For example, you could add more classes, properties, or update the name of the ends of an association.

The BUML model source code generated by the transformation from the library.plantuml model is as follows.

 1from besser.BUML.metamodel.structural import NamedElement, DomainModel, Type, Class, \
 2        Property, PrimitiveDataType, Multiplicity, Association, BinaryAssociation, Generalization, \
 3        GeneralizationSet, AssociationClass 
 4
 5# Primitive Data Types 
 6date_type = PrimitiveDataType("date")
 7str_type = PrimitiveDataType("str")
 8int_type = PrimitiveDataType("int")
 9
10# Library class definition 
11Library_name: Property = Property(name="name", type=str_type, visibility="public")
12Library_address: Property = Property(name="address", type=str_type, visibility="public")
13Library: Class = Class(name="Library", attributes={Library_name, Library_address})
14
15# Book class definition 
16Book_tittle: Property = Property(name="tittle", type=str_type, visibility="public")
17Book_pages: Property = Property(name="pages", type=int_type, visibility="public")
18Book_edition: Property = Property(name="edition", type=date_type, visibility="public")
19Book: Class = Class(name="Book", attributes={Book_tittle, Book_pages, Book_edition})
20
21# Literature class definition 
22Literature: Class = Class(name="Literature", attributes=set())
23
24# Science class definition 
25Science: Class = Class(name="Science", attributes=set())
26
27# Fantasy class definition 
28Fantasy: Class = Class(name="Fantasy", attributes=set())
29
30# Author class definition 
31Author_name: Property = Property(name="name", type=str_type, visibility="public")
32Author_email: Property = Property(name="email", type=str_type, visibility="public")
33Author: Class = Class(name="Author", attributes={Author_name, Author_email})
34
35# Relationships
36writtenBy: BinaryAssociation = BinaryAssociation(name="writtenBy", ends={
37        Property(name="writtenBy", type=Book, multiplicity=Multiplicity(0, "*")),
38        Property(name="writtenBy", type=Author, multiplicity=Multiplicity(1, "*"))})
39has: BinaryAssociation = BinaryAssociation(name="has", ends={
40        Property(name="has", type=Library, multiplicity=Multiplicity(1, 1)),
41        Property(name="has", type=Book, multiplicity=Multiplicity(1, 1))})
42
43# Generalizations
44gen_Book_Literature: Generalization = Generalization(general=Book, specific=Literature)
45gen_Book_Science: Generalization = Generalization(general=Book, specific=Science)
46gen_Book_Fantasy: Generalization = Generalization(general=Book, specific=Fantasy)
47
48
49# Domain Model
50domain: DomainModel = DomainModel(name="Domain Model", types={Library, Book, Literature, Science, Fantasy, Author}, associations={writtenBy, has}, generalizations={gen_Book_Literature, gen_Book_Science, gen_Book_Fantasy})