NativeTypes
NativeTypes represent how a ValueType is mapped to specific use-cases. They are the native representations of these Types in the different technologies.
E.g. this nativeType define the String java class:
<nativeType name="java:transport:java.lang.String">
<definition>java.lang.String</definition>
<technology name="JDK"/>
<concern>transport</concern>
</nativeType>
Each SimpleValueType is linked to a number of NativeTypes. This definition can be extended by redefining a SimpleValueType in a DataResource with the additional NativeTypes.
<simpleValueType name="String">
<nativeTypes>
<nativeType name="java:transport:java.lang.String"/>
<nativeType name="java:creation:string"/>
<nativeType name="java:isUndefined:string:nullOrEmpty"/>
</nativeTypes>
</simpleValueType>
Using NativeTypes in Expanders
Use getNativeType()
to get the type connected to a concern and technology.
This method return an Optional<NativeTypeComposite>
.
<let name="jpa" eval="technologies.get('JPA')"/>
<let name="jpaType" eval="type.getNativeType('entity', jpa)"/>
For java types, the NativeTypeComposite class has a getJavaType()
method.
Introducing NativeTypes for a new Expander
When writing a new Expander, you might need to define a new set of NativeTypes.
Pick a unique concern string and a relevant technology.
If your Expander defines a technology other than COMMON
, then this is often the best choice.
Next, create a nativeTypes dataResource and use the definition of the NativeTypes to implement the expander.
- nativeTypes.xml
- MyExpanderMapping.xml
- simpleValueTypes.xml
<dataResource type="elements::NativeType">
<nativeType name="angular:input:text">
<technology name="ANGULAR"/>
<concern>input</concern>
<definition>TextInputComponent</definition>
</nativeType>
<nativeType name="angular:input:date">
<technology name="ANGULAR"/>
<concern>input</concern>
<definition>DateInputComponent</definition>
</nativeType>
</dataResource>
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<let name="technology" eval="technologies.get('ANGULAR')"/>
<!-- or <let name="technology" eval="expander.technology"/> -->
<let name="displayType" eval="field.valueField.type.getNativeType('input', technology)"/> <!-- Optional<NativeTypeComposite> -->
<value name="component" eval="displayType.map(:[ definition ]).orElse('DisabledInputComponent')"/>
</mapping>
<dataResource type="elements::SimpleValueType">
<simpleValueType name="String">
<nativeTypes>
<nativeType name="angular:input:text"/>
</nativeTypes>
</simpleValueType>
<simpleValueType name="Date">
<nativeTypes>
<nativeType name="angular:input:date"/>
</nativeTypes>
</simpleValueType>
</dataResource>
The definition attribute is used to describe the type in a processable way. It is up to the Expander writer to decide on the format.
For java types, you can use the qualified class name as definition to be able to use nativeType#getJavaType()
.