Replies: 4 comments 5 replies
-
You are on the right track! From your There is an example for that in the workflow editor, where a The client cannot ever change the model directly, because only the server is supposed to know how to manipulate the model. Essentially the client only knows the |
Beta Was this translation helpful? Give feedback.
-
On a side note: |
Beta Was this translation helpful? Give feedback.
-
I now implemented the missing Server Operations (or at least I think so) and I can successful send my ApplyUpdate Action from the client to the server where it is processed. But I still do not understand what you mean with
My client seems not to receive this update. The model is not updated. So it looks like I am still missing this UpdateModelAction ? I have written a Quick Guide describing the procedure. Can you help me to add the missing part. I am not sure if the part with my How to update a Model ElementIf you have changed values for element properties on the client side you need to send an action event to the model server to apply the new values to the model. For this you need to implement a corresponding GLSP Server Action so that your client can send an update. On the Server Side you need to generate than another Action to update you model state. The Server SideIn the following example I assume that we have a model element named 'Event' with the properties 'name' and 'documentation'. The Apply OperationFirst of all you need to define an Apply Operation on your Server which accepts the ID of the element and an expression describing what changed. This action is later send from your client to the server: public class ApplyEventUpdateOperation extends Operation {
private String id;
private String expression;
public ApplyEventUpdateOperation() {
super("applyEventUpdate");
}
public ApplyEventUpdateOperation(final String nodeId, final String expression) {
this();
this.id = nodeId;
this.expression = expression;
}
public String getId() {
return id;
}
public void setId(final String nodeId) {
this.id = nodeId;
}
public String getExpression() {
return expression;
}
public void setExpression(final String expression) {
this.expression = expression;
}
} The expression can be any string describing the change. For example this can be simple the name of the property and the new value:
Or you can also describe your changes into some kind of XML. The Apply Operation HandlerNext you need implement a OperationHandler for your Apply Action. This class handles the incomming action: public class ApplyEventUpdateOperation extends AbstractOperationHandler<ApplyEventUpdateOperation> {
@Inject
protected ActionDispatcher actionDispatcher;
@Inject
protected GModelState modelState;
@Override
protected void executeOperation(final ApplyEventUpdateOperation operation) {
String text = operation.getExpression();
if (text.startsWith("name:")) {
// extract the property and the value
....
// dispatch a new EventEditOperation
....
actionDispatcher.dispatch(new EventEditOperation(operation.getId(), "name", value));
}
}
} The OperationHandler extracts the property name and the value from the expression. If you send more complex data like XML you have to parse the data here. The Operation Handler now need to create a new Event to update the concrete model object. For that reason we define a EditEventOperation. The Edit Operationpublic class EditEventOperation extends Operation {
private String id;
private String feature;
private String value;
public EditEventOperation() {
super("editEvent");
}
public EditEventOperation(final String id, final String feature, final String value) {
this();
System.out.println("...create new EventEditOperation - ID=" + id + " feature=" + feature + " value=" + value);
this.id = id;
this.feature = feature;
this.value = value;
}
// getter and setters ....
} Also we need an Operation Handler for this event. The Edit Operation HandlerThe Edit Operation Handler class fetches the corresponding Element from the Server model and updates the corresponding properties (features). public class EditEventOperationHandler extends AbstractOperationHandler<EditEventOperation> {
@Inject
protected GModelState modelState;
@Override
protected void executeOperation(final EditEventOperation operation) {
Optional<EventNode> element = modelState.getIndex().findElementByClass(operation.getId(), EventNode.class);
if (element.isEmpty()) {
throw new RuntimeException("Cannot find element with id '" + operation.getId() + "'");
}
switch (operation.getFeature()) {
case "name":
logger.info("...feature = name - value = " + operation.getValue());
element.get().setName(operation.getValue());
break;
case "documentation":
element.get().setDocumentation(operation.getValue());
break;
default:
throw new GLSPServerException("Cannot edit element at feature '" + operation.getFeature() + "'");
}
}
} Binding the Operation HandlersFinally you need to bind the handler to your DiagramModule in the method configureOperationHandlers public class BPMNDiagramModule extends GModelJsonDiagramModule {
....
@Override
protected void configureOperationHandlers(final MultiBinding<OperationHandler> binding) {
super.configureOperationHandlers(binding);
.....
// bind Apply Operation Hander (send from the client)
binding.add(ApplyEventUpdateOperationHandler.class);
// bind Edit Operation Handler (send by the server)
binding.add(EditEventOperationHandler.class);
}
} The Client SideNow you can fire a corresponding applyEventUpdate Action each time a property of you Event Element has changed: @injectable()
export class MyUIExtension extends AbstractUIExtension implements EditModeListener, SelectionListener {
@inject(TYPES.IActionDispatcher)
protected readonly actionDispatcher: ActionDispatcher;
....
// Update the property 'name' for the selected element ID
const action = new ApplyEventUpdateOperation(this.selectedElementId, 'name:' + _newValue);
this.actionDispatcher.dispatch(action);
}
export class ApplyEventUpdateOperation implements Action {
static readonly KIND = 'applyEventUpdate';
readonly kind = ApplyEventUpdateOperation.KIND;
constructor(readonly id: string, readonly expression: string) { }
}
|
Beta Was this translation helpful? Give feedback.
-
I finally have one more conceptional question: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
still after a lot of trial and error I have no idea how to update an model element and I need some help to get a better understanding of the GLSP Client concept. I have the following scenario:
I have written a custom UIExtension which implements the
SelectionListener
interface. So I can react on the selection of a model element within my diagram pane.I am able to see all the properties of the selected element. So I can check which type of element it is and I can see all its custom properties.
Now I have some business method in which I want compute a new value for a specific property of the selected element. (in truth I have implemented a complete Form Editor based on the JSON Forms - see also the discussion here)
But until now I can't figure out how to manipulate my model element. I think I have tried nearly everything, but I have at the end no idea how this can be achieved and I did not found one piece of code where I can find an example:
In my method
selectionChanged()
I have an readonly instance of the root of my model which looks promising:I also found this example code in the workflow example to get an instance of the task element from the SModelRoot:
So also here I can see all elements. But as far as I understand these elements are still all read only - why?
I expect that in the universe of the GLSP client there should exist some method to get a writeable instance of a model element by ID? If not, what is the correct way to update a single property, or even a set of properties for one model element. At the beginning I expected that I should send an ActionEvent to the server. But I have no idea how to do this and I am no longer sure if this is necessary. It looks like none of the examples including the coffee editor is sending events from the client to the server actively.
This question sounds to me so idiotic because it should be one of the most easiest things in GLSP.
I hope someone can lead me out of the Valley of the Unsuspecting....
Beta Was this translation helpful? Give feedback.
All reactions