Types returned by : fromHTMLBodyString() and replaceLink()

I am trying the following code :

m:let TEXT1= U3.description.trim().fromHTMLBodyString().replaceLink(U3)
m:if TEXT1 = 'ID'
Write something

I also tried

 m:let TEXT1= U3.description.trim().fromHTMLBodyString()
 m:if TEXT1 = 'ID'
 Write something

However the comparison does not seem to work.
I know that TEXT1 here is 'ID", yet the comparison does not work.
Do this 2 functions not return a string, explaining why the comparisons are failing?
I tried to check these, but wasn’t able to identify a solution:
M2DocHTMLServices - M2Doc
M2DocGenServices - M2Doc


Edit : I usually check for types on the Capella interpreter, however the M2DOC interpreter does not show the returned “type”.

The fromHTMLBodyString() returns a Sequence of MElement.
And yes, that’s why the comparison fails.

To manipulate such elements you will need to create a Java service. MElement should be converted to EObject to be used without services. The is a bug opened for this:

I am note quite familiar with creating java services, don’t know the how/where/when. My coding experience is mainly Python and C++.
Thank you for your response

I don’t know if I should make a new post to continue here, i would like to point out 2 things:

  1. In the M2DOC documentation nightly ( Reference Documentation - M2Doc), some links do not work.
    For instance in:

An example of implementation can be found in the Sirius integration plug-in see the class SiriusConfigurationProvider and the extension in the plugin .xml.

