| /******************************************************************************* |
| * 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 |
| * |
| * @author Ivar Meikas |
| ******************************************************************************/ |
| package org.eclipse.bpmn2.modeler.core.di; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.bpmn2.BaseElement; |
| import org.eclipse.bpmn2.Definitions; |
| import org.eclipse.bpmn2.DocumentRoot; |
| import org.eclipse.bpmn2.di.BPMNDiagram; |
| import org.eclipse.bpmn2.di.BPMNEdge; |
| import org.eclipse.bpmn2.di.BPMNPlane; |
| import org.eclipse.bpmn2.di.BPMNShape; |
| import org.eclipse.bpmn2.di.BpmnDiFactory; |
| import org.eclipse.bpmn2.modeler.core.Activator; |
| import org.eclipse.bpmn2.modeler.core.ModelHandler; |
| import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator; |
| import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences; |
| import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil; |
| import org.eclipse.bpmn2.modeler.core.utils.ModelUtil; |
| import org.eclipse.bpmn2.util.Bpmn2Resource; |
| import org.eclipse.dd.dc.Bounds; |
| import org.eclipse.dd.dc.DcFactory; |
| import org.eclipse.dd.dc.Point; |
| import org.eclipse.dd.di.DiagramElement; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.transaction.RecordingCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.graphiti.datatypes.IDimension; |
| import org.eclipse.graphiti.datatypes.ILocation; |
| import org.eclipse.graphiti.dt.IDiagramTypeProvider; |
| import org.eclipse.graphiti.features.IFeatureProvider; |
| import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; |
| import org.eclipse.graphiti.mm.algorithms.styles.Color; |
| import org.eclipse.graphiti.mm.algorithms.styles.Font; |
| import org.eclipse.graphiti.mm.algorithms.styles.Style; |
| 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; |
| 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.platform.IDiagramEditor; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.services.ILayoutService; |
| import org.eclipse.graphiti.ui.editor.DiagramEditor; |
| |
| public class DIUtils { |
| |
| public static void updateDIShape(PictogramElement element) { |
| |
| PictogramLink link = element.getLink(); |
| if (link == null) { |
| return; |
| } |
| |
| BPMNShape bpmnShape = BusinessObjectUtil.getFirstElementOfType(element, BPMNShape.class); |
| if (bpmnShape == null) { |
| return; |
| } |
| |
| ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram((Shape) element); |
| Bounds bounds = bpmnShape.getBounds(); |
| |
| bounds.setX(loc.getX()); |
| bounds.setY(loc.getY()); |
| |
| GraphicsAlgorithm graphicsAlgorithm = element.getGraphicsAlgorithm(); |
| IDimension size = Graphiti.getGaService().calculateSize(graphicsAlgorithm); |
| bounds.setHeight(size.getHeight()); |
| bounds.setWidth(size.getWidth()); |
| |
| if (element instanceof ContainerShape) { |
| EList<Shape> children = ((ContainerShape) element).getChildren(); |
| for (Shape shape : children) { |
| if (shape instanceof ContainerShape) { |
| updateDIShape(shape); |
| } |
| } |
| } |
| |
| updateConnections(element); |
| } |
| |
| public static void updateConnections(PictogramElement element) { |
| if (element instanceof Shape) { |
| EList<Anchor> anchors = ((Shape) element).getAnchors(); |
| |
| for (Anchor anchor : anchors) { |
| List<Connection> connections = Graphiti.getPeService().getAllConnections(anchor); |
| for (Connection connection : connections){ |
| updateDIEdge(connection); |
| } |
| connections.size(); |
| } |
| |
| anchors.size(); |
| } |
| } |
| |
| public static void updateDIEdge(Connection connection) { |
| try { |
| ILayoutService layoutService = Graphiti.getLayoutService(); |
| ModelHandler modelHandler = ModelHandlerLocator.getModelHandler(connection.getLink().getBusinessObjects() |
| .get(0).eResource()); |
| |
| EObject be = BusinessObjectUtil.getFirstElementOfType(connection, BaseElement.class); |
| BPMNEdge edge = (BPMNEdge) modelHandler.findDIElement((BaseElement) be); |
| if (edge!=null) { |
| Point point = DcFactory.eINSTANCE.createPoint(); |
| |
| List<Point> waypoint = edge.getWaypoint(); |
| waypoint.clear(); |
| |
| ILocation loc; |
| loc = layoutService.getLocationRelativeToDiagram(connection.getStart()); |
| point.setX(loc.getX()); |
| point.setY(loc.getY()); |
| waypoint.add(point); |
| |
| if (connection instanceof FreeFormConnection) { |
| FreeFormConnection freeForm = (FreeFormConnection) connection; |
| EList<org.eclipse.graphiti.mm.algorithms.styles.Point> bendpoints = freeForm.getBendpoints(); |
| for (org.eclipse.graphiti.mm.algorithms.styles.Point bp : bendpoints) { |
| point = DcFactory.eINSTANCE.createPoint(); |
| point.setX(bp.getX()); |
| point.setY(bp.getY()); |
| waypoint.add(point); |
| } |
| } |
| |
| point = DcFactory.eINSTANCE.createPoint(); |
| loc = layoutService.getLocationRelativeToDiagram(connection.getEnd()); |
| point.setX(loc.getX()); |
| point.setY(loc.getY()); |
| waypoint.add(point); |
| } |
| } catch (IOException e) { |
| Activator.logError(e); |
| } |
| } |
| |
| static void addBendPoint(FreeFormConnection freeForm, Point point) { |
| freeForm.getBendpoints().add(Graphiti.getGaService().createPoint((int) point.getX(), (int) point.getY())); |
| } |
| |
| public static BPMNShape createDIShape(Shape shape, BaseElement elem, int x, int y, int w, int h, |
| IFeatureProvider fp, Diagram diagram) { |
| |
| EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(diagram) |
| .getBusinessObjects(); |
| BPMNShape bpmnShape = null; |
| |
| for (EObject eObject : businessObjects) { |
| if (eObject instanceof BPMNDiagram) { |
| BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject; |
| |
| bpmnShape = BpmnDiFactory.eINSTANCE.createBPMNShape(); |
| bpmnShape.setBpmnElement(elem); |
| Bounds bounds = DcFactory.eINSTANCE.createBounds(); |
| bounds.setX(x); |
| bounds.setY(y); |
| bounds.setWidth(w); |
| bounds.setHeight(h); |
| bpmnShape.setBounds(bounds); |
| |
| Bpmn2Preferences.getInstance(bpmnDiagram.eResource()).applyBPMNDIDefaults(bpmnShape, null); |
| |
| addShape(bpmnShape,bpmnDiagram); |
| ModelUtil.setID(bpmnShape); |
| |
| fp.link(shape, new Object[] { elem, bpmnShape }); |
| break; |
| } |
| } |
| |
| return bpmnShape; |
| } |
| |
| public static void addShape(DiagramElement elem, BPMNDiagram bpmnDiagram) { |
| List<DiagramElement> elements = bpmnDiagram.getPlane().getPlaneElement(); |
| elements.add(elem); |
| } |
| |
| public static DiagramElement findDiagramElement(List<BPMNDiagram> diagrams, BaseElement bpmnElement) { |
| for (BPMNDiagram d : diagrams) { |
| BPMNPlane plane = d.getPlane(); |
| List<DiagramElement> planeElements = plane.getPlaneElement(); |
| return findPlaneElement(planeElements, bpmnElement); |
| } |
| return null; |
| } |
| |
| public static DiagramElement findPlaneElement(List<DiagramElement> planeElements, BaseElement bpmnElement) { |
| for (DiagramElement de : planeElements) { |
| if (de instanceof BPMNShape) { |
| if (bpmnElement == ((BPMNShape)de).getBpmnElement()) |
| return de; |
| } |
| if (de instanceof BPMNEdge) { |
| if (bpmnElement == ((BPMNEdge)de).getBpmnElement()) |
| return de; |
| } |
| else if (de instanceof BPMNPlane) { |
| return findPlaneElement(((BPMNPlane)de).getPlaneElement(), bpmnElement); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return the Graphiti Diagram for the given BPMNDiagram. If one does not exist, create it. |
| * |
| * @param editor |
| * @param bpmnDiagram |
| * @return |
| */ |
| public static Diagram getOrCreateDiagram(final IDiagramEditor editor, final BPMNDiagram bpmnDiagram) { |
| // do we need to create a new Diagram or is this already in the model? |
| Diagram diagram = findDiagram(editor, bpmnDiagram); |
| if (diagram!=null) { |
| // already exists |
| return diagram; |
| } |
| |
| // create a new one |
| IDiagramTypeProvider dtp = editor.getDiagramTypeProvider(); |
| String typeId = dtp.getDiagram().getDiagramTypeId(); |
| final Diagram newDiagram = Graphiti.getCreateService().createDiagram(typeId, bpmnDiagram.getName(), true); |
| final IFeatureProvider featureProvider = dtp.getFeatureProvider(); |
| final Resource resource = dtp.getDiagram().eResource(); |
| TransactionalEditingDomain domain = editor.getEditingDomain(); |
| domain.getCommandStack().execute(new RecordingCommand(domain) { |
| protected void doExecute() { |
| resource.getContents().add(newDiagram); |
| newDiagram.setActive(true); |
| featureProvider.link(newDiagram, bpmnDiagram); |
| } |
| }); |
| return newDiagram; |
| } |
| |
| /** |
| * Find the Graphiti Diagram that corresponds to the given BPMNDiagram object. |
| * |
| * @param editor |
| * @param bpmnDiagram |
| * @return |
| */ |
| public static Diagram findDiagram(final IDiagramEditor editor, final BPMNDiagram bpmnDiagram) { |
| ResourceSet resourceSet = editor.getResourceSet(); |
| if (resourceSet!=null) { |
| return findDiagram(resourceSet, bpmnDiagram); |
| } |
| return null; |
| } |
| |
| public static Diagram findDiagram(ResourceSet resourceSet, final BPMNDiagram bpmnDiagram) { |
| if (resourceSet!=null) { |
| for (Resource r : resourceSet.getResources()) { |
| for (EObject o : r.getContents()) { |
| if (o instanceof Diagram) { |
| Diagram diagram = (Diagram)o; |
| if (BusinessObjectUtil.getFirstElementOfType(diagram, BPMNDiagram.class) == bpmnDiagram) { |
| return diagram; |
| } |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static void deleteDiagram(final IDiagramEditor editor, final BPMNDiagram bpmnDiagram) { |
| Diagram diagram = DIUtils.findDiagram(editor, bpmnDiagram); |
| if (diagram!=null) { |
| List<EObject> list = new ArrayList<EObject>(); |
| TreeIterator<EObject> iter = diagram.eAllContents(); |
| while (iter.hasNext()) { |
| EObject o = iter.next(); |
| if (o instanceof PictogramLink) { |
| ((PictogramLink)o).getBusinessObjects().clear(); |
| if (!list.contains(o)) |
| list.add(o); |
| } |
| else if (o instanceof Color) { |
| if (!list.contains(o)) |
| list.add(o); |
| } |
| else if (o instanceof Font) { |
| if (!list.contains(o)) |
| list.add(o); |
| } |
| else if (o instanceof Style) { |
| if (!list.contains(o)) |
| list.add(o); |
| } |
| } |
| for (EObject o : list) |
| EcoreUtil.delete(o); |
| |
| EcoreUtil.delete(diagram); |
| EcoreUtil.delete(bpmnDiagram); |
| } |
| } |
| |
| public static BPMNDiagram findBPMNDiagram(final IDiagramEditor editor, final BaseElement baseElement, boolean deep) { |
| if (baseElement!=null) { |
| ResourceSet resourceSet = editor.getResourceSet(); |
| if (resourceSet!=null) { |
| for (Resource r : resourceSet.getResources()) { |
| if (r instanceof Bpmn2Resource) { |
| for (EObject o : r.getContents()) { |
| if (o instanceof DocumentRoot) { |
| DocumentRoot root = (DocumentRoot)o; |
| Definitions defs = root.getDefinitions(); |
| for (BPMNDiagram d : defs.getDiagrams()) { |
| BPMNDiagram bpmnDiagram = (BPMNDiagram)d; |
| BaseElement bpmnElement = bpmnDiagram.getPlane().getBpmnElement(); |
| if (bpmnElement == baseElement) |
| return bpmnDiagram; |
| if (deep) { |
| for (DiagramElement de : bpmnDiagram.getPlane().getPlaneElement()) { |
| if (de instanceof BPMNShape) |
| bpmnElement = ((BPMNShape)de).getBpmnElement(); |
| else if (de instanceof BPMNEdge) |
| bpmnElement = ((BPMNEdge)de).getBpmnElement(); |
| else |
| continue; |
| if (bpmnElement == baseElement) |
| return bpmnDiagram; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| public static BPMNDiagram createBPMNDiagram(Definitions definitions, BaseElement container) { |
| |
| Resource resource = definitions.eResource(); |
| BPMNDiagram bpmnDiagram = BpmnDiFactory.eINSTANCE.createBPMNDiagram(); |
| ModelUtil.setID(bpmnDiagram, resource); |
| bpmnDiagram.setName(ModelUtil.getDisplayName(container)); |
| |
| BPMNPlane plane = BpmnDiFactory.eINSTANCE.createBPMNPlane(); |
| ModelUtil.setID(plane, resource); |
| plane.setBpmnElement(container); |
| |
| bpmnDiagram.setPlane(plane); |
| |
| // this has to happen last because the IResourceChangeListener in the DesignEditor |
| // looks for add/remove to Definitions.diagrams |
| definitions.getDiagrams().add(bpmnDiagram); |
| |
| return bpmnDiagram; |
| } |
| } |