package org.activiti.designer.features; import org.activiti.bpmn.model.Activity; import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.BoundaryEvent; import org.activiti.bpmn.model.EndEvent; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.Lane; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.bpmn.model.StartEvent; import org.activiti.bpmn.model.SubProcess; import org.activiti.designer.PluginImage; import org.activiti.designer.eclipse.preferences.PreferencesUtil; import org.activiti.designer.util.editor.ModelHandler; import org.activiti.designer.util.preferences.Preferences; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.ICreateConnectionContext; import org.eclipse.graphiti.features.context.impl.AddConnectionContext; import org.eclipse.graphiti.mm.pictograms.Anchor; import org.eclipse.graphiti.mm.pictograms.Connection; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.Diagram; public class CreateSequenceFlowFeature extends AbstractCreateBPMNConnectionFeature { public static final String FEATURE_ID_KEY = "flow"; public CreateSequenceFlowFeature(IFeatureProvider fp) { // provide name and description for the UI, e.g. the palette super(fp, "SequenceFlow", "Create SequenceFlow"); //$NON-NLS-1$ //$NON-NLS-2$ } public boolean canCreate(ICreateConnectionContext context) { FlowNode source = getFlowNode(context.getSourceAnchor()); FlowNode target = getFlowNode(context.getTargetAnchor()); if (source != null && target != null && source != target) { if (source instanceof StartEvent && target instanceof StartEvent) { return false; } else if (source instanceof EndEvent) { // prevent adding outgoing connections from EndEvents return false; } return true; } return false; } public boolean canStartConnection(ICreateConnectionContext context) { // return true if source anchor isn't undefined if (getFlowNode(context.getSourceAnchor()) != null) { return true; } return false; } public Connection create(ICreateConnectionContext context) { Connection newConnection = null; FlowNode source = getFlowNode(context.getSourceAnchor()); FlowNode target = getFlowNode(context.getTargetAnchor()); if (source != null && target != null) { // create new business object SequenceFlow sequenceFlow = createSequenceFlow(source, target, context); // add connection for business object AddConnectionContext addContext = new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor()); addContext.setNewObject(sequenceFlow); newConnection = (Connection) getFeatureProvider().addIfPossible(addContext); } return newConnection; } /** * Returns the FlowNode belonging to the anchor, or null if not available. */ private FlowNode getFlowNode(Anchor anchor) { if (anchor != null) { Object obj = getBusinessObjectForPictogramElement(anchor.getParent()); if (obj instanceof FlowNode) { return (FlowNode) obj; } } return null; } /** * Creates a SequenceFlow between two BaseElements. */ private SequenceFlow createSequenceFlow(FlowNode source, FlowNode target, ICreateConnectionContext context) { SequenceFlow sequenceFlow = new SequenceFlow(); sequenceFlow.setId(getNextId()); sequenceFlow.setSourceRef(source.getId()); sequenceFlow.setTargetRef(target.getId()); if (PreferencesUtil.getBooleanPreference(Preferences.EDITOR_ADD_LABELS_TO_NEW_SEQUENCEFLOWS)) { sequenceFlow.setName(String.format("to %s", target.getName())); } else { sequenceFlow.setName(""); } ContainerShape targetContainer = null; if (source instanceof BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent) source; if (boundaryEvent.getAttachedToRef() != null) { Activity attachedActivity = boundaryEvent.getAttachedToRef(); targetContainer = (ContainerShape) getFeatureProvider().getPictogramElementForBusinessObject(attachedActivity); } } else { targetContainer = (ContainerShape) context.getSourcePictogramElement(); } ContainerShape parentContainer = targetContainer.getContainer(); if (parentContainer instanceof Diagram) { ModelHandler.getModel(EcoreUtil.getURI(getDiagram())).getBpmnModel().getMainProcess().addFlowElement(sequenceFlow); } else { Object parentObject = getBusinessObjectForPictogramElement(parentContainer); if (parentObject instanceof SubProcess) { ((SubProcess) parentObject).addFlowElement(sequenceFlow); } else if (parentObject instanceof Lane) { Lane lane = (Lane) parentObject; lane.getParentProcess().addFlowElement(sequenceFlow); } } source.getOutgoingFlows().add(sequenceFlow); target.getIncomingFlows().add(sequenceFlow); return sequenceFlow; } @Override public String getCreateImageId() { return PluginImage.IMG_EREFERENCE.getImageKey(); } @Override protected String getFeatureIdKey() { return FEATURE_ID_KEY; } @Override protected Class< ? extends BaseElement> getFeatureClass() { return new SequenceFlow().getClass(); } }