Hi, Benoit,
I have experience of extending the UML metamodel, which is very like extending a generated profile and which also uses the UML2 “operations” code generation feature.
First, the UML2 pattern provides two main benefits, as I see it: - isolating custom and generated code, which is one aim that Papyrus has had for some time. In the model, this isolation is total: as far as I know, all custom code for the implementation of operations and computed properties can be sidelined into the XyzOperations classes, and all of the code that’s in an operations class is custom code (nothing is generated that shouldn’t have @generated NOT). This is demonstrated by, for example, the Filters and Assistants models in Papyrus. In the UML metamodel you will see some @generated NOT occurrences within the XyzImpl classes for special custom behaviours that are not the implementations of modelled features (for example, destroying inapplicable stereotype applications in eBasicSetContainer). A gitignore filter can let just the operations package be committed and ignore the rest
- supporting custom code in multiple inheritance. Operations and derived properties that are generated repeatedly because UML’s multiple inheritance of classes is mapped onto Java’s single inheritance of classes results, in the EMF codegen pattern, in having to fill in TODO custom code multiple times for the same features in different XyzImpl classes. The UML2 pattern generates bodies that delegate to the static methods in the XyzOperations, which only have to be implemented once. But, redefinition is also supported by UML2 (not by Ecore), so that an operation or computed feature can be modelled as redefining an inherited feature and then a new operation is generated for it in the redefining context's operations class
(there are gaps in UML2’s pattern: custom datatype conversion is still implemented in the XyzFactoryImpl and edit item-providers are generated as in Ecore, but that’s probably not a concern for Papyrus)
In any case, we are here more concerned with the first point. For isolating generated code, I would definitely discourage option 2. It just isn’t extensible and has the same multiple-inheritance problem as Ecore, only worse, because now there are multiple XyzImpls that your custom factory’s custom impls have to subclass to create a custom impl for some class in your extending profile.
And UML2’s support for redefinition of operations and properties I think is a real plus for extending (meta)models and profiles, allowing specializations to override inherited custom code with their own.
I would advocate for all of our models in Papyrus (properties view, assistants, new-child, palette, element-types, etc.) to be designed in UML and generated with the UML2 pattern. It is difficult, if not impossible, to extend an Ecore-defined model with a UML-defined one because there’s no UML source to reference and, if the extending model imports the Ecore that it’s extending as a (local) UML model, then it won’t keep up with changes in the source Ecore. On 20 April, 2016 at 05:14:10, MAGGI Benoit (benoit.maggi@xxxxxx) wrote:
Hi,
Johan is
asking in the following bug [1] what is the good practice to
inherit/extends a profile (in our case SysML)
The main
use case it how to add an attribute in a CustomRequirement
stereotype while keeping the “hard-coded” functionalities such as
getMaster…
Did
someone has experience extending a profile (that has some custom
code inside)?
There
seems to be 3 generation options with a profile:
1 -
Generation + @generated Not
Pro:
Standard option
Con:
unclear separation between hand coded and generated (already lost
some work that were not having a generated not
indication)
2 -
Generation + override factory in extension point (The one used in
SysML 1.4)
Pro: Clear
separation of generated and hand coded files
Con: Seems
a lot of work to extend (All custom factories needs to be
re-extended)
3 –
Generation (with UML2 option) + @generated Not (but only in
specific packages named operation)
ð
Seems to be a
“middle” solution still generated not but with a little separation
from the rest of the code
Any
suggestion? It may be good to share the same approach for all
Profile used in papyrus project.
Regards,
Benoit
1 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=489151
_______________________________________________
mdt-papyrus.dev mailing list
mdt-papyrus.dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/mdt-papyrus.dev
|