-
Hi,
And this last step, is the part which I can observer, but I do not understand why this is happen? Why is the server calling To avoid this repeating calls of public class BPMNGModelFactory implements GModelFactory {
@Inject
protected BPMNGModelState modelState;
@Override
public void createGModel() {
if (!modelState.isInitalized()) {
// Creating new GModel from BPMN metha model...
.....
modelState.updateRoot(newGModel);
modelState.getRoot().setRevision(-1);
}
}
} So, why is the |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 24 replies
-
Hi @rsoika,
The reasons for that are:
Of course, adopters may choose to do it differently, by overwriting the I hope this helps! |
Beta Was this translation helpful? Give feedback.
-
I see, so I think you are suggesting, you will modify the source model directly anyway, but depending on the actual operation either
Is that right? By default the framework does option 2. We could consider also adjusting the API to accommodate that:
What do you think? I'd also like to get @tortmayr's opinion on whether we should consider extending the API like above to accommodate that. However, whether or not this is part of the official API, it shouldn't keep you from following the suggestion(s) above. |
Beta Was this translation helpful? Give feedback.
-
@planger I want to come back to the idea to provide a new flag
Now the client can start modelling based on the GModel. Moving elements creating new ones, deleting elements, change routing. On the server side I am not interested in these changes until the client finish the modelling phase. Finishing the modelling phase means the client save the model At that point the sever calls So I still wonder why I should be interested in a ModelOperation event during modelling? It may be interesting for some scenarios. But in my BPMN modelling scenario I can't see why I need to hold my BPMN file in sync during modelling. It seems to me to be totally fine to sync the source model in the final I still can't see the advantage of the Operation Handler in my scenario. Unfortunately, I still don't know exactly what the Operation Handler looks like. But I suspect it would be necessary to implement all possible kinds - like I'm lazy and just think about saving this work. |
Beta Was this translation helpful? Give feedback.
-
@planger : I give up. I think I have to wait until the documentation is published This is how my custom CreateNodeOperationHandler now looks like. The executeOperation is called when the user creates a new element in the diagram, but it does not provide the id of the element - should not the node ID be the most important part to create the corresponding element in my source model?: public abstract class CreateTaskHandler extends CreateBPMNNodeOperationHandler {
@Inject
protected BPMNGModelState modelState;
/**
* Default constructor
*/
public CreateTaskHandler() {
super(BPMNTaskType.TASK);
}
public CreateTaskHandler(final String elementTypeId) {
super(elementTypeId);
}
protected String getElementTypeId() {
return getHandledElementTypeIds().get(0);
}
@Override
protected GNode createNode(final Optional<GPoint> point, final Map<String, String> args) {
return builder(point, modelState).build();
}
protected TaskNodeBuilder builder(final Optional<GPoint> point, final GModelState modelState) {
int nodeCounter = GModelUtil.generateId(BpmnPackage.Literals.TASK_NODE, getElementTypeId(), modelState);
String name = getLabel() + " " + nodeCounter;
return new TaskNodeBuilder(getElementTypeId(), name) //
.position(point.orElse(null));
}
@Override
public void executeOperation(final CreateNodeOperation operation) {
super.executeOperation(operation);
System.out.println("===== > executeOperation " + operation.getElementTypeId() + " kind=" + operation.getKind());
System.out.println("===== > Modelstate we have now " + modelState.getIndex().allIds().size() + " elements");
// How should we generate a new element in the SourceModel if we do not know the
// ID???
}
} |
Beta Was this translation helpful? Give feedback.
-
For your scenario, where you have an EMF source model, I think it'd be best to look at the new EMF base classes that GLSP provides: https://github.com/eclipse-glsp/glsp-server/tree/master/plugins/org.eclipse.glsp.server.emf/src/org/eclipse/glsp/server/emf There is a project template that uses those EMF base classes here in the new project templates: https://github.com/eclipse-glsp/glsp-examples/tree/master/project-templates/java-emf-theia This project template just has one node type (task nodes), thus it has one This is the structure that we would recommend to follow. Of course they could be generalized or restructured to your needs (e.g. that they either delegate to commands that you write externally or that you already have from your previous implementation, etc.). To find out why your operation handlers are not invoked, I would recommend to debug into the |
Beta Was this translation helpful? Give feedback.
-
@planger I would now like to return to our original discussion. I now implemented the In my In my So this looks fine. But now I lost the undo/redo features. I guess that I have to implement more operation handlers for such kind of functionality? Can you provide a List of Operations I have to handle? Also the Create and the Delete operation handlers in my case follow now a different concept. The first is operating directly on the GModel the later not. That feels inconsistent now. |
Beta Was this translation helpful? Give feedback.
-
@planger - One more suggestion for the CreateOperation handler. My final implementation of the public BPMNCreateTaskHandler() {
super(BPMNTaskType.TASK);
handledElementTypeIds = Arrays
.asList(new String[] { //
BPMNTaskType.TASK, //
BPMNTaskType.MANUAL, //
BPMNTaskType.SEND, //
BPMNTaskType.SERVICE, //
BPMNTaskType.SCRIPT,
BPMNTaskType.USER //
});
} You would normally expect that in case you extend the @Override
public List<String> getHandledElementTypeIds() { return handledElementTypeIds; } But this is not possible, because the class itself did not use this method consequently. For example the method
uses the member variable instead of the getter. Luckily the handledElementTypeIds is protected and not private. And also (as mentioned some time before) the public AbstractCreateOperationHandler(final String... elementTypeIds) {
this(Lists.newArrayList(elementTypeIds));
}
public AbstractCreateOperationHandler(final List<String> handledElementTypeIds) {
this.handledElementTypeIds = handledElementTypeIds;
} So if the constructors would be visible I could overwrite the empty constructor (needed for the binding) like this: /* Overwrite the default constructor to define a list of elementTypeIDs
* this CreateNodeOperation handler should be responsible for.
*/
public BPMNCreateTaskHandler() {
super( Arrays
.asList(new String[] { //
BPMNTaskType.TASK, //
BPMNTaskType.MANUAL, //
BPMNTaskType.SEND, //
BPMNTaskType.SERVICE, //
BPMNTaskType.SCRIPT,
BPMNTaskType.USER //
}));
} |
Beta Was this translation helpful? Give feedback.
-
Hi @rsoika, |
Beta Was this translation helpful? Give feedback.
-
Hi @planger public class BPMNCreateSequenceFlowHandler extends AbstractGModelCreateEdgeOperationHandler {
public CreateSequenceFlowHandler() {
super(ModelTypes.SEQUENCE_FLOW, "Sequence Flow");
}
@Override
public void executeOperation(final CreateEdgeOperation operation) {
super.executeOperation(operation);
// update source model
...........
}
// Needed to show the edge live
@Override
protected Optional<GEdge> createEdge(final GModelElement source, final GModelElement target,
final GModelState modelState) {
return Optional.of(new SequenceFlowBuilder() //
.source(source) //
.target(target) //
.addArgument(GArguments.edgePadding(10)) //
.addCssClass("sequenceflow") //
.build());
}
} The edge is something which need to be shown during the connecting-process on the client side before the edge becomes part of the source model. |
Beta Was this translation helpful? Give feedback.
Hi @rsoika,
in the default case, we recommend to apply edit operations directly on the source model (not the graphical model) and regenerate the GModel after the change (see also the doc):
The reasons for that are: