Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🥳 New Feature 🥳 PlantUML visualization #1158

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

pdalfarr
Copy link

@pdalfarr pdalfarr commented Jul 5, 2024

The goal of this PR is to add the ability to dump a Spring stateMachine to PlanUML State Diagram format and to .png format 🥳

Features:

  1. Diagram Visualization 👁️
    Allow you to 'visualize' your Spring State Machine as .puml or .png !

  2. Current transition Highlight 🎯
    If a state machine is dumped at org.springframework.statemachine.StateContext.Stage.TRANSITION_END phase, a red arrow is used between the 'source' state and the 'target' state.
    see

    public String getArrowColor(boolean isCurrentTransaction) {
    return isCurrentTransaction ? "[#FF0000]" : "";
    }

  3. Actions and Guards description 🪪
    Support BeanAware for Actions and Guards, so bean names are used in diagram
    -> much better than having labels like Action@0x1f4f5d1d

  4. SpEL Expression support 🟰
    Support for SpelExpressionAction and SpelExpressionGuard : SpEL expression is used as label.

  5. Allow to 'tweak' the Diagram

  • Modifying PlantUML diagram settings 🎚️
  • Forcing Transition directions ➡️
  • Hiding some transitions 🙈
  • Adding a text note on State 📝

Unit tests:

  1. Instantiate a Spring State Machine by loading (already existing) .uml file from test folder
  2. Creating a PlantUML text representation of this state machine
  3. Comparing it to to expected result 'see (new) .puml files in test folder)

What does it looks like?

Here are some results (I dumped .puml files to .png):

action-with-transition-choice.uml -> action-with-transition-choice.puml :

image

multijoin-forkjoin.uml -> multijoin-forkjoin.puml :

image

Note:
Two *.uml files from test folder leads to inaccurate diagram.
These 2 errors, in simple-connectionpointref.puml and simple-root-regions.puml, are likely to be related to some limitations in spring statemachine UML parser.

Credit: The idea of creating this feature came to me while reading https://github.com/DeveloperUtils/spring-state-machine-chart-dumper

@pivotal-cla
Copy link

@pdalfarr Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pdalfarr pdalfarr changed the title PlantUML visualization New Feature - PlantUML visualization Jul 5, 2024
@libinbin880521
Copy link

libinbin880521 commented Jul 5, 2024 via email

@pivotal-cla
Copy link

@pdalfarr Thank you for signing the Contributor License Agreement!

Comment on lines +63 to +64
// It seems Spring statemachine does not support org.eclipse.uml2.uml.ConnectionPointReference !
// Arguments.of("org/springframework/statemachine/uml/simple-connectionpointref", null),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Limitation in Spring state machine ?

Comment on lines +89 to +90
// It seems Spring statemachine UML parser creates duplicated transitions!
// Arguments.of("org/springframework/statemachine/uml/simple-root-regions", null),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug in Spring state machine ?

Comment on lines 73 to 87
new PlantUmlWriterParameters<String>()
.hiddenTransition("S1", RIGHT, "S2")
),
Arguments.of("org/springframework/statemachine/uml/simple-guards", null),
Arguments.of("org/springframework/statemachine/uml/simple-history-deep", null),
Arguments.of("org/springframework/statemachine/uml/simple-history-default", null),
Arguments.of("org/springframework/statemachine/uml/simple-history-shallow", null),
Arguments.of("org/springframework/statemachine/uml/simple-junction", null),
Arguments.of("org/springframework/statemachine/uml/simple-localtransition",
// add some parameters to make diagram more readable
new PlantUmlWriterParameters<String>()
.arrowDirection("S22", UP, "S2")
.arrowDirection("S21", UP, "S2")
.arrowDirection("S22", UP, "S2")
.arrowDirection("S21", UP, "S2")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlantUmlWriterParameters allow to tweak diagram by 'forcing' direction of some arrows / transitions

@pdalfarr
Copy link
Author

Hi @bclozel
I would like some Spring members to tell me if this PR can be useful for the Spring State Machine project or not.
It turns out that you are second in the list of contributors here, hence this message for you 😄
Can I kindly ask you to have a look at this.
I would be happy to elaborate more on why I think this could be useful to the project.
Kind Regards,
Pascal

@bclozel
Copy link
Member

bclozel commented Jul 12, 2024

Hi there!
This is probably a UI bug in GitHub as I don't remember contributing to statemachine and I'm not listed here https://github.com/spring-projects/spring-statemachine/graphs/contributors?from=2015-02-01&to=2024-07-12&type=c

Comment on lines +41 to +53
/**
* Implement a 'name strategy' based on this sequence:
* <UL>
* <LI>{@link Expression}</LI>
* <LI>{@link BeanNameAware}</LI>
* <LI>Lambda's unique "arg$1" parameter</LI>
* </UL>
* If all these strategy are failing, fallback to "class name" of the object
*
* @param object object to get "name" from
* @return name of the object
*/
public static String getName(Object object) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class should probably be compared to

private static <S, E> String actionToName(Function<StateContext<S, E>, Mono<Void>> action) {
return ObjectUtils.getDisplayString(action);
}
private static <S, E> String actionFunctionToName(Function<StateContext<S, E>, Mono<Void>> action) {
return ObjectUtils.getDisplayString(action);
}

which seems to be the current mean to get "names" of Spring State Machine actions, guard, etc..

@pdalfarr
Copy link
Author

@bclozel
Thanks for your reply.
Yes, this is likely a bug: your avatar is visible in second position on main page of the project and you did not contribute indeed.

I see you are a committer on some Spring projects, so I take the opportunity to ask you this: how I can do to reach out to Spring State Machine "owner(s)" ?
It looks like many PR are waiting here (not only mine) and I do not see much activity in Spring State Machine GitHub project.
Should we (user of Spring State Mchine) worry about this?
Is Spring State Machine still properly maintained?

( ? Maybe someone at Pivotal / VMWare could help regarding my questions ? )

@bclozel
Copy link
Member

bclozel commented Jul 12, 2024

I think @jvalkeal knows.

@pdalfarr
Copy link
Author

Hi @jvalkeal

Who can I reach out to, to discuss this PR?

Thanks

@pdalfarr
Copy link
Author

@fmbenhassine , we can discuss this whenever you want ;-)

Comment on lines +87 to +95
public PlantUmlWriterParameters<S> note(S state, String note) {
// escape line return in note as it must fit in one single line
note = note
.replace("\n", "\\n")
.replace("\r", "\\r")
;
stateNotes.put(state, note);
return this;
}
Copy link
Author

@pdalfarr pdalfarr Mar 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New Feature:
"Adding a note" 📝 on State :-)

See

Arguments.of("org/springframework/statemachine/uml/simple-localtransition",
// add some parameters to make the diagram more readable
new PlantUmlWriterParameters<String>()
.arrow("S22", UP, "S2", 2)
.arrow("S21", UP, "S2", 2)
.note("S1", "This is the\nS1 State")
.note("S2", "This is the\nS2 State")
),

And https://github.com/spring-projects/spring-statemachine/blob/3b29592cb1b5cb383ede8530c919474d6d9cd10d/spring-statemachine-uml/src/test/resources/org/springframework/statemachine/uml/simple-localtransition.png?raw=true

image

@pdalfarr pdalfarr changed the title New Feature - PlantUML visualization 🥳 New Feature 🥳 PlantUML visualization Mar 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants