Executable UML tools based on the miUML metamodel (thanks to Leon Starr!).
- miUML metamodel XML schema
- Java model compiler (JSE/JEE)
- Javascript class diagram viewer
- Javascript state diagram viewer
The primary inspiration for this project is Executable UML - A Foundation for Model Driven Architecture by Mellor & Balcer.
Status: released to Maven Central
Maven site is here including javadocs.
Under the hood:
- JPA is used for persistence and action language
- Akka is used for asynchronous signalling.
Requirements:
- JDK 1.8 or later (for build, runtime)
- maven 3.0.3 or later (for build)
This is how to build the artifacts from source:
git clone https://github.com/davidmoten/xuml-tools.git
cd xuml-tools
mvn clean install
See the example of creating an Order Tracking system with a REST API.
Models are defined in xml that is compliant to the miUML xuml-tools schema. A sample of xml compliant with the schema is samples.xml.
With the model compiler we seek to implement the approach taken by Mellor & Balcer in their super book Executable UML - A Foundation for Model Driven Architecture. The most notable exception is using the Java Virtual Machine as the platform and Java as the Action Language (using BPAL97 equivalent commands listed below is encouraged).
The java model compiler includes the following features (denotes done):
- Generates JPA entities
- Generates State Machine
- All association types
- 1 to 1
- 0..1 to 1
- 1 to *
- 0..1 to *
- 1 to 1..*
- 0..1 to 1..*
- 1..* to * with Association Class
- 1..* to 1..* with Association Class
- Unary 1
- Unary 0..1
- Unary *
- Unary * with Association Class
- Unary 1..*
- Unary 1..* with Association Class
- Event and State signatures
- Concise usage
- Composite primary identifiers
- Secondary identifiers as unique constraints
- Specializations
- Signals to self buffered and executed within one transaction
- Asynchronous persistent signalling
- Auto-detection of signals to self
- Custom exception handlers
- Uses Akka actors to handle concurrency
- Composite Id toString, equals and hashCode methods
- Entity toString method
- Event toString method
- Generated find methods for attribute groups
- Composite Id Builder pattern
- Event Builder pattern
- Domain and global type constraints honoured:
- MaxLength
- MinLength
- Precision
- LowerLimit
- UpperLimit
- Prefix
- Suffix
- ValidationPattern
- DefaultValue
- Database tests
- Derby
- H2
- HSQLDB
- Postgres
- MySQL
- Oracle
- DB2
- SQL Server
- JPA Provider tests
- Hibernate
- EclipseLink
- TopLink
- OpenJPA
The todo list includes:
- Event polymorphism
- Comprehensive unit testing
- Synchronous signalling (?)
- Extensions for binding with existing databases (to override default generated JPA annotations).
- Integration with other products
- GUI generation (OpenXava?)
The items that may be left out:
- Structured types
- Bridges
- Derived attributes
- any specific Action Language implementation
The xuml-model-compiler runtime takes the following approach in terms of database transactions:
There are two types of signals:
- Signal to self (initiated by an entity's on entry procedure to itself)
- Signal to other
In terms of the role transactions play in relation to signals:
- When a signal is sent to an entity (detected by the runtime) that signal is persisted synchronously to the signal table within a dedicated transaction and assigned a unique id. The signal is augmented with the unique id and passed asynchronously for processing. Control returns immediately to the signaller.
- When the Signal to other for an entity is ready to be processed a database transaction is started.
- The relevant on-entry procedure is called in the entity's state machine.
- If the on-entry procedure initiates a Signal to self that signal is added to a temporary Signal to self queue specific to the current transaction unless the signal to self is scheduled in the future (in which case it is treated like a Signal to other).
- If the on-entry procedure initiates a Signal to other that signal is added to a second temporary Signal to other queue specific to the current transaction.
- Once the on-entry-procedure completes, the queue of Signal to self is processed in arrival order.
- The signal is then removed from the signal table (using the unique id assigned at time of sending).
- Only then is the transaction committed.
- If and only if the transaction succeeds the queue of Signal to other is processed (the signals are sent).
The system should be developed and tested with the aim of no uncaught exceptions being thrown. However, unexpected exceptions need to be dealt with properly when they occur. For this purpose the developer may implement a SignalProcessorListener to perform retries, log/notify errors, or even halt processing on one or all entities.
An example of setting up a SignalProcessorListenerFactory and assigning it to the current Context is in AbcTest.java.
More examples:
Purpose | Class |
---|---|
Log failures | SignalProcessorListenerUtilLogging.java |
Retry on failure with 5 min delay | SignalProcessorListenerRetryOnFailure.java |
Stop all signal processing on failure | SignalProcessorListenerStopsAllSignalProcessingOnFailure.java |
Stop signal processing on single entity on failure | SignalProcessorListenerStopsSignalProcessingSingleEntityOnFailure.java |
The current plan is to make the semantics of say BPAL 97 (Bridgepoint Action Language used by examples in Mellor & Balcer) available in a concise form as methods on the generated java entities or as static utility methods. Examples are below:
The principle is to write java on-entry methods using the above abstractions and without resorting to direct use of an EntityManager. The current EntityManager is always available via Context.em() but for simplicity and to maximize compile-time checking it is recommended to avoid using it. You might want to resort to using Context.em() for some performance tweak for example but try the EntityManager-free approach first.
Run it locally using Jetty.
cd xuml-tools/xuml-diagrams
mvn clean jetty:run
Then open http://localhost:8080/cd in a browser.
Click on the open file button and upload both domains.xml and domains.view (if you have one) in the one selection. Drag items around till they look nice. Hit save button to download the new positions to domains.view (If you use chrome you might want to disable auto-download to a folder: Settings - Show advanced settings - Downloads - tick Ask where to save each file before downloading).
Will look at this at some stage but no work done yet.