Home » Eclipse Projects » Sirius » Labeling Relation Edges(Using a Java Service to return a String label based on a source and a target)
Labeling Relation Edges [message #1854377] |
Tue, 16 August 2022 15:49 |
Bruno Curzi-Laliberté Messages: 14 Registered: January 2022 |
Junior Member |
|
|
I am trying to compute labels for my graphical representation
I have an abstract class displayed in my diagram, its children declare their references, I can get the references using a Service:
@SuppressWarnings("unchecked")
public Collection<EObject> flowTargets(EObject self) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Class<?> objclass = self.getClass();
String methodName = "getTargetObjects";
return (Collection<EObject>) objclass.getMethod(methodName).invoke(self);
}
And using the "Target Finder Expression" of a relation edge I can use "service:flowTargets" to point to the right objects.
Now I want to add a label to those edges.
I implemented the method to get a label based on the target in my class, I just want to be able to call this service
@SuppressWarnings("unchecked")
public String flowLabel(EObject self, Object target) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Class<?> objclass = self.getClass();
String methodName = "getTargetRelation";
return (String) objclass.getMethod(methodName).invoke(self, target);
}
I found this post https://www.eclipse.org/forums/index.php/t/844952/ explaining how to find the target of an edge, simply using [view.oclAsType(DEdge).targetNode.oclAsType(DSemanticDecorator).target/] to get the object it points to, that works, except in service calls I can't use service:flowLabel(self, view.oclAsType(DEdge).targetNode.oclAsType(DSemanticDecorator).target)
as the documentation says "The service interpreter supports parameters, but only variables can be used as parameter (no literals or complex expressions), for example: service:serviceName(view, diagram)."
How can I resolve my problem of calling service flowLabel?
|
|
|
Re: Labeling Relation Edges [message #1854385 is a reply to message #1854377] |
Wed, 17 August 2022 05:27 |
Bruno Curzi-Laliberté Messages: 14 Registered: January 2022 |
Junior Member |
|
|
Solution:
public String flowLabel(EObject self, Object target) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
target = invoke(target, "getTargetNode");
target = invoke(target, "getTarget");
return (String) self.getClass().getMethod("getTargetRelation", EObject.class).invoke(self, target);
}
Object invoke(Object obj, String method, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
return obj.getClass().getMethod(method).invoke(obj, args);
}
used by expression: "service:flowLabel(view)"
If, like me, you can't debug the java services, you can instead manually "debug" the valid methods on whatever object simply use a service such as
public String flowLabel2(EObject self, Object target) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
// view.oclAsType(DEdge).targetNode.oclAsType(DSemanticDecorator).target.toString()
Class<?> objclass = target.getClass();
Method[] ms = objclass.getMethods();
return Arrays.asList(ms).stream().map(m->m.getName()).collect(Collectors.joining(", "));
}
and display the result on a label in the diagram
i also suggest filtering after the map to name to narrow your search, such as .contains("node") or "Node"
[Updated on: Wed, 17 August 2022 05:27] Report message to a moderator
|
|
|
Re: Labeling Relation Edges [message #1854421 is a reply to message #1854385] |
Thu, 18 August 2022 07:18 |
|
The "service:" prefix is limited by design (to keep it simple and fast for simple cases), but AQL expressions can invoke Java services and are the recommended approach unless you are trying to optimize performance.
Maybe try this:
aql:self.flowLabel(self, view.targetNode.target)
Also, unless you are in a specific setting which prevents it, you can use more precise Java classes from your metamodel instead of plain "EObject self", and use the EMF-generated Java APIs directly in your services instead of Java reflection.
Pierre-Charles David - Obeo
Need training or professional services for Sirius?
http://www.obeodesigner.com/sirius
|
|
| | |
Goto Forum:
Current Time: Sun Dec 01 17:39:39 GMT 2024
Powered by FUDForum. Page generated in 0.02176 seconds
|