Generative AI on Enterprise Cloud with NiFi and Milvus
Acceleo Best Practices - Obeo.pdf
1. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 1/16
Acceleo Best Practices
Need help to develop your code generators?
These best practices reflect the expertise (/services/code-generation-tools) of Obeo engineers who have
developped Acceleo.
They can help you develop or tune your own Acceleo-based code generators.
Contact us (/en/contact)
The following best practices apply to Acceleo 3.0.x and Acceleo 3.1.x.
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
2. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 2/16
A. Naming conventions
B. Architecture of an Acceleo project
C. Writing a good module
D. Usage of Java services
E. Preventing problems with traceability information
F. Testing an Acceleo generator
G. Managing user code
A. Naming conventions
An Acceleo project is an Eclipse plugin project and as such it should be named following this structure:
<domain><project name (optional)><kind of input (optional)><input metamodel name>gen<output language name>
Example: com.mydomain.myproject.pim.uml.gen.java
The kind of input being "pim (http://en.wikipedia.org/wiki/Platform-independent_model)" (Platform Independent
Model), "psm (http://en.wikipedia.org/wiki/Platform-specific_model)" (Platform Specific Model) or "dsl
(http://en.wikipedia.org/wiki/Domain-specific_language)" (Domain Specific Language).
A. 1. Modules, templates and queries
Acceleo modules, templates queries and variables must use camel case name starting with a lower case character.
Example: myModule, myAmazingTemplate, etc.
A. 2. Variables
Variables should also be named using a camel case name starting with a lower case "a" or "an" and followed by the
name of the type or the name of the feature.
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
3. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 3/16
Example: aVariable, anElement, anOwnedComment.
A. 3. Reserved Keywords
Do not use any OCL or Acceleo keyword for the name of your modules, templates, queries or variables.
Acceleo keywords: module, import, extends, template, query, public, private, protected, guard, init,overrides,
each, before, after, for, if, elseif, else, let, elselet, trace, macro,file, mode, text_explicit, code_explicit, super,
stdout
OCL keywords: and, body, context, def, derive, else, end, if, endpackage, false, if, implies, in, init, inv, invalid,
let, not, null, or, package, post, pre, self, static, then, true, xor
B. Architecture of an Acceleo project
B. 1. Root package
The root package of an Acceleo project should share the same name as the project.
Example: com.mydomain.myproject.pim.uml.gen.java
B. 2. Organization of the packages
Every Acceleo project should contain several key packages.
main (this package contains all the module with main templates and their matching launcher class)
files (this package contains all the module that will generate a file)
common (this package contains all the utility modules)
request (this packages contains all the modules that contains utility requests on the input model)
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
4. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 4/16
services (this package contains all the modules that wrapped Java classes)
properties (this packages contains all the properties files)
(/images/products/screenshots/acceleo/ProjectStructure.png)
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
5. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 5/16
Example: the module generating a Java class could be named "classFile" and it should be in the package named
"files". All the other modules related to the generation of the Java class can be contained in the package
"common.classfile" for example "imports.mtl", "attributes.mtl", methods.mtl" etc.
B. 3. Exporting packages
The main package, the properties package and the service package should be exported. Java services will not work
when the generator is deployed if the package containing those package is not exported in the MANIFEST.MF
(runtime tab). It is recommended to export all the other packages but to keep them "hidden from all the plugins".
C. Writing a good module
When writing an Acceleo module, there are some rules that should be respected:
C. 1. Null in Acceleo
In Acceleo and in OCL, "null" is "OclUndefined", when you are testing for a "null" variable, you should use
"isOclUndefined()".
C. 2. Let block
In Acceleo, the "let" block is strictly equals to an 'if instanceof". For example, those two expressions are equals: "[let
x: Type = myExpression]|x.doSomething()/][/let]" and "[if (myExpression.oclIsKindOf(Type))]
[myExpression.oclAsType(Type).doSomething()/][/if]". Keep in mind that if your expression initializing the "let
variable" returns null, then Acceleo will not enter the "let block".
C. 3. Features named as a reserved keyword
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
6. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 6/16
Do not use Acceleo or OCL keywords in your expressions, for example, if you have to manipulate a feature named
body, instead of [myElement.body/] you should use [myElement._body/] since body is an OCL keyword.
C. 4. Context in Acceleo blocks
Do not use the implicit context to call an operation [myOperation()], always use an explicit variable
[myVariable.myOperation()/]. In this example, you can see what Acceleo will call with implicit variable. The result may
not be what you had in mind.
(/images/products/screenshots/acceleo/Implicit.png)
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
7. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 7/16
C. 5. Implicit variables
you should always use Acceleo operation with an explicit source for the operation
[myExplicitSource.myOperation(myFirstParameter, mySecondParameter)/] and not an implicit source
[myOperation(myFirstParameter, mySecondParameter)/]. If the operation does not have an implicit source, you may
not easily know which template or query will be called as you can see it in this example.
(/images/products/screenshots/acceleo/ImplicitSource.png)
C. 6. Documentation
Acceleo 3.1 has introduced a documentation block, it should be use to write the documentation of the templates,
queries, modules and variables.
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
8. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 8/16
(http://api.ning.com:80/files/BMK20lP7yF1**OY25c0CFc*1tnxa9IrvUQ3lZku6BJ*vBfCpaMo-
4oVIEY7LaBpXpdW1ALPLh50Im8eq2C8uU1WjJMhTd*ct/Documentation.png)
(/images/products/screenshots/acceleo/Documentation.png)
C. 7. Metrics
An Acceleo module should follow the same conventions regarding its metric as a Java class. It is thus not
recommended to have an Acceleo module with more than 30 templates and queries or with several thousands lines.
C. 8. Use of the qualified name to import or extend a module.
All the "import" or "extend" declaration should always use the qualified name of the imported or extended module
[import com::mydomain::myproject:: (...) ::myModule/] and not the simple name [myModule/]. If you use the simple
name, the first module found with the same simple name will be used.
(/images/products/screenshots/acceleo/Imports.png)
C. 9. Polymorphism
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
9. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 9/16
Polymorphism should be preferred to "[for ()] [if (a.oclIsKindOf(A))][elseif (a.oclIsKindOf(B))][elseif (a.oclIsKindOf(C))]
[/if] [/for]". If the common parent of all the type concerned by the polymorphism on a template does not generate
anything, it should at least generate a comment indicating that the given element is not taken into account.
(/images/products/screenshots/acceleo/Polymorphism.png)
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
10. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 10/16
C. 10. Generated file name
When generating a file, the path of the file should be calculated by a query. It is recommended to use queries to
calculate repetitive piece of code because a query will keep its result in cache (if you call the query again with the
same parameter, Acceleo will not re-evaluate the query, it will return the result of the query during the previous
evaluation with the same parameter).
C. 11. Granularity of an Acceleo module
While writing a module, you should think about the re-use of your generator. As such, it is recommended to have a
very small granularity for your templates even if it seems trivial. In the following example, you can see a template to
generate the name of any NamedElement. One would imagine that a template like this would be useless but if you
want to change the naming convention of all the element of your generator, you just have one template to change or
to override.
C. 12. Usage of the visibility of templates and queries
Templates and queries have a visibility, it is recommended to use as much as possible the private and protected
visibility in order to minimize the amount of template and queries in the API of the generator.
C. 13. Parenthesis in "for" and "let" blocks
Parenthesis in the "if" and "for" block should always be used.
C. 14. Entry point of a generation
It is strongly recommended to start a generation with only one entry point. In order to improve performances, there
should be at best only one main module with only one main template and this main template should take the whole
model to prevent several call to this main template. Each call to a main template by Acceleo will launch a new
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
11. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 11/16
initialization of the context of the generation and it can have an impact on the generation (the cache of the queries is
cleared, the cross referencer used for "eInverse()" is cleared too, etc).
C. 15. New cast to EObject except while generating on Ecore
If you are not generating on the Ecore metamodel (http://www.eclipse.org/2002/Ecore
(http://www.eclipse.org/2002/Ecore)), you should not try to cast anything to one of Ecore classes. If you want to
define a very generic template, you should use OclAny as the type of your variables.
C. 16. Comparing enumeration literals
In order to compare an enumeration literal, you have to do: MyObject.myEnumValue =
MyEumeration::myEnumerationLiteral.
C. 17. Manipulation of the result of a Java services
It is highly recommanded not to manipulate directly the result of an "invoke" but instead, to return the raw result as
the result of the query and then manipulate the result of the query. In the following screenshot, the result of the
query seems to be a Sequence of String while it is in reality a Sequence of Sequence of String.
The operation will return a Sequence of String (List<String> in the Java operation) but the Acceleo parser uses the
signature of the operation invoke, as such the result is "OclAny" (the engine will make sure that this OclAny is a
Sequence of String in reality). By using the type OclAny, the parser sees OclAny->asSequence() and thus the
operation is compiled as Set(OclAny)->asSequence(). When the engine executes the call to "invoke", its result
"replaces" the OclAny and as a result we obtain a Set(Sequence(String)) which is then pass to "->asSequence()" and
the final result is "Sequence(Sequence(String))".
C. 18. Defining constants
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
12. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 12/16
In order to define constants for an Acceleo generator, it is recommended to use properties files. If you want to know
more about properties files, have a look at the properties files guide (http://www.obeonetwork.com/page/acceleo-
properties-files) for Acceleo 3.1.1+
C. 19. Performances
Some operations in Acceleo can be time consuming and as such it is recommended to embed them inside of a query
to take advantage of the cache of the query. Among those operations, you can find "eAllContents()",
"eAllContents(OclType)" which are both iterating on the whole subtree of the current model element and "eInverse()"
which needs to initialize a cross referencer on the whole model the first time it is used.
D. Usage of Java services
D. 1. Role of Java services
Java services should be used to query the model and to filter the element of the model. It is not recommended to
use Java services to return large amount of text. The text should be generated by Acceleo templates.
D. 2. Java services and queries
Java services should be wrapped in a query in order to minimize their impact in the generation by having a cache of
their result and so as to only manipulate Acceleo concepts (templates and queries) in most of the generator.
D. 3. Java services and primitive type
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
13. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 13/16
It is recommended to minimize the use of Acceleo primitive as input parameter or output of Java services.
D. 4. Integration of Java services
Java services should not be called directly from a template without being wrapped in a query.
E. Preventing problems with traceability
information
In order to prevent problems with the traceability information calculated by Acceleo some conventions need to be
followed.
E. 1. Modification of the generated code
The generated text should not be heavily modified. Any modification of the generated code will create problems with
the traceability information calculated by Acceleo. Obeo Traceability can handle some modifications of the
generated code but a massive change of the generated code like the use of a formatter on the generated code
would create massive gaps between the traceability information and the code. The formatting of the generated code
should be handle by formatting correctly the Acceleo templates.
E. 2. Java services and traceability information
It is recommended not to use Java services to generated code. Java services should be use to query the model and
return one or several model elements. The code should be generated by Acceleo templates. Java services that are
taking primitive types as parameter (int, string, float, char, etc.) and that are returning a primitive type too can create
problems to the traceability information. In order to link the values returned by a Java service it is recommended to
use at least one element from the model.
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
14. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 14/16
E. 3. Parameters of templates an queries
The use of templates or queries without any parameters is also not recommended. In order to link the generated
text with a model element, Acceleo needs a model element as a parameter of the template or the query.
F. Testing an Acceleo generator
Like any project, a code generator evolves and to make sure that regression are detected it is recommended to
maintain along with the generator a test project with a non regression model. This non regression model should
contain all the type of model elements that are being handled by the generator. The test project should also contain
the code generated form this non regression model with the generator. When a modification of the generator is
done, the new generator should be launched once again with the non regression model as its input and then the
new generated code should be compared with the old generated code to ensure that no features of the code
generator has broke.
G. Managing user code
One of the key best practices in code generation is to generate code as if you would write it manually.
Nevertheless, mixing generated code and hand-written code in the same file is one of the main causes of
desynchronization between model and generated code. The traceability functionnality reduces this risk, but it can't
solve all the cases of desynchronization.
To minimize this risk, when it does not alter the quality or the performance of the code, you can break the rule
mentionned previously, by separating generated code and hand-written code in different files. There exists several
patterns depending on the implementation language (subclassing generated classes by hand-written classes in java,
partial classes in C#).
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)
15. 21/9/22, 15:33 Acceleo Best Practices - Obeo
https://www.obeosoft.com/en/acceleo-best-practices 15/16
/ Home (/en/) / Acceleo Best Practices
Solutions (/en/solutions)
Systems Engineering (/en/solutions/systems-
engineering)
Enterprise Architecture (/en/solutions/digital-
transformation)
Software Development (/en/solutions/software-
factories)
Other Domains
(https://www.obeodesigner.com/en/services)
Products (/en/products)
Obeo SmartEA (http://www.obeosmartea.com)
Obeo Designer (http://www.obeodesigner.com)
Team for Capella (/en/capella-professional-
offer#collaboration)
Sirius
(http://www.obeodesigner.com/product/sirius)
Acceleo (http://www.eclipse.org/acceleo)
UML Designer (http://www.umldesigner.org)
M2Doc (http://www.m2doc.org/)
Obeo Enterprise for POOSL (/en/obeo-enterprise-
for-poosl)
Information System Designer (/en/products/is-
designer)
Services (/en/services)
Training (/en/services/training)
Coaching (/en/services/coaching)
Custom Development (/en/services/custom-
development)
Support & Maintenance (/en/services/support-
maintenance)
Modeling Tools
(https://www.obeodesigner.com/en/services)
Code Generation Tools (/en/services/code-
generation-tools)
Eclipse Plug-ins (/en/services/plugins)
Ressources (/fr/communaute)
Blog (https://blog.obeosoft.com)
Videos
(https://www.youtube.com/user/obeocorp)
Presentations
(https://fr.slideshare.net/Obeo_corp/clipboards)
Github - Obeo Network
(https://github.com/ObeoNetwork)
Company (/en/company)
About us (/en/company#about-us)
Customers (/en/company/customers)
Partners (/en/company/partners)
ter.com/obeo_corp)
youtube.com/user/obeocorp)
.obeosoft.com)
ontact)