In Cloudfier, we use UML as the core language for building business applications. UML is usually well-equipped for general purpose business domain-centric application modeling, but that doesn’t mean it always does everything needed out of the box.
Case at hand: assuming one is developing an expense reporting application and modeled an expense’s status as a state machine (in TextUML):
class Expense
/* ... */
attribute status : Status;
operation review();
operation approve();
operation reject();
operation submit();
statemachine Status
initial state Draft
transition on call(submit) to Submitted;
state Submitted
transition on call(approve) to Approved
transition on call(reject) to Rejected
transition on call(review) to Draft;
terminate state Approved;
terminate state Rejected;
end;
end;
How do you model the following in UML?
Show me all expenses that are waiting for approval.
Turns out there is no support in UML for reasoning based on the current state of a state machine.
Creative modeling
So, what do you do when UML does not have a language element that you need? You extend it, in our case, using a stereotype applicable to the LiteralNull metaclass (in TextUML):
stereotype VertexLiteral extends LiteralNull
property vertex : Vertex;
end;
So, a vertex literal is a value specification, more specifically, a variant of LiteralNull, that can refer to a Vertex, which is a metaclass that represents the states (including pseudo-states) in a state machine.
Notation, notation
In terms of notation, I chose to make State/Vertex literals look like enumeration literals: Status#Approved or Status#Draft. So, back to the original question, this is how you could model a query that returns all expenses that are in the Submitted state:
static operation findAllSubmitted() : Expense[*];
begin
return Expense extent.select ((e : Expense) : Boolean {
return e.status == Status#Submitted
});
end;
If you are thinking to yourself: I didn’t know UML had queries or closures!?, well, it usually doesn’t. See the posts on SQL queries in UML and Closures in UML for some background on this.
Note also that if you wanted to refer to the symbol Status from a class different than the one enclosing it you will need to qualify it (i.e. Expense::Status#Submitted).
Show me more!
You can run the Expenses application showing state machines and state-based queries in Cloudfier right now (login is “guest” or any of the employee names you will see later).
The entire Expenses sample application (currently 150 lines of generously spaced TextUML) is available on BitBucket. You can also easily check it out into Cloudfier so you can run your own copy of the application on the web (there is nothing to install). Give it a try!
What do you think?
Your feedback (questions, support or criticism) to any of the ideas presented in this post is very welcome.
UPDATE: I started a thread on the subject on the UML Forum group, and turns out you can do this kind of reasoning in OCL, but indeed, not in UML itself. Well, now you can.






