package org.activiti.designer.features; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.activiti.bpmn.model.Activity; import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.BoundaryEvent; import org.activiti.bpmn.model.CallActivity; import org.activiti.bpmn.model.Event; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.Gateway; import org.activiti.bpmn.model.Lane; import org.activiti.bpmn.model.Process; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.bpmn.model.SubProcess; import org.activiti.bpmn.model.Task; import org.activiti.designer.util.editor.Bpmn2MemoryModel; import org.activiti.designer.util.editor.ModelHandler; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.ui.features.DefaultDeleteFeature; public class DeleteFlowElementFeature extends DefaultDeleteFeature { public DeleteFlowElementFeature(IFeatureProvider fp) { super(fp); } protected void deleteBusinessObject(Object bo) { if (bo instanceof Task || bo instanceof Gateway || bo instanceof Event || bo instanceof SubProcess || bo instanceof CallActivity) { deleteSequenceFlows((FlowNode) bo); } if (bo instanceof SubProcess || bo instanceof Task) { if(((Activity) bo).getBoundaryEvents() != null) { for (BoundaryEvent boundaryEvent : ((Activity) bo).getBoundaryEvents()) { removeElement(boundaryEvent); } } } if (bo instanceof BoundaryEvent) { if(((BoundaryEvent) bo).getAttachedToRef() != null) { ((BoundaryEvent) bo).getAttachedToRef().getBoundaryEvents().remove(bo); } } if (bo instanceof SubProcess) { SubProcess subProcess = (SubProcess) bo; List<FlowElement> toDeleteElements = new ArrayList<FlowElement>(); for (FlowElement subFlowElement : subProcess.getFlowElements()) { toDeleteElements.add(subFlowElement); } for (FlowElement subFlowElement : toDeleteElements) { if(subFlowElement instanceof FlowNode) { deleteSequenceFlows((FlowNode) subFlowElement); } removeElement(subFlowElement); } subProcess.getFlowElements().clear(); } removeElement((BaseElement) bo); } private void removeElement(BaseElement element) { List<Process> processes = ModelHandler.getModel(EcoreUtil.getURI(getDiagram())).getBpmnModel().getProcesses(); for (Process process : processes) { process.removeFlowElement(element.getId()); removeElementInLanes(element.getId(), process.getLanes()); removeElementInProcess(element, process); } } private void removeElementInLanes(String elementId, List<Lane> laneList) { for (Lane lane : laneList) { lane.getFlowReferences().remove(elementId); } } private void removeElementInProcess(BaseElement element, BaseElement parentElement) { Collection<FlowElement> elementList = null; if (parentElement instanceof Process) { elementList = ((Process) parentElement).getFlowElements(); } else if (parentElement instanceof SubProcess) { elementList = ((SubProcess) parentElement).getFlowElements(); } for (FlowElement flowElement : elementList) { if(flowElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) flowElement; subProcess.removeFlowElement(element.getId()); removeElementInProcess(element, subProcess); } } } private void deleteSequenceFlows(FlowNode flowNode) { List<SequenceFlow> toDeleteSequenceFlows = new ArrayList<SequenceFlow>(); for (SequenceFlow incomingSequenceFlow : flowNode.getIncomingFlows()) { SequenceFlow toDeleteObject = (SequenceFlow) getFlowElement(incomingSequenceFlow); if (toDeleteObject != null) { toDeleteSequenceFlows.add(toDeleteObject); } } for (SequenceFlow outgoingSequenceFlow : flowNode.getOutgoingFlows()) { SequenceFlow toDeleteObject = (SequenceFlow) getFlowElement(outgoingSequenceFlow); if (toDeleteObject != null) { toDeleteSequenceFlows.add(toDeleteObject); } } for (SequenceFlow deleteObject : toDeleteSequenceFlows) { deletedConnectingFlows(deleteObject); removeElement(deleteObject); } } private void deletedConnectingFlows(SequenceFlow sequenceFlow) { for (EObject diagramObject : getDiagram().eResource().getContents()) { if(diagramObject instanceof FlowNode) { SequenceFlow foundIncoming = null; SequenceFlow foundOutgoing = null; for(SequenceFlow flow : ((FlowNode) diagramObject).getIncomingFlows()) { if(flow.getId().equals(sequenceFlow.getId())) { foundIncoming = flow; } } for(SequenceFlow flow : ((FlowNode) diagramObject).getOutgoingFlows()) { if(flow.getId().equals(sequenceFlow.getId())) { foundOutgoing = flow; } } if(foundIncoming != null) { ((FlowNode) diagramObject).getIncomingFlows().remove(foundIncoming); } if(foundOutgoing != null) { ((FlowNode) diagramObject).getOutgoingFlows().remove(foundOutgoing); } } } } private FlowElement getFlowElement(FlowElement flowElement) { Bpmn2MemoryModel model = ModelHandler.getModel(EcoreUtil.getURI(getDiagram())); for (Process process : model.getBpmnModel().getProcesses()) { FlowElement processElement = getFlowElementInProcess(flowElement, process.getFlowElements()); if(processElement != null) return processElement; } return null; } private FlowElement getFlowElementInProcess(FlowElement flowElement, Collection<FlowElement> elementList) { for (FlowElement element : elementList) { if (element.getId().equals(flowElement.getId())) { return element; } if (element instanceof SubProcess) { FlowElement subFlowElement = getFlowElementInProcess(flowElement, ((SubProcess) element).getFlowElements()); if(subFlowElement != null) return subFlowElement; } } return null; } }