package org.activiti.designer.eclipse.extension.export;
import java.util.List;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.bpmn2.FlowNode;
import org.eclipse.bpmn2.SequenceFlow;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
// <SecureBPMN>
import org.hamcrest.core.IsInstanceOf;
import org.eclipse.securebpmn2.SecurityFlow;
// <SecureBPMN>
/**
* Utility class to synchronize differences between the graphical representation and business model objects of a
* diagram.
*
* @author Tiese Barrell
* @since 0.5.1
* @version 1
*
*/
public class SequenceFlowSynchronizer {
private SequenceFlowSynchronizer() {
}
/**
* Synchronizes the provided list of {@link Connection}s by inspecting any differences between the graphical
* representation and business model objects. For any {@link Connection} where the ids of corresponding graphical
* and business objects don't match, the business objects are relinked in the model so they accurately reflect the
* graphical representation.
*
* @param connections
* the list of {@link Connection} objects to inspect. In most cases, this list would contain all
* connections of the diagram
* @param diagramEditor
* the {@link DiagramEditor} of which the diagram is currently being inspected
*/
public static void synchronize(final List<Connection> connections, final DiagramEditor diagramEditor) {
for (final Connection connection : connections) {
final SyncObjects objects = new SyncObjects(connection, diagramEditor);
if (objects.isOutOfSync()) {
objects.update();
}
}
}
private static final class SyncObjects {
private final DiagramEditor diagramEditor;
private String graphicalStartId;
private String graphicalEndId;
private String businessStartId;
private String businessEndId;
private FlowElement targetStartObject;
private FlowElement targetEndObject;
private SequenceFlow businessModelObjectToUpdate;
private Connection graphicalRepresentation;
protected SyncObjects(final Connection connection, final DiagramEditor diagramEditor) {
this.graphicalRepresentation = connection;
this.diagramEditor = diagramEditor;
setup();
}
private void setup() {
// <SecureBPMN>
if(this.graphicalRepresentation.getLink().getBusinessObjects().get(0) instanceof SecurityFlow)return;
// <SecureBPMN>
if(this.graphicalRepresentation == null) return;
if(this.graphicalRepresentation.getStart() == null) return;
if(this.graphicalRepresentation.getStart().getParent() == null) return;
if(this.graphicalRepresentation.getStart().getParent().getLink().getBusinessObjects().size() == 0) return;
final EObject startPE = this.graphicalRepresentation.getStart().getParent().getLink().getBusinessObjects().get(0);
targetStartObject = (FlowElement) startPE;
graphicalStartId = targetStartObject.getId();
if(this.graphicalRepresentation.getEnd() == null) return;
if(this.graphicalRepresentation.getEnd().getParent() == null) return;
if(this.graphicalRepresentation.getEnd().getParent().getLink().getBusinessObjects().size() == 0) return;
final EObject endPE = this.graphicalRepresentation.getEnd().getParent().getLink().getBusinessObjects().get(0);
targetEndObject = (FlowElement) endPE;
graphicalEndId = targetEndObject.getId();
businessModelObjectToUpdate = (SequenceFlow) this.graphicalRepresentation.getLink().getBusinessObjects()
.get(0);
if(businessModelObjectToUpdate.getSourceRef() != null) {
businessStartId = businessModelObjectToUpdate.getSourceRef().getId();
}
if(businessModelObjectToUpdate.getTargetRef() != null) {
businessEndId = businessModelObjectToUpdate.getTargetRef().getId();
}
}
public boolean isOutOfSync() {
if(graphicalStartId == null || graphicalEndId == null) return false;
if (!graphicalStartId.equals(businessStartId) || !graphicalEndId.equals(businessEndId)) {
return true;
}
return false;
}
public boolean update() {
if (isOutOfSync()) {
System.out
.println(String
.format("Updating because the pictogram elements point from '%s' to '%s', but the business objects point from '%s' to '%s'. The difference must be corrected before saving the diagram",
graphicalStartId, graphicalEndId, businessStartId, businessEndId));
TransactionalEditingDomain editingDomain = this.diagramEditor.getEditingDomain();
editingDomain.getCommandStack().execute(new RecordingCommand(editingDomain, "ConnectionUpdate") {
protected void doExecute() {
businessModelObjectToUpdate.setSourceRef((FlowNode) targetStartObject);
businessModelObjectToUpdate.setTargetRef((FlowNode) targetEndObject);
}
});
return true;
}
return false;
}
}
}