Skip to content
Levi Starrett edited this page Feb 1, 2020 · 11 revisions

Features

Ciera is a full model compiler which can generate xtUML models top to bottom from system modeling all the way to action language. The following is a summary of the features of Ciera and how to use them.

System modeling

Multi domain support

Ciera supports generating code for single and multi-domain projects. The compilation unit for Ciera is a package (referred to as the "root" package). Any component or component reference in the root package will be generated by Ciera. Any port satisfactions in the root package will also be generated into the system. To specify the root package, the RootPackage mark must be specified. See Marking: Root Package for more detail on marking. It is possible to maintain a project with multiple system configurations by modeling several packages that can act as the "root" package. Simply change the application mark and regenerate to switch bewteen two configurations. There is no support for generating code for multiple configurations simultaneously.

Ciera only generates model elements contained within components in the root package. Any types, EEs, or other elements required by the system must be imported into the component using a package reference. See more about package references in Package references.

JSON serialized message passing

Ciera was designed with deploying components across networks in mind. For this reason, the message passing mechanism between components comes with built-in JSON serialization and deserialization support. For every message sent from a port, an instance of the IMessage interface is created for each message and passed to the port of the peer component. There, the values are unpacked and passed to the implementation within the component. The standard implementation of IMessage is simply an ordered list of values which correspond to the interface message parameters.

There are two ways to use the JSON serialization of messages to implement custom interface transports.

Hand written "half" components

A user can create a hand written implementation of the component itself which "forwards" incoming messages across some transport to the other "half" of the component. In this scheme an instance of the component exists on both sides of the network and the component implementation itself is responsible for passing messages internally. The serialize method on the IMessage instances can be used to produce well formed JSON before sending across the chosen transport.

This is the simplest way to implement interfaces across some network, however the downside is that it is difficult to have real modeled behavior in the component cleanly without having to extensively modify generated code and continue to keep it up to date when the model changes.

Note
This is the scheme that the GPS watch UI component uses. It works well since all of the behavior of the UI component is hand written graphical interface details.
Custom IPort implementation

A user can write a new Java class that implements the IPort interface and specify this class as the base for a generated port. In this scheme, the transport mechanism can be embedded directly into the port itself with no need for overriding generated code with a hand written class. This mechanism is much cleaner, but much more involved. This method would be suggested if a particular transport mechanism is expected to be widely used throughout the model (and not just a single case as in the GPS GUI example).

The details on how to mark a custom class as the base class for port can be found at Marking: Port implementation class.

Caution
This mechanism is considered advanced usage and there is not much documentation to aid in implementing it. If a user would go attempt to implement a custom port class, he should look closely at the default implementation in the Port class. This class should also be used as the supertype for any custom implementations.

Component versioning

Ciera supports tagging components with version identifiers. By default, the version is the Maven artifact version plus a date and timestamp (if using the maven build plugin). A user can replace the maven artifact version with any string using an application mark. See details on marking at Marking: Component version.

Class modeling

Ciera supports all types of class modeling constructs and relationship types. Derived attributes, referential attributes, class and instance operations, identifiers, and imported classes are all supported.

Exclusions

By default, Ciera generates an interface definition and an implementation class for every modeled xtUML class. All relationships are also generated. Classes and associations can be marked for exclusion. See details about how to mark them at Marking: Element exclusions. No code will be generated for excluded classes and associations.

Caution
If you exclude a class, be sure to exclude all associations in which it participates; if you exclude an association, be sure to exclude all classes that participate in it. It is undefined behavior to leave associations with "orphaned" ends.

Use key letters for name

By default, Ciera uses the name of the class to generate the Java class name (camel case with spaces removed and capitalized first letter). Sometimes, this can cause issues with name conflicts. The class key letters can be used as is for the class name. See Marking: Key letters for generated class name for details on how to apply this mark.

State modeling

Ciera supports basic state modeling. All features necessary to achieve any behavior is supported in Ciera, however many features are not present that would have to be replaced with more involved (and sometimes clunky) patterns. For state modeling, it makes more sense to discuss it from the perspective of what is not supported. For that, see Restrictions/Limitations: State Machines.

