0

In an Acceleo Model to Text transformation I would like to create a file for a UML class coherent with the packages of containing the class (the class namespace in the UML model). The problem I am facing is that I have to do that in line as the [file] command requires it so I am trying something like this

[file ((c.allOwningPackages().name.->sep('/')).concat(c.name.concat('.hpp')),false,'UTF-8')]

but I am getting this error on the concat:

 Cannot find operation (concat(String)) for the type (OclAny)

What is the right way of doing this?

Andrea Sindico
  • 7,358
  • 6
  • 47
  • 84

1 Answers1

1

It is not mandatory to do it on the same line as the file block. The two usual ways to accomplish what you are trying to do are to

  • nest the file block into a let block or
  • extract the logic into another template or query.

For your example, b) would give something of the sort :

[template public myMainTemplate(c : uml::Class)]
    [file (getpackage(c), false, 'UTF-8')]
        ...
    [/file]
[/template]

[template private getPackage(c : uml::Class) post(trim())]
    [c.ancestors()->reverse()->sep('/')->including(c.name.concat('.hpp'))/]
[/template]

Note the use of "->including" instead of ".concat" for collections which is the reason why you had your error message. Of course, this was only to have all inside one single expression. It might be more readable as :

[template private getPackage(c : uml::Class) post(trim())]
    [c.ancestors()->reverse()->sep('/')/]/[c.name/].hpp
[/template]
Kellindil
  • 4,523
  • 21
  • 20
  • Thank you. However the c.ancestors()->reverse() operation does not provide a meaningful result to me. I have used c.allOwningPackages().name->sep('/') and it works as you suggested. The key was putting anything I needed in a different template, I don't know why I thought it was not possible to invoke template in the file block :) again thanks – Andrea Sindico Jul 12 '12 at 14:49