blob: 1c3c22d9ccf9718a493f8676a8287e3cb56bf63e [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
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Definitions;
import org.eclipse.bpmn2.FlowElementsContainer;
import org.eclipse.bpmn2.Participant;
import org.eclipse.bpmn2.di.BPMNDiagram;
import org.eclipse.bpmn2.di.BPMNPlane;
import org.eclipse.bpmn2.di.BPMNShape;
import org.eclipse.bpmn2.modeler.core.di.DIUtils;
import org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyUtil;
import org.eclipse.bpmn2.modeler.core.model.ModelHandler;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.bpmn2.modeler.ui.ImageProvider;
import org.eclipse.dd.di.DiagramElement;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IContext;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import org.eclipse.graphiti.mm.algorithms.styles.Color;
import org.eclipse.graphiti.mm.algorithms.styles.Font;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.algorithms.styles.Style;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.PictogramLink;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.osgi.util.NLS;
/**
* @author Bob Brodt
*
*/
public class PullupFeature extends AbstractCustomFeature {
protected String description;
/**
* @param fp
*/
public PullupFeature(IFeatureProvider fp) {
super(fp);
}
@Override
public String getName() {
return Messages.PullupFeature_Name;
}
@Override
public String getDescription() {
if (description==null)
description = Messages.PullupFeature_Description;
return description;
}
@Override
public String getImageId() {
return ImageProvider.IMG_16_PULLUP;
}
@Override
public boolean isAvailable(IContext context) {
if (context instanceof ICustomContext) {
PictogramElement[] pes = ((ICustomContext)context).getPictogramElements();
if (pes != null && pes.length == 1) {
PictogramElement pe = pes[0];
if (!ChoreographyUtil.isChoreographyParticipantBand(pe)) {
return true;
}
}
}
return false;
}
@Override
public boolean canExecute(ICustomContext context) {
PictogramElement[] pes = context.getPictogramElements();
if (pes != null && pes.length == 1) {
PictogramElement pe = pes[0];
if (ChoreographyUtil.isChoreographyParticipantBand(pe))
return false;
Object bo = getBusinessObjectForPictogramElement(pe);
description = NLS.bind(
Messages.PullupFeature_Description_1,
ModelUtil.getLabel(bo)
);
if (bo instanceof Participant) {
bo = ((Participant)bo).getProcessRef();
}
if (bo instanceof FlowElementsContainer) {
BPMNDiagram bpmnDiagram = DIUtils.findBPMNDiagram((BaseElement)bo);
return bpmnDiagram != null;
}
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public void execute(ICustomContext context) {
// we already know there's one and only one PE element in canExecute() and that it's
// a ContainerShape for an expandable activity
ContainerShape shape = (ContainerShape)context.getPictogramElements()[0];
Object bo = getBusinessObjectForPictogramElement(shape);
BPMNDiagram bpmnDiagram = DIUtils.findBPMNDiagram(shape);
BPMNShape bpmnShape = null;
if (bo instanceof Participant) {
bpmnShape = DIUtils.findBPMNShape(bpmnDiagram, (Participant)bo);
bo = ((Participant)bo).getProcessRef();
}
else if (bo instanceof FlowElementsContainer) {
bpmnShape = DIUtils.findBPMNShape(bpmnDiagram, (FlowElementsContainer)bo);
}
FlowElementsContainer container = (FlowElementsContainer)bo;
// find out which BPMNPlane this sub process lives in - this will be the new home
// for the DI elements in the existing BPMNDiagram.
BPMNDiagram newBpmnDiagram = DIUtils.getBPMNDiagram(bpmnShape);
BPMNPlane newPlane = newBpmnDiagram.getPlane();
Diagram newDiagram = DIUtils.findDiagram(getDiagramBehavior(), newBpmnDiagram);
BPMNDiagram oldBpmnDiagram = DIUtils.findBPMNDiagram(container);
BPMNPlane oldPlane = oldBpmnDiagram.getPlane();
Diagram oldDiagram = DIUtils.findDiagram(getDiagramBehavior(), oldBpmnDiagram);
// copy the elements into the same plane as the sub process
while (oldPlane.getPlaneElement().size()>0) {
DiagramElement de = oldPlane.getPlaneElement().get(0);
newPlane.getPlaneElement().add(de);
}
// copy the Graphiti diagram elements
ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram(shape);
shape.getChildren().addAll( oldDiagram.getChildren() );
for (Connection c : oldDiagram.getConnections()) {
if (c instanceof FreeFormConnection) {
// adjust connection bendpoints
FreeFormConnection ffc = (FreeFormConnection)c;
for (Point pp : ffc.getBendpoints()) {
pp.setX( pp.getX() + loc.getX() );
pp.setY( pp.getY() + loc.getY() );
}
}
}
newDiagram.getConnections().addAll( oldDiagram.getConnections() );
newDiagram.getPictogramLinks().addAll(oldDiagram.getPictogramLinks());
newDiagram.getColors().addAll(oldDiagram.getColors());
newDiagram.getFonts().addAll(oldDiagram.getFonts());
newDiagram.getStyles().addAll(oldDiagram.getStyles());
// get rid of the old BPMNDiagram
DIUtils.deleteDiagram(getDiagramBehavior(), oldBpmnDiagram);
// expand the sub process
if (FeatureSupport.isExpandableElement(container)) {
bpmnShape.setIsExpanded(false);
ExpandFlowNodeFeature expandFeature = new ExpandFlowNodeFeature(getFeatureProvider());
expandFeature.execute(context);
}
}
}