Model Extensions
Model extensions are a way to add custom models to an already existing ontology.
In a Model extension there are:
- A parent ElementClass, e.g.
elements::Component
, which can be extended. - A child ElementClass, e.g.
demo::CustomElement
. - A reference with associationType
extension
, which goes from the child to the parent.
Currently, 3 ElementClasses in elements
are extendable, so they can be used as parent:
- Application
- Component
- DataElement
- Reference
- ElementClass
- Ontology
The reference describes the link from the child to the parent.
<reference name="component">
<associationType name="extension"/>
<owner name="CustomElement" ontology="demo"/>
<target name="Component" ontology="elements"/>
<cardinality>
<minimum>0</minimum>
<maximum>1</maximum>
</cardinality>
</reference>
The child ElementClass is defined like any other ElementClass.
<elementClass name="CustomElement">
<isGloballyUnique>false</isGloballyUnique>
<isAbstract>false</isAbstract>
<isSealed>false</isSealed>
<group name="custom" ontology="demo"/>
<role name="element"/>
<attributes>
<attribute name="name">
<isIdentifier>true</isIdentifier>
<dataType name="Name" ontology="demo"/>
</attribute>
</attributes>
</elementClass>
Don't forget the dependency on the target ontology.
<ontology name="demo">
<dependencies>
<ontology name="elements"/>
</dependencies>
</ontology>
Model extension files
Once a Model extension has been defined, you can add the XML files in a subdirectory next to the other child elements.
The name of the subdirectory is the name of the element, starting in lowercase, with suffix s
.
space
└── model
├── space.xml
├── dataElements
└── customElements
├── CustomElement1.xml
└── CustomElement2.xml
For extensions of DataElement
, there is a directory for every DataElement containing the extensions:
space
└── model
├── space.xml
└── dataElements
├── Starship.xml
└── Starship
└── customElements
├── CustomElement1.xml
└── CustomElement2.xml
Metamodel expansion also generates an XSD file for each ontology, which can help with writing the XML model files by hand.
Usage in Expanders
Each Composite of an extendable ElementClass has a getExtension(String)
method to retrieve extensions by the name of the child ElementClass.
<mapping>
<list name="customElements"
eval="component.getExtension('CustomElement')"
param="customElement">
<value name="name" eval="customElement.name"/>
</list>
</mapping>
If the role of the child element is element
, you can also write expanders that target this ElementClass.
<expander name="CustomElementExpander">
<packageName>org.normalizedsystem.custom.expander</packageName>
<layerType name="SHARED_LAYER"/>
<technology name="COMMON"/>
<sourceType name="SRC"/>
<elementType component="demo" name="CustomElement"/>
<artifactName>$customElement.name$.java</artifactName>
<artifactPath>$componentRoot.directory$/$artifactSubFolders$/some/package</artifactPath>
<isApplicable>true</isApplicable>
</expander>
When to use Model extensions
- If you cannot change the ontology of the parent.
- The parent element has the option
meta.composite.extendable
.