Skip to content
Sebastian Riemschüssel edited this page Jul 17, 2016 · 18 revisions

EXPRESS 2 Xcore Model Transformation

This page holds a documentation concerning the transformation.

  • Principle description
  • Specific rules
  • Annotations

Why M2M

EXPRESS is a standardized language (ISO 10303-11) which is used to model product data. It has an object flavour rather than a strict OO character. This means, that it supports the meaning of types and inheritance but does not follow strictly the meaning of type safety or a model-driven approach.

Actually, an EXPRESS scheme is a mixture of a model-driven workflow during design phase and an individual reasoning process during life-time. This fact sets up a challenge for any programmer of OO languages. Up to now, there are different approaches to provide OO APIs.

  • JSDAI
  • BIM server

Principle transformation

The structural part of EXPRESS distinguishes to basic named concepts called ENTITY and TYPE. The only distinction between TYPE and ENTITY is caused by additional properties and the ability of inheritance.

In principle each ENTITY corresponds to a class definition. Abstract entities are mapped to abstract classes. Sub classes are always disjoint (i.e. ONE OF).

Each TYPE represents a datatype. A TYPE might be an alias for a builtin datatype (i.e. REAL) or an entity. In principle the M2M method recognizes pure aliases and will replace a TYPE reference by its transitive referenced basic datatype. Special types are SELECT and any type of aggregation (ARRAY, LIST, SET and BAG).

General Transformation

Naming Conventions

Schema

The schema creates a container for all entities and types. This is to declare a containment for individual in the schema.

SCHEMA IFC4;
...
ENTITY IfcWall ... END_ENTITY;
...
END_SCHEMA;

becomes

@XpressModel(kind="new", pattern="container")
class IFC4 {
 // ...
 contains IfcWall[] ifcWall
 // ...
}

TYPE transformations

Simple data types

Simple data types in EXPRESS are NUMBER, REAL, INTEGER, LOGICAL, BOOLEAN, STRING and BINARY. These are transformed to the build-in Java primitives, except for LOGICAL and BINARY.

EXPRESS Xcore
NUMBER Double
REAL Double
INTEGER Integer
LOGICAL enum Logical { TRUE = 0, FALSE = 1, UNKNOWN = 2 }
BOOLEAN Boolean
STRING String
BINARY type Binary wraps java.util.BitSet

Defined named types

Alias types simply rename an existing concept (i.e. REAL). These aliased types are resolved to their base type. This behaviour will be optional in future.

TYPE IfcAreaMeasure = REAL;
END_TYPE;

ENTITY IfcQuantityArea
 AreaValue : IfcAreaMeasure;
END_ENTITY;

becomes

class IfcQuantityArea {
  @P21 double areaValue
}

Aggregation data types

First, there are four kinds of aggregation namely ARRAY, LIST, SET and BAG. Since all aggregations are mapped to lists in Ecore, only the properties of order and uniqueness control which insertion behaviour is implemented.

EXPRESS Xcore
A = ARRAY[0:?] A[*]
A = LIST[0:?] A[*]
A = SET[0:?] unordered unique A[*]
A = BAG[0:?] unordered A[*]

Multiple cardinalities always map to an unbound upper range. Aggregation with 0 or 1 reference map to single reference types without aggregation.

Constructed data types

ENUMERATION types

Enumerations are mapped to enums in Xcore by numbering literals starting with 0. The first literal in the list is always the default one in EMF.

TYPE A = ENUMERATION OF (
 Literal1, Literal2
);
END_TYPE;

becomes

enum A {
 Literal1 = 0, Literal2 = 1
}

SELECT types

There are two different kinds of alternative branching types called SELECT. First forms up an alternative which is aggregated into a single reference which is further called a referenced select type. The other opportunity is denoted as inverse relational select where a select acts as a branch of back references. As a result the relation becomes non-unique on the declaring side of inverse.

  • Referenced selects are mapped to special additional classes which are comprised of an attribute to identify the current type of value and a bundle of unique types.
TYPE SimpleDoubleA = REAL;
END_TYPE;

TYPE SimpleDoubleB = REAL;
END_TYPE;

ENTITY Person;
END_ENTITY;

TYPE DoubleOrPersonSelect = SELECT (
  SimpleDoubleA, SimpleDoubleB, Person 
);
END_TYPE;

becomes

enum EnumDoubleOrPersonSelect {
 SIMPLEDOUBLEA=0, SIMPLEDOUBLEB=1, PERSON=2
}

class Person {
}

class DoubleOrPersonSelect {

 EnumDoubleOrPersonSelect select

 double doubleValue
 refers Person person

