/* Copyright 2012-2015 SAP SE * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.activiti.designer.security.features; import java.util.Collection; import java.util.List; import org.activiti.designer.eclipse.bpmn.GraphicInfo; import org.activiti.designer.util.style.StyleUtil; import org.eclipse.bpmn2.EndEvent; import org.eclipse.bpmn2.FlowNode; import org.eclipse.bpmn2.Gateway; import org.eclipse.bpmn2.SequenceFlow; import org.eclipse.bpmn2.SubProcess; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.features.context.IAddConnectionContext; import org.eclipse.graphiti.features.context.IAddContext; import org.eclipse.graphiti.features.impl.AbstractAddFeature; import org.eclipse.graphiti.mm.GraphicsAlgorithmContainer; import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; import org.eclipse.graphiti.mm.algorithms.Polygon; import org.eclipse.graphiti.mm.algorithms.Polyline; import org.eclipse.graphiti.mm.algorithms.Text; import org.eclipse.graphiti.mm.algorithms.styles.LineStyle; import org.eclipse.graphiti.mm.algorithms.styles.Point; import org.eclipse.graphiti.mm.algorithms.styles.StylesFactory; import org.eclipse.graphiti.mm.pictograms.Anchor; import org.eclipse.graphiti.mm.pictograms.ChopboxAnchor; import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator; import org.eclipse.graphiti.mm.pictograms.ContainerShape; 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.graphiti.services.IGaService; import org.eclipse.graphiti.services.IPeCreateService; import org.eclipse.graphiti.util.IColorConstant; import org.eclipse.securebpmn2.SecurityFlow; /** * */ public class AddSecurityFlowFeature extends AbstractAddFeature { public AddSecurityFlowFeature(IFeatureProvider fp) { super(fp); } @SuppressWarnings("unchecked") public PictogramElement add(IAddContext context) { IAddConnectionContext addConContext = (IAddConnectionContext) context; SecurityFlow addedSecurityFlow = (SecurityFlow) context.getNewObject(); Anchor sourceAnchor = null; Anchor targetAnchor = null; if(addConContext.getSourceAnchor() == null) { EList<Shape> shapeList = getDiagram().getChildren(); for (Shape shape : shapeList) { FlowNode flowNode = (FlowNode) getBusinessObjectForPictogramElement(shape.getGraphicsAlgorithm().getPictogramElement()); if(flowNode == null || flowNode.getId() == null || addedSecurityFlow.getSourceRefNode() == null || addedSecurityFlow.getTargetRefNode() == null) continue; if(flowNode.getId().equals(addedSecurityFlow.getSourceRefNode().getId())) { EList<Anchor> anchorList = ((ContainerShape) shape).getAnchors(); for (Anchor anchor : anchorList) { if(anchor instanceof ChopboxAnchor) { sourceAnchor = anchor; break; } } } if(flowNode.getId().equals(addedSecurityFlow.getTargetRefNode().getId())) { EList<Anchor> anchorList = ((ContainerShape) shape).getAnchors(); for (Anchor anchor : anchorList) { if(anchor instanceof ChopboxAnchor) { targetAnchor = anchor; break; } } } } } else { sourceAnchor = addConContext.getSourceAnchor(); targetAnchor = addConContext.getTargetAnchor(); } if(sourceAnchor == null || targetAnchor == null) { return null; } boolean inSubProcess = false; Object parentObject = null; ContainerShape parentShape = null; if(sourceAnchor.eContainer() instanceof ContainerShape) { parentShape = (ContainerShape) sourceAnchor.eContainer().eContainer(); parentObject = getBusinessObjectForPictogramElement(parentShape.getGraphicsAlgorithm().getPictogramElement()); if(parentObject != null && parentObject instanceof SubProcess == false) { parentShape = (ContainerShape) targetAnchor.eContainer().eContainer(); parentObject = getBusinessObjectForPictogramElement(parentShape.getGraphicsAlgorithm().getPictogramElement()); } } if (parentObject != null && parentObject instanceof SubProcess) { inSubProcess = true; } IPeCreateService peCreateService = Graphiti.getPeCreateService(); // CONNECTION WITH POLYLINE FreeFormConnection connection = peCreateService.createFreeFormConnection(getDiagram()); connection.setStart(sourceAnchor); connection.setEnd(targetAnchor); sourceAnchor.getOutgoingConnections().add(connection); targetAnchor.getIncomingConnections().add(connection); GraphicsAlgorithm sourceGraphics = getPictogramElement( addedSecurityFlow.getSourceRefNode()).getGraphicsAlgorithm(); GraphicsAlgorithm targetGraphics = getPictogramElement( addedSecurityFlow.getTargetRefNode()).getGraphicsAlgorithm(); List<GraphicInfo> bendpointList = null; if(addConContext.getProperty("org.activiti.designer.bendpoints") != null) { bendpointList = (List<GraphicInfo>) addConContext.getProperty("org.activiti.designer.bendpoints"); } if(bendpointList != null && bendpointList.size() >= 0) { for (GraphicInfo graphicInfo : bendpointList) { Point bendPoint = StylesFactory.eINSTANCE.createPoint(); if(inSubProcess == true) { bendPoint.setX(parentShape.getGraphicsAlgorithm().getX() + graphicInfo.x); bendPoint.setY(parentShape.getGraphicsAlgorithm().getY() + graphicInfo.y); } else { bendPoint.setX(graphicInfo.x); bendPoint.setY(graphicInfo.y); } connection.getBendpoints().add(bendPoint); } } else { /*if (addedSequenceFlow.getSourceRef() instanceof Gateway && addedSequenceFlow.getTargetRef() instanceof Gateway == false) { if (((sourceGraphics.getY() + 10) < targetGraphics.getY() || (sourceGraphics.getY() - 10) > targetGraphics.getY()) && (sourceGraphics.getX() + (sourceGraphics.getWidth() / 2)) < targetGraphics.getX()) { boolean subProcessWithBendPoint = false; if(addedSequenceFlow.getTargetRef() instanceof SubProcess) { int middleSub = targetGraphics.getY() + (targetGraphics.getHeight() / 2); if((sourceGraphics.getY() + 20) < middleSub || (sourceGraphics.getY() - 20) > middleSub) { subProcessWithBendPoint = true; } } if(addedSequenceFlow.getTargetRef() instanceof SubProcess == false || subProcessWithBendPoint == true) { Point bendPoint = StylesFactory.eINSTANCE.createPoint(); if(inSubProcess == true) { bendPoint.setX(parentShape.getGraphicsAlgorithm().getX() + sourceGraphics.getX() + 20); bendPoint.setY(parentShape.getGraphicsAlgorithm().getY() + targetGraphics.getY() + (targetGraphics.getHeight() / 2)); } else { bendPoint.setX(sourceGraphics.getX() + 20); bendPoint.setY(targetGraphics.getY() + (targetGraphics.getHeight() / 2)); } connection.getBendpoints().add(bendPoint); } } } else if (addedSequenceFlow.getTargetRef() instanceof Gateway) { if (((sourceGraphics.getY() + 10) < targetGraphics.getY() || (sourceGraphics.getY() - 10) > targetGraphics.getY()) && (sourceGraphics.getX() + sourceGraphics.getWidth()) < targetGraphics.getX()) { boolean subProcessWithBendPoint = false; if(addedSequenceFlow.getSourceRef() instanceof SubProcess) { int middleSub = sourceGraphics.getY() + (sourceGraphics.getHeight() / 2); if((middleSub + 20) < targetGraphics.getY() || (middleSub - 20) > targetGraphics.getY()) { subProcessWithBendPoint = true; } } if(addedSequenceFlow.getSourceRef() instanceof SubProcess == false || subProcessWithBendPoint == true) { Point bendPoint = StylesFactory.eINSTANCE.createPoint(); if(inSubProcess == true) { bendPoint.setX(parentShape.getGraphicsAlgorithm().getX() + targetGraphics.getX() + 20); bendPoint.setY(parentShape.getGraphicsAlgorithm().getY() + sourceGraphics.getY() + (sourceGraphics.getHeight() / 2)); } else { bendPoint.setX(targetGraphics.getX() + 20); bendPoint.setY(sourceGraphics.getY() + (sourceGraphics.getHeight() / 2)); } connection.getBendpoints().add(bendPoint); } } } else if (addedSequenceFlow.getTargetRef() instanceof EndEvent) { int middleSource = sourceGraphics.getY() + (sourceGraphics.getHeight() / 2); int middleTarget = targetGraphics.getY() + (targetGraphics.getHeight() / 2); if (((middleSource + 10) < middleTarget && (sourceGraphics.getX() + sourceGraphics.getWidth()) < targetGraphics.getX()) || ((middleSource - 10) > middleTarget && (sourceGraphics.getX() + sourceGraphics.getWidth()) < targetGraphics.getX())) { Point bendPoint = StylesFactory.eINSTANCE.createPoint(); if(inSubProcess == true) { bendPoint.setX(parentShape.getGraphicsAlgorithm().getX() + targetGraphics.getX() + (targetGraphics.getWidth() / 2)); bendPoint.setY(parentShape.getGraphicsAlgorithm().getY() + sourceGraphics.getY() + (sourceGraphics.getHeight() / 2)); } else { bendPoint.setX(targetGraphics.getX() + (targetGraphics.getWidth() / 2)); bendPoint.setY(sourceGraphics.getY() + (sourceGraphics.getHeight() / 2)); } connection.getBendpoints().add(bendPoint); } }*/ } IGaService gaService = Graphiti.getGaService(); Polyline polyline = gaService.createPolyline(connection); polyline.setLineStyle(LineStyle.SOLID); polyline.setForeground(Graphiti.getGaService().manageColor(getDiagram(), IColorConstant.LIGHT_BLUE)); // create link and wire it link(connection, addedSecurityFlow); // add dynamic text decorator for the reference name ConnectionDecorator textDecorator = peCreateService.createConnectionDecorator(connection, true, 0.5, true); Text text = gaService.createDefaultText(getDiagram(), textDecorator); text.setStyle(StyleUtil.getStyleForTask((getDiagram()))); gaService.setLocation(text, 10, 0); // set reference name in the text decorator SecurityFlow securityFlow = (SecurityFlow) context.getNewObject(); text.setValue(securityFlow.getName()); // add static graphical decorators (composition and navigable) ConnectionDecorator cd = peCreateService.createConnectionDecorator(connection, false, 1.0, true); createArrow(cd); return connection; } public boolean canAdd(IAddContext context) { // return true if given business object is an EReference // note, that the context must be an instance of IAddConnectionContext if (context instanceof IAddConnectionContext && context.getNewObject() instanceof SecurityFlow) { return true; } return false; } private Polygon createArrow(GraphicsAlgorithmContainer gaContainer) { int xy[] = new int[] { -10, -5, 0, 0, -10, 5, -8, 0 }; int beforeAfter[] = new int[] { 3, 3, 0, 0, 3, 3, 3, 3 }; Polygon polyline = Graphiti.getGaCreateService().createPolygon(gaContainer, xy, beforeAfter); polyline.setStyle(StyleUtil.getStyleForPolygon(getDiagram())); polyline.setForeground(Graphiti.getGaService().manageColor(getDiagram(), IColorConstant.LIGHT_BLUE)); return polyline; } private PictogramElement getPictogramElement(EObject businessObject) { Collection<PictogramLink> pictogramLinks = getDiagram().getPictogramLinks(); for (PictogramLink pictogramLink : pictogramLinks) { List<EObject> businessObjects = pictogramLink.getBusinessObjects(); for (EObject obj : businessObjects) { if (EcoreUtil.equals((EObject) businessObject, obj)) { PictogramElement pe = pictogramLink.getPictogramElement(); if (pe != null) { return pe; } } } } return null; } }