Expanders-Core 8.1.1
Changes and improvements
- String interpolation
- Strict mode to catch errors in mapping.xml
- New list mapping syntax
- Improved stack-traces
- Support for extending the context of artifact paths, mapping files etc.
This version introduces a new expansion-resource ontology-metamodel-expanders
, which is included in the metamodel stack
.
Resource | Version |
---|---|
nsx-metamodel-stack | 2024.3.9 |
Expanders 2024.3.x introduce the ontology-metamodel-expanders
.
These expanders have been to made to replace the metamodel-expanders
.
They use the ontology-based metamodel directly instead of first requiring the GenerateMetamodelApplication
transmuter.
The new expanders generate a simplified project.
{ontology}-model
submodule for each ontologytest-support
module..harvestInclude
files, which contain glob patterns for which
files to harvest.expanders
module has been removed. Instead, expanders should be implemented in a separate project similar to
regular expander projects.Before, it was necessary to expand with model-builder-expanders
in a separate project to generate helper classes for
transmuters. These expanders have now been merged into the ontology-metamodel-expanders
so that this is no longer
needed.
The new expanders make use of profiles to configure cross-cutting
concerns. The Standard Metamodel
enables every feature, but it is possible to create new profiles if necessary.
<dataResource type="expansionControl::ExpansionProfile">
<profile name="Standard Metamodel">
<tags>
<tag>#meta.maven</tag>
<tag>#meta.xml</tag>
<tag>#meta.transmutation</tag>
</tags>
</profile>
</dataResource>
The expanders generate XSD files to describe the ElementClass XML files. The default namespace is
https://schemas.normalizedsystems.org/xsd/${ontology}/${version}
, which can be modified with the meta.xml.namespace
option on ontology. If it contains ${version}
, this will be replaced with the actual version.
There are also some changes to the XML representation.
xmlns
attributes. In case of mixed metamodels, the XML tags can contain prefixes.The XMLReaders are implemented to be backwards compatible (they can read both old and new formats).
meta.compatibility.mappingContext.option
for backwards compatibility.String
, Boolean
or Integer
.{element}DataRef
class.The expansion resources below provide Expanders 6.6.0
.
Resource | Version |
---|---|
Expanders | 6.6.0 |
nsx-default-stack | 2024.2.0 |
Expanders 6.6.0
mainly focuses on improvements for Expander development.
Uses statements in mapping file can now have a type attribute. The way the type is resolved in specific to the import strategy.
For java import, you can now add static imports by adding type="static"
.
<uses type="static" eval="'net.democritus.sys.NullDataRef.EMPTY_DATA_REF'"/>
The @imports statement in Expander templates can now have one or more parameters. These parameters in case you have multiple types of imports in the same artifact (e.g. in Angular).
There is now support for renaming Expanders, changing packages or changing the artifact location. By defining an ExpanderRelocation DataResource, you can redirect Features and harvest files to the new location, so that everything still works the same way after the change.
The expansion resources below provide Expanders 6.4.4
.
Resource | Version |
---|---|
Expanders | 6.4.4 |
nsx-default-stack | 2024.0.2 |
rest-jaxrs-stack | 4.11.0 |
Since Expanders 6.0.0, the expanders jars are compiled for Java 17. This means that expansion can only be executed with JDK 17 or higher.
However, expanded code is still java 8 compatible.
There are some field names that, when used, would add additional behavior:
enteredAt
: filled in with a timestamp when the instance is createdenteredBy
: filled in with a dataRef to the user that created the instancelastModifiedAt
: updated with a timestamp each time the instance is modifiedlastModifiedBy
: updated with a dataRef to the user that modified itThere are now options that add the same behavior and can be added to any field (with the correct type).
enteredAt
: option audit.create.timestamp
enteredBy
: option audit.create.author
lastModifiedAt
: option audit.modify.timestamp
lastModifiedBy
: option audit.modify.author
The options are still implicitly added to the fields with those specific names.
Maven builds will now show warnings when deprecated code is used.
Can be disabled with maven.hideDeprecationWarnings
.
DataResources have become a useful tool for expansion-resources to provide information to the Expanders. This post aims to describe how we can use the information provided by the data-resources in a set of Expanders, to gain insight in how the Expanders work. It gives a number of examples of Expanders using DataResources to make a list of libraries, option types and validation rules.
The data from DataResources is stored in a DataRegistryComposite.
This object is available in mapping file as dataRegistry
.
The examples here will all work around the getComposites(String)
method, which returns a list of all instances of an
ElementType.
Library elements define runtime libraries used by the expanded projects. The logic deciding which libraries are added to the pom.xml files depends on the LayerImplementations of each LayerTypes. This example omits that complexity and instead filters on Technologies.
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/1/0/mapping">
<list name="libraries" eval="dataRegistry.getComposites('net.democritus.settings.Library')"
param="lib">
<filter name="onlyApplicableLibraries" eval="technologies.has(lib.technology.name)"/>
<value name="name" eval="lib.name"/>
<value name="groupId" eval="lib.groupId"/>
<value name="artifactId" eval="lib.artifactId"/>
<value name="version" eval="lib.version"/>
<value name="technology" eval="lib.technology.name"/>
<value name="provider" eval="lib.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
</mapping>
delimiters "%", "%"
base() ::= <<
# Library information
## Libraries
<!-- anchor:libraries:start -->
| library | groupId | artifactId | version | technology | provided by |
|---------|---------|------------|---------|------------|-------------|
%libraries:libraryRow();separator="\n"%
<!-- anchor:libraries:end -->
## Additional Information
%expanderComment%
>>
libraryRow(lib) ::= <<
| %lib.name% | %lib.groupId% | %lib.artifactId% | %lib.version% | %lib.technology% | %lib.provider% |
>>
# Library information
## Libraries
<!-- anchor:libraries:start -->
| library | groupId | artifactId | version | technology | provided by |
|---------|---------|------------|---------|------------|-------------|
| nsx-common | net.democritus | nsx-common | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-contract-annotations | net.democritus | nsx-contract-annotations | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-logging | net.democritus | nsx-logging | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-ref | net.democritus | nsx-shared-ref | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-common | net.democritus | nsx-shared-common | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-cli | net.democritus | nsx-shared-cli | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-owasp | net.democritus | nsx-shared-owasp | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-opencsv | net.democritus | nsx-shared-opencsv | 2023.4.0 | OPENCSV | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-jpa | net.democritus | nsx-shared-jpa | 2023.4.0 | COMMON | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-testing | net.democritus | nsx-shared-testing | 2023.4.0 | EJB3 | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-tomee | net.democritus | nsx-shared-tomee | 2023.4.0 | TOMEE | net.democritus:nsx-runtime-libraries::2023.4.0 |
| nsx-shared-xml | net.democritus | nsx-shared-xml | 2023.4.0 | XML | net.democritus:nsx-runtime-libraries::2023.4.0 |
| javaee-api:jee6-jee8 | javax | javaee-api | ${javaee.version} | EJB3_1 | net.democritus:prime-data::2023.1.2 |
| servlet-api:jee6 | javax.servlet | javax.servlet-api | 3.0.1 | COMMON | net.democritus:prime-data::2023.1.2 |
| jsp-api:jee6 | javax.servlet.jsp | javax.servlet.jsp-api | 2.2.1 | COMMON | net.democritus:prime-data::2023.1.2 |
| servlet-api:jee7 | javax.servlet | javax.servlet-api | 3.1.0 | COMMON | net.democritus:prime-data::2023.1.2 |
| jsp-api:jee7 | javax.servlet.jsp | javax.servlet.jsp-api | 2.3.3 | COMMON | net.democritus:prime-data::2023.1.2 |
| servlet-api:jee8 | javax.servlet | javax.servlet-api | 4.0.1 | COMMON | net.democritus:prime-data::2023.1.2 |
| jsp-api:jee8 | javax.servlet.jsp | javax.servlet.jsp-api | 2.3.3 | COMMON | net.democritus:prime-data::2023.1.2 |
| junit | junit | junit | 4.13.2 | COMMON | net.democritus:prime-data::2023.1.2 |
| struts25-core | org.apache.struts | struts2-core | 2.5.30 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts25-json-plugin | org.apache.struts | struts2-json-plugin | 2.5.30 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| net.democritus.struts:shared-struts25 | net.democritus.struts | shared-struts25 | 2021.1.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts25-presentation-runtime | net.democritus | nsx-presentation-struts2 | 2022.4.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts23-core | org.apache.struts | struts2-core | 2.3.37 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts23-json-plugin | org.apache.struts | struts2-json-plugin | 2.3.37 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| net.democritus.struts:shared-struts23 | net.democritus.struts | shared-struts23 | 2021.1.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts23-presentation-runtime | net.democritus | nsx-presentation-struts2 | 2022.4.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts2-core | org.apache.struts | struts2-core | 6.3.0.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| struts2-json-plugin | org.apache.struts | struts2-json-plugin | 6.1.2.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| application-shared-struts2 | net.democritus.struts | application-shared-struts2 | 5.28.1 | STRUTS2 | net.democritus:Expanders::5.28.1 |
| application-shared-common | net.democritus | application-shared-common | 5.28.1 | COMMON | net.democritus:Expanders::5.28.1 |
| hibernate-core | org.hibernate | hibernate-core | 5.6.15.Final | HIBERNATE | net.democritus:Expanders::5.28.1 |
| workflow-shared-common | net.democritus | workflow-shared-common | 2023.3.2 | COMMON | net.democritus:base-components::2023.3.2 |
| workflow-shared-jpa | net.democritus | workflow-shared-jpa | 2023.3.2 | JPA | net.democritus:base-components::2023.3.2 |
| oauth2-oidc-sdk | com.nimbusds | oauth2-oidc-sdk | 10.7.2 | COMMON | net.democritus:base-components::2023.3.2 |
<!-- anchor:libraries:end -->
## Additional Information
expanded with nsx-expanders:5.37.4, expansionResource org.normalizedsystems:meta-doc-expanders:1.0.0-SNAPSHOT
Most DataResource elements contain metadata about the location where the data was found.
To use, the most interesting information is the expansion-resource that declares this DataResource.
This can be found by calling composite.getMetadata('origin.expansionResource')
, which returns Optional<String>
.
Most up-to-date expansion-resources declare the options they support as OptionTypes.
We can filter on OptionTypes with a deprecation warning or an expiration time. The example separates the options that have yet to be expired and the ones that have already expired.
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<let name="expirationHelper" eval="new org.normalizedsystems.example.OptionTypeExpirationHelper()"/>
<list name="deprecatedOptionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="deprecatedOptions" eval="not opt.deprecationWarning.empty or not opt.validUntil.empty"/>
<filter name="isNotExpired" eval="not expirationHelper.isExpired(opt)"/>
<value name="name" eval="opt.name"/>
<value name="validUntil" eval="opt.validUntil"/>
<value name="description" eval="opt.description.replace('\n', ' ')"/>
<value name="reason" eval="opt.deprecationWarning"/>
<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
<list name="expiredOptionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="hasExpirationTime" eval="not opt.validUntil.empty"/>
<filter name="isExpired" eval="expirationHelper.isExpired(opt)"/>
<value name="name" eval="opt.name"/>
<value name="validUntil" eval="opt.validUntil"/>
<value name="description" eval="opt.description.replace('\n', ' ')"/>
<value name="reason" eval="opt.deprecationWarning"/>
<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>
</list>
</mapping>
delimiters "%", "%"
base() ::= <<
# Deprecated Options List
## Deprecated
<!-- anchor:deprecated:start -->
| name | valid until | description | reason | provided by |
|------|-------------|-------------|--------|-------------|
%deprecatedOptionTypes:optionRow();separator="\n"%
<!-- anchor:deprecated:end -->
## Expired
<!-- anchor:expired:start -->
| name | expired since | description | reason | provided by |
|------|---------------|-------------|--------|-------------|
%expiredOptionTypes:optionRow();separator="\n"%
<!-- anchor:expired:end -->
## Additional Information
%expanderComment%
>>
optionRow(opt) ::= <<
| %opt.name% | %opt.validUntil% | %opt.description% | %opt.reason% | %opt.provider% |
>>
package org.normalizedsystems.example;
import net.democritus.elements.OptionTypeComposite;
import java.time.LocalDate;
public class OptionTypeExpirationHelper {
public boolean isExpired(OptionTypeComposite optionType) {
String validUntil = optionType.getValidUntil();
if (validUntil == null || validUntil.isEmpty()) {
return false;
}
LocalDate expirationTime = LocalDate.parse(validUntil);
return LocalDate.now().isAfter(expirationTime);
}
}
# Deprecated Options List
## Deprecated
<!-- anchor:deprecated:start -->
| name | valid until | description | reason | provided by |
|------|-------------|-------------|--------|-------------|
| jpa.optimization.skipDataQuery.disable | 2023-12-19 | Disables an optimization that skips redundant queries if the count query has returned null. | This will become standard, non-optional behaviour | net.democritus:Expanders::5.28.1 |
| legacy.dataDetailedConstructor.reenable | 2023-12-01 | Generate secondary constructor for all data pojo classes which has an argument for each field in the element. | Using the "detailed constructor" was a textbook anti-pattern for Action Version Transparency, the first theorem of the NS theory. Therefore, we removed this legacy constructor. It can easily be replaced by simply calling the default argument-less constructor and the setters for all fields. | net.democritus:Expanders::5.28.1 |
| ejb3.useEjbInControl | 2023-12-01 | Adds ejb3.1 as a technology to the control layer together with a dependency on `javax:javaee-api`. | EJB is a technology tied to the LOGIC layer and should not be used in the CONTROL layer. | net.democritus:Expanders::5.28.1 |
| legacy.noTaskPerform.reenable | 2024-01-01 | Revert to previous behavior where a task has no `perform` or `performOnTarget` method unless the `includePerform` option is defined. | Task delegation is known at compile time and shouldn't require a dynamic lookup. | net.democritus:Expanders::5.28.1 |
| legacy.dynamicTaskDelegation.reenable | 2024-01-01 | Replace the switch-case for delegation with a dynamic lookup of a provided fully-qualified classname. Also adds an 'Impl2' alternative delegate class. | Task delegation is known at compile time and shouldn't require a dynamic lookup. | net.democritus:Expanders::5.28.1 |
| vega.transient.taskBean.mImplementation | 2024-01-01 | | Just use `implementation` instead. | net.democritus:Expanders::5.28.1 |
| includeDelegation | 2024-01-01 | Recommended, Adds a separate, technology-independent class to provide the implementation of this task. | Task delegation is now enabled by default. | net.democritus:Expanders::5.28.1 |
| includePerform | 2024-01-01 | Recommended, Generates a `perform()` method to execute this task. Used by workflow. | A task now includes perform method(s) by default. | net.democritus:Expanders::5.28.1 |
<!-- anchor:deprecated:end -->
## Expired
<!-- anchor:expired:start -->
| name | expired since | description | reason | provided by |
|------|---------------|-------------|--------|-------------|
| struts.version | 2023-07-01 | If set to 2.3, expanders will expand for struts2.3 instead of the default, more recent version. | Support of old versions of struts will be removed, as they often contain serious vulnerabilities and receive no more security updates. As of struts 6.x, the expanders will only support a specific version of struts in every expander release. | net.democritus:Expanders::5.28.1 |
| legacy.editorconfig.disabled | 2023-04-07 | Disables the expansion of editorconfig files. | All projects should now be expanded with editorconfig to enforce consistency in formatting as much as possible. | net.democritus:Expanders::5.28.1 |
| legacy.valueFieldType.hashCodeMethod.disable | 2023-04-07 | Removes the generated `hashCode()` method in ValueFieldType class in this component. | If a custom `hashCode()` methode already exists for the class, copy the logic of that method to the anchors in the generated one. | net.democritus:Expanders::5.28.1 |
| legacy.multilingual.enable | 2023-04-07 | Enable translation support for field values. | There is currently no actively maintained translation support for data out-of-the-box. This should be custom implemented if required. | net.democritus:Expanders::5.28.1 |
| legacy.ui.rootPages.reenable | 2023-04-07 | Expand a html page for each DataElement as before version 5.0.0 | Please refactor all code that currently relies on the `-page.html` and `-io-page.html` files. | net.democritus:Expanders::5.28.1 |
| legacy.logicDataMethods.reenable | 2023-01-01 | Returns methods to DataElement Bean classes that were deleted because they were tightly coupled to the Data layer. | Please replace all affected code with the `getProjection()` and `resolveDataRef()` methods. | net.democritus:Expanders::5.28.1 |
| legacy.oldCollectionMethods.reenable | 2023-01-01 | Returns collection methods to the DataElement Agent classes that were deleted because of bad version transparency. | Please replace all affected code with the `find()` method. | net.democritus:Expanders::5.28.1 |
| legacy.oldSearchMethods.reenable | 2023-01-01 | Generate search methods to the DataElement Agent classes that were deleted because of bad version transparency. | Please replace all affected code with the `find()` method. | net.democritus:Expanders::5.28.1 |
| legacy.relationRetrievalMethods.reenable | 2023-01-01 | Generate LinkField methods to the DataElement Agent classes that were deleted because of bad version transparency. | Please replace all affected code with the `find()`, `getProjection()` and `TagValuePairAgent.getValuesForTag()` methods. | net.democritus:Expanders::5.28.1 |
| legacy.searchDataRefMethods.reenable | 2023-01-01 | Generate search methods to the DataElement Agent classes that were deleted in favour of the `find()` method. | Please refactor all code that uses the SearchDataRef class, to use the `find()` method instead. | net.democritus:Expanders::5.28.1 |
| legacy.vectorCollectionType.reenable | 2023-04-07 | Enables the use of the `Vector` collection type instead of `List/ArrayList` where it was previously in use. | Please refactor all code that uses the `java.util.Vector` class, to use `java.util.List` instead. | net.democritus:Expanders::5.28.1 |
| legacy.struts.defaultStyle | 2023-01-01 | Adds a DefaultStyleInterceptor to the login package. | DefaultStyleInterceptor is no longer used. | net.democritus:Expanders::5.28.1 |
| legacy.cruds.getProjection.emptyOnError | 2023-08-01 | Projects empty data (default constructor) when `getData` results in an error. | Please refactor code that uses `getProjection` to handle errors. Can use `CrudsResult#getValueOrElse` to get old behavior. | net.democritus:Expanders::5.28.1 |
| experimental.cruds.failOnProjectionNotFound | 2023-06-15 | Return CrudsResult.Error when DataRef in getProjection cannot be resolved. | This option has become redundant, as this is now the default behaviour. | net.democritus:Expanders::5.28.1 |
| legacy.projectionDetailedConstructor.reenable | 2023-09-01 | Generate secondary constructor for all projection pojo classes which has an argument for each field in the element. | Using the "detailed constructor" was a textbook anti-pattern for Action Version Transparency, the first theorem of the NS theory. Therefore, we removed this legacy constructor. It can easily be replaced by simply calling the default argument-less constructor and the setters for all fields. | net.democritus:Expanders::5.28.1 |
| experimental.valueFieldType.storageType | 2023-10-01 | | ValueTypes now support the StringLength restriction. Create a SimpleValueType that fits your need instead. | net.democritus:Expanders::5.28.1 |
| showLinkDetails | 2023-09-01 | | Please refactor your code to fetch the linked Details separately. | net.democritus:Expanders::5.28.1 |
| transient.cruds.useGetName | 2023-09-01 | | Cruds#getName() is no longer supported. | net.democritus:Expanders::5.28.1 |
| legacy.logic.entityManager | 2023-10-01 | | Please move all logic surrounding EntityManagers to the Data layer. | net.democritus:Expanders::5.28.1 |
| experimental.openjpa.CharacterColumnSize | 2023-09-01 | Sets the number of characters allowed in a String field database column. | If not present, a ValueType should be defined, inheriting from String that has the required maximum length. | net.democritus:Expanders::5.28.1 |
<!-- anchor:expired:end -->
## Additional Information
expanded with nsx-expanders:5.37.4, expansionResource org.normalizedsystems:meta-doc-expanders:1.0.0-SNAPSHOT
We can also get a lot more information from the OptionType elements.
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<list name="optionTypes" eval="dataRegistry.getComposites('net.democritus.elements.OptionType')"
param="opt">
<filter name="notDeprecated" eval="opt.deprecationWarning.empty and opt.validUntil.empty"/>
<value name="name" eval="opt.name"/>
<value name="docLink" eval="opt.documentationLink"/>
<value name="hasDocLink" eval="not opt.documentationLink.empty"/>
<value name="alias" eval="opt.alias.replaceAll('\\s*,\\s*', ', ')"/>
<value name="hasAlias" eval="not opt.alias.empty"/>
<value name="description" eval="opt.description.replace('\n', ' ')"/>
<list name="properties" eval="{'alwaysEnabled', 'redundant', 'hidden', 'cascading'}" param="prop">
<filter name="isEnabled" eval="opt[prop]"/>
<value name="name" eval="prop"/>
</list>
<value name="provider" eval="opt.getMetadata('origin.expansionResource').orElse('-')"/>
<value name="defaultValue" eval="opt.defaultValue"/>
<value name="hasDefaultValue" eval="not opt.defaultValue.empty"/>
<group name="value" if="opt.valueConstraint neq null">
<value name="isRequired" eval="opt.valueConstraint.isRequired"/>
<value name="noValue" eval="opt.valueConstraint.noValue"/>
<value name="regex" eval="opt.valueConstraint.matchRegularExpression.replace('|', '&#124;')"/>
<value name="hasRegex" eval="not opt.valueConstraint.matchRegularExpression.empty"/>
</group>
<list name="elementTypes" eval="opt.elementTypes" param="elementType">
<value name="name" eval="elementType.name"/>
</list>
</list>
</mapping>
delimiters "%", "%"
base() ::= <<
# Option Types List
<!-- anchor:options:start -->
| name | value | applicable to | properties | description | provided by |
|------|-------|---------------|------------|-------------|-------------|
%optionTypes:optionRow();separator="\n"%
<!-- anchor:options:end -->
## Additional Information
%expanderComment%
>>
optionRow(opt) ::= <<
| %name(opt)% | %value(opt)% | %elementTypes(opt)% | %properties(opt)% | %opt.description% | %opt.provider% |
>>
name(opt) ::= <%
%if(opt.hasDocLink)%
[
%endif%
%opt.name%
%if(opt.hasAlias)%
%\ %(alias: %opt.alias%)
%endif%
%if(opt.hasDocLink)%
](%opt.docLink%)
%endif%
%>
value(opt) ::= <%
%if(opt.value)%
%if(opt.value.noValue)%
`none`
%else%
%if(opt.value.isRequired)%
`required`
%endif%
%if(opt.value.hasRegex)%
%\ %<code>/%opt.value.regex%/</code>
%endif%
%endif%
%endif%
%if(opt.hasDefaultValue)%
%\ %(default: `%opt.defaultValue%`)
%endif%
%>
elementTypes(opt) ::= <%
%opt.elementTypes:{et|`%et.name%`};separator=", "%
%>
properties(opt) ::= <%
%opt.properties:{prop|`%prop.name%`};separator=", "%
%>
# Option Types List
<!-- anchor:options:start -->
| name | value | applicable to | properties | description | provided by |
|------|-------|---------------|------------|-------------|-------------|
| legacy.finders.keepOrder | `none` | `Application`, `ApplicationInstance` | | Keep order of finders (do not add findByNameEq and findAll as first finders) | - |
| setBatchFinder | `required` <code>/find.+/</code> | `FlowElement`, `FlowElement` | | Set finder to use to find the next batch | - |
| target.class.custom | `required` | `TaskElement` | | Sets the target class of a TaskElement | - |
| target.element.projection | `required` | `TaskElement` | | Sets the target projection of a TaskElement | - |
| valuetype.migrate.storageType | `required` | `NativeType` | | Automatically add this NativeType to custom ValueFields with the defined storageType. | - |
| valuetype.migrate.displayType | `required` | `NativeType` | | Automatically add this NativeType to custom ValueFields with the defined displayType. | - |
| valueType.migration | `required` <code>/[^:]*::[^:]+/</code> | `SimpleValueType` | | Adds a corresponding ValueFieldType so that the MigrateValueFieldsToValueType transmuter will map fields of that type to this type. | net.democritus.model:prime-transmutations::2.1.1 |
| noClientLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Do not expand client layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| noControlLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Do not expand control layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| noDataLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Do not expand data layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| noLogicLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Do not expand logic layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| noProxyLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Do not expand proxy layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| noViewLayer | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement`, `Finder` | `cascading` | Do not expand view layer files for this element. Also applies to child elements. | net.democritus:Expanders::5.28.1 |
| isDetailsOnly | `none` | `DataElement` | | Only generate 1 artifact for this element: the Details class | net.democritus:Expanders::5.28.1 |
| experimental.maven.noViewPom | `none` | `Application`, `ApplicationInstance` | | Do not generate the pom.xml file for the view layer. May speed up the build time. | net.democritus:Expanders::5.28.1 |
| hideAnchors | `none` | `ExpansionSettings` | | Hide expander and feature anchors (custom anchors are still enabled) | net.democritus:Expanders::5.28.1 |
| artifactWriter | `required` <code>/([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]*/</code> | `ExpansionSettings` | | Provide an alternative artifact writer | net.democritus:Expanders::5.28.1 |
| expansion.failFast | `none` | `ExpansionSettings` | | Stop at the first failed expander or expansionStep | net.democritus:Expanders::5.28.1 |
| cleanExpansion | `none` | `ExpansionSettings` | | Always clean expansion directory before expansion | net.democritus:Expanders::5.28.1 |
| dryRun | `none` | `ExpansionSettings` | | Run expanders without writing any files | net.democritus:Expanders::5.28.1 |
| excludeExpanders | `required` | `ExpansionSettings` | | Exclude expanders matching the given glob pattern | net.democritus:Expanders::5.28.1 |
| excludeExpansionSteps | `required` | `ExpansionSettings` | | Exclude expansion steps matching the given glob pattern | net.democritus:Expanders::5.28.1 |
| excludeFeatures | `required` | `ExpansionSettings` | | Exclude features matching the given glob pattern | net.democritus:Expanders::5.28.1 |
| experimental.localUpdate | `none` | `ExpansionSettings` | | Check local maven repository when updating expansion-resources | net.democritus:Expanders::5.28.1 |
| includeExpanders | `required` | `ExpansionSettings` | | Only run expanders matching the given glob pattern. | net.democritus:Expanders::5.28.1 |
| skipPhase | `required` | `ExpansionSettings` | | Skip all phases matching the given glob pattern | net.democritus:Expanders::5.28.1 |
| updateResources | `none` | `ExpansionSettings` | | Update expansion-resources before expansion | net.democritus:Expanders::5.28.1 |
| harvest.force | `none` | `ExpansionSettings` | | Force harvest even for modules that have the option `harvest.skip` | net.democritus:Expanders::5.28.1 |
| harvest.modelDirectory.override | `required` | `ExpansionSettings` | | Override the modelDirectory for harvest files | net.democritus:Expanders::5.28.1 |
| harvest.failOnMissingArtifact | `none` | `ExpansionSettings` | | If enabled, harvest will fail when trying harvest an Artifact that cannot be found. | net.democritus:Expanders::5.28.1 |
| struts.disableStrutsErrorsToCommandResult | `none` | `Application`, `ApplicationInstance` | | Disable the mapping of struts field errors to CommandResult errors | net.democritus:Expanders::5.28.1 |
| struts.unauthorized | <code>/redirect|error-page/</code> | `Application`, `ApplicationInstance` | | If undefined or set to redirect, the application will redirect unauthorized users to the relogin page. If set to error-page, a dedicated unauthorized error-page will be expanded. | net.democritus:Expanders::5.28.1 |
| struts.unauthorized.json | <code>/status \d\d\d/</code> | `Application`, `ApplicationInstance` | | If the value corresponds to `status {statusCode}`, that status code will be returned for unauthorized json requests. E.g. `status 401` | net.democritus:Expanders::5.28.1 |
| struts.security.custom | `none` | `Application`, `ApplicationInstance` | | Disable expansion of account security hooks in the application, so that a custom security implementation can be provided. | net.democritus:Expanders::5.28.1 |
| struts.security.csrfProtection | `none` | `Application`, `ApplicationInstance` | | Add protection against CSRF | net.democritus:Expanders::5.28.1 |
| struts.security.enforceHttpMethod | `none` | `Application`, `ApplicationInstance` | | Enforce the correct https methods on each request | net.democritus:Expanders::5.28.1 |
| jpa.datasource | `required` | `Application`, `ApplicationInstance`, `Component` | | Set the name of the target datasource in the persistence.xml | net.democritus:Expanders::5.28.1 |
| jpa.datasource.nonjta | `required` | `Application`, `ApplicationInstance`, `Component` | | Set the name of the target non-jta datasource in the persistence.xml | net.democritus:Expanders::5.28.1 |
| jpa.entity.name.format | <code>/java_underscore|element|underscore/</code> | `Application`, `ApplicationInstance` | | Set the naming strategy for entity names in the data layer. Options are java_underscore (packageName with underscores instead of dots), element (`{component}.{dataElement}`), underscore (`{component}_{dataElement}`) | net.democritus:Expanders::5.28.1 |
| jpa.columnDefinition | `required` | `SimpleValueType` | | Define a database column definition for the fields of this type. | net.democritus:Expanders::5.28.1 |
| db.global.noSchemas | `none` | `Application`, `ApplicationInstance` | | This global option disables schemas for all elements, even if there is component/dataElement schema customization. | net.democritus:Expanders::5.28.1 |
| db.global.schemaName | `required` | `Application`, `ApplicationInstance` | | Forces all elements to use the specified schema, even if there is component/dataElement schema customization. | net.democritus:Expanders::5.28.1 |
| db.tableName.format | `required` <code>/lastPackage|appl4_comp4_prefix|uppercase|lowercase/</code> | `Application`, `ApplicationInstance` | | Set special table naming format: `lastPackage` prepends the last part of the package name, `appl4_comp4_prefix` prepends a prefix based on the application and component names | net.democritus:Expanders::5.28.1 |
| db.schema.enableEscapeTableName | `none` | `Application`, `ApplicationInstance` | | Escapes the table name of the DataElement, as some names could be seen as reserved keywords by the database engine. | net.democritus:Expanders::5.28.1 |
| hasMtmMappedBy | `required` | `Field` | | Set the inverse field name for an Ln06 field. (Inverse field should be a Ln03 field on the linked element) | net.democritus:Expanders::5.28.1 |
| hasOtmMappedBy | `required` | `Field` | | Set the inverse field name for an Ln04 field. (Inverse field should be a Ln02 field on the linked element) | net.democritus:Expanders::5.28.1 |
| hasMtmTable | `required` | `Field` | | Sets the name for the join table for an Ln03 field. | net.democritus:Expanders::5.28.1 |
| hasDataFieldName | `required` | `Field` | | Changes the name of the column in the database for this field | net.democritus:Expanders::5.28.1 |
| hasDataTableName | `required` | `DataElement` | | Overrides the database table name for this DataElement. Value should be table name. | net.democritus:Expanders::5.28.1 |
| hasDataSchemaName | `required` | `DataElement` | | Overrides the schema name for this DataElement and changes the table name to be unique. Value should be schema name. If defined, it will also change the table naming to use `lastPackage` format. | net.democritus:Expanders::5.28.1 |
| databaseSchemaName | | `DataElement` | | Set the schema name for this DataElement. Value should be schema name. | net.democritus:Expanders::5.28.1 |
| hasDataBaseSchema | | `Component` | | Sets the schema name for all DataElements in the component, unless otherwise specified in the DataElement itself. | net.democritus:Expanders::5.28.1 |
| hibernate.version | `required` | `Application`, `ApplicationInstance` | | Set the hibernate version to a specific version. Defaults to 5. | net.democritus:Expanders::5.28.1 |
| persistence.useGlobalSequence | `none` | `Application`, `ApplicationInstance` | | Enables the use of a native database sequence to generate IDs. | net.democritus:Expanders::5.28.1 |
| persistence.secondLevelCache | `none` | `DataElement` | | Adds second-level cache to the persistence layer. Currently only works with Hibernate 5. | net.democritus:Expanders::5.28.1 |
| persistence.identifier (alias: experimental.persistence.identifier, experimental.persistence.defaultIdentifier) | `required` <code>/sequence|identityColumn|custom/</code> | `ApplicationInstance`, `Application`, `Component`, `DataElement` | `cascading` | Set the id generation strategy. Can be `sequence` or `identityColumn`. | net.democritus:Expanders::5.28.1 |
| persistence.sequence.name (alias: experimental.persistence.sequence.name, experimental.persistence.sequence.defaultName) | `required` <code>/\w+/</code> | `ApplicationInstance`, `Application`, `Component`, `DataElement` | `cascading` | Set the name of the native sequence that is used for id generation, if native sequences are used. The default name is `NS_SEQUENCE`. | net.democritus:Expanders::5.28.1 |
| persistence.sequence.schema (alias: experimental.persistence.sequence.schema, experimental.persistence.sequence.defaultSchema) | <code>/\w+/</code> | `ApplicationInstance`, `Application`, `Component`, `DataElement` | `cascading` | Set the name of the schema where a native sequence the located that is used for id generation, if native sequences are used. By default, the schema of the DataElement is used. | net.democritus:Expanders::5.28.1 |
| persistence.schemaUpdating | `required` <code>/update|validate|none/</code> (default: `update`) | `ApplicationInstance`, `Application` | `alwaysEnabled` | This option can toggle the automatic updating of database schemas through a JPA implementation. Currently automatic updating is enabled by default. | net.democritus:Expanders::5.28.1 |
| legacy.nameNotWanted.pojoName | `none` | `Application`, `ApplicationInstance` | | Reverts a change that unifies how option nameNotWanted removes name everywhere. | net.democritus:Expanders::5.28.1 |
| disableControlSources | `none` | `Application`, `ApplicationInstance` | | Disable source directories for application control layer, which are added to the war by default. | net.democritus:Expanders::5.28.1 |
| isBranchingTask | `none` | `TaskElement` | | Allows the task to have multiple end states. Changes the return type of the task to the target end state. | net.democritus:Expanders::5.28.1 |
| isClaimElement | `none` | `DataElement` | | This dataElement can be used as a claim. The element requires the fields element(String), claimId(String) and targetId(Long). | net.democritus:Expanders::5.28.1 |
| isClaimable | <code>/.+(\.|::).+/</code> | `DataElement` | | Provides methods to claim and release instances. Value should be a reference to the claim element (.) | net.democritus:Expanders::5.28.1 |
| isStatusField | `none` | `Field` | | This field is used as a status field for a FlowElement. Adds support methods for workflows. | net.democritus:Expanders::5.28.1 |
| findByClaimed | `none` | `Finder` | | Only find instances that have been claimed with a specified claimId | net.democritus:Expanders::5.28.1 |
| findByNotClaimed | `none` | `Finder` | | Only find instances that have not been claimed | net.democritus:Expanders::5.28.1 |
| excludeStatuses | `none` | `FlowElement` | | Don't generate TaskStatus elements for this flow. | net.democritus:Expanders::5.28.1 |
| includeTimers | `none` | `FlowElement` | | Deprecated | net.democritus:Expanders::5.28.1 |
| isService | `none` | `FlowElement` | | This workflow will act as a service. Each instance being processed will return to it's original status after execution. (Replaces Service elements) | net.democritus:Expanders::5.28.1 |
| useClaims | `none` | `FlowElement` | | The engine will use claims to retrieve its batches. This prevents multiple engines from taking up the same instances. The target dataElement should be claimable. | net.democritus:Expanders::5.28.1 |
| cruds.table.pageSize | `required` <code>/unlimited|\d+(\s*,\s*\d+)*/</code> | `Application`, `ApplicationInstance`, `Component`, `DataElement` | | Set the pageSize of the table on the DataElement page, or provide multiple comma-separated values to get a dropdown. Setting it to `unlimited` will disable paging. | net.democritus:Expanders::5.28.1 |
| cruds.table.csvExportButton | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | | Adds a button to export CSV files | net.democritus:Expanders::5.28.1 |
| cruds.createWithProjection | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Adds a method to create an instance with a projection other than details. | net.democritus:Expanders::5.28.1 |
| cruds.modifyWithProjection | `none` | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Adds a method to modify an instance with a projection other than details. | net.democritus:Expanders::5.28.1 |
| cruds.bulk.delete | `none` | `Application`, `ApplicationInstance` | | Allows the user to select and delete multiple instances at once using ctrl+click, shift+click or double+click. | net.democritus:Expanders::5.28.1 |
| cruds.softDelete | `none` | `Field` | | Overrides the default delete functionality to instead use this field as a field to filter out deleted instances. The deleted instances will still be present in the database, but not visible. | net.democritus:Expanders::5.28.1 |
| cruds.softDeleteOnModify | `none` | `Application`, `ApplicationInstance` | | Delete instances on modify if a disabled field is set to false. | net.democritus:Expanders::5.28.1 |
| cruds.form.hide | `none` | `Field` | | New UI: Hide this field in all forms | net.democritus:Expanders::5.28.1 |
| cruds.form.hideOnCreate | `none` | `Field` | | New UI: Hide this field on the create form | net.democritus:Expanders::5.28.1 |
| cruds.form.hideOnModify | `none` | `Field` | | New UI: Hide this field on the edit form | net.democritus:Expanders::5.28.1 |
| cruds.form.disable | `none` | `Field` | | New UI: Disable this field in all forms | net.democritus:Expanders::5.28.1 |
| cruds.form.disableOnCreate | `none` | `Field` | | New UI: Disable this field on the create form | net.democritus:Expanders::5.28.1 |
| cruds.form.disableOnModify | `none` | `Field` | | New UI: Disable this field on the edit form | net.democritus:Expanders::5.28.1 |
| cruds.table.hide | `none` | `Field`, `CalculatedField`, `ReferenceField` | | Hide this field in the table views. Applies to both old and new UI. | net.democritus:Expanders::5.28.1 |
| finders.enableTypedFinders | `none` | `Application`, `ApplicationInstance` | | Recommended, Adds strict typing to ensure finders that finders match the target dataElement when using `find()`. | net.democritus:Expanders::5.28.1 |
| security.hstsHeader | | `Application`, `ApplicationInstance` | | Add HSTS header to each response of the control layer. (https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Strict_Transport_Security_Cheat_Sheet.html) | net.democritus:Expanders::5.28.1 |
| baseComponents.authentication.disableInternalAuth | `none` | `Application`, `ApplicationInstance`, `Application`, `ApplicationInstance` | | Prevent the internal username/password authentication from showing up in the login screen. | net.democritus:Expanders::5.28.1 |
| mvn.version.appendUniqueLabel | `none` | `Application`, `ApplicationInstance` | | Append label to versions of maven pom files to make the artifacts of this application unique. | net.democritus:Expanders::5.28.1 |
| experimental.maven.speedOverSize | `none` | `Application`, `ApplicationInstance` | | Experimental option that speeds up builds by disabling compression on ear/war | net.democritus:Expanders::5.28.1 |
| experimental.maven.useIncrementalCompilation | `none` | `Application`, `ApplicationInstance` | | Experimental option that speeds up subsequent builds of a project | net.democritus:Expanders::5.28.1 |
| hideComponentMetaInfo | `none` | `Component` | | Do not show model and customization info of this component on the application info widget. | net.democritus:Expanders::5.28.1 |
| useLogicSecurity | `none` | `Component` | | Generate authorization check in logic layer. | net.democritus:Expanders::5.28.1 |
| maven.component.isJarModule | `none` | `Component` | | Packages the logic and data layers of this component as a jar module (without beans) | net.democritus:Expanders::5.28.1 |
| cascadeDelete | `none` | `Component` | | On delete, all instances in fields with option `aggregation: composite` will also be deleted | net.democritus:Expanders::5.28.1 |
| configuration.properties | `none` | `Component` | | Generate a `{Component}ApplicationSettings` class, which reads `{component}.ns.properties` file from the classpath and exposes the configured properties. | net.democritus:Expanders::5.28.1 |
| functionalKey | `required` <code>/.+(_.+)*/</code> | `DataElement` | | Defines 1 or more fields as a functional key. These fields will be added to the dataRef of the dataElement. Add the names of the fields as value, separated by `_` (e.g. name_version). | net.democritus:Expanders::5.28.1 |
| uniqueKey | `required` <code>/.+(_.+)*/</code> | `DataElement` | | Defines a set of fields that together should be unique. Value should be field-names separated by `_`. | net.democritus:Expanders::5.28.1 |
| nameNotWanted | `none` | `DataElement` | | Will prevent the expanders from generating a `name` field | net.democritus:Expanders::5.28.1 |
| includePrepareMethod | `none` | `DataElement` | | Adds methods to the beans to prepare command or details objects for input. | net.democritus:Expanders::5.28.1 |
| insertTableIds | `required` <code>/.+(_.+)*/</code> | `DataElement` | | Adds id's to the table of target dataElement. Value should be field-names separated by `_`. | net.democritus:Expanders::5.28.1 |
| projection.detailsWithoutRefs | `none` | `DataElement` | | Include extra 'DetailsWithoutRefs' projection which will include all value fields + id of the link fields | net.democritus:Expanders::5.28.1 |
| io.export | `none` | `DataElement` | | Adds boilerplate code to export data in various formats. Automatically added is `includeCsvExport` was set. | net.democritus:Expanders::5.28.1 |
| io.import | `none` | `DataElement` | | Adds boilerplate code to import data from various formats. Automatically added is `includeCsvImport` was set. | net.democritus:Expanders::5.28.1 |
| defaultValue | `required` | `Field` | | Provides a default value for this field for new instances. Works for Strings, numbers and booleans | net.democritus:Expanders::5.28.1 |
| generateUuid | <code>/if_empty/</code> | `Field` | | Causes a new UUID to be generated and stored in this field whenever a new instance of its parent DataElement is created. Use value "if_empty" to generate a UUID only if no value was passed to the create method in the details object. | net.democritus:Expanders::5.28.1 |
| isExposedField | `none` | `Field` | | Adds additional methods to the beans to get and set the value of this field. | net.democritus:Expanders::5.28.1 |
| isNullable | `none` | `Field` | | Field is initialized as null. | net.democritus:Expanders::5.28.1 |
| isRequired | `none` | `Field` | | This field is required and thus cannot be undefined. | net.democritus:Expanders::5.28.1 |
| isVersion | `none` | `Field` | | This is a version field. The version will be updated on modification. This prevents that data is overwritten by outdated data. | net.democritus:Expanders::5.28.1 |
| validation.listField | `none` | `Field` | | Rejects any new values for this field that are not listed as a valid TagValuePair | net.democritus:Expanders::5.28.1 |
| isCustomFinder | `none` | `Finder` | | Creates custom anchors to implement a custom finder | net.democritus:Expanders::5.28.1 |
| isCustomizableFinder | `none` | `Finder` | | Adds custom anchors to the find method in the finder bean | net.democritus:Expanders::5.28.1 |
| hasBridgeClass | `required` <code>/.+\..+/</code> | `TaskElement` | | Creates an instance of another DataElement at the end of this task. Provide the java qualified name of the target element. | net.democritus:Expanders::5.28.1 |
| hasResultClass | `required` | `TaskElement` | | Changes the return type for implementations of this task. | net.democritus:Expanders::5.28.1 |
| noDelegation | `none` | `TaskElement` | | Opt-out of Task delegation. Not recommended but allows a task to be implemented in the Bean directly. | net.democritus:Expanders::5.28.1 |
| includeRemoteAccess | `none` | `TaskElement` | | Not recommended. Generates a Proxy and Agent class to execute this task. Accessible through the struts api. | net.democritus:Expanders::5.28.1 |
| includeParameters | <code>/.+\..+/</code> | `TaskElement` | | Looks at the StateTask configuration and looks up a instance of the target element to pass as parameter. Provide the java qualified name of the target element in the value of this option or in the paramClass field. | net.democritus:Expanders::5.28.1 |
| hasImplicitNameField | `none` | `DataElement` | | Automatically added by prime-core to flag DataElements with implicit name fields. | net.democritus:Expanders::5.28.1 |
| restriction.translation.nl | | `CustomRestriction`, `Digits`, `Future`, `Past`, `NotNull`, `StringLength`, `StringPattern`, `NumberBounds` | | Define an NL translation for this restriction | net.democritus:Expanders::5.28.1 |
| restriction.translation.en | | `CustomRestriction`, `Digits`, `Future`, `Past`, `NotNull`, `StringLength`, `StringPattern`, `NumberBounds` | | Define an EN translation for this restriction | net.democritus:Expanders::5.28.1 |
| csv.export (alias: includeCsvExport) | <code>/([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]*/</code> | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Target dataElement will have a REST-endpoint and dedicated page for CSV export. Useful for extracting Data. | net.democritus:Expanders::5.28.1 |
| csv.import (alias: includeCsvImport) | <code>/([a-zA-Z_$][a-zA-Z\d_$]*\.)*[a-zA-Z_$][a-zA-Z\d_$]*/</code> | `Application`, `ApplicationInstance`, `Component`, `DataElement` | `cascading` | Target dataElement will have a REST-endpoint and dedicated page for CSV import. Useful for uploading initial Data. | net.democritus:Expanders::5.28.1 |
| csv.import.merge | `none` | `Application`, `ApplicationInstance` | | Provides merging of CSV columns with existing values during import | net.democritus:Expanders::5.28.1 |
| csv.disable | `none` | `Application`, `ApplicationInstance` | | Disables CSV options for all Components and DataElements | net.democritus:Expanders::5.28.1 |
| hasTranslation | `required` | `Field`, `Finder` | | Replaces all references to the field/finder in all translation files. | net.democritus:Expanders::5.28.1 |
| view.buttons.commands | `none` | `DataElement` | | Adds a button for each command to the standard page (useful when prototyping) | net.democritus:Expanders::5.28.1 |
| hasSearchBar | <code>/.+:.+/</code> | `DataElement` | | Provides a search bar to search on a string field. Value should be `field:op` where op is the operator(eq|lt|gt|lk) (default = name:eq) | net.democritus:Expanders::5.28.1 |
| hasDisplayName | `required` <code>/.+(_.+)*/</code> | `DataElement` | | Will override the name of the element as shown in forms. This changes the name of the instance in the DataRef and may have some unintended side effect. | net.democritus:Expanders::5.28.1 |
| isLinkDriver | `required` <code>/linkTarget:\s*".+"\s*,\s*finder:\s*".+"(\s*,\s*finderField:\s*".+")?/</code> | `Field` | | UI: filters the options of another linkField based on the value selected in this field. Set the value to `linkTarget: "$targetField$", finder: "$finderForTargetElement$", finderField: "$fieldToUseInFinder$"` | net.democritus:Expanders::5.28.1 |
| view.list.multiselect | `none` | `Application`, `ApplicationInstance` | | Enable selection of multiple items. | net.democritus:Expanders::5.28.1 |
| jndi.appName | | `Application`, `ApplicationInstance` | | Change the name of the application in jndi names for beans. Should be matched by the application server settings. | net.democritus:Expanders::5.28.1 |
| view.updateFormFix | `none` | `Application`, `ApplicationInstance` | | Fixes fields not updating in edit forms by reworking triggers. | net.democritus:Expanders::5.28.1 |
| assets.implementsCustomAsset | <code>/(?i)(?!File|Internal|Remote)(?-i)[A-Z][A-Za-z0-9]+/</code> | `DataElement` | | Indicates that a DataElement represents the data for a custom asset type, equivalent to an element such as assets::FileAsset. The value of the option is used as the name of the asset type. If no value is given, the name of the DataElement is used as the asset type name. | net.democritus:base-components::2023.3.2 |
| assets.embeddedUpload | `required` <code>/FILE|INTERNAL|REMOTE/</code> (default: `FILE`) | `Field` | | When added on a linkfield to `assets::Asset`, a file upload button for the field in the generated UI instead of a combobox. | net.democritus:base-components::2023.3.2 |
| baseComponents.authentication.enableOIDC | `required` <code>/[a-zA-Z0-9]+(?:,[a-zA-Z0-9]+)*/</code> | `Application`, `ApplicationInstance` | | Enable OpenID Connect authentication for the account component. | net.democritus:base-components::2023.3.2 |
| excludeFromSqlGeneration | `none` | `Component` | | Prevents SQL queries from being generated for the component. | net.democritus:sql-expanders::3.0.1 |
| sql.structureFile.name | `required` <code>/[a-zA-z0-9\-\_]+/</code> | `ApplicationInstance` | | Defines the name of the expanded SQL file that initializes the database structure. The name should not include the extension and the default is '000-init-database'. | net.democritus:sql-expanders::3.0.1 |
| view.date.fixTimezone | `none` | `Application`, `ApplicationInstance` | | Fixes the timezone of the date input and display so that it both uses the local time. | net.democritus:web-styles::2023.1.3 |
| valueType.date.utc | `none` | `SimpleValueType` | | Represent time in UTC | net.democritus:web-styles::2023.1.3 |
<!-- anchor:options:end -->
## Additional Information
expanded with nsx-expanders:5.37.4, expansionResource org.normalizedsystems:meta-doc-expanders:1.0.0-SNAPSHOT
ValidationRules (as well as
Transmuters) are a bit special.
We create ValidationRules by implementing classes and annotating them with @ValidationRule
.
However, behind the scenes an annotation-processor creates a DataResource files describing these ValidationRules.
And thus, the ValidationRules are also available as data in the DataRegistry.
To make everything run smoothly, it's best to add some dependencies on the validation metamodel:
<dependencies>
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-core</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-test-support</artifactId>
<version>3.3.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8" ?>
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<list name="groups" eval="dataRegistry.getComposites('net.democritus.validations.ValidationGroup')"
param="group">
<value name="name" eval="group.name"/>
<value name="provider" eval="group.getMetadata('origin.expansionResource').orElse(null)"/>
<list name="rules" eval="group.rules" param="rule">
<value name="name" eval="rule.name"/>
<value name="element" eval="rule.element"/>
<value name="severity" eval="rule.severity.name"/>
<value name="description" eval="rule.description.replace('\n', ' ')"/>
</list>
</list>
</mapping>
delimiters "%", "%"
base() ::= <<
# Validation Rules
%groups:validationGroup();separator="\n\n"%
## Additional Information
%expanderComment%
>>
validationGroup(grp) ::= <<
## %grp.name%
%if(grp.provider)%
Provided by %grp.provider%
%endif%
| rule | severity | element | description |
|------|----------|---------|-------------|
%grp.rules:ruleRow();separator="\n"%
>>
ruleRow(rule) ::= <<
| %rule.name% | %rule.severity% | %rule.element% | %rule.description% |
>>
# Validation Rules
## Types
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FieldEnteredAtLastModifiedAtTypeRule | warning | elements::Field | Fields with names enteredAt or lastModifiedAt should be Dates. |
## Configuration
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| DataElementNameNotWantedNoNameOrFinderRule | error | elements::DataElement | When the option nameNotWanted is set, no 'name' field or 'findByNameEq' finder should be present. |
## Consistency
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FieldUploadUriStringFileRule | suggestion | elements::Field | A Field with name uploadUri is typically of StringFile type. |
## Security
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| EnforceHttpsRule | warning | elements::Application | Application should have the option 'security.hstsHeader' to enforce https |
| EnforceHttpMethodRule | warning | elements::Application | Application should have the option `struts.security.enforceHttpMethod` to enforce the correct method being used |
| CsrfProtectionRule | warning | elements::Application | Application should have the option `struts.security.csrfProtection` to protect against Cross-Site Request Forgery |
## Naming
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| ComponentDuplicateElementRule | error | elements::Component | No two elements in the same namespace (dataElements/taskElements/flowElements in a component, fields/finders/dataProjections in a dataElement, ...) can share the same name. |
| TaskElementNamingRule | error | elements::TaskElement | Task Element name must start with a capital letter, be alphanumeric, and not use reserved keywords. |
| FieldReservedNamingRule | error | elements::Field | Field names must not use reserved names or non-alphanumeric characters |
| DataProjectionNamingRule | error | elements::DataProjection | Data Projection name should start with uppercase letter and must not use a reserved name. |
| FieldNamingRule | suggestion | elements::Field | The first two letters of a Field's name should be lowercase characters. E.g.: 'anInvoice', 'a', 'a3', 'a2Invoice' are correct, whereas 'aPerson', 'Invoice' are incorrect. |
| ApplicationComponentNameClashRule | error | elements::Application | The name of a component is not allowed to be identical to the name of the application. |
| ComponentJavaPackageNamingRule | error | elements::Component | Package name must be valid java package name matching regex (?:[a-zA-Z][a-zA-Z0-9_]+\.)*[a-zA-Z0-9]+. |
| DataElementNamingRule | error | elements::DataElement | Data Element name must start with a capital letter, be alphanumeric, and not use reserved keywords. |
## Recommendations
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| TaskElementHasCommonOptionsRule | suggestion | elements::TaskElement | In a standard setting (in order to simulate flows in a prototype) each task should have options 'includeDelegation', 'includePerform', and 'includeRemoteAccess' |
| TypedFindersRule | suggestion | elements::Application | Enable typed finders to have better typing. This prevents you from using a finder class with the wrong agent. |
## Duplicates
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FinderDuplicatePairsRule | error | elements::Finder | Finder should not have duplicate field operator pairs. The check is performed on the operator and field, not the pair's name. |
## Deprecated
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| TaskElementUsingTargetClassRule | deprecation | elements::TaskElement | TaskElement uses targetClass, which is deprecated. It can be replaced by setting targetElement. In case of a custom projection or entirely custom class, the options `target.element.projection` and `target.class.custom` can be used. |
| JeeVersionDeprecatedRule | warning | elements::ApplicationInstance | Support for older versions of JEE is being phased out as it imposes a considerably maintenance burden and poses potential security risks in dependencies. Applications targeting these versions should be updated to a newer version such as JEE 8. |
| ServiceElementDeprecatedRule | deprecation | elements::ServiceElement | ServiceElement should no longer be used. Instead use FlowElement with option `isService`. |
| DeprecatedOptionsRule | deprecation | any | Legacy options are enabled to allow a smooth transition to newer expander version. The dependent custom code should be updated and the legacy options removed. |
| JeeVersionNoLongerSupportedRule | error | elements::ApplicationInstance | Support for older versions of JEE has been dropped as it imposes a considerably maintenance burden and poses potential security risks in dependencies. Applications targeting these versions should be updated to a newer version such as JEE 8. |
## Missing Defaults
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| ComponentIsEmptyRule | error | elements::Component | A component must contain at least one Data Element. |
| DataElementHasInfoFieldRule | warning | elements::DataElement | A data element should have at least one info field. Without any info fields, no data will be visible in the UI tables. |
## References
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FieldEnteredByLastModifiedByRule | warning | elements::Field | Fields with names enteredBy or lastModifiedBy should be link fields to the class User from net.democritus.usr package. |
| DataChildFindByParentEqRule | prError | elements::DataChild | A findBy[ParentElement]Eq must be defined on the Data Child's ChildElement. |
| DataChildHasParentReferenceRule | error | elements::DataChild | Data childs should refer to fields that are link fields to the parent element. |
| FieldFinderForOppositeLinkFieldRule | error | elements::Field | A findBy[Opposite]Eq finder must be defined for 'to N' (Ln04, Ln05, Ln06) relationships. E.g. for City { country: Country[Ln01] } >-- Country { cities: City[Ln05] } you need findByCountryEq finder on City element. |
| FlowElementShouldTargetElementFromSameComponentRule | warning | elements::FlowElement | Each Flow Element should target a Data Element from the same Component. Introduce proxy elements for DataElements of another Component. |
| FlowElementHasTaskStatusRule | prError | elements::FlowElement | Each Flow Element must have a corresponding [Target Element]TaskStatus Data Element |
| FieldCollectionRequiresBaseFieldRule | error | elements::Field | A base (reverse) link must be defined for Ln04 (Ln02), Ln05 (Ln01), and Ln06 (Ln03) link fields. |
## Required Options
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FieldIsStatusFieldRule | error | elements::FlowElement | A FlowElement requires a status field that has the option "isStatusField" and is a String to store the states. |
## Model Integrity
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| DataElementTypeRequiredRule | error | elements::DataElement | For the model of a DataElement to be technically valid, it should have a type assigned. Though the type is mostly non-functional, it is used in some conditions in expanders and validations. These conditions expect the field to not be a null value. |
## Wrong Use
Provided by net.democritus.validations.model:prime-validations::3.1.0
| rule | severity | element | description |
|------|----------|---------|-------------|
| FieldOperatorPairForCollectionFieldRule | error | elements::FieldOperatorPair | Finders cannot search in collection-type linkfields. This means all many-to-x relationships. There exists no implementation for this in the JEE application stack. |
| FieldOptionIsRequiredOnCalculatedFieldRule | warning | elements::Field | The option isRequired cannot be used for calculated fields. The option will be ignored by the expanders. |
## Additional Information
expanded with nsx-expanders:5.37.4, expansionResource org.normalizedsystems:meta-doc-expanders:1.0.0-SNAPSHOT
This version of the expanders updates the groupId
of all Maven modules in the expanded application project, to be more
consistent and configurable.
The expansion resources below provide Expanders 5.35.1
.
Resource | Version |
---|---|
Expanders | 5.35.1 |
nsx-default-stack | 2023.18.1 |
rest-jaxrs-stack | 3.28.1 |
In the past, all modules in the application project had the groupId org.normalizedsystems
, except for the ear file
module, which was org.normalized
. To finally bring some consistency into this and differentiate them from those in
other applications (to avoid collisions between base-component artifacts), this has now been changed.
The new groupId is now uniform across the entire project and is specifically org.normalizedsystems
with the
application shortname added after it in lowercase. So for shortname testApp
it is org.normalizedsystems.testapp
.
These new groupIds are merely the default settings though, it can now be configured with the application option
maven.groupId
, for which the value will be used as the groupId instead.
We've now added PascalCase as a format for all engines in the expander framework, the same way it is available for other formats.
This version of the expanders introduces improved support for imports in Expanders.
This version includes a cleanup of several of the unused imports in Expanders. It is possible you may need to add imports for classes you use in custom code after upgrading.
The expansion resources below provide Expanders 5.33.2
.
Resource | Version |
---|---|
Expanders | 5.33.2 |
nsx-default-stack | 2023.16.4 |
The mapping file syntax has been extended with 2 new keywords: artifact
and uses
.
Mapping files often had a separate list
statement to resolve imports:
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/0/0/mapping">
<list name="valueTypes"
eval="finder.fieldOperatorPairs.{ field }.{? valueField neq null }.{ javaType }"
param="javaType" unique="javaType">
<filter name="requiresImport" eval="javaType.requiresImport()"/>
<value name="qualifiedType" eval="javaType.qualifiedTypeName"/>
</list>
<list name="fields" eval="finder.fieldOperatorPairs"
param="fieldOperatorPair" filter="fieldOperatorPair.field neq null">
<let name="field" eval="fieldOperatorPair.field"/>
<value name="name" eval="field.name"/>
<!-- ... -->
</list>
<!-- ... -->
</mapping>
This can be replaced by adding uses
statements for the imported classes. The artifact
definition describes which
import resolver to use.
<mapping xmlns="https://schemas.normalizedsystems.org/xsd/expanders/2023/1/0/mapping">
<artifact this="classBuilder.from(finder).qualifiedName + 'Details'" importStrategy="java"/>
<list name="fields" eval="finder.fieldOperatorPairs"
param="fieldOperatorPair" filter="fieldOperatorPair.field neq null">
<let name="field" eval="fieldOperatorPair.field"/>
<value name="name" eval="field.name"/>
<uses eval="field.javaType"/>
<!-- ... -->
</list>
<!-- ... -->
</mapping>
The imports can then be inserted into the template with @imports
:
base() ::= <<
package <dataElement.type.packageName>;
// <expanderComment>
// anchor:imports:start
@imports
// anchor:imports:end
@anchor:imports
...
>>
Check out the article to learn more.
In this release of Expanders, we've cleaned up some long-deprecated code that still uses UserContext
as the main
context transport object. There's also been several improvements in the infrastructure to improve ease of use for
functional keys.
The expansion resources below provide Expanders 5.32.0
.
Resource | Version |
---|---|
Expanders | 5.32.0 |
nsx-default-stack | 2023.15.2 |
rest-jaxrs-stack | 3.27.0 |
FinderResolver
A new class FinderResolver
has been introduced, which is called from the Bean.find()
method in the logic layer. This
class will automatically resolve the DataRefs for any field operator pairs that target link fields. Resolving means that
it will resolve the DataRef against the database in case there's no database identifier present in it. While much of the
methods in the stack already did this, the finders still did not, which often caused some confusion. The finder would
not work as intended if the database identifier was not present in the DataRefs. This resolution will only occur if
there is no database identifier in the DataRef, so the impact on performance should be negligible in existing code.
Agent.getDetails()
The Agent.getDetails(DataRef)
method did not behave quite the same as LocalAgent.getDetails(DataRef)
. Even though
the same code was called down the line, the way it worked on the remote agent would lose all information in the DataRef
except for the database identifier. This meant that it had to be resolved prior to use. This issue has now been resolved
as well, by having it call getProjection()
instead, just like its LocalAgent
counterpart.
In a distant past, there was no Context
class, rather the only context was UserContext
ans it was used to pass all
context information. This has been replaced for years in favor of the Context
class and the UserContext
has since
only been used for actual information about the user. Therefore, we've started removing a lot of this deprecated
infrastructure that still relied on UserContext
where Context
should be used instead. Some of these methods include
Agent.getAgent(UserContext)
and LocalAgent.getLocalAgent()
.
We intend to remove a lot of clutter that has been created in the stack over the years, with methods for backwards
compatibility that should no longer be used. We've started marking many of these methods as deprecated for removal, so
it is already clear to developers that these should not be used in new code and should be refactored if they are still
in use in older code. A prime example of these are methods in the stack that still use a database identifier as a Long
parameter, rather than a DataRef. We'll be marking more of these as deprecated in future releases.
The typed finders system is now the default for all applications. The option finders.enableTypedFinders
is now no
longer required. Typed finders means that generics are used through the stack for finders, to ensure that the compiler
will verify that they are not used with infrastructure of the wrong DataElement. It also changes the FinderBean to use
mapped method references for the finder implementations, rather than reflection. This means that it is no longer
possible to defined custom finders that are not present in the model.
This release of Expanders is the final push to remove all uses of net.palver.util.Options.Option
in our JEE stack.
The expansion resources below provide Expanders 5.30.0
.
Resource | Version |
---|---|
Expanders | 5.30.1 |
nsx-default-stack | 2023.14.1 |
rest-jaxrs-stack | 3.23.0 |
Some very specific fixes were made after the release of 5.30.0
itself, hence the discrepancy in versions here. But
this is not relevant for projects that were already on 3.28.0
and use Java 17. But it is best to use the latest
versions anyway.
Options.Option
This last refactoring of Options.Option
to Optional
in the application stack required reworking code across several
projects. Extensive changes were made to nsx-runtime
, Expanders
, base-components
and alerting-component
. We did
manage however to reduce the impact of the changes to a minimum, so most projects will experience little impact from the
migration.
We did choose to introduce a hard breaking change in one location, namely the getProperty()
method of the expanded
<component>ApplicationSettings
class when the option configuration.properties
is added to a component. The use of this option is still fairly limited at this time, so it seemed better to go for some
minor refactoring in those projects that use it, than to add a new method like we did in Context
and SearchResult
.
The Options.Option
class itself will still be available for quite some time, so projects can migrate to Optional
on
their own time, but we do intend to remove it in the future.
This release of Expanders is mostly focused around changes related to Struts2, amongst which the removal of all support
for versions 2.3.x
and 2.5.x
, as well as the update to version 6.2.0
.
The expansion resources below provide Expanders 5.29.0
.
Resource | Version |
---|---|
Expanders | 5.29.0 |
nsx-default-stack | 2023.13.0 |
rest-jaxrs-stack | 3.22.0 |
We have been working towards removing support for outdated versions of Struts2 for some time now. On July 1st, the
deprecated option struts.version
expired. We've now removed all support that relied on this option to target Struts
2.3
and 2.5
. This was announced last year with the release of Expanders 5.15.0.
Struts version 6.2
was released yesterday as announced by Apache.
This version brings mostly bugfixes and some improvements, but it also comes with some breaking changes. There's no
official migration guide for this, but we've described some of these changes and the fixes in our
migration guide below. Most of these changes will however be handled by our expanders, so the
impact on projects should be fairly minimal.
With the refactoring needed for the new Struts update, we've also taken the time to revisit some of the code in our JEE
stack related to Struts and made some minor improvements. This includes replacing remaining code that still pulled the
UserContext
object directly from the session with Context
. Though UserContext
remains part of the session for now,
this might change in the future