package org.activiti.designer.features; import java.util.ArrayList; import java.util.List; import org.eclipse.bpmn2.BaseElement; import org.eclipse.bpmn2.FlowElement; import org.eclipse.bpmn2.FlowNode; import org.eclipse.bpmn2.SequenceFlow; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; 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.Anchor; import org.eclipse.graphiti.mm.pictograms.ChopboxAnchor; import org.eclipse.graphiti.mm.pictograms.Connection; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.mm.pictograms.PictogramLink; 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) { PictogramElement element = (PictogramElement) 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.eContainer(); taskContext.setTargetContainer(targetContainer); taskContext.setLocation(x, y); taskContext.setHeight(elementGraphics.getHeight()); taskContext.setWidth(elementGraphics.getWidth()); FlowElement oldObject = (FlowElement) element.getLink().getBusinessObjects().get(0); String objectId = oldObject.getId(); List<SequenceFlow> sourceList = new ArrayList<SequenceFlow>(); List<SequenceFlow> targetList = new ArrayList<SequenceFlow>(); for(EObject eObject : targetContainer.eResource().getContents()) { if(eObject instanceof SequenceFlow) { SequenceFlow sequenceFlow = (SequenceFlow) eObject; if(sequenceFlow.getSourceRef().getId().equals(objectId)) { sourceList.add(sequenceFlow); } if(sequenceFlow.getTargetRef().getId().equals(objectId)) { targetList.add(sequenceFlow); } } } 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()); Anchor elementAnchor = null; for (Shape shape : targetContainer.getChildren()) { FlowNode flowNode = (FlowNode) getBusinessObjectForPictogramElement(shape.getGraphicsAlgorithm().getPictogramElement()); if(flowNode == null || flowNode.getId() == null) continue; if(flowNode.getId().equals(objectId)) { EList<Anchor> anchorList = ((ContainerShape) shape).getAnchors(); for (Anchor anchor : anchorList) { if(anchor instanceof ChopboxAnchor) { elementAnchor = anchor; break; } } } } List<Connection> sourceConnections = new ArrayList<Connection>(); List<Connection> targetConnections = new ArrayList<Connection>(); for(Connection connection : getDiagram().getConnections()) { if(connection.getStart().equals(elementAnchor)) { sourceConnections.add(connection); } if(connection.getEnd().equals(elementAnchor)) { targetConnections.add(connection); } } taskContext.putProperty("org.activiti.designer.changetype.sourceconnections", sourceConnections); taskContext.putProperty("org.activiti.designer.changetype.targetconnections", targetConnections); List<PictogramLink> toDeleteLinks = new ArrayList<PictogramLink>(); for (PictogramLink link : getDiagram().getPictogramLinks()) { BaseElement flowNode = (BaseElement) getBusinessObjectForPictogramElement(link.getPictogramElement()); if(flowNode.getId().equals(objectId)) { toDeleteLinks.add(link); } } List<Shape> toDeleteShapes = new ArrayList<Shape>(); for(Shape shape : targetContainer.getChildren()) { BaseElement flowNode = (BaseElement) getBusinessObjectForPictogramElement(shape.getGraphicsAlgorithm().getPictogramElement()); if(flowNode.getId().equals(objectId)) { toDeleteShapes.add(shape); } } for (PictogramLink link : toDeleteLinks) { getDiagram().getPictogramLinks().remove(link); } for (Shape shape : toDeleteShapes) { targetContainer.getChildren().remove(shape); } EcoreUtil.delete(oldObject, true); 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); } } }