package org.activiti.designer.eclipse.editor; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.activiti.bpmn.model.Activity; import org.activiti.bpmn.model.Artifact; import org.activiti.bpmn.model.Association; import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.BoundaryEvent; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.GraphicInfo; import org.activiti.bpmn.model.Lane; import org.activiti.bpmn.model.Pool; import org.activiti.bpmn.model.Process; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.bpmn.model.SubProcess; import org.activiti.designer.util.editor.Bpmn2MemoryModel; import org.apache.commons.lang.StringUtils; import org.eclipse.emf.common.util.EList; import org.eclipse.graphiti.datatypes.ILocation; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator; import org.eclipse.graphiti.mm.pictograms.FreeFormConnection; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.mm.pictograms.Shape; import org.eclipse.graphiti.services.Graphiti; public class GraphitiToBpmnDI { protected Bpmn2MemoryModel model; protected IFeatureProvider featureProvider; public GraphitiToBpmnDI(Bpmn2MemoryModel model, IFeatureProvider featureProvider) { this.model = model; this.featureProvider = featureProvider; } public void processGraphitiElements() throws Exception { List<Pool> toDeletePoolList = new ArrayList<Pool>(); for (Pool pool : model.getBpmnModel().getPools()) { PictogramElement pictElementPool = featureProvider.getPictogramElementForBusinessObject(pool); if (pictElementPool != null) { updateFlowElement(pool); Process process = model.getBpmnModel().getProcess(pool.getId()); if(process != null) { List<Lane> toDeleteLaneList = new ArrayList<Lane>(); for (Lane lane : process.getLanes()) { PictogramElement pictElementLane = featureProvider.getPictogramElementForBusinessObject(lane); if (pictElementLane != null) { updateFlowElement(lane); } else { toDeleteLaneList.add(lane); } } for (Lane toDeleteLane : toDeleteLaneList) { process.getLanes().remove(toDeleteLane); model.getBpmnModel().removeGraphicInfo(toDeleteLane.getId()); } } } else { toDeletePoolList.add(pool); } } for (Pool toDeletePool : toDeletePoolList) { model.getBpmnModel().getPools().remove(toDeletePool); model.getBpmnModel().removeGraphicInfo(toDeletePool.getId()); } for (Process process : model.getBpmnModel().getProcesses()) { loopThroughElements(process.getFlowElements(), process); loopThroughElements(process.getArtifacts(), process); } } protected void loopThroughElements(Collection<? extends BaseElement> elementList, BaseElement parentElement) throws Exception { List<BaseElement> toDeleteElementList = new ArrayList<BaseElement>(); for (BaseElement element : elementList) { PictogramElement pictElement = featureProvider.getPictogramElementForBusinessObject(element); if (pictElement != null) { if (element instanceof SequenceFlow) { updateSequenceFlow((SequenceFlow) element); } else if (element instanceof FlowElement) { updateFlowElement(element); if(element instanceof SubProcess) { SubProcess subProcess = (SubProcess) element; loopThroughElements(subProcess.getFlowElements(), subProcess); loopThroughElements(subProcess.getArtifacts(), subProcess); } if(element instanceof Activity) { Activity activity = (Activity) element; for (BoundaryEvent boundaryEvent : activity.getBoundaryEvents()) { updateFlowElement(boundaryEvent); } } } else if (element instanceof Artifact) { if (element instanceof Association) { updateAssociation((Association) element); } else { updateFlowElement(element); } } } else { // no pictogram exist so delete it from the model as well toDeleteElementList.add(element); } } if (toDeleteElementList.size() > 0) { if (parentElement instanceof Process) { Process process = (Process) parentElement; for (BaseElement toDeleteElement : toDeleteElementList) { process.removeFlowElement(toDeleteElement.getId()); model.getBpmnModel().removeGraphicInfo(toDeleteElement.getId()); model.getBpmnModel().removeFlowGraphicInfoList(toDeleteElement.getId()); model.getBpmnModel().removeLabelGraphicInfo(toDeleteElement.getId()); } } else if (parentElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) parentElement; for (BaseElement toDeleteElement : toDeleteElementList) { subProcess.removeFlowElement(toDeleteElement.getId()); model.getBpmnModel().removeGraphicInfo(toDeleteElement.getId()); model.getBpmnModel().removeFlowGraphicInfoList(toDeleteElement.getId()); model.getBpmnModel().removeLabelGraphicInfo(toDeleteElement.getId()); } } } } protected void updateFlowElement(BaseElement flowElement) { PictogramElement picElement = featureProvider.getPictogramElementForBusinessObject(flowElement); if(picElement instanceof Shape) { Shape shape = (Shape) picElement; ILocation shapeLocation = Graphiti.getLayoutService().getLocationRelativeToDiagram(shape); model.getBpmnModel().addGraphicInfo(flowElement.getId(), createGraphicInfo(shapeLocation.getX(), shapeLocation.getY(), shape.getGraphicsAlgorithm().getWidth(), shape.getGraphicsAlgorithm().getHeight())); } } protected void updateSequenceFlow(SequenceFlow sequenceFlow) { Shape sourceShape = null; Shape targetShape = null; if(StringUtils.isNotEmpty(sequenceFlow.getSourceRef())) { sourceShape = (Shape) featureProvider.getPictogramElementForBusinessObject(model.getFlowElement(sequenceFlow.getSourceRef())); } if(StringUtils.isNotEmpty(sequenceFlow.getTargetRef())) { targetShape = (Shape) featureProvider.getPictogramElementForBusinessObject(model.getFlowElement(sequenceFlow.getTargetRef())); } if(sourceShape == null || targetShape == null) { return; } FreeFormConnection freeFormConnection = (FreeFormConnection) featureProvider.getPictogramElementForBusinessObject(sequenceFlow); if(freeFormConnection == null) return; List<GraphicInfo> flowGraphicsList = createFlowGraphicInfoList(sourceShape, targetShape, freeFormConnection); model.getBpmnModel().addFlowGraphicInfoList(sequenceFlow.getId(), flowGraphicsList); EList<ConnectionDecorator> decoratorList = freeFormConnection.getConnectionDecorators(); for (ConnectionDecorator decorator : decoratorList) { if (decorator.getGraphicsAlgorithm() instanceof org.eclipse.graphiti.mm.algorithms.MultiText) { org.eclipse.graphiti.mm.algorithms.MultiText text = (org.eclipse.graphiti.mm.algorithms.MultiText) decorator.getGraphicsAlgorithm(); if(text.getHeight() > 0) { model.getBpmnModel().addLabelGraphicInfo(sequenceFlow.getId(), createGraphicInfo( text.getX(), text.getY(), text.getWidth(), text.getHeight())); break; } } } } protected void updateAssociation(Association association) { Shape sourceShape = null; Shape targetShape = null; if(StringUtils.isNotEmpty(association.getSourceRef())) { BaseElement sourceElement = model.getFlowElement(association.getSourceRef()); if (sourceElement == null) { sourceElement = model.getArtifact(association.getSourceRef()); } sourceShape = (Shape) featureProvider.getPictogramElementForBusinessObject(sourceElement); } if(StringUtils.isNotEmpty(association.getTargetRef())) { BaseElement targetElement = model.getFlowElement(association.getTargetRef()); if (targetElement == null) { targetElement = model.getArtifact(association.getTargetRef()); } targetShape = (Shape) featureProvider.getPictogramElementForBusinessObject(targetElement); } if(sourceShape == null || targetShape == null) { return; } FreeFormConnection freeFormConnection = (FreeFormConnection) featureProvider.getPictogramElementForBusinessObject(association); if(freeFormConnection == null) return; List<GraphicInfo> flowGraphicsList = createFlowGraphicInfoList(sourceShape, targetShape, freeFormConnection); model.getBpmnModel().addFlowGraphicInfoList(association.getId(), flowGraphicsList); } protected List<GraphicInfo> createFlowGraphicInfoList(Shape sourceElement, Shape targetElement, FreeFormConnection freeFormConnection) { ILocation sourceLocation = Graphiti.getLayoutService().getLocationRelativeToDiagram(sourceElement); int sourceX = sourceLocation.getX(); int sourceY = sourceLocation.getY(); int sourceWidth = sourceElement.getGraphicsAlgorithm().getWidth(); int sourceHeight = sourceElement.getGraphicsAlgorithm().getHeight(); int sourceMiddleX = sourceX + (sourceWidth / 2); int sourceMiddleY = sourceY + (sourceHeight / 2); int sourceBottomY = sourceY + sourceHeight; ILocation targetLocation = Graphiti.getLayoutService().getLocationRelativeToDiagram(targetElement); int targetX = targetLocation.getX(); int targetY = targetLocation.getY(); int targetWidth = targetElement.getGraphicsAlgorithm().getWidth(); int targetHeight = targetElement.getGraphicsAlgorithm().getHeight(); int targetMiddleX = targetX + (targetWidth / 2); int targetMiddleY = targetY + (targetHeight / 2); int targetBottomY = targetY + targetHeight; List<GraphicInfo> flowGraphicsList = new ArrayList<GraphicInfo>(); if (sourceElement instanceof BoundaryEvent) { flowGraphicsList.add(createFlowGraphicInfo(sourceMiddleX, sourceY + sourceHeight)); } else { if((freeFormConnection.getBendpoints() == null || freeFormConnection.getBendpoints().size() == 0)) { if((sourceBottomY + 11) < targetY) { flowGraphicsList.add(createFlowGraphicInfo(sourceMiddleX, sourceY + sourceHeight)); } else if((sourceY - 11) > (targetY + targetHeight)) { flowGraphicsList.add(createFlowGraphicInfo(sourceMiddleX, sourceY)); } else if(sourceX > targetX) { flowGraphicsList.add(createFlowGraphicInfo(sourceX, sourceMiddleY)); } else { flowGraphicsList.add(createFlowGraphicInfo(sourceX + sourceWidth, sourceMiddleY)); } } else { org.eclipse.graphiti.mm.algorithms.styles.Point bendPoint = freeFormConnection.getBendpoints().get(0); if((sourceBottomY + 5) < bendPoint.getY()) { flowGraphicsList.add(createFlowGraphicInfo(sourceMiddleX, sourceY + sourceHeight)); } else if((sourceY - 5) > bendPoint.getY()) { flowGraphicsList.add(createFlowGraphicInfo(sourceMiddleX, sourceY)); } else if(sourceX > bendPoint.getX()) { flowGraphicsList.add(createFlowGraphicInfo(sourceX, sourceMiddleY)); } else { flowGraphicsList.add(createFlowGraphicInfo(sourceX + sourceWidth, sourceMiddleY)); } } } if(freeFormConnection.getBendpoints() != null && freeFormConnection.getBendpoints().size() > 0) { for (org.eclipse.graphiti.mm.algorithms.styles.Point point : freeFormConnection.getBendpoints()) { flowGraphicsList.add(createFlowGraphicInfo(point.getX(), point.getY())); } } int difference = 5; if((freeFormConnection.getBendpoints() == null || freeFormConnection.getBendpoints().size() == 0)) { difference = 11; } GraphicInfo lastGraphicInfo = flowGraphicsList.get(flowGraphicsList.size() - 1); if((targetBottomY + difference) < lastGraphicInfo.getY()) { flowGraphicsList.add(createFlowGraphicInfo(targetMiddleX, targetY + targetHeight)); } else if((targetY - difference) > lastGraphicInfo.getY()) { flowGraphicsList.add(createFlowGraphicInfo(targetMiddleX, targetY)); } else if(targetX > lastGraphicInfo.getX()) { flowGraphicsList.add(createFlowGraphicInfo(targetX, targetMiddleY)); } else { flowGraphicsList.add(createFlowGraphicInfo(targetX + targetWidth, targetMiddleY)); } return flowGraphicsList; } protected GraphicInfo createFlowGraphicInfo(int x, int y) { GraphicInfo graphicInfo = new GraphicInfo(); graphicInfo.setX(x); graphicInfo.setY(y); return graphicInfo; } protected GraphicInfo createGraphicInfo(int x, int y, int width, int height) { GraphicInfo graphicInfo = new GraphicInfo(); graphicInfo.setX(x); graphicInfo.setY(y); graphicInfo.setWidth(width); graphicInfo.setHeight(height); return graphicInfo; } }