-
Task
-
Resolution: Done
-
Major
-
None
-
None
-
None
-
5
-
2019 Week 35-37
current code generation supports "explicit" method generation of the form:
- create$ELEM
where $ELEM is the name of a process or rule unit.
the idea was to avoid intermediate control flow or data structures, such as maps or switch tables and just execute the code attached to that method.
This task proposes to *drop* this facility, since (1) this is only used internally in code generation, (2) the flat namespace makes it easier for name clashes to occur (3) it makes it harder to code against interfaces.
In contrast, we propose to adopt an interface-friendly API
Processes already do this with `findProcessById`. We propose to add the same the method for rules:
interface RuleUnits { RuleUnit<RuleUnitMemory> findById(String ruleUnitCanonicalName) }
contextually, we may also rename Processes#findProcessById to findById() since, app.processes().findById() is clear enough
and also:
interface RuleUnits { <T extends RuleUnitMemory> RuleUnit<T> RuleUnits.create(Class<T> ruleUnitMemory) }
we may also provide the same for processes:
<T extends Model> Process<T> create(Class<T> model)
Benefits:
- we will be able to write tests directly using code-generated classes, but they can stay inside of target because we do not have to reference them directly
- users can code against the interfaces
Downsides:
- it will always be possible to pass-in invalid values, e.g. Rules.create(AWrongClass.class), which may throw at runtime; however we may be able to catch the error when we compile and provide error reporting at compile time.
Users will be able to load the main Application class using
(1) CDI, if applicable
(2) some static method, e.g. Application.create() on the generic interface. This in turn will act as a stub loading the code-generated Application implementation using reflection (or dependency injection, if applicable). This is not breaking native binary generation, because we will be doing reflection of a constant class name.
IF the Application class name is not constant, we can always generate an intermediate class stub at a known place; e.g.
package a.known.place; public class ApplicationStub { public Application create(){ new group.id.Application(); } }