Model services

Modelio API model services are used to manipulate the model of the currently opened project.

Quick outline:

  1. IModelingSession
  2. Model API naming rules
  3. Transactions
  4. Creating and deleting elements
  5. Listening to model changes

IModelingSession

The IModelingSession object provided by Modelio to the module represents the very core access point to the model. A modeling session is a transaction-based access to the model contained in the currently opened project. Without a valid modeling session you have neither read nor write access to the model.

A modeling session can be opened or closed. A closed session is useless as it does not provide more help than no session at all. An opened session is really what you need to work with the model. Note that,however, a “closing-in-progress” session might be useful as it can mean that it is time to stop certain activities of your module or to free some resources and so on.

For now let us stick to simple principles, Modelio can provide you with a valid modeling session using the following code:

1IModelingSession session = Modelio.getInstance().getModelingSession();

And if you ask what happens when there is no current valid session?

the answer is straightforward getModelingSession() just returns a null object.

Does it mean that you’ll have to check the returned value of getModelingSession() each time you call it?

no, a properly designed module can never fall in such a situation where its code is running without a valid session being available. See Modules core concepts to understand how this magic is possible.

Model API Naming rules

The so-called Model API is the set of Java classes and methods that represent the model elements.

The Model API Java classes and their methods follow some fixed naming rules that help a lot in identifying which object and which methods to use to navigate in the model. So it is worth spending a little time on these naming rules, the alternative would be to browse and learn the complete Model API classes and methods from the Java documentation… more than 250 classes and 3000 methods. Go for the naming rules!

Metaclass representation

For each metaclass of the Modelio metamodel, a corresponding Java interface is defined. It is named from the Modelio metaclass name prefixed by “I”. The metamodel inheritance graph between metaclasses is cloned at the Model level.

The following table provides several examples.

Modelio metaclass nameModelio parent metaclassJava interfaceJava parent interface
OperationFeatureIOperationIFeature
ClassGeneralClassIClassIGeneralClass
UseCaseGeneralClassIUseCaseIGeneralClass
xxxxyyyyIxxxxIyyyy

Associations and Attributes methods

The model API provides direct access to attributes and associations in the metamodel in the form of accessor methods or accessors. Accessors that are used to read the model are called setters while accessors that modify the model are called getters.

As for metaclasses, the model API has been designed so that accessors names directly relate to the navigated attributes or associations thereby making it easy to guess the name of the concrete accessors of any attribute or association from a quick look to the metamodel diagrams.

The following table shows the prefixing rules for a association role or an attribute named XXX.

AccessorCardinalityPrefix rule
Getter 1getXXX() or isXXX() for a boolean
Getter getXXX()
Setter 1setXXX()
Setter addXXX() and removeXXX()

Get a general description of the accessor naming rules usage see here.
Watch the accessor naming rules in action on concrete examples here.

Transactions

Modelio Transactions:

  • are required to modify the model: no modification of the model can be carried out without being encapsulated within a Transaction.
  • have to be committed for the modification to take place: changes in the model are only effective after a transaction has been successfully committed).
  • can be rolled back, leaving the model unchanged up to its state when starting the transaction

Any modification of the model made outside any transaction will throw an exception.

Transactions guarantee that the modifications of the model follow the ACID paradigm. ACID is an acronym for Atomic, Consistent, Isolation, and Durable.

Atomicity

A transaction allows for the grouping of one or more changes in the model to form an atomic or indivisible operation. In other words, either all of the changes occur or none of them do. If for any reason the transaction cannot be completed, everything this transaction changed can be restored to the state it was in prior to the start of the transaction, via a rollback operation.

Consistency

Transactions always operate on a correct model and when they end always leave the model in a correct state. The model is said to be correct as long as the Modelio audit system does not return blocking errors for it. During a transaction, the model may be incorrect at some point, however no other transaction will be allowed to see these inconsistencies, and all such inconsistencies will have been eliminated by the time the transaction ends.

Isolation

To a given transaction, it should appear as though it is running all by itself on the model. In Modelio, there is only one active transaction at a time. Such a unique transaction is de facto isolated.

Durability

Once a transaction is committed, its effects become definitive, ie they are definitively applied to the model. As long as the transaction is not committed, the modifications can be rolled back to restore the model to its initial state.

The transaction management API is available on the IModelingSession object. More details on the transaction API here.

Transactions and Audit

Modelio constantly monitors the model for correctness by running an Audit.

Some of the controls carried out by the audit are blocking, ie they cannot fail without breaking the model. These strong inconsistencies are always controlled by Modelio in real-time each time a transaction is committed. This is why committing a transaction can fail, the changes can simply NOT be carried out by the tool without leading to serious troubles (including tool crashing in the worst cases). Modelio will throw an exception at any model modification out of a transaction because it needs this final check at commit time to ensure its own integrity.

Creating and deleting model elements

To create a model element, the modeling session provides a model element creation factory IUmlModel. The model element factory provides many creation methods, listing them all would be useless.

Just have a look to a code fragment:

1// get the modeling session
2IModelingSession session = Modelio.getInstance().getModelingSession();
3
4// get the factory
5IUmlModel factory = session.getModel();
6
7// use the factory to create elements, here a simple class
8IClass newClass = factory.createClass();

A complete and explained example is visible here.

IMPORTANT WARNINGS

  • Using the factory is the unique operational means of creating new model elements.
  • do not attempt to modify the model outside an opened transaction
  • the Java newoperator is of no help when it comes to create new elements in the model

Deleting elements

In order to delete an element, simply call its delete method.

Example: deleting all the classes under the root package

 1IModelingSession session = Modelio.getInstance().getModelingSession();
 2ITransactionManager transactionManager = session.getTransactionManager();
 3ITransaction transaction = transactionManager.createTransaction("a transaction");
 4
 5try {
 6    // get the model root package (to be used as the new class owner)
 7    IPackage root = session.getModel().getRoot();
 8
 9    // loop on classes under root
10    for (IClass clazz : root.getOwnedElement(IClass.class)) {
11        clazz.delete();
12    }
13
14    // commit the transaction 
15    transactionManager.commit(transaction);
16    transaction = null;
17
18} catch (InvalidTransactionException e) {
19    System.err.print(e);
20    transaction = null;
21} finally {
22    if (transaction != null) {
23        transactionManager.rollback(transaction);
24    }
25}

Note in line 10 the use of the filtered getter accessor getOwnedElement(IClass.class that will return only the classes under root. The deletion of the class is done on line 11 but will only become effective after the commit on line 15.

Listening to model changes

The Modeling session can register so-called ‘model listeners’. A model listener is any object implementing the IModelChangeListener interface. Registered model listeners are called when a change is committed in the model and a IModelChangeEvent object describing the changes is passed to them. Model change listeners can, for example, be used to update views displaying model elements or any information that depends on model elements.

 1IModelingSession session = Modelio.getInstance().getModelingSession();
 2
 3// register a IModelChangeListener
 4
 5session.addModelListener(new IModelChangeListener() {
 6    public void modelChanged(IModelingSession session, IModelChangeEvent event) {
 7        System.out.println("model changed");    
 8    }
 9});

The above code fragment registers a IModelChangeListener that simply prints out a message whenever the model is modified (see about using System.out). Of course by exploiting the passed IModelChangeEvent more advanced behavior can be implemented. More complete details about model change listening is available here.

Tip

You can remove a model change listener by

1    session.removeModelListener(myListener)


but this supposes that you have previously kept a reference to your listener.