 // ... additional operations
}
  • Inverse relational selects are mapped to a inheritance driven class graph where additional classes serve as delegates between both inverse bundled entities. Since non-unique relations cannot be embedded into Xcore directly, this normalization behaviour is needed. The pattern is denoted as relational delegation (see below).

Entity types

An entity concept of EXPRESS is mapped to a class in Xcore. Abstract entities are mapped to abstract classes. Inheritance is mapped directly to Xcore. Multiple inheritance is and will be not supported. There are 3 types of attributes, explicit, derived and inverse attributes. Derived attributes are currently not handled. Inverse relations are handled by the opposite mechanism of Xcore.

ENTITY Organization;
  ThePerson : Person;
END_ENTITY;

ENTITY Person;
  GivenName : STRING;
  FamilyName : STRING;
INVERSE
  EngagedIn : Organization FOR ThePerson;
DERIVE
  FullName : STRING := GivenName + ' ' + FamilyName;
END_ENTITY;

ENTITY Male SUBTYPE OF (Person);
END_ENTITY;

ENTITY Female SUBTYPE OF (Person);
END_ENTITY;

becomes

class Organization{
  @P21 refers Person thePerson opposite engagedIn
}

class Person {
  String givenName
  String familyName

  refers Organization engagedIn opposite thePerson
}

class Male extends Person {
}

class Female extends Person {
}

Specific transformation rules

Aggregation type mapping

Nested aggregations

EXPRESS has the possbility to define nested lists / multi-dimensional arrays. To support this in Xcore we need to introduce wrapper classes for the contained lists. An aggregration aggregates a class with another aggregration. :)

sectors : ARRAY [ 1 : 10 ] OF -- first dimension
ARRAY [ 11 : 14 ] OF -- second dimension
Something;

complex_list : LIST[0:10] OF UNIQUE ARRAY[1:10] OF INTEGER;

becomes

class XYZ {

  @XpressModel(pattern="delegate") 
  @P21 
  contains SomethingInList [] sectors

  @XpressModel(pattern="delegate") 
  @P21 
  contains IntInList[] complex_list 
}

@XpressModel(kind="new", pattern="nested")
class SomethingInList {
  refers Something[] aList
}

@XpressModel(kind="new", pattern="nested")
class IntInList {
  int[] aList
}

Inverse delegation rules

Relational properties of a pair of entities

Complex IFC4 examples

ENTITY IfcBSplineSurface
 ABSTRACT SUPERTYPE OF (ONEOF(IfcBSplineSurfaceWithKnots))
 SUBTYPE OF (IfcBoundedSurface);
	UDegree : IfcInteger;
	VDegree : IfcInteger;
	ControlPointsList : LIST [2:?] OF LIST [2:?] OF IfcCartesianPoint;
	SurfaceForm : IfcBSplineSurfaceForm;
	UClosed : IfcLogical;
	VClosed : IfcLogical;
	SelfIntersect : IfcLogical;
 DERIVE
	UUpper : IfcInteger := SIZEOF(ControlPointsList) - 1;
	VUpper : IfcInteger := SIZEOF(ControlPointsList[1]) - 1;
	ControlPoints : ARRAY [0:UUpper] OF ARRAY [0:VUpper] OF IfcCartesianPoint := IfcMakeArrayOfArray(ControlPointsList,
0,UUpper,0,VUpper);
END_ENTITY;

ENTITY IfcBSplineSurfaceWithKnots
 SUPERTYPE OF (ONEOF(IfcRationalBSplineSurfaceWithKnots))
 SUBTYPE OF (IfcBSplineSurface);
	UMultiplicities : LIST [2:?] OF IfcInteger;
	VMultiplicities : LIST [2:?] OF IfcInteger;
	UKnots : LIST [2:?] OF IfcParameterValue;
	VKnots : LIST [2:?] OF IfcParameterValue;
	KnotSpec : IfcKnotType;
 DERIVE
	KnotVUpper : IfcInteger := SIZEOF(VKnots);
	KnotUUpper : IfcInteger := SIZEOF(UKnots);
END_ENTITY;

becomes

@XpressModel(name="IfcBSplineSurface",kind="generated") 
abstract class IfcBSplineSurface extends IfcBoundedSurface {
  @P21 int uDegree  
  @P21 int vDegree  
  @XpressModel(pattern="delegate") @P21 contains IfcCartesianPointInList[] controlPointsList  
  @P21 IfcBSplineSurfaceForm surfaceForm  
  @P21 Logical uClosed
  @P21 Logical vClosed
  @P21 Logical selfIntersect
}

