Boolean conditional or conditional creation of participants or order priority of participants

0 votes
asked Jan 18, 2018 in Closed feature request by mgrol (2,730 points)
edited Jan 18, 2018 by mgrol

Hi,

currently I work on an internal service repository defining macros for sequence diagrams that describe how services call subsequent other services. For that I need to automatically create participant for services if they are used.

 I tried to use the following, as there is no "real if" condition, such as !if boolean=true of !if boolean, but only  !ifdef MACRO:

'Definition of the participant
!ifndef PARTICIPANT_CREATED
    participant "P" as p #color
    !define PARTICIPANT_CREATED true
!endif

However, this doesn't work reliable. So sometimes plantuml generates the according participant automatically, which is a good behavior, but for me the color and the name of the participant are wrong.
If I always create a participant by "participant "P" as p #Red" the moment a service call would expect it. However the ordering of participants is often weird. Therefore, I would need either: 

  • a real boolean condition to check a flag

    • e.g. !if boolean=true or !if boolean/!ifn boolean

  • a conditional to check whether a participant was already create

  • a priority that I can attach to a participant which orders the participants

    • e.g. participant "P" as p order 10 #color

Is there any chance to get something like that?

Best Regards,

Michael

2 Answers

0 votes
answered Jan 20, 2018 by plantuml (208,820 points)
selected Mar 21, 2018 by Anthony-Gaudino
 
Best answer

In last beta http://beta.plantuml.net/plantuml.jar , we have added the "order" feature.

So you can now have:

@startuml
participant A30 as P30 order 30
participant A20 order 20
participant A21 order 20
participant A10
@enduml

Tell us if this is what you were expecting and if it helps.

Note that few tests have been done, so feedback is welcome!

commented Jan 22, 2018 by mgrol (2,730 points)
Hi,

thank you. At first glance it looks exactly for what I was looking for. I try to "stress test" this feature in the next days.

BR,
Michael
commented Jan 23, 2018 by mgrol (2,730 points)
HI,

after a few more tests, it looks good and was exacly what I was looking for.

* What I found out is that no "order <number>" is equal to "order 0". Thus they are ordered by time of creation, which I am fine with. Correct?
* Negative values are not allowed and Iget a syntax error.
* If the number is to big, you will get a NumberFormatException (CommandParticipant.java:101). Maybe add a high default value to the catch block or ignore the parse int.  Try "order 100000000000" to get the error.


BR,
Michael
commented Jan 25, 2018 by plantuml (208,820 points)
Thanks for your tests!

Yes, the order by default is 0.
When two participants have the same order (either 0 or any other value), they are ordered by time of creation.
We've just publish a new beta http://beta.plantuml.net/plantuml.jar :
* Negative value are now accepted.
* Large numbers (more than 7 digit) throw now an error.
commented Jan 26, 2018 by mgrol (2,730 points)
Hi,

thank you for beta10
* negative numbers for ordering work fine and give an additional degree of freedom
* the default behavior is perfect
* for large numbers I am not quit sure about the syntax error. In general, I have sometimes problems to pinpoint the exact location of the syntax error. Maybe there is a hint for that.

Nevertheless, good work. Thank you, the feature works perfect for me.

BR,
Michael
0 votes
answered Jan 18, 2018 by plantuml (208,820 points)
  • 1) Conditional to check wether a participant was already created :

This is really not possible. The preprocessor runs *before* any processing and parsing of the diagram.

  • 2) a priority that I can attach to a participant which orders the participants

This is possible and should be easy to implement

  • 3) a real boolean condition to check a flag

We need more information about what you are expecting. Are you looking for some variable definition ?
Something like:

!define MY_BOOLEAN=true
...
!if MY_BOOLEAN
...
!endif

That does not sound very different of what we have today ? So probably we miss the point here.

commented Jan 19, 2018 by mgrol (2,730 points)
Hi,

thanks for getting back.

* 1) I though so and this would be my least preferred option.

* 2) IMHO is this solution the most interesting as it also covers other feature requests made here to keep certain participants stick together put them close to each other.

* 3) It might be that I have a bug in my definitions. However, I currently can't figure it out and it is difficult to prepare a sample for that.  I have prepared a sample below that is similar to the setup I use today.

