|Collections and typecasting... [message #987427]
||Mon, 26 November 2012 15:03
| Carsten Reckord
Registered: June 2012
I'm still having fun with QVT/OCL and UML profiles. I have a profile that
defines a Stereotype MyStereo that has a to-n reference to NamedElement:
usages : NamedElement[*];
Now, in an inplace QVTO transformation I'm working with elements that have
MyStereo applied and I want to 1) access and 2) add to the MyStereo::usages
I've tried several ways, but always hit a dead end at some typecast or
other. I can get the value typed as OclAny with
var stereo := self.getAppliedStereotype("MyProfile::MyStereo");
var value := self.getValue(stereo, "usages");
but then I don't know how to proceed to work with it as a Collection. I can
get a collection of the correct type doing something like
var usages := value.oclAsSet()->flatten()->selectByKind(NamedElement);
But the resulting Set is no longer the original collection. So when adding
an element to it with e.g.
I guess I have to set the resulting collection back on the Stereotype.
Unfortunately, this doesn't work:
self.setValue(stereo, "usages", usages);
"Cannot find operation (setValue(Stereotype, String,
Collection(NamedElement))) for the type Element"
I can't figure out how to cast usages so the setValue() operation is applicable.
Going the other way round by directly casting value to the correct type
doesn't work either. From what I could gather by stepping through the
parser, it's due to the known issues with type expressions. This:
var usages := value.oclAsType(Collection(NamedElement));
gives me "Unrecognized Variable: (Collection)" because it's resolved as a
variable expression instead of a collection type literal.
Do you have any suggestions for another, working way to add something into a
|Re: Collections and typecasting... [message #987457 is a reply to message #987441]
||Mon, 26 November 2012 16:54
| Ed Willink
Registered: July 2009
I'm afraid you're hitting one of the limitations of the Ecore-based OCL,
which endeavours to deduce types from values and compensates the
commonest errors with a strange heuristic. The problem is that eGet()
returns Object for Collections requiring the heuristic compensation.
(The new Pivot-based approach retains static type information for eGet
and stereotypes so that the correct behaviour is achievable without
This doesn't help you today.
I recommend using a Java function with a clear name so that you can take
control. If you try tricking the compiler/evaluator you will just move
from one strange combination to another.
On 26/11/2012 15:54, Carsten Reckord wrote:
> tl;dr; - What it seems to come down to is this:
> How can I cast a variable of type Collection(NamedElement) to OclAny?
> var stereo := self.getAppliedStereotype("MyProfile::MyStereo");
> var value := self.getValue(stereo, "usages");
> var usages := value.oclAsSet()->flatten()->selectByKind(NamedElement);
> var x : OclAny := usages.oclAsType(OclAny);
> self.setValue(stereo, "usages", x);
> Here, the cast 'usages.oclAsType(OclAny)' only seems to change the member
> type of the collection, resulting in this error:
> Type mismatch: can not convert from 'MyTrafo::Collection(NamedElement)'
> to 'oclstdlib::OclAny' type
Powered by FUDForum
. Page generated in 0.03540 seconds