@XpressModel(name="IfcBSplineSurfaceWithKnots",kind="generated") 
class IfcBSplineSurfaceWithKnots extends IfcBSplineSurface {
  @P21 int[] uMultiplicities  
  @P21 int[] vMultiplicities  
  @P21 double[] uKnots 
  @P21 double[] vKnots  
  @P21 IfcKnotType knotSpec
}

Inverse relation with inheritance involved

IfcAnnotation, IfcGrid and IfcElement (not shown here) declare an inverse relation ContainedInStructure to the attribute RelatedElements of the objectified relation IfcRelContainedInSpatialStructure. This attribute itself declares the type of the attribute to be IfcProject the suppertype of IfcAnnotation, IfcGrid and IfcElement. The inverse relation opens a triangle of involved entities through the inheritance graph. This can not be reflected in Xcore directly and need helper classes to resolve the inverse relations correctly.

ENTITY IfcAnnotation
 SUBTYPE OF (IfcProduct);
 INVERSE
	ContainedInStructure : SET [0:1] OF IfcRelContainedInSpatialStructure FOR RelatedElements;
END_ENTITY;

ENTITY IfcGrid
 SUBTYPE OF (IfcProduct);
	UAxes : LIST [1:?] OF UNIQUE IfcGridAxis;
	VAxes : LIST [1:?] OF UNIQUE IfcGridAxis;
	WAxes : OPTIONAL LIST [1:?] OF UNIQUE IfcGridAxis;
	PredefinedType : OPTIONAL IfcGridTypeEnum;
 INVERSE
	ContainedInStructure : SET [0:1] OF IfcRelContainedInSpatialStructure FOR RelatedElements;
END_ENTITY;

ENTITY IfcRelContainedInSpatialStructure
 SUBTYPE OF (IfcRelConnects);
	RelatedElements : SET [1:?] OF IfcProduct;
	RelatingStructure : IfcSpatialElement;
END_ENTITY;

becomes

@XpressModel(name="IfcAnnotation",kind="generated") 
class IfcAnnotation extends IfcProduct {
  @XpressModel(pattern="delegate") 
  contains unordered unique DelegateIfcAnnotationIfcRelContainedInSpatialStructure[] containedInStructure opposite relatedElements
  
}

@XpressModel(name="IfcGrid",kind="generated") 
class IfcGrid extends IfcProduct {
  // ...
  @XpressModel(pattern="delegate") 
  contains unordered unique DelegateIfcGridIfcRelContainedInSpatialStructure[] containedInStructure opposite relatedElements
  
}

@XpressModel(name="IfcRelContainedInSpatialStructure",kind="generated") 
class IfcRelContainedInSpatialStructure extends IfcRelConnects {
  @XpressModel(pattern="delegate") 
  @P21 refers unordered unique DelegateIfcRelContainedInSpatialStructureIfcProduct[] relatedElements opposite ifcRelContainedInSpatialStructure
  // ...
}

@XpressModel(kind="new", pattern="delegate")
interface DelegateIfcRelContainedInSpatialStructureIfcProduct {						
	// Inverse super type
	op IfcProduct getRelatedElements()
	// Non-unique counter part, using concept QN as reference name
	refers IfcRelContainedInSpatialStructure ifcRelContainedInSpatialStructure opposite relatedElements
}

@XpressModel(kind="new", pattern="delegate")
class DelegateIfcAnnotationIfcRelContainedInSpatialStructure extends DelegateIfcRelContainedInSpatialStructureIfcProduct {
	// Containment on declaring side of IfcAnnotation
	container IfcAnnotation relatedElements opposite containedInStructure	
}

@XpressModel(kind="new", pattern="delegate")
class DelegateIfcGridIfcRelContainedInSpatialStructure extends DelegateIfcRelContainedInSpatialStructureIfcProduct {
	// Containment on declaring side of IfcGrid
	container IfcGrid relatedElements opposite containedInStructure	
}

Limitations

Version 0.2


  • No WHERE rules are embedded
  • No Functions are embedded
  • Derived attributes are marked as derived but will not be computed (since this feature is based on functions)

Xpress-Annotations

During the process of transformation the generator creates annotations to mark decisions made by the procedure. Since not all features of EXPRESS can be handled by an OO language like Java, additional information are needed to support the P21 reading and writing process. Only explicit attributes are exchanged through P21 files and the appear in the order of their declaration inside of the entity. The @P21 annotation marks attributes which are exchanged to garranty the correct mapping.

The namespace of XpressModel-annotations is http://www.bitub.de/express/XpressModel.

The namespace of P21-annotations is http://www.bitub.de/express/P21.

Properties

Key Values Context Description
name text class, method, property Name of original entity or type
type {mapped, delegate, nested} class, method, property Type of approach