M2DOC: (Literal)NumericValue : Discrepancies between Sirius Interpreter and m2doc and avoidable casting?

Hi,

  • in Sirius Interpreter {m: class.containedProperties.ownedMinCard} results into LiteralNumericValue and thus {m: classAttribute.ownedMinCard.value} obtains this value, e.g. the String “1”.
  • in m2doc the former results in “LiteralNumericValue[TRANSIENT]” but the latter generates and error “Invalid query statement: Feature value not found in EClass NumericValue”

Now, this is caused probably by having in CapellaCore.ecore MultiplicityElement::ownedMinCard : NumericValue but setting it to LiteralNumericValue, so that the actual value of ownedMin/MaxCard can be obtained in m2Doc by casting class.containedProperties.ownedMinCard.oclAsType(datavalue::LiteralNumericValue).value.

This, and other similar intricacies, make the actual usage of m2doc more tedious than it needs to be. Is there a special reason for not having the type of MultiplicityElement::ownedMin/MaxCard to be LiteralNumericValue instead of NumericValue?

br
Marek

This is related to the way the Capella metamodel was designed. By looking at the core/plugins/org.polarsys.capella.core.data.gen/model/Information.ecore You can see that the EReference ownedMinCard type is NumericValue and this EClass is abstract. So the reference can be any sub EClass of this type (BinaryExpression, UnaryExpression, LiteralNumericValue, NumericReference). In this list of EClasses only one has an EStructuralFeature named value.
When validating M2Doc or more specificaly AQL tells you it doesn’t know the feature value for the EClass NumericValue which is totally normal. At runtime you might or might not get an error depending on your model. If you only have LiteralNumericValue then everything will be fine at runtime. But the only way for M2Doc/AQL to know that at validation time is an explicit cast.
A more resilient way of dealing with this design would be a service that receive the value of any NumericValue. By looking at the ./core/plugins/org.polarsys.capella.core.sirius.analysis/description/common.odesign (definition of Sirius editor used in Capella) I can see that a service called getDatavalueLabel() is used, it is declared in the class org.polarsys.capella.core.sirius.analysis.InformationServices. You should probably use this service by importing the class in your template and calling it:
{m:class.containedProperties.ownedMinCard.getDatavalueLabel()}

I think I will had those classes to the Capella token accessible in the template properties wizard:

Hi,

thanks, it was clear to me that plymorphism (LSP) is used here. In the model there are only LIteralNumericValue as this is set in teh Capella UI editors, obviously. So tha cast via oclAsType() should always work. The service getDatavalueLabel() is not available (I have added all sirius nsURIs…). Imho, anyway, the design of the metamodel is flawed - NumericValue shoudl of course have an operation to get the actual value, which should be implemented in each subclass. If this OO principle is not possible in an EClass, than, as you rightly proposed, a service should be provided to get the value. Until it becomes available, the above mentioned cast should do.