blob: 6f078bb7104a0d5bc3ea17e27bc4760440da6bcf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.bpmn2.modeler.ui.views.outline;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.Activity;
import org.eclipse.bpmn2.BoundaryEvent;
import org.eclipse.bpmn2.CallActivity;
import org.eclipse.bpmn2.CallableElement;
import org.eclipse.bpmn2.CatchEvent;
import org.eclipse.bpmn2.Choreography;
import org.eclipse.bpmn2.ChoreographyActivity;
import org.eclipse.bpmn2.Definitions;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.bpmn2.FlowElementsContainer;
import org.eclipse.bpmn2.FlowNode;
import org.eclipse.bpmn2.Lane;
import org.eclipse.bpmn2.LaneSet;
import org.eclipse.bpmn2.Participant;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.SequenceFlow;
import org.eclipse.bpmn2.SubChoreography;
import org.eclipse.bpmn2.SubProcess;
import org.eclipse.bpmn2.ThrowEvent;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
public class FlowElementTreeEditPart extends AbstractGraphicsTreeEditPart {
public FlowElementTreeEditPart(DiagramTreeEditPart dep, FlowElement flowElement) {
super(dep, flowElement);
}
public FlowElement getFlowElement() {
return (FlowElement) getModel();
}
// ======================= overwriteable behaviour ========================
/**
* Creates the EditPolicies of this EditPart. Subclasses often overwrite
* this method to change the behaviour of the editpart.
*/
@Override
protected void createEditPolicies() {
}
@Override
protected List<Object> getModelChildren() {
List<Object> retList = new ArrayList<Object>();
FlowElement elem = getFlowElement();
if (elem instanceof FlowElementsContainer) {
FlowElementsContainer container = (FlowElementsContainer)elem;
return getFlowElementsContainerChildren(container);
}
else if (elem instanceof ChoreographyActivity) {
ChoreographyActivity ca = (ChoreographyActivity)elem;
retList.addAll(ca.getParticipantRefs());
}
else if (elem instanceof CallActivity) {
// render a Call Activity with its called activity target
// (a Process or Global Task) as the child node.
CallableElement target = ((CallActivity)elem).getCalledElementRef();
if (target!=null) {
retList.add(target);
}
}
else if (elem instanceof CatchEvent) {
retList.addAll(((CatchEvent)elem).getEventDefinitions());
retList.addAll(((CatchEvent)elem).getDataOutputAssociation());
}
else if (elem instanceof ThrowEvent) {
retList.addAll(((ThrowEvent)elem).getEventDefinitions());
retList.addAll(((ThrowEvent)elem).getDataInputAssociation());
}
if (elem instanceof Activity) {
// Boundary Events are children nodes of Activities
Definitions definitions = ModelUtil.getDefinitions(elem);
if (definitions!=null) {
TreeIterator<EObject> iter = definitions.eAllContents();
while (iter.hasNext()) {
EObject o = iter.next();
if (o instanceof BoundaryEvent && ((BoundaryEvent)o).getAttachedToRef() == elem) {
retList.add(o);
}
}
retList.addAll(((Activity)elem).getDataInputAssociations());
retList.addAll(((Activity)elem).getDataOutputAssociations());
}
}
return retList;
}
public static List<Object> getFlowElementsContainerChildren(FlowElementsContainer container) {
List<Object> retList = new ArrayList<Object>();
List<FlowElement> flowElements = new ArrayList<FlowElement>();
for (FlowElement fe : container.getFlowElements()) {
if (!(fe instanceof BoundaryEvent))
flowElements.add(fe);
}
if (container.getLaneSets().size()==0)
retList.addAll(flowElements);
else {
for (LaneSet ls : container.getLaneSets()) {
retList.addAll(ls.getLanes());
}
// only add the flow element if it's not contained in a Lane
List<Object> laneElements = new ArrayList<Object>();
for (FlowElement fe : flowElements) {
boolean inLane = false;
for (LaneSet ls : container.getLaneSets()) {
if (isInLane(fe,ls)) {
inLane = true;
break;
}
}
if (inLane)
laneElements.add(fe);
else
retList.add(fe);
}
// don't include any sequence flows that connect flow
// nodes that are contained in Lanes
List<SequenceFlow> flows = new ArrayList<SequenceFlow>();
for (Object fn : laneElements) {
if (fn instanceof FlowNode) {
for (SequenceFlow sf : ((FlowNode)fn).getIncoming()) {
if (
laneElements.contains(sf.getSourceRef()) &&
laneElements.contains(sf.getTargetRef()) &&
!flows.contains(sf)) {
flows.add(sf);
}
}
for (SequenceFlow sf : ((FlowNode)fn).getOutgoing()) {
if (
laneElements.contains(sf.getSourceRef()) &&
laneElements.contains(sf.getTargetRef()) &&
!flows.contains(sf)) {
flows.add(sf);
}
}
}
}
retList.removeAll(flows);
}
// add the list of Artifacts
if (container instanceof Process) {
retList.addAll(((Process)container).getArtifacts());
}
else if (container instanceof SubProcess) {
retList.addAll(((SubProcess)container).getArtifacts());
}
if (container instanceof SubChoreography) {
retList.addAll(((SubChoreography)container).getArtifacts());
}
if (container instanceof Choreography) {
// Add Pools as children if the Pool has a Process associated with it,
// or if the Participant is NOT referenced by a Choreography Activity.
for (Participant p : ((Choreography)container).getParticipants()) {
if (p.getProcessRef()!=null)
retList.add(p);
else {
for (FlowElement fe : flowElements) {
if (fe instanceof ChoreographyActivity) {
if (!((ChoreographyActivity)fe).getParticipantRefs().contains(p)) {
retList.add(p);
}
}
}
}
}
}
return retList;
}
public static boolean isInLane(FlowElement fe, LaneSet ls) {
if (ls==null || ls.getLanes().size()==0)
return false;
for (Lane ln : ls.getLanes()) {
if (ln.getFlowNodeRefs().contains(fe))
return true;
if (isInLane(fe, ln.getChildLaneSet()))
return true;
}
return false;
}
}