protected DiagramNode transformBoundsForImage(DiagramNode diagramBoundsImage, DiagramNode diagramBoundsXml, DiagramNode elementBounds) { double scalingFactorX = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); double scalingFactorY = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); DiagramNode elementBoundsForImage = new DiagramNode(elementBounds.getId()); elementBoundsForImage.setX((double) Math.round((elementBounds.getX() - diagramBoundsXml.getX()) * scalingFactorX + diagramBoundsImage.getX())); elementBoundsForImage.setY((double) Math.round((elementBounds.getY() - diagramBoundsXml.getY()) * scalingFactorY + diagramBoundsImage.getY())); elementBoundsForImage.setWidth((double) Math.round(elementBounds.getWidth() * scalingFactorX)); elementBoundsForImage.setHeight((double) Math.round(elementBounds.getHeight() * scalingFactorY)); return elementBoundsForImage; }
protected DiagramNode parseBounds(Element boundsElement) { DiagramNode bounds = new DiagramNode(); bounds.setX(Double.valueOf(boundsElement.getAttribute("x"))); bounds.setY(Double.valueOf(boundsElement.getAttribute("y"))); bounds.setWidth(Double.valueOf(boundsElement.getAttribute("width"))); bounds.setHeight(Double.valueOf(boundsElement.getAttribute("height"))); return bounds; }
protected Map<String, DiagramNode> fixFlowNodePositionsIfModelFromAdonis(Document bpmnModel, Map<String, DiagramNode> elementBoundsFromBpmnDi) { if (isExportedFromAdonis50(bpmnModel)) { Map<String, DiagramNode> mapOfFixedBounds = new HashMap<String, DiagramNode>(); XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); xPath.setNamespaceContext(new Bpmn20NamespaceContext()); for (Entry<String, DiagramNode> entry : elementBoundsFromBpmnDi.entrySet()) { String elementId = entry.getKey(); DiagramNode elementBounds = entry.getValue(); String expression = "local-name(//bpmn:*[@id = '" + elementId + "'])"; try { XPathExpression xPathExpression = xPath.compile(expression); String elementLocalName = xPathExpression.evaluate(bpmnModel); if (!"participant".equals(elementLocalName) && !"lane".equals(elementLocalName) && !"textAnnotation".equals(elementLocalName) && !"group".equals(elementLocalName)) { elementBounds.setX(elementBounds.getX() - elementBounds.getWidth() / 2); elementBounds.setY(elementBounds.getY() - elementBounds.getHeight() / 2); } } catch (XPathExpressionException e) { throw new ActivitiException("Error while evaluating the following XPath expression on a BPMN XML document: '" + expression + "'.", e); } mapOfFixedBounds.put(elementId, elementBounds); } return mapOfFixedBounds; } else { return elementBoundsFromBpmnDi; } }
protected Map<String, DiagramNode> getElementBoundsFromBpmnDi(Document bpmnModel) { Map<String, DiagramNode> listOfBounds = new HashMap<String, DiagramNode>(); // iterate over all DI shapes NodeList shapes = bpmnModel.getElementsByTagNameNS(BpmnParser.BPMN_DI_NS, "BPMNShape"); for (int i = 0; i < shapes.getLength(); i++) { Element shape = (Element) shapes.item(i); String bpmnElementId = shape.getAttribute("bpmnElement"); // get bounds of shape NodeList childNodes = shape.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node childNode = childNodes.item(j); if (childNode instanceof Element && BpmnParser.BPMN_DC_NS.equals(childNode.getNamespaceURI()) && "Bounds".equals(childNode.getLocalName())) { DiagramNode bounds = parseBounds((Element) childNode); bounds.setId(bpmnElementId); listOfBounds.put(bpmnElementId, bounds); break; } } } return listOfBounds; }
listOfBounds.put(diagramBoundsXml.getId(), diagramBoundsXml);
protected DiagramNode transformBoundsForImage(DiagramNode diagramBoundsImage, DiagramNode diagramBoundsXml, DiagramNode elementBounds) { double scalingFactorX = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); double scalingFactorY = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); DiagramNode elementBoundsForImage = new DiagramNode(elementBounds.getId()); elementBoundsForImage.setX((double) Math.round((elementBounds.getX() - diagramBoundsXml.getX()) * scalingFactorX + diagramBoundsImage.getX())); elementBoundsForImage.setY((double) Math.round((elementBounds.getY() - diagramBoundsXml.getY()) * scalingFactorY + diagramBoundsImage.getY())); elementBoundsForImage.setWidth((double) Math.round(elementBounds.getWidth() * scalingFactorX)); elementBoundsForImage.setHeight((double) Math.round(elementBounds.getHeight() * scalingFactorY)); return elementBoundsForImage; }
protected DiagramNode parseBounds(Element boundsElement) { DiagramNode bounds = new DiagramNode(); bounds.setX(Double.valueOf(boundsElement.getAttribute("x"))); bounds.setY(Double.valueOf(boundsElement.getAttribute("y"))); bounds.setWidth(Double.valueOf(boundsElement.getAttribute("width"))); bounds.setHeight(Double.valueOf(boundsElement.getAttribute("height"))); return bounds; }
protected Map<String, DiagramNode> fixFlowNodePositionsIfModelFromAdonis(Document bpmnModel, Map<String, DiagramNode> elementBoundsFromBpmnDi) { if (isExportedFromAdonis50(bpmnModel)) { Map<String, DiagramNode> mapOfFixedBounds = new HashMap<>(); XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); xPath.setNamespaceContext(new Bpmn20NamespaceContext()); for (Entry<String, DiagramNode> entry : elementBoundsFromBpmnDi.entrySet()) { String elementId = entry.getKey(); DiagramNode elementBounds = entry.getValue(); String expression = "local-name(//bpmn:*[@id = '" + elementId + "'])"; try { XPathExpression xPathExpression = xPath.compile(expression); String elementLocalName = xPathExpression.evaluate(bpmnModel); if (!"participant".equals(elementLocalName) && !"lane".equals(elementLocalName) && !"textAnnotation".equals(elementLocalName) && !"group".equals(elementLocalName)) { elementBounds.setX(elementBounds.getX() - elementBounds.getWidth() / 2); elementBounds.setY(elementBounds.getY() - elementBounds.getHeight() / 2); } } catch (XPathExpressionException e) { throw new ActivitiException("Error while evaluating the following XPath expression on a BPMN XML document: '" + expression + "'.", e); } mapOfFixedBounds.put(elementId, elementBounds); } return mapOfFixedBounds; } else { return elementBoundsFromBpmnDi; } }
protected Map<String, DiagramNode> getElementBoundsFromBpmnDi(Document bpmnModel) { Map<String, DiagramNode> listOfBounds = new HashMap<String, DiagramNode>(); // iterate over all DI shapes NodeList shapes = bpmnModel.getElementsByTagNameNS(BpmnParser.BPMN_DI_NS, "BPMNShape"); for (int i = 0; i < shapes.getLength(); i++) { Element shape = (Element) shapes.item(i); String bpmnElementId = shape.getAttribute("bpmnElement"); // get bounds of shape NodeList childNodes = shape.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node childNode = childNodes.item(j); if (childNode instanceof Element && BpmnParser.BPMN_DC_NS.equals(childNode.getNamespaceURI()) && "Bounds".equals(childNode.getLocalName())) { DiagramNode bounds = parseBounds((Element) childNode); bounds.setId(bpmnElementId); listOfBounds.put(bpmnElementId, bounds); break; } } } return listOfBounds; }
/** * Provides positions and dimensions of elements in a BPMN process diagram as provided by {@link RepositoryService#getProcessDiagram(String)}. * * @param bpmnModel BPMN 2.0 XML document * @param imageStream BPMN 2.0 diagram in PNG format (JPEG and other formats supported by {@link ImageIO} may also work) * @return Layout of the process diagram; null when parameter imageStream is null */ public DiagramLayout getBpmnProcessDiagramLayout(Document bpmnModel, InputStream imageStream) { if (imageStream == null) { return null; } DiagramNode diagramBoundsXml = getDiagramBoundsFromBpmnDi(bpmnModel); DiagramNode diagramBoundsImage; if (isExportedFromAdonis50(bpmnModel)) { int offsetTop = 29; // Adonis header int offsetBottom = 61; // Adonis footer diagramBoundsImage = getDiagramBoundsFromImage(imageStream, offsetTop, offsetBottom); } else { diagramBoundsImage = getDiagramBoundsFromImage(imageStream); } Map<String, DiagramNode> listOfBounds = new HashMap<>(); listOfBounds.put(diagramBoundsXml.getId(), diagramBoundsXml); // listOfBounds.putAll(getElementBoundsFromBpmnDi(bpmnModel)); listOfBounds.putAll(fixFlowNodePositionsIfModelFromAdonis(bpmnModel, getElementBoundsFromBpmnDi(bpmnModel))); Map<String, DiagramElement> listOfBoundsForImage = transformBoundsForImage(diagramBoundsImage, diagramBoundsXml, listOfBounds); return new DiagramLayout(listOfBoundsForImage); }
protected DiagramNode transformBoundsForImage(DiagramNode diagramBoundsImage, DiagramNode diagramBoundsXml, DiagramNode elementBounds) { double scalingFactorX = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); double scalingFactorY = diagramBoundsImage.getWidth() / diagramBoundsXml.getWidth(); DiagramNode elementBoundsForImage = new DiagramNode(elementBounds.getId()); elementBoundsForImage.setX((double) Math.round((elementBounds.getX() - diagramBoundsXml.getX()) * scalingFactorX + diagramBoundsImage.getX())); elementBoundsForImage.setY((double) Math.round((elementBounds.getY() - diagramBoundsXml.getY()) * scalingFactorY + diagramBoundsImage.getY())); elementBoundsForImage.setWidth((double) Math.round(elementBounds.getWidth() * scalingFactorX)); elementBoundsForImage.setHeight((double) Math.round(elementBounds.getHeight() * scalingFactorY)); return elementBoundsForImage; }
protected DiagramNode parseBounds(Element boundsElement) { DiagramNode bounds = new DiagramNode(); bounds.setX(Double.valueOf(boundsElement.getAttribute("x"))); bounds.setY(Double.valueOf(boundsElement.getAttribute("y"))); bounds.setWidth(Double.valueOf(boundsElement.getAttribute("width"))); bounds.setHeight(Double.valueOf(boundsElement.getAttribute("height"))); return bounds; }
protected Map<String, DiagramNode> fixFlowNodePositionsIfModelFromAdonis(Document bpmnModel, Map<String, DiagramNode> elementBoundsFromBpmnDi) { if (isExportedFromAdonis50(bpmnModel)) { Map<String, DiagramNode> mapOfFixedBounds = new HashMap<String, DiagramNode>(); XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); xPath.setNamespaceContext(new Bpmn20NamespaceContext()); for (Entry<String, DiagramNode> entry : elementBoundsFromBpmnDi.entrySet()) { String elementId = entry.getKey(); DiagramNode elementBounds = entry.getValue(); String expression = "local-name(//bpmn:*[@id = '" + elementId + "'])"; try { XPathExpression xPathExpression = xPath.compile(expression); String elementLocalName = xPathExpression.evaluate(bpmnModel); if (!"participant".equals(elementLocalName) && !"lane".equals(elementLocalName) && !"textAnnotation".equals(elementLocalName) && !"group".equals(elementLocalName)) { elementBounds.setX(elementBounds.getX() - elementBounds.getWidth()/2); elementBounds.setY(elementBounds.getY() - elementBounds.getHeight()/2); } } catch (XPathExpressionException e) { throw new ActivitiException("Error while evaluating the following XPath expression on a BPMN XML document: '" + expression + "'.", e); } mapOfFixedBounds.put(elementId, elementBounds); } return mapOfFixedBounds; } else { return elementBoundsFromBpmnDi; } }
protected Map<String, DiagramNode> getElementBoundsFromBpmnDi(Document bpmnModel) { Map<String, DiagramNode> listOfBounds = new HashMap<>(); // iterate over all DI shapes NodeList shapes = bpmnModel.getElementsByTagNameNS(BpmnParser.BPMN_DI_NS, "BPMNShape"); for (int i = 0; i < shapes.getLength(); i++) { Element shape = (Element) shapes.item(i); String bpmnElementId = shape.getAttribute("bpmnElement"); // get bounds of shape NodeList childNodes = shape.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node childNode = childNodes.item(j); if (childNode instanceof Element && BpmnParser.BPMN_DC_NS.equals(childNode.getNamespaceURI()) && "Bounds".equals(childNode.getLocalName())) { DiagramNode bounds = parseBounds((Element) childNode); bounds.setId(bpmnElementId); listOfBounds.put(bpmnElementId, bounds); break; } } } return listOfBounds; }
/** * Provides positions and dimensions of elements in a BPMN process diagram as provided by {@link RepositoryService#getProcessDiagram(String)}. * * @param bpmnXmlStream * BPMN 2.0 XML document * @param imageStream * BPMN 2.0 diagram in PNG format (JPEG and other formats supported by {@link ImageIO} may also work) * @return Layout of the process diagram * @return null when parameter imageStream is null */ public DiagramLayout getBpmnProcessDiagramLayout(Document bpmnModel, InputStream imageStream) { if (imageStream == null) { return null; } DiagramNode diagramBoundsXml = getDiagramBoundsFromBpmnDi(bpmnModel); DiagramNode diagramBoundsImage; if (isExportedFromAdonis50(bpmnModel)) { int offsetTop = 29; // Adonis header int offsetBottom = 61; // Adonis footer diagramBoundsImage = getDiagramBoundsFromImage(imageStream, offsetTop, offsetBottom); } else { diagramBoundsImage = getDiagramBoundsFromImage(imageStream); } Map<String, DiagramNode> listOfBounds = new HashMap<String, DiagramNode>(); listOfBounds.put(diagramBoundsXml.getId(), diagramBoundsXml); // listOfBounds.putAll(getElementBoundsFromBpmnDi(bpmnModel)); listOfBounds.putAll(fixFlowNodePositionsIfModelFromAdonis(bpmnModel, getElementBoundsFromBpmnDi(bpmnModel))); Map<String, DiagramElement> listOfBoundsForImage = transformBoundsForImage(diagramBoundsImage, diagramBoundsXml, listOfBounds); return new DiagramLayout(listOfBoundsForImage); }
DiagramNode diagramBounds = new DiagramNode("BPMNDiagram"); diagramBounds.setX(minX); diagramBounds.setY(minY); diagramBounds.setWidth(maxX - minX); diagramBounds.setHeight(maxY - minY); return diagramBounds;
DiagramNode diagramBounds = new DiagramNode("BPMNDiagram"); diagramBounds.setX(minX); diagramBounds.setY(minY); diagramBounds.setWidth(maxX - minX); diagramBounds.setHeight(maxY - minY); return diagramBounds;