Expansion Runners
Expansion and harvest start in the FullCompositeExpansionRunner, which calls the ExpansionConfigurationExpansionRunner.
The ExpansionConfigurationExpansionRunner iterates over each program and then performs a number of expansion phases.
- For expansion, the phases are
initialize
,before-expansion
,expansion
,after-expansion
,overlay
andafter-overlay
- For harvest, the phases are
initialize
,before-harvest
,harvest
andafter-harvest
Expanders and AdditionalExpansionSteps are attached to a specific phase and will be executed only during that phase. For most expanders, this is the expansion
phase. (There is some extra logic that includes all expanders during the harvest phase.)
ExpansionRunners
For each phase, the ProgramComposite is passed to a ProgramExpansionRunner.
There are 3 ExpansionRunners. Each ExpansionRunner runs all applicable expanders and additionalExpansionSteps for the target element.
- ProgramExpansionRunner: Runs expansion for target program element, then executes ModuleExpansionRunner for each Module and ElementExpansionRunner for each direct child element.
- ModuleExpansionRunner: Runs expansion for target module element, then executes ElementExpansionRunner for each child element
- ElementExpansionRunner: Runs expansion for target element and executes ElementExpansionRunner for child elements
Each ExpansionRunner adds an ExpansionContext. The expansionContext wraps the expandable element and adds context information:
- ProgramExpansionContext: Adds expansionDirectory and sourceDirectory for the entire program, both calculated from the ProgramType
- ModuleExpansionContext: Adds expansionDirectory and sourceDirectory for the specific module, both calculated from the ModuleType
- ElementExpansionContext: Adds a reference to the ExpandableElementComposite, which represents the element
For backwards compatibility, it is possible to define ExpansionContext classes that replace the common ExpansionContext classes for specific elements.
ExpandableElement configuration
Each element that can be expanded is represented by data in the form of ExpandableElements. This data is expanded during the meta-expansion and provides information from the Meta-elements and options on those elements.
The ExpandableElement xml provides data for the expanders, such as the class-name, optionally a expansionContextClass, parent-element, a container-field that is to be used to get the instances from the parent element etc.
<expandableElement name="DataElement">
<component>elements</component>
<elementTypeCanonicalName>net.democritus.elements.DataElement</elementTypeCanonicalName>
<expansionContextClass>net.democritus.elements.DataElementExpansionContext</expansionContextClass>
<parentElement component="elements" name="Component"/>
<containerField>dataElements</containerField>
<isDelegate value="false"/>
<isExtendable value="true"/>
</expandableElement>
The ExpansionRunners are implemented to be completely independent of the element they are expanding. All logic is based on this data.
Filtering expanders
During each run of an ExpansionRunner, expanders are filtered based on a number of constraints:
- Is the type of the current element the same as the elementType listed on the expander?
- Is the current phase the correct phase for the expander?
For Programs and direct child elements of the Program:
- Does the layerType of the expander occur in the layerTypes defined in the programType?
- Does the technology of the expander occur in the technologies linked to the programComposite? (see enrich model step)
For Modules and their descendants:
- Does the layerType of the expander occur in the layerTypes defined in the moduleType?
- Does the technology of the expander occur in the technologies linked to the moduleComposite? (see enrich model step)