Expanders 5.20.0
Changes and Improvements
New ValueType System
ValueFieldTypes are now obsolete and will be replaced with ValueTypes.
You can use the MigrateValueFieldsToValueType
transmutation to migrate your ValueFields to the new ValueType representation.
The new ValueTypes support adding restrictions to some basic ValueTypes, like String patterns. So, it will be useful to check out the supported restrictions and see where they can be used in the model.
To make the model compatible with both new and old Expanders, ValueTypes are transformed to an equivalent ValueFieldType model and vice versa.
Custom ValueFieldTypes will not be automatically migrated. Instead, look at the use-case and see if you can replace it with a SimpleValueType.
In case of a custom front-end, you can use the correct feature anchors to replace the default implementation using a feature. A reference implementation will be provided in the near future.
Furthermore, there are plans to implement more complex ValueTypes.
The Strings ValueType is limited to 255 characters. Before this version, this limit was not enforced in the code. However, this version will enforce the limit in the SharedValidator class.
If you have a field that should not be limited, use the Text
ValueType.
<field name="foo">
<valueField>
<type name="Text"/>
</valueField>
</field>
Mapping Xml Improvements
Some improvements have been added to simplify mapping files.
Filter and Distinct in List
First, the <list>
tag has 2 new child tags:
<filter name="filterName" eval="condition">
: Evaluate the condition. If the condition is false, the item will not appear in the list.<distinct name="distinctionName" eval="value">
: Evaluate the value. Items with duplicate values will be de-duplicated.
These feature were previously already available as the filter
and unique
attributes on the <list>
tag.
However, these tags can be interleaved with <let>
tags to simplify some of the logic.
E.g. this:
<list name="oneToManyLinkFields" eval="dataElement.fields" param="field"
filter="field.linkField neq null and not field.linkField.linkFieldType.isMultivalued">
<value name="name" eval="field.name"/>
<value name="element" eval="field.linkField.linkFieldType.targetElement.name"/>
</list>
becomes:
<list name="oneToManyLinkFields" eval="dataElement.fields" param="field">
<filter name="isLinkField" eval="field.linkField neq null"/>
<let name="linkFieldType" eval="field.linkField.linkFieldType"/>
<filter name="isOneToMany" eval="not linkFieldType.isMultivalued"/>
<value name="name" eval="field.name"/>
<value name="element" eval="linkFieldType.targetElement.name"/>
</list>
NotEmpty and Flatten in ognl
2 methods have been attached to lists in OGNL statements in the mapping files:
<mapping>
<!-- List#notEmpty returns true iff the list has no items -->
<value name="hasDataElements" eval="component.dataElements.notEmpty"/>
<!-- List#flatten will turn a list-of-lists List<List<T>> into a flat list List<T> -->
<value name="allDataElements" eval="application.components.{ dataElements }.flatten"/>
</mapping>
String manipulation in OGNL
Several properties have been attached to Strings to give them similar features to the StringTemplates:
<value name="fieldCapitalized" eval="field.name.firstToUpper"/>
It is best to leave all formatting to the StringTemplate files. However, this might help to simplify some specific use-cases.
Lambdas in OGNL
OGNL does not support java 8 lambda syntax. And while OGNL did have its own version of lambdas, these did not work together with java 8 functional interfaces.
This has been fixed for the Function
, Predicate
and Supplier
functions.
So now, you can use the OGNL lambda syntax with, for example, Optional:
<value name="valueName" eval="someOptionalValue.map(:[ #this.name ]).orElse('no value')"/>