SiriusConfigurationProvider lead to an empty page.

  1. A) In 2019, you said that you would create a service that returns the “element of interest” in Capella (here:https:// stackoverflow. com/questions/59457543/how-can-i-access-to-the-dannotation-eoi-of-a-diagram-elements-of-interest-with )

It this the one : (((((https:// www.m2doc. org/ref-doc/nightly/m2doc_service_semanticbrowserservices.html#orgpolarsyskitalphaemdemodelelementgetelementofinterestfordiagram–sequenceeobject)))))

  1. B) I usually use the “selection” or “selection.eClass()” to obtain the class of an element in my model, however the “element of interest” is not something that can be selected. How was it possible to establish that “element of interest” is actually a DAnnotation?

Same question for all other elements of the model that are not clickable.

  1. C) When tryign to add the service related to the element of interest manually, it was impossible., Whether i have written ( getElementsOfInterest()) in the research bar, or SemanticBrowserServices, or even the full link org.eclipse.sirius.viewpoint, DRepresentationDescriptor.getElementsOfInterest(), nothing would show under the research bar. Only when selecting “Capella” package that i got all the services shown below.

    This begs the question, how to actually add a single service… without having to tick the capella package box.

  2. As I said earlier, I am quite used to Python & C++, however I never had to code a Java service or anything similar, I would not know where to start it. Maybe the missing page/link in my question number 1, would help? That’s an example of a full service?
    From my understanding, i am guessing that creating a service can be done through Capella Studio maybe (following a tutorial similar to this one? https:// www.youtube. com/watch?v=NWCyKsPfc2Y ) or with Capella, following a tutorial similar to this one? ( Add Menu · eclipse/capella Wiki · GitHub ) and configuring org.eclipse.ui.commands and org.eclipse.ui.menus, but both examples seems to be targeting the developpemnt of a full add-on, rather than a service. Is creating a service for M2DOC a much simpler task? I would have loved to be guided through the process, eventhough this might be out of the scope of document generation? I am not sure. Instead, maybe get hints/guides where to start actually.

  1. Thank you I fixed the documentation.

2.A) Yes I think it should return the same objects.

2.B) I had to look at the code of Capella and the XMI .aird model to find how this information was stored. I made a copy of the model to use as reference then added an element of interest and compared the two files.

2.C) You need to search for SemanticBrowserServices, but if you don’t have the class in your workspace nor you template is inside a plug-in project that depend on org.obeonetwork.capella.m2doc.aql.queries, you will not be able to import it. You can edit the custom properties with MS Word and set:

 package org.obeonetwork.capella.m2doc.aql.queries.SemanticBrowserServices
  1. Using an IServicesConfigurator is not mandatory to create a service. But you will need to be familliar with plug-in development and build. You can have a look at the Capella extensions on github to see how it is done. The build is done using maven and run using github action.

The viewpoint generates plug-ins but not what you will need here. But yes the Plug-in development perspective and plug-in project will be needed. A good starting point can be found here. And yes you should be able to do all this with the Capella studio.

1 Like

I made a service Java in Capella Studio correctly, I was able to call it using one of the aql fields (service:MyFunction()). Now to transfert this java service into M2DOC template I believe that, in the case of no custom constructor ( Reference Documentation - M2Doc), then I need to do it through Template wizard ( Reference Documentation - M2Doc). Question: How am I supposed to transfert a function I made within a viewpoint in Capella studio to the menu of “Edit Template Properties” and add it to the services run by my template? Am I supposed to “pack” the function into some file or something…I don’t see how that works. Reminder: The java service I made was defined within a “java extension”:

I don’t use Maven nor interact with github, it is still possible to pack the function into my template?

Your service should be a Java Method into a class. This method should at least have one parameter. You can then import it with the template properties wizard. You will probably need to have the project containing your service class in your workspace. Then you can start typing the name of your class and it should show up in the dialog.

Then you will be able to use it like this in your template:


If you have more than one parameters:

myObject.myService(param2, parma3, ...)

Yes the plug-in containing the service must be installed if you want to use it outside your development environment. In your development environment it should be accessible if the class is compiled without error.

1 Like

Very interesting, indeed the project containing the service class open in the workspace made it possible to add the java service. It went smooth! Perfect.
Question: isn’t there a simpler way to pack the function? I will always have to ask an M2DOC user to “open” a workspace containing my JS?

To be honest with you I thought I had to add the name of the function (NEW6()) in the template properties wizard,

A Java Function


In reality it was the name of the J extension.

Thanks a lot! This was a mystery for me for a long time.

Edit: 3 days later,
Question about this:

The first function takes a “Capability” as a parameter and the second function takes “CapellaElement”, I added the JS with “edit Template properties”.
And the JS shows no “error”.
Why would my item “UCD” here, not accept/recognize my functions?

For distributing the template and the service you will need to include them to your update site. The service is a simple Java class that can be included in an plug-in. You can also add the template to this plug-in and declare the following extension point in your plugin.xml file. Then you can create a .genconf file and select it by using the browse registry button, you can also import it in your workspace for modifications see the link above.

For the Java service not being resolved, You need to have the metamodel declaring used EClass referenced in your template. Use the template properties wizard and check/add needed nsURIs. Your method also need to be public and should look somethink like this:

public Test1(Capalility capability) {

Note: naming convention from Java the service should not start with a capital letter.

and the value of the UCD variable should be an instance of Capability or one of it sub types. Otherwise AQL will not resolve the service since it signature doesn’t match.

1 Like

Interesting! Thank you

Well I thought I had only to add the JS with the TPWizard?
In any case, when i go the nsURIs tab, and I filter by “name of my class”, “name of my function” or “name of my extension” I see no new available nsURI to add?


It is!

I actually was able to make a JS work fine, when the param was Eobject and returned simply a string.

It is! Look:
ctx::Capability is “Capability” right?

However something wrong, here is the result for 3 similar functions:

They all have the same “return” and type. Only first one works.

First one has Eobject as a param → works fine
Second one has Capability → Error
Third one: CapellaElement → Error

Although both are sucessfully imported I believe:

import org.polarsys.capella.core.data.capellacore.CapellaElement;
import org.polarsys.capella.core.data.ctx.Capability;

AQL is only able to resolve types declared in its context. So you need to add the nsURIs for capellacore and ctx or make sure they are imported:


Change the version number to fit your version of Capella.

If you look in the Java package org.polarsys.capella.core.data.capellacore you will see a class CapellacorePackage the EPackage (or metamodel) for this part of Capella and it declare the nsURI you need to use.

I am on 5.1 but only 5.0.0 is available, I suppose that’s the version for all Capella 5.X (X>=0)
Well, I have them:

I think “checking” the ‘Capella’ checkbox in the first tab of the wizard, make them all part of the template.

It seems like M2Doc is able to load the Class with your services so maybe it has not been compiled since you added the last two services. Can you check if you have enable the automatic build:


I actually made sure any change in the JS’s is take, in account by Capella (thus by M2DOC?),
Right now I am just having the workspace of my JS open at the same time as my Capella projects (like you described the other time)
So I found out that, any change in the JS, can only be effective when you “restart” Capella. Not a big deal, that works for me. I also made sure to create everytime new functions to test them and to see if the new class is well incorporated, it seems so.

In any case build automatically is “ON”:

That’s strange because the class is loaded each time a generation is launched. On the M2Doc interperter view there is a refresh button to reload the template context so this kind of change can be taken into account.

Maybe you have the service in one workspace and start a runtime with the M2Doc template ? In this case a restart is needed unless you start your runtime in debug and the code might be hot swapped.

Just retried it to be sure:
Changed the value returned into:
(–> I added “3” as an extra character)

And regenerated here:

(service not updated)

Now, I restarted Capella and re regnerated a new word doc:

This time the new return value has been updated (notice the extra “3” character).
Maybe it has something to do with the fact i have an error, thus making M2DOC somehow reload older version of services somehow to be faster or something?
Or maybe because I am using 3.1.0? Idk.

I am not sure what you mean by “a runtime with M2DOC template” (If you are thinking about a runtime by CS then no)
Here is my configuration:
=> workspace1
=> A capella project, is already open, which is located inside workspace1.
=> I also open: plugin items containing my JS from “another workspace” indeed (workspace2) (it stays open when I restart Capella even if my workspace is “workspace1”).

The Capella workspace is “workspace1”, and the JS come from from workspace2 indeed, the projects containing the JS are just “opened”.

To resolve my issue, I tried to restart Capella Studio (where I have my JS) AND capella everytime I could. Yet It did not seem to get rid of the

Invalid query statement: Couldn't find the 'test2(EClassifier=Capability)' service

error message.

The .class file is only produced by the JDT if there is no error in the Java source file. Then this .class is loaded by M2Doc.

It’s possible that both instances of JDT try to compile the class if it’s present in two running workspace.

I was describing:

  • one Capella Studio for instance with your plugins (services, templates, addon, …)
  • You create an Eclipse launch configuration
    • in this workspace you have your .genconf file and your model

But to work with M2Doc you really only need one workspace since M2Doc will be able to load service class in the current workspace.

It was exactly the opposite (in some sort) haha:

  • Open Capella with my projects
  • Bring my services, by just opening the plugins located in my CS.

Very possible!
Indeed the changes I made were in CS, at the same time I had opened it in Capella and both were running.
Capella is such a machine, let’s agree.

I will try to copy paste my plugins inside the Capella workspace and see how it goes,
I could also compile those (with the Template) into an update site like you described, will keep you updated.

Copy pasting the Plugins of CS into Capella Workspace does not seem to get me that far:

You are using the Capella Studio ? because in Capella PDE tools are not installed by default I think (or might need the developer capability to be selected).