/******************************************************************************* * Copyright (c) 2011 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.features.choreography; import static org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties.INITIATING_PARTICIPANT_REF; import static org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties.MESSAGE_REF_IDS; import static org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties.PARTICIPANT_REF_IDS; import static org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties.R; import static org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties.TEXT_H; import static org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographyUtil.drawMultiplicityMarkers; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.eclipse.bpmn2.ChoreographyActivity; import org.eclipse.bpmn2.ChoreographyTask; import org.eclipse.bpmn2.Participant; import org.eclipse.bpmn2.di.BPMNShape; import org.eclipse.bpmn2.di.ParticipantBandKind; import org.eclipse.bpmn2.modeler.core.Activator; import org.eclipse.bpmn2.modeler.core.ModelHandler; import org.eclipse.bpmn2.modeler.core.di.DIImport; import org.eclipse.bpmn2.modeler.core.features.AbstractBpmnAddFeature; import org.eclipse.bpmn2.modeler.core.features.choreography.ChoreographyProperties; import org.eclipse.bpmn2.modeler.core.utils.AnchorUtil; import org.eclipse.bpmn2.modeler.core.utils.StyleUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.IAddContext; import org.eclipse.graphiti.mm.algorithms.RoundedRectangle; import org.eclipse.graphiti.mm.algorithms.Text; import org.eclipse.graphiti.mm.algorithms.styles.Orientation; import org.eclipse.graphiti.mm.pictograms.ContainerShape; import org.eclipse.graphiti.mm.pictograms.PictogramElement; import org.eclipse.graphiti.mm.pictograms.Shape; import org.eclipse.graphiti.services.Graphiti; import org.eclipse.graphiti.services.IGaService; import org.eclipse.graphiti.services.IPeService; public class ChoreographyAddFeature extends AbstractBpmnAddFeature { protected final IGaService gaService = Graphiti.getGaService(); protected final IPeService peService = Graphiti.getPeService(); public ChoreographyAddFeature(IFeatureProvider fp) { super(fp); } @Override public boolean canAdd(IAddContext context) { return context.getTargetContainer().equals(getDiagram()); } @Override public PictogramElement add(IAddContext context) { ChoreographyActivity choreography = (ChoreographyActivity) context.getNewObject(); int width = context.getWidth() > 0 ? context.getWidth() : 150; int height = context.getHeight() > 0 ? context.getHeight() : 150; ContainerShape choreographyContainer = peService.createContainerShape(context.getTargetContainer(), true); RoundedRectangle containerRect = gaService.createRoundedRectangle(choreographyContainer, R, R); gaService.setLocationAndSize(containerRect, context.getX(), context.getY(), width, height); StyleUtil.applyBGStyle(containerRect, this); decorateContainerRect(containerRect); Object importProperty = context.getProperty(DIImport.IMPORT_PROPERTY); if (importProperty != null && (Boolean) importProperty) { addedFromImport(choreography, choreographyContainer, context); } Shape nameShape = peService.createShape(choreographyContainer, false); Text text = gaService.createDefaultText(getDiagram(), nameShape); text.setValue(choreography.getName()); text.setStyle(StyleUtil.getStyleForText(getDiagram())); text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER); text.setVerticalAlignment(Orientation.ALIGNMENT_TOP); text.getFont().setBold(false); setTextLocation(choreographyContainer, text, width, height); peService.setPropertyValue(nameShape, ChoreographyProperties.CHOREOGRAPHY_NAME, Boolean.toString(true)); // use it when property editor supports enums // ContainerShape markerShape = peService.createContainerShape(choreographyContainer, false); // Rectangle markerRectangle = gaService.createInvisibleRectangle(markerShape); // List<ContainerShape> bands = ChoreographyUtil.getParticipantBandContainerShapes(choreographyContainer); // List<ContainerShape> bottomBands = ChoreographyUtil.getTopAndBottomBands(bands).getSecond(); // int x = (width / 2) - (MARKER_H / 2); // int y = height - MARKER_H; // if (!bottomBands.isEmpty()) { // ContainerShape b = bottomBands.get(0); // y = b.getGraphicsAlgorithm().getY() - MARKER_H; // } // gaService.setLocationAndSize(markerRectangle, x, y, MARKER_H, MARKER_H); // ChoreographyUtil.drawChoreographyLoopType(markerShape, choreography.getLoopType()); // // String loopType = choreography.getLoopType() == null ? "null" : choreography.getLoopType().getName(); // peService.setPropertyValue(choreographyContainer, ChoreographyProperties.CHOREOGRAPHY_MARKER, loopType); // // peService.setPropertyValue(markerShape, ChoreographyProperties.CHOREOGRAPHY_MARKER_SHAPE, // Boolean.toString(true)); if (choreography instanceof ChoreographyTask) { peService.setPropertyValue(choreographyContainer, MESSAGE_REF_IDS, ChoreographyUtil.getMessageRefIds((ChoreographyTask) choreography)); } peService.createChopboxAnchor(choreographyContainer); createDIShape(choreographyContainer, choreography); AnchorUtil.addFixedPointAnchors(choreographyContainer, containerRect); ChoreographyUtil.drawMessageLinks(choreographyContainer); return choreographyContainer; } protected void decorateContainerRect(RoundedRectangle containerRect) { } protected void addedFromImport(ChoreographyActivity choreography, ContainerShape choreographyContainer, IAddContext context) { ModelHandler mh = null; try { mh = ModelHandler.getInstance(getDiagram()); } catch (IOException e) { Activator.logError(e); return; } List<Participant> participants = choreography.getParticipantRefs(); List<BPMNShape> shapes = mh.getAll(BPMNShape.class); List<BPMNShape> filteredShapes = new ArrayList<BPMNShape>(); BPMNShape choreoBpmnShape = null; for (BPMNShape shape : shapes) { if (shape.getBpmnElement().equals(choreography)) { choreoBpmnShape = shape; break; } } for (BPMNShape shape : shapes) { if (participants.contains(shape.getBpmnElement()) && choreoBpmnShape.equals(shape.getChoreographyActivityShape())) { filteredShapes.add(shape); } } for (BPMNShape bpmnShape : filteredShapes) { ParticipantBandKind bandKind = bpmnShape.getParticipantBandKind(); ContainerShape createdShape = ChoreographyUtil.createParticipantBandContainerShape(bandKind, choreographyContainer, bpmnShape, isShowNames()); createDIShape(createdShape, bpmnShape.getBpmnElement(), bpmnShape); Participant p = (Participant) bpmnShape.getBpmnElement(); if (p.getParticipantMultiplicity() != null && p.getParticipantMultiplicity().getMaximum() > 1) { drawMultiplicityMarkers(createdShape); } } peService.setPropertyValue(choreographyContainer, PARTICIPANT_REF_IDS, ChoreographyUtil.getParticipantRefIds(choreography)); Participant initiatingParticipant = choreography.getInitiatingParticipantRef(); String id = initiatingParticipant == null ? "null" : initiatingParticipant.getId(); peService.setPropertyValue(choreographyContainer, INITIATING_PARTICIPANT_REF, id); } protected void setTextLocation(ContainerShape choreographyContainer, Text text, int w, int h) { int y = (h / 2) - (TEXT_H / 2); gaService.setLocationAndSize(text, 0, y, w, TEXT_H); } protected boolean isShowNames() { return true; } }