OAL action modeling

Ciera supports the majority of the OAL specification. Like state modeling, it is better to discuss in terms of what is missing. See Restrictions/Limitations

Package references

Ciera supports package references within components. Any elements defined in a package referred to in a component will be translated as if they were defined within the referring package.

Automatic selection sorting

For some applications, it makes sense to always sort selections by a specific attribute (e.g an integer identifier or a name). For model compilers, this allows output code to be diffable without explicit sorting in the application.

Ciera allows users to mark an attribute to be the global default sort key. Details on how to mark this can be found at Marking: Sort comparator

Ciera also provides more complex sorting with the SORT external entity. See Ciera specific utilities for more information.

Caution
If a sort key is marked, every selection of a class with that attribute will be sorted. Consider how this may effect application performance.

Simulated time

Ciera supports executing models in simulated time. In simulated time, after initialization, the system clock is advanced to the expected generation time of the next delayed event. This event is generated and the system is allowed to run until no more events are waiting. The system clock is once again advanced to the next delayed event and so on.

Simulated time allows applications to be tested without waiting for wall clock time events, while maintaining timing rules.

The details on how to mark a system to use simulated time can be found at Marking: Simulated time.

Integration with hand written Java

Ciera provides the ability to integrate with external libaries or legacy code with hand written Java.

Basic principle

Ciera allows any generated Java file to be overridden by a handwritten implementation by placing a file with the identical path in the source folder.

For example, the default output location for a Maven based Ciera build is target/generated-sources/java and the default source folder is src/main/java. A generated Java class FooBar located at target/generated-sources/java/foo/bar/FooBar.java could be replaced by installing a hand written class at src/main/java/foo/bar/FooBar.java. In this case, the original generated class will be renamed to FooBar.java.orig and the hand written class will be compiled into the binary package by the Java compiler.

External Entities

Although any file can be overridden by a hand written implementation, it is not recommended since generated changes need to be merged in any time the model changes. External entities provide a clean interface to external code. Simply generate the empty EE once, copy the skeleton class into the source folder and fill in the implementation.

Running a Ciera model

Ciera generates an "Application" class for every system deployment. This class contains a "main" method and can be used as the entry point for the application, however, it can also be imported and launched by a different hand written class that serves as the entry point for the application. The name of this class can be specified by a mark. See Marking: Application name for more detail.

Running a Ciera model in a subordinate thread.

It is also possible to run an entire Ciera model in its own thread. This can be useful when working with legacy code where the xtUML model is only a part of a larger application.

This may look something like the following:

ExampleApplication app = new ExampleApplication();
app.setup(args, logger);
app.initialize();
Thread t = new Thread(app);
t.start();

Then to send a message to a port of a modeled component:

app.Component1().getRunContext().execute(new ReceivedMessageTask() {
     @Override
     public void run() throws XtumlException {
         app.Component1().Port1().message(param1, param2);
     }
});

It is required to execute the port message in this way to ensure that any modeled code is running in the context of the component’s thread (to avoid data synchronization issues).

Arbitrary code can be run in the context of a modeled component the following way:

app.Component1().getRunContext().execute(new GenericExecutionTask() {
    @Override
    public void run() throws XtumlException {
        // arbitrary code here
        // ...
    }
});

Built-in utilities

Ciera provides default implementations for useful external entities. Unlike other model compilers, with Ciera, it is not supported or recommended to overwrite the built-in external entities with hand written implementations (although this feature may be supported in the future). If a user would like to write a custom implementation of these external entities, a completely new EE with unique key letters should be created to do so.

The built-in EEs are included in the Ciera runtime library, so they should not be added to individual projects. Read more about this in the Build section.

xtUML standard bridges

Ciera provides a standard implementation for the following EEs built into xtUML.

Ciera does not implement the "State Save" external entity.

Ciera specific utilities

Ciera provides implementations for the following additional utilities. Detailed usage and descriptions can be found in the API docs for each utility.

  • Math library (MATH)

  • String library (STRING)

  • Command line parsing (CMD)

  • Selection sorting (SORT)

Clone this wiki locally