Basic Usage

To get started with using Static Meta Models within your application you need to generate the respective Java artifacts using either the Java Tooling or Maven plugin.

After the artifacts have been generated you’ll find for each Aspect and Entity a new source file called MetaElementName.java which contains the Static Meta Model.

All the following chapters again assume the Movement Aspect with its accompanying static MetaMovement class.

Meta Class Overview

General Information within the Meta Classes

The Meta Classes contain some general Model information within static fields:

Field Description Type (Sample) value

NAMESPACE

The namespace of this Model Element

String

urn:samm:org.eclipse.esmf.examples.movement:1.0.0#

MODEL_ELEMENT_URN

The full URN of this Model Element

String

urn:samm:org.eclipse.esmf.examples.movement:1.0.0#Movement

CHARACTERISTIC_NAMESPACE

The Characteristic Namespace of the Model

String

urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#

INSTANCE

The singleton instance of this Meta class. Used to access non-static information.

MetaMovement

N/A

Type and Property Information within the Meta Classes

The instances of the Meta Classes themselves can be used for application development as well as the contained information about Properties, depending on which Model information is required. Most applications will predominantly use the property information, however when implementations take multiple Aspects and/or Entities into account, also class-level information can be of great use.

Field or Method Description (Return) Type (Sample) value

getModelClass()

The Java Class for this Model Element

Class<MetaMovement>

MetaMovement.class

getAspectModelUrn()

The URN of this Model Element

AspectModelUrn

AspectModelUrn.fromUrn(MODEL_ELEMENT_URN)

getMetaModelVersion()

The used Meta Model version

KnownVersion

KnownVersion.SAMM_2_1_0

getName()

The name of this Model Element

String

Movement

getProperties()

All StaticProperty​s of this Model Element

List<StaticProperty<Movement, ?> or List<StaticProperty<? super Movement, ?>

Arrays.asList(SOME_STRING, SOME_INT, SOME_FLOAT);

getAllProperties()

All StaticProperty​s of this Model Element, including inherited properties. If no inheritance is used it returns the same value as getProperties()

List<StaticProperty<Movement, ?> or List<StaticProperty<? super Movement, ?>

Arrays.asList(SOME_STRING, SOME_INT, SOME_FLOAT);

For each property of the respective Model Element the Meta Class contains one StaticProperty field. The name of the field is derived from the property name, converting it into from camelCase to UPPER_UNDERSCORE. A property named firstName would result in the field FIRST_NAME.
Each property then again provides information through its member methods:

Method Description Return Type (Sample) value

getPropertyType()

The Java Class of this property including generics

Class<…​>

String.class, List.class

getContainingType()

The Java Class of the element containing this property (e.g. an Aspect or an Entity)

Class<…​>

Class<Movement>

getContainedType()

Only present on properties with container types like List, Set, Optional etc. The Java Class of the element contained within the container.

Class<…​>

Class<Movement>

isComplexType()

Whether this property has a complex type, e.g. an Entity.

boolean

true for complex types, false else

getValue(Movement object)

The property value of the given element instance

The property type

someStringValue (using the getter, e.g. object.getTestString())

Types of Static Properties

Different kinds of Static Properties exist to reflect all possible elements within an Aspect Model:

Property Type Description Generics

StaticProperty<C, T>

A simple scalar property

C is the containing type (an Aspect or Entity)
T is the property type (e.g. String)

StaticContainerProperty<E, C, T>

A property with a container type like Optional or Collection

E is the containing type (an Aspect or Entity)
C is the type inside the container (e.g. String)
T is the property type (e.g. Optional<String>)

StaticUnitProperty<C, T>

A simple scalar property but with an additional method to get its Unit

C is the containing type (an Aspect or Entity)
T is the property type (e.g. String)

All of the above Property types have a counterpart with a Constraint, namely StaticConstraintProperty, StaticConstraintContainerProperty and StaticConstraintUnitProperty.
Their API and generics are the same, but they have an additional method to get a list of their constraints.

Writing Code using Static Meta Classes

Addressing Properties

Independent from what you’ll finally use a Property for it is important to understand how you can use them to navigate through your Model. Every Model Element that is a Property Container offers access to its properties - most prominently Aspects and Entities.
Their properties are directly addressed using the respective fields from their Meta Classes.

However, you can also go beyond that. Properties can be chained so that it’s possible to address properties nested inside your Model.

This is useful in situations where it is required to use nested properties as if they would belong to a higher Element. Such operations can be for example:

  • flattening data structures

  • filtering on criteria defined on nested properties

Property Chains are defined using type safe builders:

PropertyChain<Movement, BigDecimal> latitude =
    PropertyChain.from( MetaMovement.POSITION )
                 .to( MetaSpatialPosition.LATITUDE );

Property Chains can follow deeply nested structures and are not limited in that. Assuming another Aspect that contains the structure Aspectentity: EntitysubEntity: SubEntity we can define a chain like this:

PropertyChain<Aspect, String> nestedString =
    PropertyChain.from( MetaAspect.ENTITY )
                 .via( MetaEntity.SUB_ENTITY )
                 .to( MetaSubEntity.STRING_PROPERTY );

Container properties can also appear anywhere, either at the start or in the middle or end of a chain. The respective container type then will be propagated from the moment on it appears. One thing to note is, that for collection valued properties the concrete collection type is not preserved but always replaced with a List.

ContainerPropertyChain<Movement, Optional<Float>, Float> altitude =
    PropertyChain.from( MetaMovement.POSITION )
                 .to( MetaSpatialPosition.ALTITUDE );


ContainerPropertyChain<Aspect, List<String>, String> nestedEntityCollectionStrings =
    PropertyChain.from( MetaAspect.ENTITY )
                 .viaCollection( MetaEntity.SUB_ENTITY_LIST )
                 .to( MetaSubEntity.STRING_PROPERTY );

Accessing Property data

Static Properties can act as accessors and thus be used to retrieve the data they represent from instances of their enclosing Model Elements.

All Static Properties provide the method R getValue(C object) and additionally extend the interface Function<C, R> so that it is also possible to directly use them within stream operations like .map().

For example, simply extracting and printing all property values of an entity could be written like this:

Entity entity = getEntity();

MetaEntity.INSTANCE.getProperties().stream()
                                   .map( StaticProperty::getValue )
                                   .forEach( System.out::println );

When accessing the values of Property Chains please note the following:

  • Chain resolution of non-Optional chains ends at null values and also will be returned as the result. Client code thus has to handle those situations accordingly.

  • Nested structures with multiple collections in between might result in large final Lists of data. For example, if you have an Aspect with a list of 1000 or more measurements and each measurement again contains a list of a few hundred data samples, resolving the chain to the data samples might easily give you results into the millions.