package org.activiti.designer.features; 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.FlowElement; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.Process; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.bpmn.model.SubProcess; import org.activiti.designer.util.editor.ModelHandler; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.ICustomContext; import org.eclipse.graphiti.features.context.impl.CreateContext; import org.eclipse.graphiti.features.custom.AbstractCustomFeature; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.Shape; public class ChangeElementTypeFeature extends AbstractCustomFeature { private String newType; public ChangeElementTypeFeature(IFeatureProvider fp) { super(fp); } public ChangeElementTypeFeature(IFeatureProvider fp, String newType) { super(fp); this.newType = newType; } @Override public boolean canExecute(ICustomContext context) { return true; } @Override public void execute(ICustomContext context) { Shape element = (Shape) context.getProperty("org.activiti.designer.changetype.pictogram"); GraphicsAlgorithm elementGraphics = element.getGraphicsAlgorithm(); int x = elementGraphics.getX(); int y = elementGraphics.getY(); CreateContext taskContext = new CreateContext(); ContainerShape targetContainer = (ContainerShape) element.getContainer(); taskContext.setTargetContainer(targetContainer); taskContext.setLocation(x, y); taskContext.setHeight(elementGraphics.getHeight()); taskContext.setWidth(elementGraphics.getWidth()); FlowNode oldObject = (FlowNode) getFeatureProvider().getBusinessObjectForPictogramElement(element); if (oldObject instanceof BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent) oldObject; ContainerShape parentShape = (ContainerShape) getFeatureProvider().getPictogramElementForBusinessObject(boundaryEvent.getAttachedToRef()); taskContext.setTargetContainer(parentShape); taskContext.setLocation(x - parentShape.getGraphicsAlgorithm().getX(), y - parentShape.getGraphicsAlgorithm().getY()); } List<SequenceFlow> sourceList = oldObject.getOutgoingFlows(); List<SequenceFlow> targetList = oldObject.getIncomingFlows(); taskContext.putProperty("org.activiti.designer.changetype.sourceflows", sourceList); taskContext.putProperty("org.activiti.designer.changetype.targetflows", targetList); taskContext.putProperty("org.activiti.designer.changetype.name", oldObject.getName()); targetContainer.getChildren().remove(element); List<Process> processes = ModelHandler.getModel(EcoreUtil.getURI(getDiagram())).getBpmnModel().getProcesses(); for (Process process : processes) { process.removeFlowElement(oldObject.getId()); removeElement(oldObject, process); } if("servicetask".equals(newType)) { new CreateServiceTaskFeature(getFeatureProvider()).create(taskContext); } else if("businessruletask".equals(newType)) { new CreateBusinessRuleTaskFeature(getFeatureProvider()).create(taskContext); } else if("mailtask".equals(newType)) { new CreateMailTaskFeature(getFeatureProvider()).create(taskContext); } else if("manualtask".equals(newType)) { new CreateManualTaskFeature(getFeatureProvider()).create(taskContext); } else if("receivetask".equals(newType)) { new CreateReceiveTaskFeature(getFeatureProvider()).create(taskContext); } else if("scripttask".equals(newType)) { new CreateScriptTaskFeature(getFeatureProvider()).create(taskContext); } else if("usertask".equals(newType)) { new CreateUserTaskFeature(getFeatureProvider()).create(taskContext); } else if("exclusivegateway".equals(newType)) { new CreateExclusiveGatewayFeature(getFeatureProvider()).create(taskContext); } else if("inclusivegateway".equals(newType)) { new CreateInclusiveGatewayFeature(getFeatureProvider()).create(taskContext); } else if("parallelgateway".equals(newType)) { new CreateParallelGatewayFeature(getFeatureProvider()).create(taskContext); } else if("nonestartevent".equals(newType)) { new CreateStartEventFeature(getFeatureProvider()).create(taskContext); } else if("timerstartevent".equals(newType)) { new CreateTimerStartEventFeature(getFeatureProvider()).create(taskContext); } else if("messagestartevent".equals(newType)) { new CreateMessageStartEventFeature(getFeatureProvider()).create(taskContext); } else if("errorstartevent".equals(newType)) { new CreateErrorStartEventFeature(getFeatureProvider()).create(taskContext); } else if("noneendevent".equals(newType)) { new CreateEndEventFeature(getFeatureProvider()).create(taskContext); } else if("errorendevent".equals(newType)) { new CreateErrorEndEventFeature(getFeatureProvider()).create(taskContext); } else if("terminateendevent".equals(newType)) { new CreateTerminateEndEventFeature(getFeatureProvider()).create(taskContext); } else if ("timerboundaryevent".equals(newType)) { new CreateBoundaryTimerFeature(getFeatureProvider()).create(taskContext); } else if ("errorboundaryevent".equals(newType)) { new CreateBoundaryErrorFeature(getFeatureProvider()).create(taskContext); } else if ("messageboundaryevent".equals(newType)) { new CreateBoundaryMessageFeature(getFeatureProvider()).create(taskContext); } else if ("signalboundaryevent".equals(newType)) { new CreateBoundarySignalFeature(getFeatureProvider()).create(taskContext); } } private void removeElement(FlowElement element, BaseElement parentElement) { Collection<FlowElement> elementList = null; if (parentElement instanceof Process) { elementList = ((Process) parentElement).getFlowElements(); } else if (parentElement instanceof SubProcess) { elementList = ((SubProcess) parentElement).getFlowElements(); ((SubProcess) parentElement).getBoundaryEvents().remove(element); } for (FlowElement flowElement : elementList) { if (flowElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) flowElement; subProcess.removeFlowElement(element.getId()); removeElement(element, subProcess); } if (flowElement instanceof Activity) { ((Activity) flowElement).getBoundaryEvents().remove(element); } } } }