Closed carstenSpraener closed 1 year ago
When grouping this aspects into small pieces, a code generator could now look like:
def myClass = (MClass)getProperty("ModelElement");
ClassTarget classTarget = new JavaClassTarget(myClass.getName(), myClass.getPackage());
myClass.applyDeclarationAspects(myClass, classTarget);
myClass.attributes.forEach {
applyAttributeAspects(it, myClass, classTarget);
}
myClass.associations.forEach {
applyAssociationAspects(it, myClass, classTarget);
}
myClass.dependencies.forEach {
applyDependencyAspects(it, myClass, classTarget);
}
return classTarget.evaluate();
To minimize the risk, this feature could be implemented in the PoJo or Rest cartridge and from there seep into the core. This way the implementation can not break the current implementation of the meta cartridge, which is a main component of cgV19.
The PoJo cartridge is very simple but limited to java. The REST cartridge is way more complicated but also has generators for TypeScript and PHP. That will help to identify common needs for different target languages.
So the feature should be implemented in an cgV19-oom package in the cgv19-restcartridge module. That will make it easy to migrate it later into the cgv19-oom module when it is out of incubator state.
This way it can be started to implement on a sub branch of Release-23 branch and merged into the release when it is finished.
With the concept of Target->Section->Snippet it should be possible to request a Section in a Target by an ModelElement. So a CodeGenerator for Entities working onMClass entityClass
could use a PoJo-Generator and do the following:
MClass entityClass = getProperty("MClass");
// Use the PoJoGenerator from another Cartridge to build a base Java Class with all its
// imports, inheritance, implementations ...
ClassTarget entityTarget = PoJoGenerator.buildTarget(entityClass);
Now add the Aspect of JPA-Mapping to the created ClassTarget:
entityTarget.getSection(JavaSection.IMPORTS)
.getSnippet(PoJoGenerator.ASPECT_STANDARD_IMPORTS)
.insertAfter(ASPECT_JPA, "import javax.persistence.*");
Before the class declaration there have to be some entity annotations
entityTarget.getSection(JavaSection.CLASS_DECLARATION)
.getSnippet(PoJoGenerator.ASPECT_CLASS, entityClass)
.insertBefore(ASPECT_JPA, "@Entity", "@Table(\"${getTabelName(entityClass)}\"");
Each attribute needs some JPA-Mapping information
for( MAttribute attr : entityClass.getAttributes() ) {
entityTarget.getSection(JavaSection.ATTRIBUTES)
.getSnippetFor(PoJoGenerator.ASPECT_ATTRIBUTE, anAttribute)
.insertBefore(ASPECT_JPA, " @Column");
}
This includes:
The root is a Target
A Target has several Sections
A Section is referenced by an ID which is a constant value of some known Generator
A Section has a collection of Snippets
a Snippet can be referenced by an Aspect and a ModelElement
a new Snippet can be added before or after an existing Snippet.
a Snippet can be replaced with another Snippet
Release 23.1 contains this feature
When writing templates for code generators a certain aspect, that needs to be handled results in many output targets. To make this more clear take a look at the following situation:
In The model is a Class A that has a reference to another Class B. Like this
A <>------myB-> B
A and B my not in the same package. To generate this in Java, TypeScript, PHP or most other language there are several areas in the target code related to this aspect:With the current template technique this aspects will spread into several section/methods of the template. The implementation of this aggregation spreads out to more than one point.
To avoid this there should be some kind of structure that allows to apply sinppets to several sections of a target code and evaluate them, when the handling of all modled aspects is done.
So a implementation of such an aggregation aspect should look like:
So the CodeGenerator can now look like:
Each section in a ClassTarget should have different requirements/behaviour.