Search code examples
eclipseemfacceleoocl

Acceleo Collection of Collections


I have defined this query

[query public genCascadePath(aCSharpResourceModel : CSharpResourceModel) : Sequence(Sequence(CSharpResourceModel)) =
    aCSharpResourceModel.hasRelatedCSharpRMManager->collect(rmm | rmm.hasRelatedCSharpRModel->asSequence()->prepend(aCSharpResourceModel))
/]

What I actually do is:

  1. get a sequence from the "aCSharpModel"

  2. for each element in this sequence, I define it as a sequence, and prepend another element (the rmm.hasRelatedCSharpRModel inside the collect is irrelevant, it's just a 1 to 1 relationship)

So I need something like this:

{element} -> {{element , element1},{element, element2}}

But when I try to access each of the inner sequences in the result from a template, ex:

[for (path :Sequence(CSharpResourceModel) | aCSharpResourceModelManager.hasRelatedCSharpRModel.genCascadePath())  separator(' -> \n')]
[/for]

I get an error :

org.eclipse.acceleo.engine.AcceleoEvaluationException: Invalid type for iteration at line 18 in Module TODODbResourceRepositoryCSharpFile for block for (genCascadePath(aCSharpResourceModelManager.hasRelatedCSharpRModel)) separator(' -> '). org.eclipse.emf.ecore.impl.DynamicEObjectImpl was not an instanceof Sequence(CSharpResourceModel).

If I try to do the same for loop, but with the iterator as type CSharpResourceModel instead of Sequence(CSharpResourceModel), it doesn't produce an error, but it treats my query's result as a single sequence, like a flattened one.

The thing is that I need to have the behavior I described at the start.

How can I achieve that?

Thank you.


Solution

  • In OCL, "collect" will flatten the result. The operation "collectNested" should be used if you don't want a flattened result. See the Acceleo documentation for more information.