Implementing and Calling Java Services in M2Doc

Hello everyone,

In a previous post on this forum, it was mentioned that “all variables are immutable in M2Doc” (See here). However, I am attempting to create a loop that checks, per iteration, if a certain string isn’t already stored in a List. If it isn’t, I want to add this string to the list. I am facing difficulties accomplishing this in M2Doc, as it seems like the variables defined with the ‘let’ statement won’t work as they are immutable.

Therefore, I am now trying to tackle this problem via Java Services: For now, I have created a new Java project, written some simple code (to become familiar with extending M2Doc with Java services), and exported it as a JAR file. I then added this service in the M2Doc template properties. However, I wasn’t able to access this created service. Am I missing some steps for registration/implementation of the Java Services, or are there some things I need to take care of? In other words, how would one normally call the created services in an M2Doc template?

(This is the example Java code I wrote. In M2Doc, I was using a for loop and wanted to call the iterationCount. However, for now that does not work and I am not sure how to properly call this service in M2Doc)
grafik

Thank you very much for your help!

I don’t have all the details but it looks like using the union and possibly a select should answer your issue:

(collection1->select(...) + collection2->select(...))...

Then you can sortBy(a | a....) and/or remove duplicates asOrderedSet()

For the Java service part, you need to create the class in a plugin project if you plan to deploy it in Eclipse (since you are using Capella this is the way to go) or a Java project if you plan on running standalone.
For testing purpose if the project is in your workspace and the class is compiled (enable development capabilities in the preferences), M2Doc should be able to load the class. You need to import it in your template using the template properties wizard. You will need to select the service tab and select your class.

Once this work, you can start creating your feature plugin and your update site to be able to install your plugin in an other Eclipse (Capella). First enable development capability in your Capella preferences.
You can read this documentation for more details (plugin, feature, update site). As an example you can also have a look at the M2Doc extension for Capella github repository. In the repository you will also find everything needed to build the update site with Maven an Tycho.

1 Like

Thank you!
Unfortunatly, I still encounter some problems :confused:
For now, I just concentrated on creating a new Java class in a plugin project and tried to integrate it into Capella for M2Doc templates. Therefore, I created the following example class:

package com.carexmaple;

public class Car {
    // attributes
    String brand;
    int year;
    double price;
    // Constructor
    public Car(String brand, int year, double price) {
        this.brand = brand;
        this.year = year;
        this.price = price;
    }

    // Method
    public void displayInfo() {
        System.out.println("Brand: " + brand);
        System.out.println("Year: " + year);
        System.out.println("Price: $" + price);
    }
}

and the MainApp class to demonstrate the usage of the Car class:

package com.carexmaple;

public class MainApp {

	public static void main(String[] args) {
		 // Create a new Car object
        Car myCar = new Car("Toyota", 2022, 25000.50);
        Car youCar = new Car("VW", 2000, 13.3);

        // Display information about the car
        System.out.println("Car Information:");
        myCar.displayInfo();
        System.out.println("Your Car is built in " + youCar.year);
	}

}

My initial goal is to integrate this plugin into my Capella project and be able to call the Car class in an M2Doc template. Specifically, I’d like to print variables like myCar.year or the output of the MainApp class in the generated document.

I’ve taken the following steps:

  1. Exported the plugin and installed it directly into the host repository.
  2. Added the services in the template properties.
    grafik
    However, I’m currently unable to access the Car class within the M2Doc template. Using defined variables does not seem to work, and I’m unsure about the commands to run the MainApp class.
    grafik

Any insights or guidance on effectively integrating and utilizing this Java class in my M2Doc template would be greatly appreciated!

Thanks for your help!

Best,
Falk

You can only use primitive types or EObject. You can’t declare a plain Java class as a variable of your template. It’s also not possible to pass a plain Java value in the .genconf file.

Here the myCar variable is declared as a String as shown in the error message.

To use EObject, you will need to create an Ecore metamodel and a corresponding model. You can have a look at this tutorial. When you have your metamodel (EPackage) deployed, you can register its nsURI in your template with the template property wizard to declare a variable which type can be any of the EClass you created. Then you will be able to navigate any EStructuraFeature from your metamodel.

Hi,
I’m also following this topic for more or less the same reason: having external data that might be used as kind of VM, like for having an external counter.
Considering the tutorials, I quickly create the metamodel till the editor plugin (a capellaData class with a counter):
image image
The bundle seems to be well deployed and loaded by Capella:


I’m also able to add its associated nsURI in the template, but unfortunately I’m not able to access my data.
I suspect an issue linked in the loading of the bundle where the capella IDE does not allocate my class appropriately, considering that the MainApp is not present as a class loader.
Is there a way to define such capellaData as a Singleton or reference it in a data provider so that it is “automatically” loaded?

1 Like

For a counter since it’s a primitive type you can use a Java service:

public class CounterService {

	private int counter;

	public int incrementCounter(Object obj) {
		counter++;
		return counter(obj);
	}

	public int decrementCounter(Object obj) {
		counter--;
		return counter(obj);
	}

	public int setCounter(Object obj, int value) {
		counter = value;
		return counter(obj);
	}

	public int counter(Object obj) {
		return counter;
	}

}

Then you can import the service class using the template properties wizard.

To attach new data to a Capella model you need to create an addon using the Capella Studio. A metmaodel will be created and you can use its nsURI as described above.

If you have a Jave service Class in your workspace referencing types from your metamodel, there is a known issue that prevent the resolution of the Java service. I’m not sure if this apply to your case…

I hope this help.