Skip to main content

Making the Expander Conditional

Not all expandersExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact. and features should be applied to each element. Most expandersExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact. only run when some option is defined or a certain setting is used. For this, we can use the isApplicable condition.

Testing the condition​

By default, {Expander}Test.java will contain test methods to test this condition:

  @Test
void testIsApplicable(TestExpansion<DataElementComposite> expansion) {
expansion
.assertThatExpander()
.isApplicable();
}

@Test
@UseModel("invalidModel")
void testIsNotApplicable(TestExpansion<DataElementComposite> expansion) {
expansion
.assertThatExpander()
.isNotApplicable();
}

Let's say that the expanderExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact. should only run when the dataOption demo.includeSomeClass is added. We update the base model to contain the option. We also define an invalid model without the option to test the negative case.

@TestModel(select = "testComp::City")
Spec baseModel() {
return component("testComp",
dataElement("City",
option("demo.includeSomeClass"),
set("packageName", "net.palver.test")));
}

@TestModel(select = "testComp::City")
Spec invalidModel() {
return component("testComp",
dataElement("City"));
}

Implementing the isApplicable condition​

Next, the isApplicable condition should be implemented. To do this, we implement the condition as an OGNL expression in the xml:

<isApplicable>dataElement.getOption('demo.includeSomeClass').defined</isApplicable>
note

Each element with options has the getOption(String optionTypeName) which will return an object with a value and isDefined()/isEmpty() methods.

Context Variables​

The isApplicable condition shares most of its context variables with regular expanderExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact. mapping, namely:

  • the currently expanded element as an instance of its composite projectionProjectionA tailored subset of fields on a DataElement designed to encapsulate data for a specific technical or functional view.
    • e.g. dataElement is instance of DataElementComposite
  • expansionContext for the current element type and expanded element,
    • e.g. expansionContext is instance of DataElementExpansionContext

And convenience shortcuts:

  • applicationApplicationThe overarching model container grouping all components, domain logic, and configurations for an enterprise solution.
  • applicationInstance
  • businessLogicSettings
  • globalOptionSettings
  • presentationSettings
  • technicalInfrastructure

Note that you can access these elements by navigating through the model.

For example the following two conditions are the same (for a dataElement expanderExpanderA unit of generation that combines a data tree instance (functional M1 model) with a template to generate an artifact.):

<isApplicable>globalOptionSettings.enforceHttpMethod</isApplicable>
<isApplicable>dataElement.component.application.applicationInstance.globalOptionSettings.enforceHttpMethod</isApplicable>