For the ordering I prepared the following setup to display the ordering problem:
* file application.puml:
___
@startuml
participant "App" as application #green
!include service.iuml
!include service2.iuml

' call 1st service
service_one(application)
' call 2nd directly
service_two(application)
'call 1st service again
service_one(application,"set of parameters")

@enduml
___

* file service.iuml:
' 1st Service(s)

!definelong service_one(CALLER="consumer", PARAM="parameter")
!ifdef SIMPLE
    note over CALLER: Simple service call with parameter
!else
    'Definition of the participant
    !ifndef PARTICIPANT_CREATED
        participant "P1" as p #red
        !define PARTICIPANT_CREATED true
    !endif
    CALLER -> p ++: request(PARAM)
    CALLER <-- p --: response
!endif
!enddefinelong
___

* file service2.iuml:
___
' 2nd service
!definelong service_two(CALLER="consumer")
!ifdef SIMPLE
    note over CALLER: yet another simple service call
!else
'Definition of the participant
    !ifndef PARTICIPANT_CREATED
        participant "P1" as p #orange
        !define PARTICIPANT_CREATED true
    !endif
    !ifndef PARTICIPANT2_CREATED
        participant "P2" as ptwo #orange
        !define PARTICIPANT2_CREATED true
    !endif
    CALLER -> ptwo ++: request
    CALLER <-- ptwo --: response
!endif
!enddefinelong
___

This setup results in my case P2 showing up in front of P1 which is not the preferred order. The different colors for P1 just tell me which "service" created the participant.

I hope that helps.

BR,
Michael
commented Mar 1 by Dylan Vos
I'm also interested in a setup like below because I'm working on a library for internal-use to build ERD's but I want to check if a class has been defined or not and can't get it to work...

```
!define MY_BOOLEAN=true
...
!if MY_BOOLEAN
...
!endif
```
commented Mar 1 by mgrol (2,730 points)
Hi,

the problem you are facing is that the processes of defining and interpreting code run at different times (hint: pre-processing)

@startuml
class "A" as a {
 - String member
 +getMember()
}

'!define BOOL true

!ifndef BOOL
   class "B" as b
!endif
@enduml

This piece of code works and depending of commenting or uncommenting the !define BOOL line you get either another class or not. However, when building up a library you need to be sure that you do not wrap your !define CLASS_CREATED boolean that you want to use if a class was already created within a macro. That was discussed here before.
I use something similar and I put my single components into separate files which include this:
@startuml
!ifndef <specifier>_CLASS_CREATED
        class "A" as b
    !define <specifier>_CLASS_CREATED true
!endif
'...
@enduml
You just need to include this file and the class is conditionally created if it does not exist. You need to make sure that the preprocessor reaches this block of code, so please do not wrap it into a macro, which won't work.

BR,
Michael
commented Mar 1 by Dylan Vos
Just a question, am I right in thinking that an !ifdef or !ifndef is processed before a Macro?
Because I got a define as follows

@startuml
!definelong Table(name)
!define name##_table
class name as "name"
!enddefinelong
!definelong Check(name)
!ifndef name##_table
Table(name) {
  ID Checked
}
!endif
!enddefinelong

Table(Table1) {
  ID Test
}

Check(Table1)
@enduml

Now I've got two tables - better said - the fields are merged - which I don't want - check should only create the table if it doens't exists
I've tried it in all different kind of ways, no luck...

https://www.planttext.com/?text=SoWkIImgAStDuL9CIKtBp4lDoSzBLmX9JCf9rSXBp4tLX8ahW7ZAol4b82ckv9p4ucAma49YiO8IYA74fPYQbu8m1CL0vupKv6oOWPbfUK0fL0EHR5Ievb9Gy7I1w4bDuQe56voPXcu-L0-OD8Jh2aajBW5guOBO29NaSW1g1NeI0000
commented Mar 1 by Dylan Vos
Sorry Micheal,

Just read the last line of your comment again - so !ifdef and !ifndef won't work inside Macro's?
That's exactly where I need them sadly...
commented Mar 1 by Dylan Vos
I've currently got an ERD looking like this:
https://pasteboard.co/I3pBjhd.png

The only thing missing is being able to check inside macro's
...