diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/ActivitiConfig.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/ActivitiConfig.java
new file mode 100644
index 00000000..64b34801
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/config/ActivitiConfig.java
@@ -0,0 +1,34 @@
+package com.jero.modules.activiti.config;
+
+import com.jero.modules.activiti.service.impl.image.ICustomProcessDiagramGenerator;
+import org.activiti.engine.impl.form.DoubleFormType;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+/**
+ * @author liJiaRao
+ * @date 2023-09-05 17:53
+ */
+public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {
+ @Autowired
+ private ICustomProcessDiagramGenerator customProcessDiagramGenerator;
+ @Autowired
+ private DoubleFormType doubleFormType;
+
+ /**
+ * 解決工作流生成图片乱码问题
+ *
+ * @param processEngineConfiguration
+ */
+ @Override
+ public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
+ int[] result = {};
+ processEngineConfiguration.setActivityFontName("宋体");
+ processEngineConfiguration.setAnnotationFontName("宋体");
+ processEngineConfiguration.setLabelFontName("宋体");
+ processEngineConfiguration.setProcessDiagramGenerator(customProcessDiagramGenerator);
+ }
+
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramCanvas.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramCanvas.java
deleted file mode 100644
index 2c7c87d7..00000000
--- a/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramCanvas.java
+++ /dev/null
@@ -1,2097 +0,0 @@
-package com.jero.modules.activiti.config;
-
-
-import org.activiti.bpmn.model.AssociationDirection;
-import org.activiti.bpmn.model.EventSubProcess;
-import org.activiti.bpmn.model.GraphicInfo;
-import org.activiti.bpmn.model.Transaction;
-import org.activiti.image.exception.ActivitiImageException;
-import org.activiti.image.impl.ProcessDiagramSVGGraphics2D;
-import org.activiti.image.impl.icon.*;
-import org.apache.batik.dom.GenericDOMImplementation;
-import org.apache.batik.svggen.SVGGraphics2DIOException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.font.FontRenderContext;
-import java.awt.font.LineBreakMeasurer;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.awt.geom.*;
-import java.awt.image.BufferedImage;
-import java.io.*;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
-import java.util.ArrayList;
-import java.util.List;
-/**
- * @author liJiaRao
- * @date 2023-08-04 11:18
- */
-/**
- 1. Represents a canvas on which BPMN 2.0 constructs can be drawn.
- 2.
- 3. @see org.activiti.image.impl.DefaultProcessDiagramGenerator
- */
-public class DefaultProcessDiagramCanvas {
-
- protected static final Logger LOGGER = LoggerFactory.getLogger(DefaultProcessDiagramCanvas.class);
-
- public enum SHAPE_TYPE {
- Rectangle,
- Rhombus,
- Ellipse
- }
-
- // Predefined sized
- protected static final int ARROW_WIDTH = 5;
- protected static final int CONDITIONAL_INDICATOR_WIDTH = 16;
- protected static final int DEFAULT_INDICATOR_WIDTH = 10;
- protected static final int MARKER_WIDTH = 12;
- protected static final int FONT_SIZE = 11;
- protected static final int FONT_SPACING = 2;
- protected static final int TEXT_PADDING = 3;
- protected static final int ANNOTATION_TEXT_PADDING = 7;
- //protected static final int ARROW_WIDTH = 5;
- //protected static final int CONDITIONAL_INDICATOR_WIDTH = 13;
- //protected static final int DEFAULT_INDICATOR_WIDTH = 8;
- //protected static final int MARKER_WIDTH = 6;
- //protected static final int FONT_SIZE = 8;
- //protected static final int FONT_SPACING = 1;
- //protected static final int TEXT_PADDING = 2;
- //protected static final int ANNOTATION_TEXT_PADDING = 4;
- protected static final int LINE_HEIGHT = FONT_SIZE + FONT_SPACING;
-
- // Colors
- protected static Color TASK_BOX_COLOR = new Color(249,
- 249,
- 249);
- protected static Color SUBPROCESS_BOX_COLOR = new Color(255,
- 255,
- 255);
- protected static Color EVENT_COLOR = new Color(255,
- 255,
- 255);
- protected static Color CONNECTION_COLOR = new Color(88,
- 88,
- 88);
- protected static Color CONDITIONAL_INDICATOR_COLOR = new Color(255,
- 255,
- 255);
- protected static Color HIGHLIGHT_COLOR = Color.GREEN; // 已流转高亮节点颜色
- protected static Color FINISHHIGHLIGHT_COLOR = Color.decode("#F68535") ; // 当前节点颜色
- protected static Color LABEL_COLOR = new Color(112,
- 146,
- 190);
- protected static Color TASK_BORDER_COLOR = new Color(187,
- 187,
- 187);
- protected static Color EVENT_BORDER_COLOR = new Color(88,
- 88,
- 88);
- protected static Color SUBPROCESS_BORDER_COLOR = new Color(0,
- 0,
- 0);
-
- // Fonts
- protected static Font LABEL_FONT = null;
- protected static Font ANNOTATION_FONT = null;
-
- // Strokes
- protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(3.0f); // 流程节点圆圈大小
- protected static Stroke GATEWAY_TYPE_STROKE = new BasicStroke(3.0f);
- protected static Stroke END_EVENT_STROKE = new BasicStroke(3.0f); // 结束节点圆圈大小
- protected static Stroke MULTI_INSTANCE_STROKE = new BasicStroke(1.3f);
- protected static Stroke EVENT_SUBPROCESS_STROKE = new BasicStroke(1.0f,
- BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_MITER,
- 1.0f,
- new float[]{1.0f},
- 0.0f);
- protected static Stroke NON_INTERRUPTING_EVENT_STROKE = new BasicStroke(1.0f,
- BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_MITER,
- 1.0f,
- new float[]{4.0f, 3.0f},
- 0.0f);
- protected static Stroke HIGHLIGHT_FLOW_STROKE = new BasicStroke(1.3f);
- protected static Stroke ANNOTATION_STROKE = new BasicStroke(2.0f);
- protected static Stroke ASSOCIATION_STROKE = new BasicStroke(2.0f,
- BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_MITER,
- 1.0f,
- new float[]{2.0f, 2.0f},
- 0.0f);
-
- // icons
- protected static int ICON_PADDING = 5;
- protected static TaskIconType USERTASK_IMAGE;
- protected static TaskIconType SCRIPTTASK_IMAGE;
- protected static TaskIconType SERVICETASK_IMAGE;
- protected static TaskIconType RECEIVETASK_IMAGE;
- protected static TaskIconType SENDTASK_IMAGE;
- protected static TaskIconType MANUALTASK_IMAGE;
- protected static TaskIconType BUSINESS_RULE_TASK_IMAGE;
-
- protected static IconType TIMER_IMAGE;
- protected static IconType COMPENSATE_THROW_IMAGE;
- protected static IconType COMPENSATE_CATCH_IMAGE;
- protected static IconType ERROR_THROW_IMAGE;
- protected static IconType ERROR_CATCH_IMAGE;
- protected static IconType MESSAGE_CATCH_IMAGE;
- protected static IconType SIGNAL_CATCH_IMAGE;
- protected static IconType SIGNAL_THROW_IMAGE;
-
- protected int canvasWidth = -1;
- protected int canvasHeight = -1;
- protected int minX = -1;
- protected int minY = -1;
- protected ProcessDiagramSVGGraphics2D g;
- protected FontMetrics fontMetrics;
- protected boolean closed;
- protected BufferedImage processDiagram;
- protected ClassLoader customClassLoader;
- protected String activityFontName = "宋体";
- protected String labelFontName = "宋体";
- protected String annotationFontName = "宋体";
-
- /**
- * Creates an empty canvas with given width and height.
- *
- * Allows to specify minimal boundaries on the left and upper side of the
- * canvas. This is useful for diagrams that have white space there.
- * Everything beneath these minimum values will be cropped.
- * It's also possible to pass a specific font name and a class loader for the icon images.
- */
- public DefaultProcessDiagramCanvas(int width,
- int height,
- int minX,
- int minY,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
-
- this.canvasWidth = width;
- this.canvasHeight = height;
- this.minX = minX;
- this.minY = minY;
- if (activityFontName != null) {
- this.activityFontName = activityFontName;
- }
- if (labelFontName != null) {
- this.labelFontName = labelFontName;
- }
- if (annotationFontName != null) {
- this.annotationFontName = annotationFontName;
- }
-
- initialize();
- }
-
- public DefaultProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
- this.canvasWidth = width;
- this.canvasHeight = height;
- this.minX = minX;
- this.minY = minY;
- if(activityFontName != null) {
- this.activityFontName = activityFontName;
- }
-
- if(labelFontName != null) {
- this.labelFontName = labelFontName;
- }
-
- if(annotationFontName != null) {
- this.annotationFontName = annotationFontName;
- }
-
- this.customClassLoader = customClassLoader;
- this.initialize(imageType);
- }
-
- /**
- * Creates an empty canvas with given width and height.
- *
- * Allows to specify minimal boundaries on the left and upper side of the
- * canvas. This is useful for diagrams that have white space there (eg
- * Signavio). Everything beneath these minimum values will be cropped.
- * @param minX Hint that will be used when generating the image. Parts that fall
- * below minX on the horizontal scale will be cropped.
- * @param minY Hint that will be used when generating the image. Parts that fall
- * below minX on the horizontal scale will be cropped.
- */
- public DefaultProcessDiagramCanvas(int width,
- int height,
- int minX,
- int minY) {
- this.canvasWidth = width;
- this.canvasHeight = height;
- this.minX = minX;
- this.minY = minY;
-
- initialize();
- }
-
- public void initialize(String imageType) {
- if("png".equalsIgnoreCase(imageType)) {
- this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 2);
- } else {
- this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 1);
- }
-
- // Get a DOMImplementation.
- DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
-
- // Create an instance of org.w3c.dom.Document.
- String svgNS = "http://www.w3.org/2000/svg";
- Document document = domImpl.createDocument(svgNS,
- "svg",
- null);
-
- // Create an instance of the SVG Generator.`
- this.g = new ProcessDiagramSVGGraphics2D(document);
-
- this.g.setSVGCanvasSize(new Dimension(this.canvasWidth, this.canvasHeight));
-
- this.g.setBackground(new Color(255,
- 255,
- 255,
- 0));
- this.g.clearRect(0,
- 0,
- canvasWidth,
- canvasHeight);
-
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g.setPaint(Color.black);
-
- Font font = new Font(activityFontName,
- Font.BOLD,
- FONT_SIZE);
- g.setFont(font);
- this.fontMetrics = g.getFontMetrics();
-
- LABEL_FONT = new Font(labelFontName,
- Font.ITALIC,
- 10);
- ANNOTATION_FONT = new Font(annotationFontName,
- Font.PLAIN,
- FONT_SIZE);
-
- USERTASK_IMAGE = new UserTaskIconType();
- SCRIPTTASK_IMAGE = new ScriptTaskIconType();
- SERVICETASK_IMAGE = new ServiceTaskIconType();
- RECEIVETASK_IMAGE = new ReceiveTaskIconType();
- SENDTASK_IMAGE = new SendTaskIconType();
- MANUALTASK_IMAGE = new ManualTaskIconType();
- BUSINESS_RULE_TASK_IMAGE = new BusinessRuleTaskIconType();
-
- TIMER_IMAGE = new TimerIconType();
- COMPENSATE_THROW_IMAGE = new CompensateThrowIconType();
- COMPENSATE_CATCH_IMAGE = new CompensateIconType();
- ERROR_THROW_IMAGE = new ErrorThrowIconType();
- ERROR_CATCH_IMAGE = new ErrorIconType();
- MESSAGE_CATCH_IMAGE = new MessageIconType();
- SIGNAL_THROW_IMAGE = new SignalThrowIconType();
- SIGNAL_CATCH_IMAGE = new SignalIconType();
- }
-
- public void initialize() {
- // Get a DOMImplementation.
- DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
-
- // Create an instance of org.w3c.dom.Document.
- String svgNS = "http://www.w3.org/2000/svg";
- Document document = domImpl.createDocument(svgNS,
- "svg",
- null);
-
- // Create an instance of the SVG Generator.
- this.g = new ProcessDiagramSVGGraphics2D(document);
-
- this.g.setSVGCanvasSize(new Dimension(this.canvasWidth, this.canvasHeight));
-
- this.g.setBackground(new Color(255,
- 255,
- 255,
- 0));
- this.g.clearRect(0,
- 0,
- canvasWidth,
- canvasHeight);
-
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- g.setPaint(Color.black);
-
- Font font = new Font(activityFontName,
- Font.BOLD,
- FONT_SIZE);
- g.setFont(font);
- this.fontMetrics = g.getFontMetrics();
-
- LABEL_FONT = new Font(labelFontName,
- Font.ITALIC,
- 10);
- ANNOTATION_FONT = new Font(annotationFontName,
- Font.PLAIN,
- FONT_SIZE);
-
- USERTASK_IMAGE = new UserTaskIconType();
- SCRIPTTASK_IMAGE = new ScriptTaskIconType();
- SERVICETASK_IMAGE = new ServiceTaskIconType();
- RECEIVETASK_IMAGE = new ReceiveTaskIconType();
- SENDTASK_IMAGE = new SendTaskIconType();
- MANUALTASK_IMAGE = new ManualTaskIconType();
- BUSINESS_RULE_TASK_IMAGE = new BusinessRuleTaskIconType();
-
- TIMER_IMAGE = new TimerIconType();
- COMPENSATE_THROW_IMAGE = new CompensateThrowIconType();
- COMPENSATE_CATCH_IMAGE = new CompensateIconType();
- ERROR_THROW_IMAGE = new ErrorThrowIconType();
- ERROR_CATCH_IMAGE = new ErrorIconType();
- MESSAGE_CATCH_IMAGE = new MessageIconType();
- SIGNAL_THROW_IMAGE = new SignalThrowIconType();
- SIGNAL_CATCH_IMAGE = new SignalIconType();
- }
-
- /**
- * Generates an image of what currently is drawn on the canvas.
- *
- * Throws an {@link ActivitiImageException} when {@link #close()} is already
- * called.
- */
- public InputStream generateImage() {
- if (closed) {
- throw new ActivitiImageException("ProcessDiagramGenerator already closed");
- }
-
- try {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- Writer out;
- out = new OutputStreamWriter(stream,
- "UTF-8");
- g.stream(out,
- true);
- return new ByteArrayInputStream(stream.toByteArray());
- } catch (UnsupportedEncodingException | SVGGraphics2DIOException e) {
- throw new ActivitiImageException("Error while generating process image",
- e);
- }
- }
-
- /**
- * Closes the canvas which dissallows further drawing and releases graphical
- * resources.
- */
- public void close() {
- g.dispose();
- closed = true;
- }
-
- public void drawNoneStartEvent(String id,
- GraphicInfo graphicInfo) {
- drawStartEvent(id,
- graphicInfo,
- null);
- }
-
- public void drawTimerStartEvent(String id,
- GraphicInfo graphicInfo) {
- drawStartEvent(id,
- graphicInfo,
- TIMER_IMAGE);
- }
-
- public void drawSignalStartEvent(String id,
- GraphicInfo graphicInfo) {
- drawStartEvent(id,
- graphicInfo,
- SIGNAL_CATCH_IMAGE);
- }
-
- public void drawMessageStartEvent(String id,
- GraphicInfo graphicInfo) {
- drawStartEvent(id,
- graphicInfo,
- MESSAGE_CATCH_IMAGE);
- }
-
- public void drawStartEvent(String id,
- GraphicInfo graphicInfo,
- IconType icon) {
- Paint originalPaint = g.getPaint();
- g.setPaint(EVENT_COLOR);
- Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight());
- g.fill(circle);
- g.setPaint(EVENT_BORDER_COLOR);
- g.draw(circle);
- g.setPaint(originalPaint);
-
- // calculate coordinates to center image
- if (icon != null) {
- int imageX = (int) Math.round(graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (icon.getWidth() / 2));
- int imageY = (int) Math.round(graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (icon.getHeight() / 2));
-
- icon.drawIcon(imageX,
- imageY,
- ICON_PADDING,
- g);
- }
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawNoneEndEvent(String id,
- String name,
- GraphicInfo graphicInfo) {
- Paint originalPaint = g.getPaint();
- Stroke originalStroke = g.getStroke();
- g.setPaint(EVENT_COLOR);
- Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight());
- g.fill(circle);
- g.setPaint(EVENT_BORDER_COLOR);
- g.setStroke(END_EVENT_STROKE);
- g.draw(circle);
- g.setStroke(originalStroke);
- g.setPaint(originalPaint);
-
- // set element's id
- g.setCurrentGroupId(id);
-
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawErrorEndEvent(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawNoneEndEvent(id,
- name,
- graphicInfo);
-
- int imageX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 4));
- int imageY = (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 4));
-
- ERROR_THROW_IMAGE.drawIcon(imageX,
- imageY,
- ICON_PADDING,
- g);
- }
-
- public void drawErrorStartEvent(String id,
- GraphicInfo graphicInfo) {
- drawNoneStartEvent(id,
- graphicInfo);
-
- int imageX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 4));
- int imageY = (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 4));
-
- ERROR_THROW_IMAGE.drawIcon(imageX,
- imageY,
- ICON_PADDING,
- g);
- }
-
- public void drawCatchingEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting,
- IconType icon,
- String eventType) {
-
- // event circles
- Ellipse2D outerCircle = new Ellipse2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight());
- int innerCircleSize = 4;
- int innerCircleX = (int) graphicInfo.getX() + innerCircleSize;
- int innerCircleY = (int) graphicInfo.getY() + innerCircleSize;
- int innerCircleWidth = (int) graphicInfo.getWidth() - (2 * innerCircleSize);
- int innerCircleHeight = (int) graphicInfo.getHeight() - (2 * innerCircleSize);
- Ellipse2D innerCircle = new Ellipse2D.Double(innerCircleX,
- innerCircleY,
- innerCircleWidth,
- innerCircleHeight);
-
- Paint originalPaint = g.getPaint();
- Stroke originalStroke = g.getStroke();
- g.setPaint(EVENT_COLOR);
- g.fill(outerCircle);
-
- g.setPaint(EVENT_BORDER_COLOR);
- if (!isInterrupting) {
- g.setStroke(NON_INTERRUPTING_EVENT_STROKE);
- }
- g.draw(outerCircle);
- g.setStroke(originalStroke);
- g.setPaint(originalPaint);
- g.draw(innerCircle);
-
- if (icon != null) {
- // calculate coordinates to center image
- int imageX = (int) (graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (icon.getWidth() / 2));
- int imageY = (int) (graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (icon.getHeight() / 2));
- if ("timer".equals(eventType)) {
- // move image one pixel to center timer image
- imageX++;
- imageY++;
- }
- icon.drawIcon(imageX,
- imageY,
- ICON_PADDING,
- g);
- }
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawCatchingCompensateEvent(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingCompensateEvent(id,
- graphicInfo,
- isInterrupting);
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawCatchingCompensateEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
-
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- COMPENSATE_CATCH_IMAGE,
- "compensate");
- }
-
- public void drawCatchingTimerEvent(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingTimerEvent(id,
- graphicInfo,
- isInterrupting);
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawCatchingTimerEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- TIMER_IMAGE,
- "timer");
- }
-
- public void drawCatchingErrorEvent(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingErrorEvent(id,
- graphicInfo,
- isInterrupting);
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawCatchingErrorEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
-
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- ERROR_CATCH_IMAGE,
- "error");
- }
-
- public void drawCatchingSignalEvent(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingSignalEvent(id,
- graphicInfo,
- isInterrupting);
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawCatchingSignalEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- SIGNAL_CATCH_IMAGE,
- "signal");
- }
-
- public void drawCatchingMessageEvent(String id,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
-
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- MESSAGE_CATCH_IMAGE,
- "message");
- }
-
- public void drawCatchingMessageEvent(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean isInterrupting) {
- drawCatchingEvent(id,
- graphicInfo,
- isInterrupting,
- MESSAGE_CATCH_IMAGE,
- "message");
-
- drawLabel(name,
- graphicInfo);
- }
-
- public void drawThrowingCompensateEvent(String id,
- GraphicInfo graphicInfo) {
- drawCatchingEvent(id,
- graphicInfo,
- true,
- COMPENSATE_THROW_IMAGE,
- "compensate");
- }
-
- public void drawThrowingSignalEvent(String id,
- GraphicInfo graphicInfo) {
- drawCatchingEvent(id,
- graphicInfo,
- true,
- SIGNAL_THROW_IMAGE,
- "signal");
- }
-
- public void drawThrowingNoneEvent(String id,
- GraphicInfo graphicInfo) {
- drawCatchingEvent(id,
- graphicInfo,
- true,
- null,
- "none");
- }
-
- public void drawSequenceflow(int srcX,
- int srcY,
- int targetX,
- int targetY,
- boolean conditional) {
- drawSequenceflow(srcX,
- srcY,
- targetX,
- targetY,
- conditional,
- false);
- }
-
- public void drawSequenceflow(int srcX,
- int srcY,
- int targetX,
- int targetY,
- boolean conditional,
- boolean highLighted) {
- Paint originalPaint = g.getPaint();
- if (highLighted) {
- g.setPaint(HIGHLIGHT_COLOR);
- }
-
- Line2D.Double line = new Line2D.Double(srcX,
- srcY,
- targetX,
- targetY);
- g.draw(line);
- drawArrowHead(line);
-
- if (conditional) {
- drawConditionalSequenceFlowIndicator(line);
- }
-
- if (highLighted) {
- g.setPaint(originalPaint);
- }
- }
-
- public void drawSequenceflow(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, boolean highLighted, double scaleFactor) {
- this.drawConnection(xPoints, yPoints, conditional, isDefault, "sequenceFlow", AssociationDirection.ONE, highLighted, scaleFactor);
- }
-
- public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDirection, boolean highLighted, double scaleFactor) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(CONNECTION_COLOR);
- if(connectionType.equals("association")) {
- this.g.setStroke(ASSOCIATION_STROKE);
- } else if(highLighted) {
- this.g.setPaint(HIGHLIGHT_COLOR);
- this.g.setStroke(HIGHLIGHT_FLOW_STROKE);
- }
-
- for(int i = 1; i < xPoints.length; ++i) {
- Integer sourceX = Integer.valueOf(xPoints[i - 1]);
- Integer sourceY = Integer.valueOf(yPoints[i - 1]);
- Integer targetX = Integer.valueOf(xPoints[i]);
- Integer targetY = Integer.valueOf(yPoints[i]);
- Line2D.Double line = new Line2D.Double((double)sourceX.intValue(), (double)sourceY.intValue(), (double)targetX.intValue(), (double)targetY.intValue());
- this.g.draw(line);
- }
-
- Line2D.Double line;
- if(isDefault) {
- line = new Line2D.Double((double)xPoints[0], (double)yPoints[0], (double)xPoints[1], (double)yPoints[1]);
- this.drawDefaultSequenceFlowIndicator(line);
- }
-
- if(conditional) {
- line = new Line2D.Double((double)xPoints[0], (double)yPoints[0], (double)xPoints[1], (double)yPoints[1]);
- this.drawConditionalSequenceFlowIndicator(line);
- }
-
- if(associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) {
- line = new Line2D.Double((double)xPoints[xPoints.length - 2], (double)yPoints[xPoints.length - 2], (double)xPoints[xPoints.length - 1], (double)yPoints[xPoints.length - 1]);
- this.drawArrowHead(line);
- }
-
- if(associationDirection.equals(AssociationDirection.BOTH)) {
- line = new Line2D.Double((double)xPoints[1], (double)yPoints[1], (double)xPoints[0], (double)yPoints[0]);
- this.drawArrowHead(line);
- }
-
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawAssociation(int[] xPoints,
- int[] yPoints,
- AssociationDirection associationDirection,
- boolean highLighted) {
- boolean conditional = false;
- boolean isDefault = false;
- drawConnection(xPoints,
- yPoints,
- conditional,
- isDefault,
- "association",
- associationDirection,
- highLighted);
- }
-
- public void drawSequenceflow(int[] xPoints,
- int[] yPoints,
- boolean conditional,
- boolean isDefault,
- boolean highLighted) {
- drawConnection(xPoints,
- yPoints,
- conditional,
- isDefault,
- "sequenceFlow",
- AssociationDirection.ONE,
- highLighted);
- }
-
- public void drawConnection(int[] xPoints,
- int[] yPoints,
- boolean conditional,
- boolean isDefault,
- String connectionType,
- AssociationDirection associationDirection,
- boolean highLighted) {
-
- Paint originalPaint = g.getPaint();
- Stroke originalStroke = g.getStroke();
-
- g.setPaint(CONNECTION_COLOR);
- if ("association".equals(connectionType)) {
- g.setStroke(ASSOCIATION_STROKE);
- } else if (highLighted) {
- g.setPaint(HIGHLIGHT_COLOR);
- g.setStroke(HIGHLIGHT_FLOW_STROKE);
- }
-
- for (int i = 1; i < xPoints.length; i++) {
- Integer sourceX = xPoints[i - 1];
- Integer sourceY = yPoints[i - 1];
- Integer targetX = xPoints[i];
- Integer targetY = yPoints[i];
- Line2D.Double line = new Line2D.Double(sourceX,
- sourceY,
- targetX,
- targetY);
- g.draw(line);
- }
-
- if (isDefault) {
- Line2D.Double line = new Line2D.Double(xPoints[0],
- yPoints[0],
- xPoints[1],
- yPoints[1]);
- drawDefaultSequenceFlowIndicator(line);
- }
-
- if (conditional) {
- Line2D.Double line = new Line2D.Double(xPoints[0],
- yPoints[0],
- xPoints[1],
- yPoints[1]);
- drawConditionalSequenceFlowIndicator(line);
- }
-
- if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) {
- Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2],
- yPoints[xPoints.length - 2],
- xPoints[xPoints.length - 1],
- yPoints[xPoints.length - 1]);
- drawArrowHead(line);
- }
- if (associationDirection.equals(AssociationDirection.BOTH)) {
- Line2D.Double line = new Line2D.Double(xPoints[1],
- yPoints[1],
- xPoints[0],
- yPoints[0]);
- drawArrowHead(line);
- }
- g.setPaint(originalPaint);
- g.setStroke(originalStroke);
- }
-
- public void drawSequenceflowWithoutArrow(int srcX,
- int srcY,
- int targetX,
- int targetY,
- boolean conditional) {
- drawSequenceflowWithoutArrow(srcX,
- srcY,
- targetX,
- targetY,
- conditional,
- false);
- }
-
- public void drawSequenceflowWithoutArrow(int srcX,
- int srcY,
- int targetX,
- int targetY,
- boolean conditional,
- boolean highLighted) {
- Paint originalPaint = g.getPaint();
- if (highLighted) {
- g.setPaint(HIGHLIGHT_COLOR);
- }
-
- Line2D.Double line = new Line2D.Double(srcX,
- srcY,
- targetX,
- targetY);
- g.draw(line);
-
- if (conditional) {
- drawConditionalSequenceFlowIndicator(line);
- }
-
- if (highLighted) {
- g.setPaint(originalPaint);
- }
- }
-
- public void drawArrowHead(Line2D.Double line) {
- int doubleArrowWidth = (int) (2 * ARROW_WIDTH);
- if (doubleArrowWidth == 0) {
- doubleArrowWidth = 2;
- }
- Polygon arrowHead = new Polygon();
- arrowHead.addPoint(0,
- 0);
- int arrowHeadPoint = (int) (-ARROW_WIDTH);
- if (arrowHeadPoint == 0) {
- arrowHeadPoint = -1;
- }
- arrowHead.addPoint(arrowHeadPoint,
- -doubleArrowWidth);
- arrowHeadPoint = (int) (ARROW_WIDTH);
- if (arrowHeadPoint == 0) {
- arrowHeadPoint = 1;
- }
- arrowHead.addPoint(arrowHeadPoint,
- -doubleArrowWidth);
-
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- double angle = Math.atan2(line.y2 - line.y1,
- line.x2 - line.x1);
- transformation.translate(line.x2,
- line.y2);
- transformation.rotate((angle - Math.PI / 2d));
-
- AffineTransform originalTransformation = g.getTransform();
- g.setTransform(transformation);
- g.fill(arrowHead);
- g.setTransform(originalTransformation);
- }
-
- public void drawDefaultSequenceFlowIndicator(Line2D.Double line) {
- double length = DEFAULT_INDICATOR_WIDTH;
- double halfOfLength = length / 2;
- double f = 8;
- Line2D.Double defaultIndicator = new Line2D.Double(-halfOfLength,
- 0,
- halfOfLength,
- 0);
-
- double angle = Math.atan2(line.y2 - line.y1,
- line.x2 - line.x1);
- double dx = f * Math.cos(angle);
- double dy = f * Math.sin(angle);
- double x1 = line.x1 + dx;
- double y1 = line.y1 + dy;
-
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- transformation.translate(x1,
- y1);
- transformation.rotate((angle - 3 * Math.PI / 4));
-
- AffineTransform originalTransformation = g.getTransform();
- g.setTransform(transformation);
- g.draw(defaultIndicator);
-
- g.setTransform(originalTransformation);
- }
-
- public void drawConditionalSequenceFlowIndicator(Line2D.Double line) {
- int horizontal = (int) (CONDITIONAL_INDICATOR_WIDTH * 0.7);
- int halfOfHorizontal = horizontal / 2;
- int halfOfVertical = CONDITIONAL_INDICATOR_WIDTH / 2;
-
- Polygon conditionalIndicator = new Polygon();
- conditionalIndicator.addPoint(0,
- 0);
- conditionalIndicator.addPoint(-halfOfHorizontal,
- halfOfVertical);
- conditionalIndicator.addPoint(0,
- CONDITIONAL_INDICATOR_WIDTH);
- conditionalIndicator.addPoint(halfOfHorizontal,
- halfOfVertical);
-
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- double angle = Math.atan2(line.y2 - line.y1,
- line.x2 - line.x1);
- transformation.translate(line.x1,
- line.y1);
- transformation.rotate((angle - Math.PI / 2d));
-
- AffineTransform originalTransformation = g.getTransform();
- g.setTransform(transformation);
- g.draw(conditionalIndicator);
-
- Paint originalPaint = g.getPaint();
- g.setPaint(CONDITIONAL_INDICATOR_COLOR);
- g.fill(conditionalIndicator);
-
- g.setPaint(originalPaint);
- g.setTransform(originalTransformation);
- }
-
- public void drawTask(TaskIconType icon,
- String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(id,
- name,
- graphicInfo);
-
- icon.drawIcon((int) graphicInfo.getX(),
- (int) graphicInfo.getY(),
- ICON_PADDING,
- g);
- }
-
- public void drawTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(id,
- name,
- graphicInfo,
- false);
- }
-
- public void drawPoolOrLane(String id,
- String name,
- GraphicInfo graphicInfo) {
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- g.drawRect(x,
- y,
- width,
- height);
-
- // Add the name as text, vertical
- if (name != null && name.length() > 0) {
- // Include some padding
- int availableTextSpace = height - 6;
-
- // Create rotation for derived font
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- transformation.rotate(270 * Math.PI / 180);
-
- Font currentFont = g.getFont();
- Font theDerivedFont = currentFont.deriveFont(transformation);
- g.setFont(theDerivedFont);
-
- String truncated = fitTextToWidth(name,
- availableTextSpace);
- int realWidth = fontMetrics.stringWidth(truncated);
-
- g.drawString(truncated,
- x + 2 + fontMetrics.getHeight(),
- 3 + y + availableTextSpace - (availableTextSpace - realWidth) / 2);
- g.setFont(currentFont);
- }
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- protected void drawTask(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean thickBorder) {
- Paint originalPaint = g.getPaint();
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- // Create a new gradient paint for every task box, gradient depends on x and y and is not relative
- g.setPaint(TASK_BOX_COLOR);
-
- int arcR = 6;
- if (thickBorder) {
- arcR = 3;
- }
-
- // shape
- RoundRectangle2D rect = new RoundRectangle2D.Double(x,
- y,
- width,
- height,
- arcR,
- arcR);
- g.fill(rect);
- g.setPaint(TASK_BORDER_COLOR);
-
- if (thickBorder) {
- Stroke originalStroke = g.getStroke();
- g.setStroke(THICK_TASK_BORDER_STROKE);
- g.draw(rect);
- g.setStroke(originalStroke);
- } else {
- g.draw(rect);
- }
-
- g.setPaint(originalPaint);
- // text
- if (name != null && name.length() > 0) {
- int boxWidth = width - (2 * TEXT_PADDING);
- int boxHeight = height - 16 - ICON_PADDING - ICON_PADDING - MARKER_WIDTH - 2 - 2;
- int boxX = x + width / 2 - boxWidth / 2;
- int boxY = y + height / 2 - boxHeight / 2 + ICON_PADDING + ICON_PADDING - 2 - 2;
-
- drawMultilineCentredText(name,
- boxX,
- boxY,
- boxWidth,
- boxHeight);
-
-
- }
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- protected void drawMultilineCentredText(String text,
- int x,
- int y,
- int boxWidth,
- int boxHeight) {
- drawMultilineText(text,
- x,
- y,
- boxWidth,
- boxHeight,
- true);
- }
-
- protected void drawMultilineAnnotationText(String text,
- int x,
- int y,
- int boxWidth,
- int boxHeight) {
- drawMultilineText(text,
- x,
- y,
- boxWidth,
- boxHeight,
- false);
- }
-
- protected void drawMultilineText(String text,
- int x,
- int y,
- int boxWidth,
- int boxHeight,
- boolean centered) {
- // Create an attributed string based in input text
- AttributedString attributedString = new AttributedString(text);
- attributedString.addAttribute(TextAttribute.FONT,
- g.getFont());
- attributedString.addAttribute(TextAttribute.FOREGROUND,
- Color.black);
-
- AttributedCharacterIterator characterIterator = attributedString.getIterator();
-
- int currentHeight = 0;
- // Prepare a list of lines of text we'll be drawing
- List layouts = new ArrayList();
- String lastLine = null;
-
- LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator,
- g.getFontRenderContext());
-
- TextLayout layout = null;
- // while (measurer.getPosition() < characterIterator.getEndIndex() && currentHeight <= boxHeight) {
- while (measurer.getPosition() < characterIterator.getEndIndex()) {
-
- int previousPosition = measurer.getPosition();
-
- // Request next layout
- layout = measurer.nextLayout(boxWidth);
-
- int height = ((Float) (layout.getDescent() + layout.getAscent() + layout.getLeading())).intValue();
- if (currentHeight + height > boxHeight) {
- // The line we're about to add should NOT be added anymore, append three dots to previous one instead
- // to indicate more text is truncated
- if (!layouts.isEmpty()) {
- layouts.remove(layouts.size() - 1);
-
- if (lastLine.length() >= 4) {
- lastLine = lastLine.substring(0,
- lastLine.length() - 4) + "...";
- }
- layouts.add(new TextLayout(lastLine,
- g.getFont(),
- g.getFontRenderContext()));
- } else {
- // at least, draw one line
- // even if text does not fit
- // in order to avoid empty box
- layouts.add(layout);
- currentHeight += height;
- }
- break;
- } else {
- layouts.add(layout);
- lastLine = text.substring(previousPosition,
- measurer.getPosition());
- currentHeight += height;
- }
- }
- int currentY = y + (centered ? ((boxHeight - currentHeight) / 2) : 0);
- int currentX = 0;
-
- // Actually draw the lines
- for (TextLayout textLayout : layouts) {
-
- currentY += textLayout.getAscent();
- currentX = x + (centered ? ((boxWidth - ((Double) textLayout.getBounds().getWidth()).intValue()) / 2) : 0);
-
- textLayout.draw(g,
- currentX,
- currentY);
- currentY += textLayout.getDescent() + textLayout.getLeading();
- }
- }
-
- protected String fitTextToWidth(String original,
- int width) {
- String text = original;
-
- // remove length for "..."
- int maxWidth = width - 10;
-
- while (fontMetrics.stringWidth(text + "...") > maxWidth && text.length() > 0) {
- text = text.substring(0,
- text.length() - 1);
- }
-
- if (!text.equals(original)) {
- text = text + "...";
- }
-
- return text;
- }
-
- public void drawUserTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(USERTASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawScriptTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(SCRIPTTASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawServiceTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(SERVICETASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawReceiveTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(RECEIVETASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawSendTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(SENDTASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawManualTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(MANUALTASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawBusinessRuleTask(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawTask(BUSINESS_RULE_TASK_IMAGE,
- id,
- name,
- graphicInfo);
- }
-
- public void drawExpandedSubProcess(String id,
- String name,
- GraphicInfo graphicInfo,
- Class> type) {
- RoundRectangle2D rect = new RoundRectangle2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight(),
- 8,
- 8);
-
- if (type.equals(EventSubProcess.class)) {
- Stroke originalStroke = g.getStroke();
- g.setStroke(EVENT_SUBPROCESS_STROKE);
- g.draw(rect);
- g.setStroke(originalStroke);
- } else if (type.equals(Transaction.class)) {
- RoundRectangle2D outerRect = new RoundRectangle2D.Double(graphicInfo.getX()-3,
- graphicInfo.getY()-3,
- graphicInfo.getWidth()+6,
- graphicInfo.getHeight()+6,
- 8,
- 8);
-
- Paint originalPaint = g.getPaint();
- g.setPaint(SUBPROCESS_BOX_COLOR);
- g.fill(outerRect);
- g.setPaint(SUBPROCESS_BORDER_COLOR);
- g.draw(outerRect);
- g.setPaint(SUBPROCESS_BOX_COLOR);
- g.fill(rect);
- g.setPaint(SUBPROCESS_BORDER_COLOR);
- g.draw(rect);
- g.setPaint(originalPaint);
- } else {
- Paint originalPaint = g.getPaint();
- g.setPaint(SUBPROCESS_BOX_COLOR);
- g.fill(rect);
- g.setPaint(SUBPROCESS_BORDER_COLOR);
- g.draw(rect);
- g.setPaint(originalPaint);
- }
-
- if (name != null && !name.isEmpty()) {
- String text = fitTextToWidth(name,
- (int) graphicInfo.getWidth());
- g.drawString(text,
- (int) graphicInfo.getX() + 10,
- (int) graphicInfo.getY() + 15);
- }
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawCollapsedSubProcess(String id,
- String name,
- GraphicInfo graphicInfo,
- Boolean isTriggeredByEvent) {
- drawCollapsedTask(id,
- name,
- graphicInfo,
- false);
- }
-
- public void drawCollapsedCallActivity(String id,
- String name,
- GraphicInfo graphicInfo) {
- drawCollapsedTask(id,
- name,
- graphicInfo,
- true);
- }
-
- protected void drawCollapsedTask(String id,
- String name,
- GraphicInfo graphicInfo,
- boolean thickBorder) {
- // The collapsed marker is now visualized separately
- drawTask(id,
- name,
- graphicInfo,
- thickBorder);
- }
-
- public void drawCollapsedMarker(int x,
- int y,
- int width,
- int height) {
- // rectangle
- int rectangleWidth = MARKER_WIDTH;
- int rectangleHeight = MARKER_WIDTH;
- Rectangle rect = new Rectangle(x + (width - rectangleWidth) / 2,
- y + height - rectangleHeight - 3,
- rectangleWidth,
- rectangleHeight);
- g.draw(rect);
-
- // plus inside rectangle
- Line2D.Double line = new Line2D.Double(rect.getCenterX(),
- rect.getY() + 2,
- rect.getCenterX(),
- rect.getMaxY() - 2);
- g.draw(line);
- line = new Line2D.Double(rect.getMinX() + 2,
- rect.getCenterY(),
- rect.getMaxX() - 2,
- rect.getCenterY());
- g.draw(line);
- }
-
- public void drawActivityMarkers(int x,
- int y,
- int width,
- int height,
- boolean multiInstanceSequential,
- boolean multiInstanceParallel,
- boolean collapsed) {
- if (collapsed) {
- if (!multiInstanceSequential && !multiInstanceParallel) {
- drawCollapsedMarker(x,
- y,
- width,
- height);
- } else {
- drawCollapsedMarker(x - MARKER_WIDTH / 2 - 2,
- y,
- width,
- height);
- if (multiInstanceSequential) {
- drawMultiInstanceMarker(true,
- x + MARKER_WIDTH / 2 + 2,
- y,
- width,
- height);
- } else {
- drawMultiInstanceMarker(false,
- x + MARKER_WIDTH / 2 + 2,
- y,
- width,
- height);
- }
- }
- } else {
- if (multiInstanceSequential) {
- drawMultiInstanceMarker(true,
- x,
- y,
- width,
- height);
- } else if (multiInstanceParallel) {
- drawMultiInstanceMarker(false,
- x,
- y,
- width,
- height);
- }
- }
- }
-
- public void drawGateway(GraphicInfo graphicInfo) {
- Polygon rhombus = new Polygon();
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- rhombus.addPoint(x,
- y + (height / 2));
- rhombus.addPoint(x + (width / 2),
- y + height);
- rhombus.addPoint(x + width,
- y + (height / 2));
- rhombus.addPoint(x + (width / 2),
- y);
- g.draw(rhombus);
- }
-
- public void drawParallelGateway(String id,
- GraphicInfo graphicInfo) {
- // rhombus
- drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- // plus inside rhombus
- Stroke orginalStroke = g.getStroke();
- g.setStroke(GATEWAY_TYPE_STROKE);
- Line2D.Double line = new Line2D.Double(x + 10,
- y + height / 2,
- x + width - 10,
- y + height / 2); // horizontal
- g.draw(line);
- line = new Line2D.Double(x + width / 2,
- y + height - 10,
- x + width / 2,
- y + 10); // vertical
- g.draw(line);
- g.setStroke(orginalStroke);
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawExclusiveGateway(String id,
- GraphicInfo graphicInfo) {
- // rhombus
- drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- int quarterWidth = width / 4;
- int quarterHeight = height / 4;
-
- // X inside rhombus
- Stroke orginalStroke = g.getStroke();
- g.setStroke(GATEWAY_TYPE_STROKE);
- Line2D.Double line = new Line2D.Double(x + quarterWidth + 3,
- y + quarterHeight + 3,
- x + 3 * quarterWidth - 3,
- y + 3 * quarterHeight - 3);
- g.draw(line);
- line = new Line2D.Double(x + quarterWidth + 3,
- y + 3 * quarterHeight - 3,
- x + 3 * quarterWidth - 3,
- y + quarterHeight + 3);
- g.draw(line);
- g.setStroke(orginalStroke);
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawInclusiveGateway(String id,
- GraphicInfo graphicInfo) {
- // rhombus
- drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- int diameter = width / 2;
-
- // circle inside rhombus
- Stroke orginalStroke = g.getStroke();
- g.setStroke(GATEWAY_TYPE_STROKE);
- Ellipse2D.Double circle = new Ellipse2D.Double(((width - diameter) / 2) + x,
- ((height - diameter) / 2) + y,
- diameter,
- diameter);
- g.draw(circle);
- g.setStroke(orginalStroke);
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawEventBasedGateway(String id,
- GraphicInfo graphicInfo) {
- // rhombus
- drawGateway(graphicInfo);
-
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- double scale = .6;
-
- GraphicInfo eventInfo = new GraphicInfo();
- eventInfo.setX(x + width * (1 - scale) / 2);
- eventInfo.setY(y + height * (1 - scale) / 2);
- eventInfo.setWidth(width * scale);
- eventInfo.setHeight(height * scale);
- drawCatchingEvent(null,
- eventInfo,
- true,
- null,
- "eventGateway");
-
- double r = width / 6.;
-
- // create pentagon (coords with respect to center)
- int topX = (int) (.95 * r); // top right corner
- int topY = (int) (-.31 * r);
- int bottomX = (int) (.59 * r); // bottom right corner
- int bottomY = (int) (.81 * r);
-
- int[] xPoints = new int[]{0, topX, bottomX, -bottomX, -topX};
- int[] yPoints = new int[]{-(int) r, topY, bottomY, bottomY, topY};
- Polygon pentagon = new Polygon(xPoints,
- yPoints,
- 5);
- pentagon.translate(x + width / 2,
- y + width / 2);
-
- // draw
- g.drawPolygon(pentagon);
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawMultiInstanceMarker(boolean sequential,
- int x,
- int y,
- int width,
- int height) {
- int rectangleWidth = MARKER_WIDTH;
- int rectangleHeight = MARKER_WIDTH;
- int lineX = x + (width - rectangleWidth) / 2;
- int lineY = y + height - rectangleHeight - 3;
-
- Stroke orginalStroke = g.getStroke();
- g.setStroke(MULTI_INSTANCE_STROKE);
-
- if (sequential) {
- g.draw(new Line2D.Double(lineX,
- lineY,
- lineX + rectangleWidth,
- lineY));
- g.draw(new Line2D.Double(lineX,
- lineY + rectangleHeight / 2,
- lineX + rectangleWidth,
- lineY + rectangleHeight / 2));
- g.draw(new Line2D.Double(lineX,
- lineY + rectangleHeight,
- lineX + rectangleWidth,
- lineY + rectangleHeight));
- } else {
- g.draw(new Line2D.Double(lineX,
- lineY,
- lineX,
- lineY + rectangleHeight));
- g.draw(new Line2D.Double(lineX + rectangleWidth / 2,
- lineY,
- lineX + rectangleWidth / 2,
- lineY + rectangleHeight));
- g.draw(new Line2D.Double(lineX + rectangleWidth,
- lineY,
- lineX + rectangleWidth,
- lineY + rectangleHeight));
- }
-
- g.setStroke(orginalStroke);
- }
-
- public void drawHighLight(int x,
- int y,
- int width,
- int height) {
- Paint originalPaint = g.getPaint();
- Stroke originalStroke = g.getStroke();
-
- g.setPaint(HIGHLIGHT_COLOR);
- g.setStroke(THICK_TASK_BORDER_STROKE);
-
- RoundRectangle2D rect = new RoundRectangle2D.Double(x,
- y,
- width,
- height,
- 20,
- 20);
- g.draw(rect);
-
- g.setPaint(originalPaint);
- g.setStroke(originalStroke);
- }
-
- public void drawHighLight(int x, int y, int width, int height, Color color) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(color);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- RoundRectangle2D rect = new RoundRectangle2D.Double((double)x, (double)y, (double)width, (double)height, 20.0D, 20.0D);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawHighLightEvent(int x, int y, int width, int height, Color color) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- Ellipse2D.Double circle = new Ellipse2D.Double(x, y, width, height);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- this.g.setPaint(color);
- this.g.draw(circle);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawHighLightGateway(int x, int y, int width, int height, Color color){
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- Polygon rhombus = new Polygon();
- this.g.setPaint(color);
- rhombus.addPoint(x, y + (height / 2));
- rhombus.addPoint(x + (width / 2), y + height);
- rhombus.addPoint(x + width, y + (height / 2));
- rhombus.addPoint(x + (width / 2), y);
- this.g.draw(rhombus);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawHighLightTask(int x, int y, int width, int height, Color color) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(color);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- RoundRectangle2D rect = new RoundRectangle2D.Double((double)x, (double)y, (double)width, (double)height, 10.0D, 10.0D);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawHighLightSubProcess(int x, int y, int width, int height, Color color) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(color);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- RoundRectangle2D rect = new RoundRectangle2D.Double(x + 1, y + 1,width - 2, height - 2, 5.0D, 5.0D);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawTextAnnotation(String id,
- String text,
- GraphicInfo graphicInfo) {
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
-
- Font originalFont = g.getFont();
- Stroke originalStroke = g.getStroke();
-
- g.setFont(ANNOTATION_FONT);
-
- Path2D path = new Path2D.Double();
- x += .5;
- int lineLength = 18;
- path.moveTo(x + lineLength,
- y);
- path.lineTo(x,
- y);
- path.lineTo(x,
- y + height);
- path.lineTo(x + lineLength,
- y + height);
-
- path.lineTo(x + lineLength,
- y + height - 1);
- path.lineTo(x + 1,
- y + height - 1);
- path.lineTo(x + 1,
- y + 1);
- path.lineTo(x + lineLength,
- y + 1);
- path.closePath();
-
- g.draw(path);
-
- int boxWidth = width - (2 * ANNOTATION_TEXT_PADDING);
- int boxHeight = height - (2 * ANNOTATION_TEXT_PADDING);
- int boxX = x + width / 2 - boxWidth / 2;
- int boxY = y + height / 2 - boxHeight / 2;
-
- if (text != null && !text.isEmpty()) {
- drawMultilineAnnotationText(text,
- boxX,
- boxY,
- boxWidth,
- boxHeight);
- }
-
- // restore originals
- g.setFont(originalFont);
- g.setStroke(originalStroke);
-
- // set element's id
- g.setCurrentGroupId(id);
- }
-
- public void drawLabel(String text,
- GraphicInfo graphicInfo) {
- drawLabel(text,
- graphicInfo,
- true);
- }
-
- public void drawLabel(String text,
- GraphicInfo graphicInfo,
- boolean centered) {
- float interline = 1.0f;
-
- // text
- if (text != null && text.length() > 0) {
- Paint originalPaint = g.getPaint();
- Font originalFont = g.getFont();
-
- g.setPaint(SUBPROCESS_BORDER_COLOR);
- g.setFont(LABEL_FONT);
-
- int wrapWidth = 100;
- int textY = (int) graphicInfo.getY();
-
- // TODO: use drawMultilineText()
- AttributedString as = new AttributedString(text);
- as.addAttribute(TextAttribute.FOREGROUND,
- g.getPaint());
- as.addAttribute(TextAttribute.FONT,
- g.getFont());
- AttributedCharacterIterator aci = as.getIterator();
- FontRenderContext frc = new FontRenderContext(null,
- true,
- false);
- LineBreakMeasurer lbm = new LineBreakMeasurer(aci,
- frc);
-
- while (lbm.getPosition() < text.length()) {
- TextLayout tl = lbm.nextLayout(wrapWidth);
- textY += tl.getAscent();
- Rectangle2D bb = tl.getBounds();
- double tX = graphicInfo.getX();
- if (centered) {
- tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2);
- }
- tl.draw(g,
- (float) tX,
- textY);
- textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent();
- }
-
- // restore originals
- g.setFont(originalFont);
- g.setPaint(originalPaint);
- }
- }
-
- /**
- * This method makes coordinates of connection flow better.
- * @param sourceShapeType
- * @param targetShapeType
- * @param sourceGraphicInfo
- * @param targetGraphicInfo
- * @param graphicInfoList
- */
- public List connectionPerfectionizer(SHAPE_TYPE sourceShapeType,
- SHAPE_TYPE targetShapeType,
- GraphicInfo sourceGraphicInfo,
- GraphicInfo targetGraphicInfo,
- List graphicInfoList) {
- Shape shapeFirst = createShape(sourceShapeType,
- sourceGraphicInfo);
- Shape shapeLast = createShape(targetShapeType,
- targetGraphicInfo);
-
- if (graphicInfoList != null && graphicInfoList.size() > 0) {
- GraphicInfo graphicInfoFirst = graphicInfoList.get(0);
- GraphicInfo graphicInfoLast = graphicInfoList.get(graphicInfoList.size() - 1);
- if (shapeFirst != null) {
- graphicInfoFirst.setX(shapeFirst.getBounds2D().getCenterX());
- graphicInfoFirst.setY(shapeFirst.getBounds2D().getCenterY());
- }
- if (shapeLast != null) {
- graphicInfoLast.setX(shapeLast.getBounds2D().getCenterX());
- graphicInfoLast.setY(shapeLast.getBounds2D().getCenterY());
- }
-
- Point p = null;
-
- if (shapeFirst != null) {
- Line2D.Double lineFirst = new Line2D.Double(graphicInfoFirst.getX(),
- graphicInfoFirst.getY(),
- graphicInfoList.get(1).getX(),
- graphicInfoList.get(1).getY());
- p = getIntersection(shapeFirst,
- lineFirst);
- if (p != null) {
- graphicInfoFirst.setX(p.getX());
- graphicInfoFirst.setY(p.getY());
- }
- }
-
- if (shapeLast != null) {
- Line2D.Double lineLast = new Line2D.Double(graphicInfoLast.getX(),
- graphicInfoLast.getY(),
- graphicInfoList.get(graphicInfoList.size() - 2).getX(),
- graphicInfoList.get(graphicInfoList.size() - 2).getY());
- p = getIntersection(shapeLast,
- lineLast);
- if (p != null) {
- graphicInfoLast.setX(p.getX());
- graphicInfoLast.setY(p.getY());
- }
- }
- }
-
- return graphicInfoList;
- }
-
- /**
- * This method creates shape by type and coordinates.
- * @param shapeType
- * @param graphicInfo
- * @return Shape
- */
- private static Shape createShape(SHAPE_TYPE shapeType,
- GraphicInfo graphicInfo) {
- if (SHAPE_TYPE.Rectangle.equals(shapeType)) {
- // source is rectangle
- return new Rectangle2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight());
- } else if (SHAPE_TYPE.Rhombus.equals(shapeType)) {
- // source is rhombus
- Path2D.Double rhombus = new Path2D.Double();
- rhombus.moveTo(graphicInfo.getX(),
- graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2,
- graphicInfo.getY() + graphicInfo.getHeight());
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth(),
- graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2,
- graphicInfo.getY());
- rhombus.lineTo(graphicInfo.getX(),
- graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.closePath();
- return rhombus;
- } else if (SHAPE_TYPE.Ellipse.equals(shapeType)) {
- // source is ellipse
- return new Ellipse2D.Double(graphicInfo.getX(),
- graphicInfo.getY(),
- graphicInfo.getWidth(),
- graphicInfo.getHeight());
- }
- // unknown source element, just do not correct coordinates
- return null;
- }
-
- /**
- * This method returns intersection point of shape border and line.
- * @param shape
- * @param line
- * @return Point
- */
- private static Point getIntersection(Shape shape,
- Line2D.Double line) {
- if (shape instanceof Ellipse2D) {
- return getEllipseIntersection(shape,
- line);
- } else if (shape instanceof Rectangle2D || shape instanceof Path2D) {
- return getShapeIntersection(shape,
- line);
- } else {
- // something strange
- return null;
- }
- }
-
- /**
- * This method calculates ellipse intersection with line
- * @param shape Bounds of this shape used to calculate parameters of inscribed into this bounds ellipse.
- * @param line
- * @return Intersection point
- */
- private static Point getEllipseIntersection(Shape shape,
- Line2D.Double line) {
- double angle = Math.atan2(line.y2 - line.y1,
- line.x2 - line.x1);
- double x = shape.getBounds2D().getWidth() / 2 * Math.cos(angle) + shape.getBounds2D().getCenterX();
- double y = shape.getBounds2D().getHeight() / 2 * Math.sin(angle) + shape.getBounds2D().getCenterY();
- Point p = new Point();
- p.setLocation(x,
- y);
- return p;
- }
-
- /**
- * This method calculates shape intersection with line.
- * @param shape
- * @param line
- * @return Intersection point
- */
- private static Point getShapeIntersection(Shape shape,
- Line2D.Double line) {
- PathIterator it = shape.getPathIterator(null);
- double[] coords = new double[6];
- double[] pos = new double[2];
- Line2D.Double l = new Line2D.Double();
- while (!it.isDone()) {
- int type = it.currentSegment(coords);
- switch (type) {
- case PathIterator.SEG_MOVETO:
- pos[0] = coords[0];
- pos[1] = coords[1];
- break;
- case PathIterator.SEG_LINETO:
- l = new Line2D.Double(pos[0],
- pos[1],
- coords[0],
- coords[1]);
- if (line.intersectsLine(l)) {
- return getLinesIntersection(line,
- l);
- }
- pos[0] = coords[0];
- pos[1] = coords[1];
- break;
- case PathIterator.SEG_CLOSE:
- break;
- default:
- // whatever
- }
- it.next();
- }
- return null;
- }
-
- /**
- * This method calculates intersections of two lines.
- * @param a Line 1
- * @param b Line 2
- * @return Intersection point
- */
- private static Point getLinesIntersection(Line2D a,
- Line2D b) {
- double d = (a.getX1() - a.getX2()) * (b.getY2() - b.getY1()) - (a.getY1() - a.getY2()) * (b.getX2() - b.getX1());
- double da = (a.getX1() - b.getX1()) * (b.getY2() - b.getY1()) - (a.getY1() - b.getY1()) * (b.getX2() - b.getX1());
- double ta = da / d;
- Point p = new Point();
- p.setLocation(a.getX1() + ta * (a.getX2() - a.getX1()),
- a.getY1() + ta * (a.getY2() - a.getY1()));
- return p;
- }
-
- public InputStream generateImage(String imageType) {
- if(this.closed) {
- throw new ActivitiImageException("ProcessDiagramGenerator already closed");
- } else {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- try {
- ImageIO.write(this.processDiagram, imageType, out);
- } catch (IOException var11) {
- throw new ActivitiImageException("Error while generating process image", var11);
- } finally {
- try {
- if(out != null) {
- out.close();
- }
- } catch (IOException var10) {
- ;
- }
-
- }
-
- return new ByteArrayInputStream(out.toByteArray());
- }
- }
-}
-
-
-
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramGenerator.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramGenerator.java
deleted file mode 100644
index efde9ee8..00000000
--- a/laws-modules/src/main/java/com/jero/modules/activiti/config/DefaultProcessDiagramGenerator.java
+++ /dev/null
@@ -1,1604 +0,0 @@
-package com.jero.modules.activiti.config;
-
-import org.activiti.bpmn.model.Event;
-import org.activiti.bpmn.model.Process;
-import org.activiti.bpmn.model.*;
-import org.activiti.image.ProcessDiagramGenerator;
-import org.activiti.image.exception.ActivitiImageException;
-import org.activiti.image.exception.ActivitiInterchangeInfoNotFoundException;
-
-import java.awt.*;
-import java.io.InputStream;
-import java.util.List;
-import java.util.*;
-
-/**
- 1. Class to generate an svg based the diagram interchange information in a
- 2. BPMN 2.0 process.
- */
-public class DefaultProcessDiagramGenerator implements ProcessDiagramGenerator {
-
- private static final String DEFAULT_ACTIVITY_FONT_NAME = "宋体";
-
- private static final String DEFAULT_LABEL_FONT_NAME = "宋体";
-
- private static final String DEFAULT_ANNOTATION_FONT_NAME = "宋体";
-
- private static final String DEFAULT_DIAGRAM_IMAGE_FILE_NAME = "/image/na.svg";
-
- protected Map, ActivityDrawInstruction> activityDrawInstructions = new HashMap, ActivityDrawInstruction>();
-
- protected Map, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap, ArtifactDrawInstruction>();
-
- @Override
- public String getDefaultActivityFontName() {
- return DEFAULT_ACTIVITY_FONT_NAME;
- }
-
- @Override
- public String getDefaultLabelFontName() {
- return DEFAULT_LABEL_FONT_NAME;
- }
-
- @Override
- public String getDefaultAnnotationFontName() {
- return DEFAULT_ANNOTATION_FONT_NAME;
- }
-
- @Override
- public String getDefaultDiagramImageFileName() {
- return DEFAULT_DIAGRAM_IMAGE_FILE_NAME;
- }
-
- // The instructions on how to draw a certain construct is
- // created statically and stored in a map for performance.
- public DefaultProcessDiagramGenerator() {
- // start event
- activityDrawInstructions.put(StartEvent.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw( DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- StartEvent startEvent = (StartEvent) flowNode;
- if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) {
- EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
- if (eventDefinition instanceof TimerEventDefinition) {
- processDiagramCanvas.drawTimerStartEvent(flowNode.getId(),
- graphicInfo);
- } else if (eventDefinition instanceof ErrorEventDefinition) {
- processDiagramCanvas.drawErrorStartEvent(flowNode.getId(),
- graphicInfo);
- } else if (eventDefinition instanceof SignalEventDefinition) {
- processDiagramCanvas.drawSignalStartEvent(flowNode.getId(),
- graphicInfo);
- } else if (eventDefinition instanceof MessageEventDefinition) {
- processDiagramCanvas.drawMessageStartEvent(flowNode.getId(),
- graphicInfo);
- } else {
- processDiagramCanvas.drawNoneStartEvent(flowNode.getId(),
- graphicInfo);
- }
- } else {
- processDiagramCanvas.drawNoneStartEvent(flowNode.getId(),
- graphicInfo);
- }
- }
- });
-
- // signal catch
- activityDrawInstructions.put(IntermediateCatchEvent.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode;
- if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent.getEventDefinitions()
- .isEmpty()) {
- if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- true);
- } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
- processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- true);
- } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
- processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- true);
- }
- }
- }
- });
-
- // signal throw
- activityDrawInstructions.put(ThrowEvent.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- ThrowEvent throwEvent = (ThrowEvent) flowNode;
- if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) {
- if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawThrowingSignalEvent(flowNode.getId(),
- graphicInfo);
- } else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
- processDiagramCanvas.drawThrowingCompensateEvent(flowNode.getId(),
- graphicInfo);
- } else {
- processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(),
- graphicInfo);
- }
- } else {
- processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(),
- graphicInfo);
- }
- }
- });
-
- // end event
- activityDrawInstructions.put(EndEvent.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- EndEvent endEvent = (EndEvent) flowNode;
- if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) {
- if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
- processDiagramCanvas.drawErrorEndEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- } else {
- processDiagramCanvas.drawNoneEndEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- } else {
- processDiagramCanvas.drawNoneEndEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- }
- });
-
- // task
- activityDrawInstructions.put(Task.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // user task
- activityDrawInstructions.put(UserTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawUserTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // script task
- activityDrawInstructions.put(ScriptTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawScriptTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // service task
- activityDrawInstructions.put(ServiceTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- ServiceTask serviceTask = (ServiceTask) flowNode;
- processDiagramCanvas.drawServiceTask(flowNode.getId(),
- serviceTask.getName(),
- graphicInfo);
- }
- });
-
- // receive task
- activityDrawInstructions.put(ReceiveTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawReceiveTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // send task
- activityDrawInstructions.put(SendTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawSendTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // manual task
- activityDrawInstructions.put(ManualTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawManualTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // businessRuleTask task
- activityDrawInstructions.put(BusinessRuleTask.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawBusinessRuleTask(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // exclusive gateway
- activityDrawInstructions.put(ExclusiveGateway.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawExclusiveGateway(flowNode.getId(),
- graphicInfo);
- }
- });
-
- // inclusive gateway
- activityDrawInstructions.put(InclusiveGateway.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawInclusiveGateway(flowNode.getId(),
- graphicInfo);
- }
- });
-
- // parallel gateway
- activityDrawInstructions.put(ParallelGateway.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawParallelGateway(flowNode.getId(),
- graphicInfo);
- }
- });
-
- // event based gateway
- activityDrawInstructions.put(EventGateway.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawEventBasedGateway(flowNode.getId(),
- graphicInfo);
- }
- });
-
- // Boundary timer
- activityDrawInstructions.put(BoundaryEvent.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode;
- if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) {
- if (boundaryEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
-
- processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
-
- processDiagramCanvas.drawCatchingErrorEvent(flowNode.getId(),
- graphicInfo,
- boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
- processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
- processDiagramCanvas.drawCatchingCompensateEvent(flowNode.getId(),
- graphicInfo,
- boundaryEvent.isCancelActivity());
- }
- }
- }
- });
-
- // subprocess
- activityDrawInstructions.put(SubProcess.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
- processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- false);
- } else {
- processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- SubProcess.class);
- }
- }
- });
- // transaction
- activityDrawInstructions.put(Transaction.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
- processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- false);
- } else {
- processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- Transaction.class);
- }
- }
- });
-
- // Event subprocess
- activityDrawInstructions.put(EventSubProcess.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
- processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- true);
- } else {
- processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(),
- flowNode.getName(),
- graphicInfo,
- EventSubProcess.class);
- }
- }
- });
-
- // call activity
- activityDrawInstructions.put(CallActivity.class,
- new ActivityDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawCollapsedCallActivity(flowNode.getId(),
- flowNode.getName(),
- graphicInfo);
- }
- });
-
- // text annotation
- artifactDrawInstructions.put(TextAnnotation.class,
- new ArtifactDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- Artifact artifact) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
- TextAnnotation textAnnotation = (TextAnnotation) artifact;
- processDiagramCanvas.drawTextAnnotation(textAnnotation.getId(),
- textAnnotation.getText(),
- graphicInfo);
- }
- });
-
- // association
- artifactDrawInstructions.put(Association.class,
- new ArtifactDrawInstruction() {
-
- @Override
- public void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- Artifact artifact) {
- Association association = (Association) artifact;
- String sourceRef = association.getSourceRef();
- String targetRef = association.getTargetRef();
-
- // source and target can be instance of FlowElement or Artifact
- BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef);
- BaseElement targetElement = bpmnModel.getFlowElement(targetRef);
- if (sourceElement == null) {
- sourceElement = bpmnModel.getArtifact(sourceRef);
- }
- if (targetElement == null) {
- targetElement = bpmnModel.getArtifact(targetRef);
- }
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
- graphicInfoList = connectionPerfectionizer(processDiagramCanvas,
- bpmnModel,
- sourceElement,
- targetElement,
- graphicInfoList);
- int xPoints[] = new int[graphicInfoList.size()];
- int yPoints[] = new int[graphicInfoList.size()];
- for (int i = 1; i < graphicInfoList.size(); i++) {
- GraphicInfo graphicInfo = graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
- if (i == 1) {
- xPoints[0] = (int) previousGraphicInfo.getX();
- yPoints[0] = (int) previousGraphicInfo.getY();
- }
- xPoints[i] = (int) graphicInfo.getX();
- yPoints[i] = (int) graphicInfo.getY();
- }
-
- AssociationDirection associationDirection = association.getAssociationDirection();
- processDiagramCanvas.drawAssociation(xPoints,
- yPoints,
- associationDirection,
- false);
- }
- });
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
- return generateDiagram(bpmnModel,
- highLightedActivities,
- highLightedFlows,
- activityFontName,
- labelFontName,
- annotationFontName,
- false,
- null);
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName,
- boolean generateDefaultDiagram) {
- return generateDiagram(bpmnModel,
- highLightedActivities,
- highLightedFlows,
- activityFontName,
- labelFontName,
- annotationFontName,
- generateDefaultDiagram,
- null);
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName,
- boolean generateDefaultDiagram,
- String defaultDiagramImageFileName) {
-
- if (!bpmnModel.hasDiagramInterchangeInfo()) {
- if (!generateDefaultDiagram) {
- throw new ActivitiInterchangeInfoNotFoundException("No interchange information found.");
- }
-
- return getDefaultDiagram(defaultDiagramImageFileName);
- }
-
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- highLightedFlows,
- activityFontName,
- labelFontName,
- annotationFontName).generateImage();
- }
-
- /**
- * Get default diagram image as bytes array
- * @return the default diagram image
- */
- protected InputStream getDefaultDiagram(String diagramImageFileName) {
- String imageFileName = diagramImageFileName != null ?
- diagramImageFileName :
- getDefaultDiagramImageFileName();
- InputStream imageStream = getClass().getResourceAsStream(imageFileName);
- if (imageStream == null) {
- throw new ActivitiImageException("Error occurred while getting default diagram image from file: " + imageFileName);
- }
- return imageStream;
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows) {
- return generateDiagram(bpmnModel,
- highLightedActivities,
- highLightedFlows,
- null,
- null,
- null,
- false,
- null);
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- List highLightedActivities) {
- return generateDiagram(bpmnModel,
- highLightedActivities,
- Collections.emptyList());
- }
-
- @Override
- public InputStream generateDiagram(BpmnModel bpmnModel,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
-
- return generateDiagram(bpmnModel,
- Collections.emptyList(),
- Collections.emptyList(),
- activityFontName,
- labelFontName,
- annotationFontName);
- }
-
- protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
-
- prepareBpmnModel(bpmnModel);
-
- DefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel,
- activityFontName,
- labelFontName,
- annotationFontName);
-
- // Draw pool shape, if process is participant in collaboration
- for (Pool pool : bpmnModel.getPools()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- processDiagramCanvas.drawPoolOrLane(pool.getId(),
- pool.getName(),
- graphicInfo);
- }
-
- // Draw lanes
- for (Process process : bpmnModel.getProcesses()) {
- for (Lane lane : process.getLanes()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
- processDiagramCanvas.drawPoolOrLane(lane.getId(),
- lane.getName(),
- graphicInfo);
- }
- }
-
- // Draw activities and their sequence-flows
- for (Process process : bpmnModel.getProcesses()) {
- for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) {
- drawActivity(processDiagramCanvas,
- bpmnModel,
- flowNode,
- highLightedActivities,
- highLightedFlows);
- }
- }
-
- // Draw artifacts
- for (Process process : bpmnModel.getProcesses()) {
-
- for (Artifact artifact : process.getArtifacts()) {
- drawArtifact(processDiagramCanvas,
- bpmnModel,
- artifact);
- }
-
- List subProcesses = process.findFlowElementsOfType(SubProcess.class,
- true);
- if (subProcesses != null) {
- for (SubProcess subProcess : subProcesses) {
- for (Artifact subProcessArtifact : subProcess.getArtifacts()) {
- drawArtifact(processDiagramCanvas,
- bpmnModel,
- subProcessArtifact);
- }
- }
- }
- }
-
- return processDiagramCanvas;
- }
-
- protected void prepareBpmnModel(BpmnModel bpmnModel) {
-
- // Need to make sure all elements have positive x and y.
- // Check all graphicInfo and update the elements accordingly
-
- List allGraphicInfos = new ArrayList();
- if (bpmnModel.getLocationMap() != null) {
- allGraphicInfos.addAll(bpmnModel.getLocationMap().values());
- }
- if (bpmnModel.getLabelLocationMap() != null) {
- allGraphicInfos.addAll(bpmnModel.getLabelLocationMap().values());
- }
- if (bpmnModel.getFlowLocationMap() != null) {
- for (List flowGraphicInfos : bpmnModel.getFlowLocationMap().values()) {
- allGraphicInfos.addAll(flowGraphicInfos);
- }
- }
-
- if (allGraphicInfos.size() > 0) {
-
- boolean needsTranslationX = false;
- boolean needsTranslationY = false;
-
- double lowestX = 0.0;
- double lowestY = 0.0;
-
- // Collect lowest x and y
- for (GraphicInfo graphicInfo : allGraphicInfos) {
-
- double x = graphicInfo.getX();
- double y = graphicInfo.getY();
-
- if (x < lowestX) {
- needsTranslationX = true;
- lowestX = x;
- }
- if (y < lowestY) {
- needsTranslationY = true;
- lowestY = y;
- }
- }
-
- // Update all graphicInfo objects
- if (needsTranslationX || needsTranslationY) {
-
- double translationX = Math.abs(lowestX);
- double translationY = Math.abs(lowestY);
-
- for (GraphicInfo graphicInfo : allGraphicInfos) {
- if (needsTranslationX) {
- graphicInfo.setX(graphicInfo.getX() + translationX);
- }
- if (needsTranslationY) {
- graphicInfo.setY(graphicInfo.getY() + translationY);
- }
- }
- }
- }
- }
-
- protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode,
- List highLightedActivities,
- List highLightedFlows) {
-
- ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
- if (drawInstruction != null) {
-
- drawInstruction.draw(processDiagramCanvas,
- bpmnModel,
- flowNode);
-
- // Gather info on the multi instance marker
- boolean multiInstanceSequential = false;
- boolean multiInstanceParallel = false;
- boolean collapsed = false;
- if (flowNode instanceof Activity) {
- Activity activity = (Activity) flowNode;
- MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
- if (multiInstanceLoopCharacteristics != null) {
- multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
- multiInstanceParallel = !multiInstanceSequential;
- }
- }
-
- // Gather info on the collapsed marker
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (flowNode instanceof SubProcess) {
- collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
- } else if (flowNode instanceof CallActivity) {
- collapsed = true;
- }
-
- // Actually draw the markers
- processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(),
- (int) graphicInfo.getY(),
- (int) graphicInfo.getWidth(),
- (int) graphicInfo.getHeight(),
- multiInstanceSequential,
- multiInstanceParallel,
- collapsed);
-
- // Draw highlighted activities
- if (highLightedActivities.contains(flowNode.getId())) {
- drawHighLight(processDiagramCanvas,
- bpmnModel.getGraphicInfo(flowNode.getId()));
- }
- }
-
- // Outgoing transitions of activity
- for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
- boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
- String defaultFlow = null;
- if (flowNode instanceof Activity) {
- defaultFlow = ((Activity) flowNode).getDefaultFlow();
- } else if (flowNode instanceof Gateway) {
- defaultFlow = ((Gateway) flowNode).getDefaultFlow();
- }
-
- boolean isDefault = false;
- if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
- isDefault = true;
- }
- boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
-
- String sourceRef = sequenceFlow.getSourceRef();
- String targetRef = sequenceFlow.getTargetRef();
- FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
- FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
- if (graphicInfoList != null && graphicInfoList.size() > 0) {
- graphicInfoList = connectionPerfectionizer(processDiagramCanvas,
- bpmnModel,
- sourceElement,
- targetElement,
- graphicInfoList);
- int xPoints[] = new int[graphicInfoList.size()];
- int yPoints[] = new int[graphicInfoList.size()];
-
- for (int i = 1; i < graphicInfoList.size(); i++) {
- GraphicInfo graphicInfo = graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
- if (i == 1) {
- xPoints[0] = (int) previousGraphicInfo.getX();
- yPoints[0] = (int) previousGraphicInfo.getY();
- }
- xPoints[i] = (int) graphicInfo.getX();
- yPoints[i] = (int) graphicInfo.getY();
- }
-
- processDiagramCanvas.drawSequenceflow(xPoints,
- yPoints,
- drawConditionalIndicator,
- isDefault,
- highLighted);
-
- // Draw sequenceflow label
- GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
- if (labelGraphicInfo != null) {
- processDiagramCanvas.drawLabel(sequenceFlow.getName(),
- labelGraphicInfo,
- false);
- }
- }
- }
-
- // Nested elements
- if (flowNode instanceof FlowElementsContainer) {
- for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
- if (nestedFlowElement instanceof FlowNode) {
- drawActivity(processDiagramCanvas,
- bpmnModel,
- (FlowNode) nestedFlowElement,
- highLightedActivities,
- highLightedFlows);
- }
- }
- }
- }
-
- /**
- * This method makes coordinates of connection flow better.
- * @param processDiagramCanvas
- * @param bpmnModel
- * @param sourceElement
- * @param targetElement
- * @param graphicInfoList
- * @return
- */
- protected static List connectionPerfectionizer(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- BaseElement sourceElement,
- BaseElement targetElement,
- List graphicInfoList) {
- GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId());
- GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId());
-
- DefaultProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement);
- DefaultProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement);
-
- return processDiagramCanvas.connectionPerfectionizer(sourceShapeType,
- targetShapeType,
- sourceGraphicInfo,
- targetGraphicInfo,
- graphicInfoList);
- }
-
- /**
- * This method returns shape type of base element.
- * Each element can be presented as rectangle, rhombus, or ellipse.
- * @param baseElement
- * @return DefaultProcessDiagramCanvas.SHAPE_TYPE
- */
- protected static DefaultProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) {
- if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) {
- return DefaultProcessDiagramCanvas.SHAPE_TYPE.Rectangle;
- } else if (baseElement instanceof Gateway) {
- return DefaultProcessDiagramCanvas.SHAPE_TYPE.Rhombus;
- } else if (baseElement instanceof Event) {
- return DefaultProcessDiagramCanvas.SHAPE_TYPE.Ellipse;
- }
- // unknown source element, just do not correct coordinates
- return null;
- }
-
- protected static GraphicInfo getLineCenter(List graphicInfoList) {
- GraphicInfo gi = new GraphicInfo();
-
- int xPoints[] = new int[graphicInfoList.size()];
- int yPoints[] = new int[graphicInfoList.size()];
-
- double length = 0;
- double[] lengths = new double[graphicInfoList.size()];
- lengths[0] = 0;
- double m;
- for (int i = 1; i < graphicInfoList.size(); i++) {
- GraphicInfo graphicInfo = graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
- if (i == 1) {
- xPoints[0] = (int) previousGraphicInfo.getX();
- yPoints[0] = (int) previousGraphicInfo.getY();
- }
- xPoints[i] = (int) graphicInfo.getX();
- yPoints[i] = (int) graphicInfo.getY();
-
- length += Math.sqrt(
- Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(),
- 2) +
- Math.pow((int) graphicInfo.getY() - (int) previousGraphicInfo.getY(),
- 2)
- );
- lengths[i] = length;
- }
- m = length / 2;
- int p1 = 0;
- int p2 = 1;
- for (int i = 1; i < lengths.length; i++) {
- double len = lengths[i];
- p1 = i - 1;
- p2 = i;
- if (len > m) {
- break;
- }
- }
-
- GraphicInfo graphicInfo1 = graphicInfoList.get(p1);
- GraphicInfo graphicInfo2 = graphicInfoList.get(p2);
-
- double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX();
- double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY();
- double OB = lengths[p2] - lengths[p1];
- double ob = m - lengths[p1];
- double ab = AB * ob / OB;
- double oa = OA * ob / OB;
-
- double mx = graphicInfo1.getX() + ab;
- double my = graphicInfo1.getY() + oa;
-
- gi.setX(mx);
- gi.setY(my);
- return gi;
- }
-
- protected void drawArtifact(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- Artifact artifact) {
-
- ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass());
- if (drawInstruction != null) {
- drawInstruction.draw(processDiagramCanvas,
- bpmnModel,
- artifact);
- }
- }
-
- private static void drawHighLight(DefaultProcessDiagramCanvas processDiagramCanvas,
- GraphicInfo graphicInfo) {
- processDiagramCanvas.drawHighLight((int) graphicInfo.getX(),
- (int) graphicInfo.getY(),
- (int) graphicInfo.getWidth(),
- (int) graphicInfo.getHeight());
- }
-
- private static void drawHighLight(DefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo, Color color, FlowNode flowNode) {
- if(flowNode instanceof Event){
- processDiagramCanvas.drawHighLightEvent((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(),color);
- }else if(flowNode instanceof Gateway){
- processDiagramCanvas.drawHighLightGateway((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(),color);
- }else if(flowNode instanceof Task){
- processDiagramCanvas.drawHighLightTask((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(),color);
- }else if(flowNode instanceof SubProcess){
- processDiagramCanvas.drawHighLightSubProcess((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(),color);
- }else{
- processDiagramCanvas.drawHighLight((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(),color);
- }
- }
-
- protected static DefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
-
- // We need to calculate maximum values to know how big the image will be in its entirety
- double minX = Double.MAX_VALUE;
- double maxX = 0;
- double minY = Double.MAX_VALUE;
- double maxY = 0;
-
- for (Pool pool : bpmnModel.getPools()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- minX = graphicInfo.getX();
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
- minY = graphicInfo.getY();
- maxY = graphicInfo.getY() + graphicInfo.getHeight();
- }
-
- List flowNodes = gatherAllFlowNodes(bpmnModel);
- for (FlowNode flowNode : flowNodes) {
-
- GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-
- if (flowNodeGraphicInfo == null) {
- continue;
- }
-
- // width
- if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {
- maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth();
- }
- if (flowNodeGraphicInfo.getX() < minX) {
- minX = flowNodeGraphicInfo.getX();
- }
- // height
- if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {
- maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight();
- }
- if (flowNodeGraphicInfo.getY() < minY) {
- minY = flowNodeGraphicInfo.getY();
- }
-
- for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
- if (graphicInfoList != null) {
- for (GraphicInfo graphicInfo : graphicInfoList) {
- // width
- if (graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
- }
- if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
- // height
- if (graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
- }
- if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
- }
-
- List artifacts = gatherAllArtifacts(bpmnModel);
- for (Artifact artifact : artifacts) {
-
- GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
-
- if (artifactGraphicInfo != null) {
- // width
- if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {
- maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();
- }
- if (artifactGraphicInfo.getX() < minX) {
- minX = artifactGraphicInfo.getX();
- }
- // height
- if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {
- maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();
- }
- if (artifactGraphicInfo.getY() < minY) {
- minY = artifactGraphicInfo.getY();
- }
- }
-
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
- if (graphicInfoList != null) {
- for (GraphicInfo graphicInfo : graphicInfoList) {
- // width
- if (graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
- }
- if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
- // height
- if (graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
- }
- if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
-
- int nrOfLanes = 0;
- for (Process process : bpmnModel.getProcesses()) {
- for (Lane l : process.getLanes()) {
-
- nrOfLanes++;
-
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(l.getId());
- if (graphicInfo != null) {
- // width
- if (graphicInfo.getX() + graphicInfo.getWidth() > maxX) {
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
- }
- if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
- // height
- if (graphicInfo.getY() + graphicInfo.getHeight() > maxY) {
- maxY = graphicInfo.getY() + graphicInfo.getHeight();
- }
- if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
-
- // Special case, see https://activiti.atlassian.net/browse/ACT-1431
- if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
- // Nothing to show
- minX = 0;
- minY = 0;
- }
-
- return new DefaultProcessDiagramCanvas((int) maxX + 10,
- (int) maxY + 10,
- (int) minX,
- (int) minY,
- activityFontName,
- labelFontName,
- annotationFontName);
- }
-
- protected static List gatherAllArtifacts(BpmnModel bpmnModel) {
- List artifacts = new ArrayList();
- for (Process process : bpmnModel.getProcesses()) {
- artifacts.addAll(process.getArtifacts());
- }
- return artifacts;
- }
-
- protected static List gatherAllFlowNodes(BpmnModel bpmnModel) {
- List flowNodes = new ArrayList();
- for (Process process : bpmnModel.getProcesses()) {
- flowNodes.addAll(gatherAllFlowNodes(process));
- }
- return flowNodes;
- }
-
- protected static List gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) {
- List flowNodes = new ArrayList();
- for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
- if (flowElement instanceof FlowNode) {
- flowNodes.add((FlowNode) flowElement);
- }
- if (flowElement instanceof FlowElementsContainer) {
- flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement));
- }
- }
- return flowNodes;
- }
-
- public Map, ActivityDrawInstruction> getActivityDrawInstructions() {
- return activityDrawInstructions;
- }
-
- public void setActivityDrawInstructions(
- Map, ActivityDrawInstruction> activityDrawInstructions) {
- this.activityDrawInstructions = activityDrawInstructions;
- }
-
- public Map, ArtifactDrawInstruction> getArtifactDrawInstructions() {
- return artifactDrawInstructions;
- }
-
- public void setArtifactDrawInstructions(
- Map, ArtifactDrawInstruction> artifactDrawInstructions) {
- this.artifactDrawInstructions = artifactDrawInstructions;
- }
-
- protected interface ActivityDrawInstruction {
-
- void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- FlowNode flowNode);
- }
-
- protected interface ArtifactDrawInstruction {
-
- void draw(DefaultProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel,
- Artifact artifact);
- }
-
- public InputStream generateDiagram(BpmnModel bpmnModel, String imageType,List highLightedFinishes, List highLightedActivities, List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, List runningActivityIdList) {
- return this.generateProcessDiagram(bpmnModel, imageType,highLightedFinishes, highLightedActivities, highLightedFlows, activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor, runningActivityIdList).generateImage();
- }
-
- protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType,List highLightedFinishes, List highLightedActivities, List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, List runningActivityIdList) {
- this.prepareBpmnModel(bpmnModel);
- DefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
- Iterator var12 = bpmnModel.getPools().iterator();
-
- while(var12.hasNext()) {
- Pool pool = (Pool)var12.next();
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- processDiagramCanvas.drawPoolOrLane(pool.getId(), pool.getName(), graphicInfo);
- }
-
- var12 = bpmnModel.getProcesses().iterator();
-
- Process process;
- Iterator var20;
- while(var12.hasNext()) {
- process = (Process)var12.next();
- var20 = process.getLanes().iterator();
-
- while(var20.hasNext()) {
- Lane lane = (Lane)var20.next();
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
- processDiagramCanvas.drawPoolOrLane(lane.getId(), lane.getName(), graphicInfo);
- }
- }
-
- var12 = bpmnModel.getProcesses().iterator();
- while(var12.hasNext()) {
- process = (Process)var12.next();
- var20 = process.findFlowElementsOfType(FlowNode.class).iterator();
-
- while(var20.hasNext()) {
- FlowNode flowNode = (FlowNode)var20.next();
- this.drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedFinishes,highLightedActivities, highLightedFlows, scaleFactor, runningActivityIdList);
- }
- }
-
- var12 = bpmnModel.getProcesses().iterator();
-
- while(true) {
- List subProcesses;
- do {
- if(!var12.hasNext()) {
- return processDiagramCanvas;
- }
-
- process = (Process)var12.next();
- var20 = process.getArtifacts().iterator();
-
- while(var20.hasNext()) {
- Artifact artifact = (Artifact)var20.next();
- this.drawArtifact(processDiagramCanvas, bpmnModel, artifact);
- }
-
- subProcesses = process.findFlowElementsOfType(SubProcess.class, true);
- } while(subProcesses == null);
-
- Iterator var24 = subProcesses.iterator();
-
- while(var24.hasNext()) {
- SubProcess subProcess = (SubProcess)var24.next();
- Iterator var17 = subProcess.getArtifacts().iterator();
-
- while(var17.hasNext()) {
- Artifact subProcessArtifact = (Artifact)var17.next();
- this.drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);
- }
- }
- }
- }
-
- protected static DefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
- //double minX = 1.7976931348623157E308D;
- //double maxX = 0.0D;
- //double minY = 1.7976931348623157E308D;
- //double maxY = 0.0D;
-
- double minX = 10;
- double maxX = 2;
- double minY = 6;
- double maxY = 0.0D;
-
- GraphicInfo graphicInfo;
- for(Iterator var14 = bpmnModel.getPools().iterator(); var14.hasNext(); maxY = graphicInfo.getY() + graphicInfo.getHeight()) {
- Pool pool = (Pool)var14.next();
- graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- minX = graphicInfo.getX();
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
- minY = graphicInfo.getY();
- }
-
- List flowNodes = gatherAllFlowNodes(bpmnModel);
- Iterator var24 = flowNodes.iterator();
-
- label155:
- while(var24.hasNext()) {
- FlowNode flowNode = (FlowNode)var24.next();
- GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if(flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {
- maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth();
- }
-
- if(flowNodeGraphicInfo.getX() < minX) {
- minX = flowNodeGraphicInfo.getX();
- }
-
- if(flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {
- maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight();
- }
-
- if(flowNodeGraphicInfo.getY() < minY) {
- minY = flowNodeGraphicInfo.getY();
- }
-
- Iterator var18 = flowNode.getOutgoingFlows().iterator();
-
- while(true) {
- List graphicInfoList;
- do {
- if(!var18.hasNext()) {
- continue label155;
- }
-
- SequenceFlow sequenceFlow = (SequenceFlow)var18.next();
- graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
- } while(graphicInfoList == null);
-
- Iterator var21 = graphicInfoList.iterator();
-
- while(var21.hasNext()) {
- graphicInfo = (GraphicInfo)var21.next();
- if(graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
- }
-
- if(graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
-
- if(graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
- }
-
- if(graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
-
- List artifacts = gatherAllArtifacts(bpmnModel);
- Iterator var27 = artifacts.iterator();
-
- while(var27.hasNext()) {
- Artifact artifact = (Artifact)var27.next();
- GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
- if(artifactGraphicInfo != null) {
- if(artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {
- maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();
- }
-
- if(artifactGraphicInfo.getX() < minX) {
- minX = artifactGraphicInfo.getX();
- }
-
- if(artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {
- maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();
- }
-
- if(artifactGraphicInfo.getY() < minY) {
- minY = artifactGraphicInfo.getY();
- }
- }
-
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
- if(graphicInfoList != null) {
- Iterator var35 = graphicInfoList.iterator();
-
- while(var35.hasNext()) {
- graphicInfo = (GraphicInfo)var35.next();
- if(graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
- }
-
- if(graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
-
- if(graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
- }
-
- if(graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
-
- int nrOfLanes = 0;
- Iterator var30 = bpmnModel.getProcesses().iterator();
-
- while(var30.hasNext()) {
- Process process = (Process)var30.next();
- Iterator var34 = process.getLanes().iterator();
-
- while(var34.hasNext()) {
- Lane l = (Lane)var34.next();
- ++nrOfLanes;
- graphicInfo = bpmnModel.getGraphicInfo(l.getId());
- if(graphicInfo.getX() + graphicInfo.getWidth() > maxX) {
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
- }
-
- if(graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
-
- if(graphicInfo.getY() + graphicInfo.getHeight() > maxY) {
- maxY = graphicInfo.getY() + graphicInfo.getHeight();
- }
-
- if(graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
-
- if(flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
- minX = 0.0D;
- minY = 0.0D;
- }
-
- return new DefaultProcessDiagramCanvas((int)maxX + 10, (int)maxY + 10, (int)minX, (int)minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
- }
-
- protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,List highLightedFinishes, List highLightedActivities, List highLightedFlows, double scaleFactor, List runningActivityIdList) {
- ActivityDrawInstruction drawInstruction = this.activityDrawInstructions.get(flowNode.getClass());
- boolean highLighted;
- if(drawInstruction != null) {
- drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
- boolean multiInstanceSequential = false;
- boolean multiInstanceParallel = false;
- highLighted = false;
- if(flowNode instanceof Activity) {
- Activity activity = (Activity)flowNode;
- MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
- if(multiInstanceLoopCharacteristics != null) {
- multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
- multiInstanceParallel = !multiInstanceSequential;
- }
- }
-
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if(!(flowNode instanceof SubProcess)) {
- if(flowNode instanceof CallActivity) {
- highLighted = true;
- }
- } else {
- highLighted = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded().booleanValue();
- }
-
- if(scaleFactor == 1.0D) {
- processDiagramCanvas.drawActivityMarkers((int)graphicInfo.getX(), (int)graphicInfo.getY(), (int)graphicInfo.getWidth(), (int)graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, highLighted);
- }
- // 历史节点高亮
- if(highLightedActivities.contains(flowNode.getId())) {
- drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()),DefaultProcessDiagramCanvas.HIGHLIGHT_COLOR,flowNode);
- }
-
- // if(highLightedFinishes.contains(flowNode.getId()) && !highLightedActivities.contains(flowNode.getId())) {
- // 正在执行的节点高亮
- if(runningActivityIdList.contains(flowNode.getId())) {
-
- drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()),DefaultProcessDiagramCanvas.FINISHHIGHLIGHT_COLOR,flowNode);
- }
- }
-
- Iterator var25 = flowNode.getOutgoingFlows().iterator();
-
- while(var25.hasNext()) {
- SequenceFlow sequenceFlow = (SequenceFlow)var25.next();
- highLighted = highLightedFlows.contains(sequenceFlow.getId());
- String defaultFlow = null;
- if(flowNode instanceof Activity) {
- defaultFlow = ((Activity)flowNode).getDefaultFlow();
- } else if(flowNode instanceof Gateway) {
- defaultFlow = ((Gateway)flowNode).getDefaultFlow();
- }
-
- boolean isDefault = false;
- if(defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
- isDefault = true;
- }
-
- boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
- String sourceRef = sequenceFlow.getSourceRef();
- String targetRef = sequenceFlow.getTargetRef();
- FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
- FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
- if(graphicInfoList != null && graphicInfoList.size() > 0) {
- graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
- int[] xPoints = new int[graphicInfoList.size()];
- int[] yPoints = new int[graphicInfoList.size()];
-
- for(int i = 1; i < graphicInfoList.size(); ++i) {
- GraphicInfo graphicInfo = (GraphicInfo)graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = (GraphicInfo)graphicInfoList.get(i - 1);
- if(i == 1) {
- xPoints[0] = (int)previousGraphicInfo.getX();
- yPoints[0] = (int)previousGraphicInfo.getY();
- }
-
- xPoints[i] = (int)graphicInfo.getX();
- yPoints[i] = (int)graphicInfo.getY();
- }
-
- processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor);
- GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
- if(labelGraphicInfo != null) {
- processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
- }
- }
- }
-
- if(flowNode instanceof FlowElementsContainer) {
- var25 = ((FlowElementsContainer)flowNode).getFlowElements().iterator();
-
- while(var25.hasNext()) {
- FlowElement nestedFlowElement = (FlowElement)var25.next();
- if(nestedFlowElement instanceof FlowNode) {
- this.drawActivity(processDiagramCanvas, bpmnModel, (FlowNode)nestedFlowElement, highLightedFinishes,highLightedActivities, highLightedFlows, scaleFactor, runningActivityIdList);
- }
- }
- }
-
- }
-}
-
-
-
-
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/MultiInstanceTaskHandler.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/MultiInstanceTaskHandler.java
new file mode 100644
index 00000000..46d50063
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/config/MultiInstanceTaskHandler.java
@@ -0,0 +1,29 @@
+package com.jero.modules.activiti.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.activiti.bpmn.model.FlowElement;
+import org.activiti.bpmn.model.UserTask;
+import org.activiti.engine.delegate.DelegateExecution;
+import org.activiti.engine.delegate.DelegateTask;
+import org.activiti.engine.delegate.ExecutionListener;
+import org.activiti.engine.delegate.TaskListener;
+
+import java.util.List;
+
+/**
+ * @author liJiaRao
+ * @date 2023-09-05 14:54
+ */
+@Slf4j
+public class MultiInstanceTaskHandler implements TaskListener {
+
+ @Override
+ public void notify(DelegateTask delegateTask) {
+ DelegateExecution execution = delegateTask.getExecution();
+ System.out.println("流程实例总数:" + execution.getVariable("nrOfInstances"));
+ System.out.println("当前活动的流程实例总数:" + execution.getVariable("nrOfActiveInstances"));
+ System.out.println("已经完成实例的数目:" + execution.getVariable("nrOfCompletedInstances"));
+ System.out.println("leader:" + execution.getVariable("leader"));
+ System.out.println("---------------------------------------分隔线----------------------------------------------------");
+ }
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/MyGen.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/MyGen.java
new file mode 100644
index 00000000..00f40768
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/config/MyGen.java
@@ -0,0 +1,17 @@
+package com.jero.modules.activiti.config;
+
+import org.activiti.engine.impl.cfg.IdGenerator;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author liJiaRao
+ * @date 2023-09-05 17:39
+ */
+public class MyGen implements IdGenerator {
+ private AtomicLong aLong = new AtomicLong(100);
+ @Override
+ public synchronized String getNextId() {
+ return String.valueOf(aLong.incrementAndGet());
+ }
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/config/WorkflowConstants.java b/laws-modules/src/main/java/com/jero/modules/activiti/config/WorkflowConstants.java
new file mode 100644
index 00000000..8197ceec
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/config/WorkflowConstants.java
@@ -0,0 +1,130 @@
+package com.jero.modules.activiti.config;
+
+import java.awt.*;
+
+/**
+ * 常量类
+ *@author jjd
+ **/
+public final class WorkflowConstants {
+
+ /**businessKey**/
+ public static final String WORKLOW_BUSINESS_KEY = "businessKey";
+ /**按钮网关**/
+ public static final String WAY_TYPE = "wayType";
+ /**按钮网关**/
+ public static final String WAY_TYPE_PREFIX = "way_type_";
+ /**项目id**/
+ public static final String PROJECT_ID = "projectId";
+ /**核心企业Id变量**/
+ public static final String CORE_ENTERPRISE_ID="coreEnterpriseId";
+ /**链属企业Id变量**/
+ public static final String CHAIN_ENTERPRISE_ID="chainEnterpriseId";
+ /**银行企业Id变量**/
+ public static final String BANK_ENTERPRISE_ID="bankEnterpriseId";
+ /**保理公司Id变量**/
+ public static final String BAOLI_ENTERPRISE_ID="baoliEnterpriseId";
+ /**立账开立企业Id变量**/
+ public static final String START_ENTERPRISE_ID="startEnterpriseId";
+ /**立账合作企业Id变量**/
+ public static final String PARTNER_ENTERPRISE_ID="partnerEnterpriseId";
+ /**母公司企业id**/
+ public static final String PARENT_ENTERPRISE_ID="parentEnterpriseId";
+ /**指定签收企业id**/
+ public static final String RECEIVE_ENTERPRISE_ID ="receiveEnterpriseId";
+ /**转出方企业Id变量**/
+ public static final String TRANSFER_ENTERPRISE_ID="transEnterpriseId";
+ /**指定签收企业id**/
+ public static final String AC_TASK_ID ="acTaskId";
+ /**企业所有角色**/
+ public static final String ENT_ALL_ROLE ="all";
+ /**运营所有角色**/
+ public static final String OPER_ALL_ROLE ="oper";
+ /**流程定义缓存时间**/
+ public static final int PROCESS_DEFINITION_CACHE = 60;
+ /**流程实例激活**/
+ public static final int PROCESS_INSTANCE_ACTIVE = 1;
+
+ /**流程实例挂起**/
+ public static final int PROCESS_INSTANCE_SUSPEND = 0;
+
+ /**读取图片**/
+ public static final String READ_IMAGE = "image";
+
+ /**读取xml**/
+ public static final String READ_XML = "xml";
+
+ /**流程激活**/
+ public static final Integer ACTIVE_PROCESSDEFINITION = 1;
+
+ /**流程挂起**/
+ public static final Integer SUSPEND_PROCESSDEFINITION = 2;
+
+ /**流程状态:0-全部,1-正常,2-已挂起**/
+ public static final int QUERY_ALL = 0;
+ public static final int QUERY_NORMAL = 1;
+ public static final int QUERY_SUSPENDED = 2;
+
+ /**流程实例状态:0-全部,1-正常,2-已删除**/
+ public static final int INSTANCE_ALL = 0;
+ public static final int INSTANCE_NOT_DELETED = 1;
+ public static final int INSTANCE_DELETED = 2;
+
+ /** 系统管理员ID **/
+ public static final String INTERFACE_SYSTEM_ID = "-1";
+ /** 系统管理员名称 **/
+ public static final String INTERFACE_SYSTEM_NAME = "系统操作";
+
+ /** 流程部署类型:1-启动并激活,2-启动即挂起 **/
+ public static final int PROCESS_START_ACTIVE = 1;
+ public static final int PROCESS_START_SUSPEND = 2;
+
+ /** 用于标识流程项目配置信息校验结果:1:新流程,2:新版本, 3:流程类别有误 **/
+ public static final int CHECK_NEW_PROCESS = 1;
+ public static final int CHECK_NEW_VERSION = 2;
+ public static final int CHECK_ERROR_PROCESS_TYPE = 3;
+
+ /** 默认网关条件值 **/
+ public static final Integer default_GATEWAY_CONDITION_VALUE = 1;
+
+ /** 工作流-业务状态表数据类型:1-工作流状态,2-业务状态 **/
+ public static final Integer PROCESS_STATUS = 1;
+ public static final Integer BIZNESS_STATUS = 2;
+
+ /** 新增流程时标识:1-直接保存,2-提示覆盖 **/
+ public static final Integer PROCESS_STATUS_SAVE = 1;
+ public static final Integer BIZNESS_STATUS_WARN = 2;
+
+ /** 模板类型标识:1-新创建或直接导入的模板,2-默认模板生成 **/
+ public static final Integer MODEL_TYPE_1 = 1;
+ public static final Integer MODEL_TYPE_2 = 2;
+
+ /** 查询流程定义标识:1-查询最新版本流程定义,2-查询所有版本 **/
+ public static final Integer QUERY_PROCESS_LATEST_VERSION = 1;
+ public static final Integer QUERY_PROCESS_ALL_VERSION = 2;
+
+ /** 按钮网关 通过1 */
+ public static final String WAY_TYPE_PASS = "1";
+ /** 按钮网关 驳回或结束0 */
+ public static final String WAY_TYPE_REJECT = "0";
+
+ /** 按钮网关 退回2 */
+ public static final String WAY_TYPE_BACK = "2";
+
+ /**任务参数为空**/
+ public static final int TASK_CHECK_PARAM_NULL = -1;
+ /**任务已办理**/
+ public static final int TASK_CHECK_COMPLETED = 1;
+ /**无权限办理**/
+ public static final int TASK_CHECK_NO_PERMISSIONS= 2;
+ /**任务校验通过**/
+ public static final int TASK_CHECK_PASS = 0;
+ /** 动态流程图颜色定义 **/
+ public static final Color COLOR_NORMAL = new Color(0, 205, 0);
+ public static final Color COLOR_CURRENT = new Color(255, 0, 0);
+
+ /** 定义生成流程图时的边距(像素) **/
+ public static final int PROCESS_PADDING = 5;
+
+
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/controller/AController.java b/laws-modules/src/main/java/com/jero/modules/activiti/controller/AController.java
index 483f77b0..b59ba940 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/controller/AController.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/controller/AController.java
@@ -10,7 +10,10 @@ import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.bpmn.model.FlowElement;
+import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.*;
+import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
@@ -21,12 +24,15 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.util.*;
@@ -48,18 +54,28 @@ public class AController {
@GetMapping("/deploy")
public Result> deploy(@RequestParam(value = "name", required = false) String name,
- @RequestParam(value = "classpathResource") String classpathResource) {
- if (StringUtils.isNotBlank(name)) {
+ @RequestParam(value = "classpathResource") String classpathResource,
+ @RequestParam(value = "resourceName") String resourceName,
+ @RequestPart(value = "files", required = false) MultipartFile file) {
+ if (StringUtils.isBlank(name)) {
//根据流程定义Key查询
name = "出差申请流程";
}
+
// 3、使用RepositoryService进行部署
- Deployment deployment = repositoryService.createDeployment()
- //.addClasspathResource("bpmn/diagram_1.bpmn20.xml") // 添加bpmn资源
- //.addClasspathResource("bpmn/business-trips.png") // 添加png资源
- .addClasspathResource(classpathResource)
- .name(name)
- .deploy();
+ Deployment deployment = null;
+ try {
+ deployment = repositoryService.createDeployment()
+ //.addClasspathResource("bpmn/diagram_1.bpmn20.xml") // 添加bpmn资源
+ //.addClasspathResource("bpmn/business-trips.png") // 添加png资源
+ //.addClasspathResource(classpathResource)
+ .addInputStream(resourceName, file.getInputStream())
+ .key(name)
+ .name(name)
+ .deploy();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
// 4、输出部署信息
Map map = new HashMap<>();
@@ -114,9 +130,12 @@ public class AController {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
+ Map vars = new HashMap<>();
+ vars.put("mainDrafter", "admin");
+
// 3、根据流程定义Id启动流程
ProcessInstance processInstance = runtimeService
- .startProcessInstanceByKey(key);
+ .startProcessInstanceByKey(key, vars);
// 输出内容
Map map = new HashMap<>();
@@ -155,12 +174,21 @@ public class AController {
@GetMapping("/complete")
public Result complete(@RequestParam(value = "taskId") String taskId) {
- taskService.complete(taskId);
+ Map vars = new HashMap<>();
+ List otherDrafterList = new ArrayList<>();
+ otherDrafterList.add("zhangsan");
+ otherDrafterList.add("lisi");
+ otherDrafterList.add("wangwu");
+ vars.put("leaderList", otherDrafterList);
+ Map map = new HashMap<>();
+ map.put("status", 2);
+ taskService.complete(taskId, map, vars);
return Result.OK();
}
/**
* 加签
+ *
* @param taskId
* @param loginName
* @return
@@ -181,19 +209,25 @@ public class AController {
@GetMapping("/addTask")
// @ApiOperation("新增节点")
public Object addTask(String taskId, String assignee) {
- return processService.addTask(taskId,assignee);
+ return processService.addTask(taskId, assignee);
}
@GetMapping(value = "/readResource")
@ApiOperation(value = "获取实时流程图", notes = "获取实时流程图,输出跟踪流程信息")
- public void getFlowImgByInstanceId(@RequestParam(value = "processInstanceId") String processInstanceId, HttpServletResponse response) {
- processService.getFlowImgByInstanceId(processInstanceId, response);
+ public void getFlowImgByInstanceId(@RequestParam(value = "processInstanceId") String
+ processInstanceId, HttpServletResponse response) {
+ try {
+ processService.readResource(processInstanceId, response);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
@GetMapping(value = "/export/{modelId}")
- @ApiOperation(value = "将流程模型导出为 bpmn文件",notes = "将流程模型导出为 bpmn文件")
- public void export(@PathVariable("modelId") @ApiParam("流程模型Id") String modelId, HttpServletResponse response) {
+ @ApiOperation(value = "将流程模型导出为 bpmn文件", notes = "将流程模型导出为 bpmn文件")
+ public void export(@PathVariable("modelId") @ApiParam("流程模型Id") String modelId, HttpServletResponse
+ response) {
try {
BpmnModel bpmnModel = repositoryService.getBpmnModel(modelId);
@@ -214,11 +248,12 @@ public class AController {
log.error("导出model的bpmn文件失败:modelId={}", modelId, e);
}
}
+
@GetMapping("test")
- public Result getRedisTest(){
+ public Result getRedisTest() {
String msg1 = MessageUtils.getMessage("message");
- String msg2 = MessageUtils.getMessage("message.operate.error","123456");
+ String msg2 = MessageUtils.getMessage("message.operate.error", "123456");
LanguageEnum language = MessageUtils.getLanguage();
- return Result.OK(msg1+"\n"+msg2) ;
+ return Result.OK(msg1 + "\n" + msg2);
}
}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/service/ProcessService.java b/laws-modules/src/main/java/com/jero/modules/activiti/service/ProcessService.java
index 0459ea04..37af6b42 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/service/ProcessService.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/service/ProcessService.java
@@ -7,7 +7,7 @@ import javax.servlet.http.HttpServletResponse;
* @date 2023-08-03 15:37
*/
public interface ProcessService {
- void getFlowImgByInstanceId(String pProcessInstanceId, HttpServletResponse response);
-
Object addTask(String taskId, String assignee);
+
+ void readResource(String pProcessInstanceId, HttpServletResponse response) throws Exception;
}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/ProcessServiceImpl.java b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/ProcessServiceImpl.java
index e3a92b38..aa9366b0 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/ProcessServiceImpl.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/ProcessServiceImpl.java
@@ -1,10 +1,11 @@
package com.jero.modules.activiti.service.impl;
import com.jero.common.exception.JeroBootException;
-import com.jero.modules.activiti.config.DefaultProcessDiagramGenerator;
+import com.jero.modules.activiti.config.WorkflowConstants;
import com.jero.modules.activiti.entity.ActGeBytearray;
import com.jero.modules.activiti.mapper.ActGeBytearrayMapper;
import com.jero.modules.activiti.service.ProcessService;
+import com.jero.modules.activiti.service.impl.image.ICustomProcessDiagramGenerator;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.converter.BpmnXMLConverter;
@@ -13,23 +14,30 @@ import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
+import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.persistence.deploy.DeploymentManager;
+import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
+import org.activiti.engine.repository.ProcessDefinition;
+import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.Execution;
+import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
+import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
+import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.ArrayList;
+import java.util.*;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -54,87 +62,6 @@ public class ProcessServiceImpl implements ProcessService {
@Resource
private ActGeBytearrayMapper actGeBytearrayMapper;
- @Override
- public void getFlowImgByInstanceId(String processInstanceId, HttpServletResponse response) {
- InputStream imageStream = null;
- try {
- // 获取历史流程实例
- HistoricProcessInstance historicProcessInstance = historyService
- .createHistoricProcessInstanceQuery()
- .processInstanceId(processInstanceId).singleResult();
- if (historicProcessInstance == null){
- throw new JeroBootException("历史流程不存在");
- }
- // 获取流程中已经执行的节点,按照执行先后顺序排序
- List historicActivityInstances = historyService
- .createHistoricActivityInstanceQuery()
- .processInstanceId(processInstanceId)
- .orderByHistoricActivityInstanceId()
- .asc().list();
- // 高亮已经执行流程节点ID集合
- List highLightedActivitiIds = new ArrayList<>();
- for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
- // 用默认颜色
- highLightedActivitiIds.add(historicActivityInstance.getActivityId());
- }
- // 正在执行的节点
- List runTaskList = runtimeService.createExecutionQuery()
- .processInstanceId(processInstanceId)
- .list();
- List runningActivityIdList = new ArrayList<>();
- for (Execution execution : runTaskList) {
- if (!StringUtils.isEmpty(execution.getActivityId())) {
- runningActivityIdList.add(execution.getActivityId());
- }
- }
- List currIds = historicActivityInstances.stream()
- .filter(item -> item.getEndTime() != null)
- .map(HistoricActivityInstance::getActivityId).collect(Collectors.toList());
-
- // 获得流程引擎配置
- ProcessEngineConfiguration processEngineConfiguration = processEngine.getProcessEngineConfiguration();
-
- BpmnModel bpmnModel = repositoryService
- .getBpmnModel(historicProcessInstance.getProcessDefinitionId());
- // 高亮流程已发生流转的线id集合
- List highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstances);
- //
- imageStream = new DefaultProcessDiagramGenerator().generateDiagram(
- bpmnModel,
- "png",
- highLightedActivitiIds,//所有活动过的节点,包括当前在激活状态下的节点
- currIds,//当前为激活状态下的节点
- highLightedFlowIds,//活动过的线
- "宋体",
- "宋体",
- "宋体",
- processEngineConfiguration.getClassLoader(),
- 1.0,
- runningActivityIdList);
-
- OutputStream out = null;
- out = response.getOutputStream();
- int len = 0;
- byte[] b = new byte[1024];
- while ((len = imageStream.read(b)) != -1) {
- out.write(b, 0, len);
- }
- out.flush();
-
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (imageStream != null) {
- try {
- imageStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
@Override
public Object addTask(String taskId, String assignee) {
// 1、创建ProcessEngine
@@ -191,154 +118,183 @@ public class ProcessServiceImpl implements ProcessService {
flow.setTargetRef(to);
return flow;
}
- /**
- * @param bpmnModel bpmnModel
- * @param historicActivityInstanceList historicActivityInstanceList
- * @return HighLightedFlows
- */
- public List getHighLightedFlows(BpmnModel bpmnModel,
- List historicActivityInstanceList) {
- //historicActivityInstanceList 是 流程中已经执行的历史活动实例
- // 已经流经的顺序流,需要高亮显示
- List highFlows = new ArrayList<>();
+ private List getHighLightedFlows(BpmnModel bpmnModel, ProcessDefinitionEntity processDefinitionEntity, List historicActivityInstances) {
+ // 高亮流程已发生流转的线id集合
+ List highLightedFlowIds = new ArrayList<>();
// 全部活动节点
- List allHistoricActivityNodeList = new ArrayList<>();
+ List historicActivityNodes = new ArrayList<>();
+ // 已完成的历史活动节点
+ List finishedActivityInstances = new ArrayList<>();
- // 拥有endTime的历史活动实例,即已经完成了的节点
- List finishedActivityInstancesList = new ArrayList<>();
-
- /*
- * 循环的目的:
- * 获取所有的历史节点FlowNode并放入allHistoricActivityNodeList
- * 获取所有确定结束了的历史节点finishedActivityInstancesList
- */
- for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
- // 获取流程节点
- // bpmnModel.getMainProcess()获取一个Process对象
+ for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true);
- allHistoricActivityNodeList.add(flowNode);
-
- // 如果结束时间不为空,表示当前节点已经完成
+ historicActivityNodes.add(flowNode);
if (historicActivityInstance.getEndTime() != null) {
- finishedActivityInstancesList.add(historicActivityInstance);
+ finishedActivityInstances.add(historicActivityInstance);
}
}
- FlowNode currentFlowNode;
- FlowNode targetFlowNode;
- HistoricActivityInstance currentActivityInstance;
-
- // 遍历已经完成的活动实例,从每个实例的outgoingFlows中找到已经执行的
- for (int k = 0; k < finishedActivityInstancesList.size(); k++) {
- currentActivityInstance = finishedActivityInstancesList.get(k);
-
- // 获得当前活动对应的节点信息以及outgoingFlows信息
+ FlowNode currentFlowNode = null;
+ FlowNode targetFlowNode = null;
+ // 遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的
+ for (HistoricActivityInstance currentActivityInstance : finishedActivityInstances) {
+ // 获得当前活动对应的节点信息及outgoingFlows信息
currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true);
+ List sequenceFlows = currentFlowNode.getOutgoingFlows();
- // 当前节点的所有流出线
- List outgoingFlowList = currentFlowNode.getOutgoingFlows();
-
- /*
- * 遍历outgoingFlows并找到已经流转的 满足如下条件认为已经流转:
- * 1、当前节点是并行网关或者兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已经流转
- * 2、当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
- * (第二点有问题,有过驳回的,会只绘制驳回的流程线,通过走向下一级的流程线没有高亮显示)
+ /**
+ * 遍历outgoingFlows并找到已已流转的 满足如下条件认为已已流转: 1.当前节点是并行网关或兼容网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最早的流转节点视为有效流转
*/
- if ("parallelGateway".equals(currentActivityInstance.getActivityType()) ||
- "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
+ if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) {
// 遍历历史活动节点,找到匹配流程目标节点的
- for (SequenceFlow outgoingFlow : outgoingFlowList) {
- // 获取当前节点流程线对应的下一级节点
- targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef(), true);
-
- // 如果下级节点包含在所有历史节点中,则将当前节点的流出线高亮显示
- if (allHistoricActivityNodeList.contains(targetFlowNode)) {
- highFlows.add(outgoingFlow.getId());
+ for (SequenceFlow sequenceFlow : sequenceFlows) {
+ targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true);
+ if (historicActivityNodes.contains(targetFlowNode)) {
+ highLightedFlowIds.add(targetFlowNode.getId());
}
}
} else {
- /*
- * 2、当前节点不是并行网关或者兼容网关
- * 【已解决-问题】如果当前节点有驳回功能,驳回到申请节点,
- * 则因为申请节点在历史节点中,导致当前节点驳回到申请节点的流程线被高亮显示,但实际并没有进行驳回操作
- */
List> tempMapList = new ArrayList<>();
-
- // 当前节点ID
- String currentActivityId = currentActivityInstance.getActivityId();
-
- int size = historicActivityInstanceList.size();
- boolean ifStartFind = false;
- boolean ifFinded = false;
- HistoricActivityInstance historicActivityInstance;
-
- // 循环当前节点的所有流出线
- // 循环所有的历史节点
-// log.info("【开始】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
-// log.info("循环历史节点");
-
- for (int i = 0; i < size; i++) {
- // // 如果当前节点流程线对应的下级节点在历史节点中,则该条流程线进行高亮显示(【问题】有驳回流程线时,即使没有进行驳回操作,因为申请节点在历史节点中,也会将驳回流程线高亮显示-_-||)
- // if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
- // Map map = new HashMap<>();
- // map.put("highLightedFlowId", sequenceFlow.getId());
- // map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
- // tempMapList.add(map);
- // // highFlows.add(sequenceFlow.getId());
- // }
-
- // 历史节点
- historicActivityInstance = historicActivityInstanceList.get(i);
-// log.info("第【{}/{}】个历史节点-ActivityId=【{}】", i + 1, size, historicActivityInstance.getActivityId());
-
- // 如果循环历史节点中的id等于当前节点id,从当前历史节点继续先后查找是否有当前流程线等于的节点
- // 历史节点的序号需要大于等于已经完成历史节点的序号,放置驳回重审一个节点经过两次时只取第一次的流出线高亮显示,第二次的不显示
- if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) {
-// log.info("第【{}】个历史节点和当前节点一致-ActivityId=【{}】", i + 1, historicActivityInstance.getActivityId());
- ifStartFind = true;
- // 跳过当前节点继续查找下一个节点
- continue;
- }
- if (ifStartFind) {
-// log.info("[开始]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
-
- ifFinded = false;
- for (SequenceFlow sequenceFlow : outgoingFlowList) {
- // 如果当前节点流程线对应的下级节点在其后面的历史节点中,则该条流程线进行高亮显示
- // 【问题】
-// log.info("当前流出线的下级节点=[{}]", sequenceFlow.getTargetRef());
- if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
-// log.info("当前节点[{}]需高亮显示的流出线=[{}]", currentActivityId, sequenceFlow.getId());
- highFlows.add(sequenceFlow.getId());
- // 暂时默认找到离当前节点最近的下一级节点即退出循环,否则有多条流出线时将全部被高亮显示
- ifFinded = true;
- break;
- }
+ for (SequenceFlow sequenceFlow : sequenceFlows) {
+ for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
+ if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
+ Map map = new HashMap<>();
+ map.put("highLightedFlowId", sequenceFlow.getId());
+ map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
+ tempMapList.add(map);
}
-// log.info("[完成]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
- }
- if (ifFinded) {
- // 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环,否则有多条流出线时将全部被高亮显示
- break;
}
}
-// log.info("【完成】-匹配当前节点-ActivityId=【{}】需要高亮显示的流出线", currentActivityId);
- // if (!CollectionUtils.isEmpty(tempMapList)) {
- // // 遍历匹配的集合,取得开始时间最早的一个
- // long earliestStamp = 0L;
- // String highLightedFlowId = null;
- // for (Map map : tempMapList) {
- // long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
- // if (earliestStamp == 0 || earliestStamp <= highLightedFlowStartTime) {
- // highLightedFlowId = map.get("highLightedFlowId").toString();
- // earliestStamp = highLightedFlowStartTime;
- // }
- // }
- // highFlows.add(highLightedFlowId);
- // }
+
+ if (!CollectionUtils.isEmpty(tempMapList)) {
+ // 遍历匹配的集合,取得开始时间最早的一个
+ long earliestStamp = 0L;
+ String highLightedFlowId = null;
+ for (Map map : tempMapList) {
+ long highLightedFlowStartTime = Long.valueOf(map.get("highLightedFlowStartTime").toString());
+ if (earliestStamp == 0 || earliestStamp >= highLightedFlowStartTime) {
+ highLightedFlowId = map.get("highLightedFlowId").toString();
+ earliestStamp = highLightedFlowStartTime;
+ }
+ }
+
+ highLightedFlowIds.add(highLightedFlowId);
+ }
+
+ }
+
+ }
+ return highLightedFlowIds;
+ }
+
+ @Override
+ public void readResource(String pProcessInstanceId, HttpServletResponse response)
+ throws Exception {
+ // 设置页面不缓存
+ response.setHeader("Pragma", "No-cache");
+ response.setHeader("Cache-Control", "no-cache");
+ response.setDateHeader("Expires", 0);
+
+ String processDefinitionId = "";
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(pProcessInstanceId).singleResult();
+ if(processInstance == null) {
+ HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(pProcessInstanceId).singleResult();
+ processDefinitionId = historicProcessInstance.getProcessDefinitionId();
+ } else {
+ processDefinitionId = processInstance.getProcessDefinitionId();
+ }
+ ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
+ ProcessDefinition pd = pdq.processDefinitionId(processDefinitionId).singleResult();
+
+ String resourceName = pd.getDiagramResourceName();
+
+ if(resourceName.endsWith(".png") && StringUtils.isEmpty(pProcessInstanceId) == false)
+ {
+ getActivitiProccessImage(pProcessInstanceId,response);
+ //ProcessDiagramGenerator.generateDiagram(pde, "png", getRuntimeService().getActiveActivityIds(processInstanceId));
+ }
+ else
+ {
+ // 通过接口读取
+ InputStream resourceAsStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
+
+ // 输出资源内容到相应对象
+ byte[] b = new byte[1024];
+ int len = -1;
+ while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
+ response.getOutputStream().write(b, 0, len);
}
}
- return highFlows;
+ }
+
+ /**
+ * 获取流程图像,已执行节点和流程线高亮显示
+ */
+ public void getActivitiProccessImage(String pProcessInstanceId, HttpServletResponse response) {
+ //logger.info("[开始]-获取流程图图像");
+ try {
+ // 获取历史流程实例
+ HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
+ .processInstanceId(pProcessInstanceId).singleResult();
+
+ if (historicProcessInstance == null) {
+ //throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败!");
+ }
+ else {
+ // 获取流程定义
+ ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
+ .getDeployedProcessDefinition(historicProcessInstance.getProcessDefinitionId());
+
+ // 获取流程历史中已执行节点,并按照节点在流程中执行先后顺序排序
+ List historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery()
+ .processInstanceId(pProcessInstanceId).orderByHistoricActivityInstanceId().asc().list();
+
+ // 已执行的节点ID集合
+ List executedActivityIdList = new ArrayList();
+ int index = 1;
+ //logger.info("获取已经执行的节点ID");
+ for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
+ executedActivityIdList.add(activityInstance.getActivityId());
+
+ //logger.info("第[" + index + "]个已执行节点=" + activityInstance.getActivityId() + " : " +activityInstance.getActivityName());
+ index++;
+ }
+
+ BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
+
+ // 已执行的线集合
+ List flowIds = new ArrayList();
+ // 获取流程走过的线 (getHighLightedFlows是下面的方法)
+ flowIds = getHighLightedFlows(bpmnModel,processDefinition, historicActivityInstanceList);
+
+// // 获取流程图图像字符流
+// ProcessDiagramGenerator pec = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
+// //配置字体
+// InputStream imageStream = pec.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds,"宋体","微软雅黑","黑体",null,2.0);
+
+ Set currIds = runtimeService.createExecutionQuery().processInstanceId(pProcessInstanceId).list()
+ .stream().map(e->e.getActivityId()).collect(Collectors.toSet());
+
+ ICustomProcessDiagramGenerator diagramGenerator = (ICustomProcessDiagramGenerator) processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator();
+ InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", executedActivityIdList,
+ flowIds, "宋体", "宋体", "宋体", null, 1.0, new Color[] { WorkflowConstants.COLOR_NORMAL, WorkflowConstants.COLOR_CURRENT }, currIds);
+
+ response.setContentType("image/png");
+ OutputStream os = response.getOutputStream();
+ int bytesRead = 0;
+ byte[] buffer = new byte[8192];
+ while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) {
+ os.write(buffer, 0, bytesRead);
+ }
+ os.close();
+ imageStream.close();
+ }
+ //logger.info("[完成]-获取流程图图像");
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ //logger.error("【异常】-获取流程图失败!" + e.getMessage());
+ //throw new BusinessException("获取流程图失败!" + e.getMessage());
+ }
}
}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramCanvas.java b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramCanvas.java
index 8810f0db..147ec706 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramCanvas.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramCanvas.java
@@ -1,1194 +1,246 @@
package com.jero.modules.activiti.service.impl.image;
+import com.jero.modules.activiti.config.WorkflowConstants;
import org.activiti.bpmn.model.AssociationDirection;
-import org.activiti.bpmn.model.EventSubProcess;
import org.activiti.bpmn.model.GraphicInfo;
-import org.activiti.bpmn.model.Transaction;
-import org.activiti.engine.ActivitiException;
import org.activiti.image.exception.ActivitiImageException;
import org.activiti.image.impl.DefaultProcessDiagramCanvas;
-import org.activiti.image.impl.ProcessDiagramSVGGraphics2D;
-import org.activiti.image.impl.icon.*;
-import org.apache.batik.dom.GenericDOMImplementation;
-import org.apache.batik.svggen.SVGGraphics2DIOException;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-import org.w3c.dom.DocumentType;
+import org.activiti.image.util.ReflectUtil;
+import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
-import java.awt.geom.*;
-import java.io.*;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-public class CustomProcessDiagramCanvas {
+public class CustomProcessDiagramCanvas extends DefaultProcessDiagramCanvas {
- /**
- * 矩形、菱形、椭圆形
- */
- public enum SHAPE_TYPE {
- Rectangle, Rhombus, Ellipse;
+ protected static Color LABEL_COLOR = new Color(0, 0, 0);
- SHAPE_TYPE() {
+ //font
+ protected String activityFontName = "宋体";
+ protected String labelFontName = "宋体";
+ protected String annotationFontName = "宋体";
+
+ private static volatile boolean flag = false;
+
+ public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType) {
+ super(width, height, minX, minY, imageType);
+ }
+
+ public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType,
+ String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
+ super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName,
+ customClassLoader);
+ }
+
+ public void drawHighLight(boolean isStartOrEnd, int x, int y, int width, int height, Color color) {
+ Paint originalPaint = g.getPaint();
+ Stroke originalStroke = g.getStroke();
+
+ g.setPaint(color);
+ g.setStroke(MULTI_INSTANCE_STROKE);
+ if (isStartOrEnd) {// 开始、结束节点画圆
+ g.drawOval(x, y, width, height);
+ } else {// 非开始、结束节点画圆角矩形
+ RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 5, 5);
+ g.draw(rect);
}
+ g.setPaint(originalPaint);
+ g.setStroke(originalStroke);
}
- protected static final int ARROW_WIDTH = 5;
- protected static final int CONDITIONAL_INDICATOR_WIDTH = 16;
- protected static final int DEFAULT_INDICATOR_WIDTH = 10;
- protected static final int MARKER_WIDTH = 12;
- protected static final int FONT_SIZE = 12;
- protected static final int FONT_SPACING = 2;
- protected static final int TEXT_PADDING = 3;
- protected static final int ANNOTATION_TEXT_PADDING = 7;
- protected static final int LINE_HEIGHT = FONT_SIZE + FONT_SPACING;
-
- /**
- * Colors
- */
- protected static Color TASK_BOX_COLOR = new Color(249, 249, 249);
- protected static Color SUBPROCESS_BOX_COLOR = new Color(255, 255, 255);
- protected static Color EVENT_COLOR = Color.WHITE;
- protected static Color CONNECTION_COLOR = new Color(128, 128, 128);
- protected static Color CONDITIONAL_INDICATOR_COLOR = new Color(255, 255, 255);
- protected static Color RUNNING_HIGHLIGHT_COLOR = Color.RED;
- protected static Color LAST_HIGHLIGHT_COLOR = new Color(252, 75, 52);
- protected static Color HIGHLIGHT_COLOR = Color.GREEN;
- protected static Color LABEL_COLOR = new Color(67, 150, 246);
- // protected static Color LABEL_COLOR = Color.blue;
- protected static Color TASK_BORDER_COLOR = new Color(149, 148, 148);
- protected static Color EVENT_BORDER_COLOR = new Color(76, 76, 76);
- protected static Color SUBPROCESS_BORDER_COLOR = Color.BLACK;
-
- // Fonts
- protected static Font LABEL_FONT = new Font("微软雅黑", Font.ITALIC, 14);
- protected static Font ANNOTATION_FONT = new Font("微软雅黑", Font.PLAIN, FONT_SIZE);
- protected static Font TASK_FONT = new Font("微软雅黑", Font.PLAIN, FONT_SIZE);
-
- // Strokes笔画
- //TODO 边框宽度修改
- //protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(3.0f);
- protected static Stroke THICK_TASK_BORDER_STROKE = new BasicStroke(2.0f);
- protected static Stroke GATEWAY_TYPE_STROKE = new BasicStroke(3.0f);
- protected static Stroke END_EVENT_STROKE = new BasicStroke(3.0f);
- protected static Stroke MULTI_INSTANCE_STROKE = new BasicStroke(1.3f);
- protected static Stroke EVENT_SUBPROCESS_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{1.0f}, 0.0f);
- protected static Stroke NON_INTERRUPTING_EVENT_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{4.0f, 3.0f}, 0.0f);
- protected static Stroke HIGHLIGHT_FLOW_STROKE = new BasicStroke(1.3f);
- protected static Stroke ANNOTATION_STROKE = new BasicStroke(2.0f);
- protected static Stroke ASSOCIATION_STROKE = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[]{2.0f, 2.0f}, 0.0f);
-
- // icons
- protected static int ICON_PADDING = 5;
- protected static TaskIconType USERTASK_IMAGE;
- protected static TaskIconType SCRIPTTASK_IMAGE;
- protected static TaskIconType SERVICETASK_IMAGE;
- protected static TaskIconType RECEIVETASK_IMAGE;
- protected static TaskIconType SENDTASK_IMAGE;
- protected static TaskIconType MANUALTASK_IMAGE;
- protected static TaskIconType BUSINESS_RULE_TASK_IMAGE;
-
- protected static IconType TIMER_IMAGE;
- protected static IconType COMPENSATE_THROW_IMAGE;
- protected static IconType COMPENSATE_CATCH_IMAGE;
- protected static IconType ERROR_THROW_IMAGE;
- protected static IconType ERROR_CATCH_IMAGE;
- protected static IconType MESSAGE_CATCH_IMAGE;
- protected static IconType SIGNAL_CATCH_IMAGE;
- protected static IconType SIGNAL_THROW_IMAGE;
-
- protected int canvasWidth = -1;
- protected int canvasHeight = -1;
- protected int minX = -1;
- protected int minY = -1;
- protected ProcessDiagramSVGGraphics2D g;
- protected FontMetrics fontMetrics;
- protected boolean closed;
- protected String activityFontName = "微软雅黑";
- protected String labelFontName = "微软雅黑";
- protected String annotationFontName = "微软雅黑";
-
- /**
- * Creates an empty canvas with given width and height. Allows to specify minimal boundaries on the left and upper side of the canvas. This is useful for diagrams that have
- * white space there. Everything beneath these minimum values will be cropped. It's also possible to pass a specific font name and a class loader for the icon images.
- */
- public CustomProcessDiagramCanvas(int width, int height, int minX, int minY, String activityFontName, String labelFontName, String annotationFontName) {
- this.canvasWidth = width;
- this.canvasHeight = height;
- this.minX = minX;
- this.minY = minY;
- if (activityFontName != null) {
- this.activityFontName = activityFontName;
- }
- if (labelFontName != null) {
- this.labelFontName = labelFontName;
- }
- if (annotationFontName != null) {
- this.annotationFontName = annotationFontName;
- }
- this.initialize();
+ public void drawSequenceflow(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault,
+ boolean highLighted, double scaleFactor, Color color) {
+ drawConnection(xPoints, yPoints, conditional, isDefault, "sequenceFlow", AssociationDirection.ONE, highLighted,
+ scaleFactor, color);
}
- /**
- * Creates an empty canvas with given width and height. Allows to specify minimal boundaries on the left and upper side of the canvas. This is useful for diagrams that have
- * white space there (eg Signavio). Everything beneath these minimum values will be cropped.
- *
- * @param minX Hint that will be used when generating the image. Parts that fall below minX on the horizontal scale will be cropped.
- * @param minY Hint that will be used when generating the image. Parts that fall below minX on the horizontal scale will be cropped.
- */
- public CustomProcessDiagramCanvas(int width, int height, int minX, int minY) {
- this.canvasWidth = width;
- this.canvasHeight = height;
- this.minX = minX;
- this.minY = minY;
- this.initialize();
- }
+ public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault,
+ String connectionType, AssociationDirection associationDirection, boolean highLighted, double scaleFactor,
+ Color color) {
- public void initialize() {
- DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
- String svgNS = "http://www.w3.org/2000/svg";
- Document document = domImpl.createDocument(svgNS, "svg", (DocumentType) null);
- this.g = new ProcessDiagramSVGGraphics2D(document);
- this.g.setSVGCanvasSize(new Dimension(this.canvasWidth, this.canvasHeight));
- this.g.setBackground(new Color(255, 255, 255, 0));
- this.g.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
- this.g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- this.g.setPaint(Color.black);
- Font font = new Font(this.activityFontName, 1, 11);
- this.g.setFont(font);
- this.fontMetrics = this.g.getFontMetrics();
- LABEL_FONT = new Font(this.labelFontName, 2, 10);
- ANNOTATION_FONT = new Font(this.annotationFontName, 0, 11);
+ Paint originalPaint = g.getPaint();
+ Stroke originalStroke = g.getStroke();
- USERTASK_IMAGE = new UserTaskIconType();
- SCRIPTTASK_IMAGE = new ScriptTaskIconType();
- SERVICETASK_IMAGE = new ServiceTaskIconType();
- RECEIVETASK_IMAGE = new ReceiveTaskIconType();
- SENDTASK_IMAGE = new SendTaskIconType();
- MANUALTASK_IMAGE = new ManualTaskIconType();
- BUSINESS_RULE_TASK_IMAGE = new BusinessRuleTaskIconType();
- TIMER_IMAGE = new TimerIconType();
- COMPENSATE_THROW_IMAGE = new CompensateThrowIconType();
- COMPENSATE_CATCH_IMAGE = new CompensateIconType();
- ERROR_THROW_IMAGE = new ErrorThrowIconType();
- ERROR_CATCH_IMAGE = new ErrorIconType();
- MESSAGE_CATCH_IMAGE = new MessageIconType();
- SIGNAL_THROW_IMAGE = new SignalThrowIconType();
- SIGNAL_CATCH_IMAGE = new SignalIconType();
-
- }
-
- /**
- * Generates an image of what currently is drawn on the canvas. Throws an {@link ActivitiException} when {@link #close()} is already called.
- */
- public InputStream generateImage() {
- if (closed) {
- throw new ActivitiImageException("ProcessDiagramGenerator already closed");
- } else {
- try {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- Writer out = new OutputStreamWriter(stream, "UTF-8");
- this.g.stream(out, true);
- return new ByteArrayInputStream(stream.toByteArray());
- } catch (SVGGraphics2DIOException | UnsupportedEncodingException var3) {
- throw new ActivitiImageException("Error while generating process image", var3);
- }
- }
- }
-
- public void close() {
- g.dispose();
- closed = true;
- }
-
-
- public void drawNoneStartEvent(String id, GraphicInfo graphicInfo) {
- this.drawStartEvent(id, graphicInfo, (IconType) null);
- }
-
- public void drawTimerStartEvent(String id, GraphicInfo graphicInfo) {
- this.drawStartEvent(id, graphicInfo, TIMER_IMAGE);
- }
-
- public void drawSignalStartEvent(String id, GraphicInfo graphicInfo) {
- this.drawStartEvent(id, graphicInfo, SIGNAL_CATCH_IMAGE);
- }
-
- public void drawMessageStartEvent(String id, GraphicInfo graphicInfo) {
- this.drawStartEvent(id, graphicInfo, MESSAGE_CATCH_IMAGE);
- }
-
- public void drawStartEvent(String id, GraphicInfo graphicInfo, IconType icon) {
- Paint originalPaint = this.g.getPaint();
- this.g.setPaint(EVENT_COLOR);
- Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight());
- this.g.fill(circle);
- this.g.setPaint(EVENT_BORDER_COLOR);
- this.g.draw(circle);
- this.g.setPaint(originalPaint);
- if (icon != null) {
- // calculate coordinates to center image
- int imageX = (int) Math.round(graphicInfo.getX() + graphicInfo.getWidth() / 2.0D - (double) (icon.getWidth() / 2));
- int imageY = (int) Math.round(graphicInfo.getY() + graphicInfo.getHeight() / 2.0D - (double) (icon.getHeight() / 2));
- icon.drawIcon(imageX, imageY, ICON_PADDING, this.g);
- }
- this.g.setCurrentGroupId(id);
- }
-
- public void drawNoneEndEvent(String id, String name, GraphicInfo graphicInfo) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(EVENT_COLOR);
- Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight());
- this.g.fill(circle);
- this.g.setPaint(EVENT_BORDER_COLOR);
- this.g.setStroke(END_EVENT_STROKE);
- this.g.draw(circle);
- this.g.setStroke(originalStroke);
- this.g.setPaint(originalPaint);
- this.g.setCurrentGroupId(id);
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawErrorEndEvent(String id, String name, GraphicInfo graphicInfo) {
- this.drawNoneEndEvent(id, name, graphicInfo);
- int imageX = (int) (graphicInfo.getX() + graphicInfo.getWidth() / 4.0D);
- int imageY = (int) (graphicInfo.getY() + graphicInfo.getHeight() / 4.0D);
- ERROR_THROW_IMAGE.drawIcon(imageX, imageY, ICON_PADDING, this.g);
- }
-
- public void drawErrorStartEvent(String id, GraphicInfo graphicInfo) {
- this.drawNoneStartEvent(id, graphicInfo);
- int imageX = (int) (graphicInfo.getX() + graphicInfo.getWidth() / 4.0D);
- int imageY = (int) (graphicInfo.getY() + graphicInfo.getHeight() / 4.0D);
- ERROR_THROW_IMAGE.drawIcon(imageX, imageY, ICON_PADDING, this.g);
- }
-
- public void drawCatchingEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting, IconType icon, String eventType) {
-
- // event circles
- Ellipse2D outerCircle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight());
- int innerCircleSize = 4;
- int innerCircleX = (int) graphicInfo.getX() + innerCircleSize;
- int innerCircleY = (int) graphicInfo.getY() + innerCircleSize;
- int innerCircleWidth = (int) graphicInfo.getWidth() - 2 * innerCircleSize;
- int innerCircleHeight = (int) graphicInfo.getHeight() - 2 * innerCircleSize;
- Ellipse2D innerCircle = new Ellipse2D.Double((double) innerCircleX, (double) innerCircleY, (double) innerCircleWidth, (double) innerCircleHeight);
-
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(EVENT_COLOR);
- this.g.fill(outerCircle);
-
- this.g.setPaint(EVENT_BORDER_COLOR);
- if (!isInterrupting) {
- this.g.setStroke(NON_INTERRUPTING_EVENT_STROKE);
- }
- this.g.draw(outerCircle);
- this.g.setStroke(originalStroke);
- this.g.setPaint(originalPaint);
- this.g.draw(innerCircle);
-
- if (icon != null) {
- // calculate coordinates to center image
- int imageX = (int) (graphicInfo.getX() + graphicInfo.getWidth() / 2.0D - (double) (icon.getWidth() / 2));
- int imageY = (int) (graphicInfo.getY() + graphicInfo.getHeight() / 2.0D - (double) (icon.getHeight() / 2));
- if ("timer".equals(eventType)) {
- imageX++;
- imageY++;
- }
- icon.drawIcon(imageX, imageY, ICON_PADDING, this.g);
- }
- this.g.setCurrentGroupId(id);
- }
-
- public void drawCatchingCompensateEvent(String id, String name, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingCompensateEvent(id, graphicInfo, isInterrupting);
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawCatchingCompensateEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, COMPENSATE_CATCH_IMAGE, "compensate");
- }
-
- public void drawCatchingTimerEvent(String id, String name, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingTimerEvent(id, graphicInfo, isInterrupting);
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawCatchingTimerEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, TIMER_IMAGE, "timer");
- }
-
- public void drawCatchingErrorEvent(String id, String name, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingErrorEvent(id, graphicInfo, isInterrupting);
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawCatchingErrorEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, ERROR_CATCH_IMAGE, "error");
- }
-
- public void drawCatchingSignalEvent(String id, String name, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingSignalEvent(id, graphicInfo, isInterrupting);
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawCatchingSignalEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, SIGNAL_CATCH_IMAGE, "signal");
- }
-
- public void drawCatchingMessageEvent(String id, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, MESSAGE_CATCH_IMAGE, "message");
- }
-
- public void drawCatchingMessageEvent(String id, String name, GraphicInfo graphicInfo, boolean isInterrupting) {
- this.drawCatchingEvent(id, graphicInfo, isInterrupting, MESSAGE_CATCH_IMAGE, "message");
- this.drawLabel(name, graphicInfo);
- }
-
- public void drawThrowingCompensateEvent(String id, GraphicInfo graphicInfo) {
- this.drawCatchingEvent(id, graphicInfo, true, COMPENSATE_THROW_IMAGE, "compensate");
- }
-
- public void drawThrowingSignalEvent(String id, GraphicInfo graphicInfo) {
- this.drawCatchingEvent(id, graphicInfo, true, SIGNAL_THROW_IMAGE, "signal");
- }
-
- public void drawThrowingNoneEvent(String id, GraphicInfo graphicInfo) {
- this.drawCatchingEvent(id, graphicInfo, true, (IconType) null, "none");
- }
-
- public void drawSequenceflow(int srcX, int srcY, int targetX, int targetY, boolean conditional) {
- this.drawSequenceflow(srcX, srcY, targetX, targetY, conditional, false);
- }
-
- public void drawSequenceflow(int srcX, int srcY, int targetX, int targetY, boolean conditional, boolean highLighted) {
- Paint originalPaint = this.g.getPaint();
- if (highLighted) {
- this.g.setPaint(HIGHLIGHT_COLOR);
- }
-
- Line2D.Double line = new Line2D.Double((double) srcX, (double) srcY, (double) targetX, (double) targetY);
- this.g.draw(line);
- this.drawArrowHead(line);
- if (conditional) {
- this.drawConditionalSequenceFlowIndicator(line);
- }
-
- if (highLighted) {
- this.g.setPaint(originalPaint);
- }
-
- }
-
- public void drawAssociation(int[] xPoints, int[] yPoints, AssociationDirection associationDirection, boolean highLighted) {
- boolean conditional = false;
- boolean isDefault = false;
- this.drawConnection(xPoints, yPoints, conditional, isDefault, "association", associationDirection, highLighted, HIGHLIGHT_COLOR);
- }
-
- public void drawSequenceflow(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, boolean highLighted) {
- this.drawConnection(xPoints, yPoints, conditional, isDefault, "sequenceFlow", AssociationDirection.ONE, highLighted, HIGHLIGHT_COLOR);
- }
-
- public void drawLastSequenceflow(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, boolean highLighted) {
- this.drawConnection(xPoints, yPoints, conditional, isDefault, "sequenceFlow", AssociationDirection.ONE, highLighted, LAST_HIGHLIGHT_COLOR);
- }
-
- public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDirection, boolean highLighted, Color HIGHLIGHT_COLOR) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(CONNECTION_COLOR);
- if ("association".equals(connectionType)) {
- this.g.setStroke(ASSOCIATION_STROKE);
+ g.setPaint(CONNECTION_COLOR);
+ if (connectionType.equals("association")) {
+ g.setStroke(ASSOCIATION_STROKE);
} else if (highLighted) {
- this.g.setPaint(HIGHLIGHT_COLOR);
- this.g.setStroke(HIGHLIGHT_FLOW_STROKE);
+ g.setPaint(color);
+ g.setStroke(HIGHLIGHT_FLOW_STROKE);
}
- for (int i = 1; i < xPoints.length; ++i) {
+ for (int i = 1; i < xPoints.length; i++) {
Integer sourceX = xPoints[i - 1];
Integer sourceY = yPoints[i - 1];
Integer targetX = xPoints[i];
Integer targetY = yPoints[i];
- Line2D.Double line = new Line2D.Double((double) sourceX, (double) sourceY, (double) targetX, (double) targetY);
- this.g.draw(line);
+ Line2D.Double line = new Line2D.Double(sourceX, sourceY, targetX, targetY);
+ g.draw(line);
}
- Line2D.Double line;
if (isDefault) {
- line = new Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]);
- this.drawDefaultSequenceFlowIndicator(line);
+ Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
+ drawDefaultSequenceFlowIndicator(line, scaleFactor);
}
if (conditional) {
- line = new Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]);
- this.drawConditionalSequenceFlowIndicator(line);
+ Line2D.Double line = new Line2D.Double(xPoints[0], yPoints[0], xPoints[1], yPoints[1]);
+ drawConditionalSequenceFlowIndicator(line, scaleFactor);
}
- if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) {
- line = new Line2D.Double((double) xPoints[xPoints.length - 2], (double) yPoints[xPoints.length - 2], (double) xPoints[xPoints.length - 1], (double) yPoints[xPoints.length - 1]);
- this.drawArrowHead(line);
+ if (associationDirection.equals(AssociationDirection.ONE)
+ || associationDirection.equals(AssociationDirection.BOTH)) {
+ Line2D.Double line = new Line2D.Double(xPoints[xPoints.length - 2], yPoints[xPoints.length - 2],
+ xPoints[xPoints.length - 1], yPoints[xPoints.length - 1]);
+ drawArrowHead(line, scaleFactor);
}
-
if (associationDirection.equals(AssociationDirection.BOTH)) {
- line = new Line2D.Double((double) xPoints[1], (double) yPoints[1], (double) xPoints[0], (double) yPoints[0]);
- this.drawArrowHead(line);
+ Line2D.Double line = new Line2D.Double(xPoints[1], yPoints[1], xPoints[0], yPoints[0]);
+ drawArrowHead(line, scaleFactor);
}
-
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
+ g.setPaint(originalPaint);
+ g.setStroke(originalStroke);
}
- public void drawSequenceflowWithoutArrow(int srcX, int srcY, int targetX, int targetY, boolean conditional) {
- this.drawSequenceflowWithoutArrow(srcX, srcY, targetX, targetY, conditional, false);
- }
-
- public void drawSequenceflowWithoutArrow(int srcX, int srcY, int targetX, int targetY, boolean conditional, boolean highLighted) {
- Paint originalPaint = this.g.getPaint();
- if (highLighted) {
- this.g.setPaint(HIGHLIGHT_COLOR);
- }
-
- Line2D.Double line = new Line2D.Double((double) srcX, (double) srcY, (double) targetX, (double) targetY);
- this.g.draw(line);
- if (conditional) {
- this.drawConditionalSequenceFlowIndicator(line);
- }
-
- if (highLighted) {
- this.g.setPaint(originalPaint);
- }
-
- }
-
- public void drawArrowHead(Line2D.Double line) {
- int doubleArrowWidth = 10;
- if (doubleArrowWidth == 0) {
- doubleArrowWidth = 2;
- }
-
- Polygon arrowHead = new Polygon();
- arrowHead.addPoint(0, 0);
-
- int arrowHeadPoint = -5;
- if (arrowHeadPoint == 0) {
- arrowHeadPoint = -1;
- }
-
- arrowHead.addPoint(arrowHeadPoint, -doubleArrowWidth);
- arrowHeadPoint = 5;
- if (arrowHeadPoint == 0) {
- arrowHeadPoint = 1;
- }
-
- arrowHead.addPoint(arrowHeadPoint, -doubleArrowWidth);
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
- transformation.translate(line.x2, line.y2);
- transformation.rotate(angle - 1.5707963267948966D);
- AffineTransform originalTransformation = this.g.getTransform();
- this.g.setTransform(transformation);
- this.g.fill(arrowHead);
- this.g.setTransform(originalTransformation);
- }
-
- public void drawDefaultSequenceFlowIndicator(Line2D.Double line) {
- double length = 10.0D;
- double halfOfLength = length / 2.0D;
- double f = 8.0D;
- Line2D.Double defaultIndicator = new Line2D.Double(-halfOfLength, 0.0D, halfOfLength, 0.0D);
- double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
- double dx = f * Math.cos(angle);
- double dy = f * Math.sin(angle);
- double x1 = line.x1 + dx;
- double y1 = line.y1 + dy;
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- transformation.translate(x1, y1);
- transformation.rotate(angle - 2.356194490192345D);
- AffineTransform originalTransformation = this.g.getTransform();
- this.g.setTransform(transformation);
- this.g.draw(defaultIndicator);
- this.g.setTransform(originalTransformation);
- }
-
- public void drawConditionalSequenceFlowIndicator(Line2D.Double line) {
- int horizontal = 11;
- int halfOfHorizontal = horizontal / 2;
- int halfOfVertical = 8;
- Polygon conditionalIndicator = new Polygon();
- conditionalIndicator.addPoint(0, 0);
- conditionalIndicator.addPoint(-halfOfHorizontal, halfOfVertical);
- conditionalIndicator.addPoint(0, 16);
- conditionalIndicator.addPoint(halfOfHorizontal, halfOfVertical);
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
- transformation.translate(line.x1, line.y1);
- transformation.rotate(angle - 1.5707963267948966D);
- AffineTransform originalTransformation = this.g.getTransform();
- this.g.setTransform(transformation);
- this.g.draw(conditionalIndicator);
- Paint originalPaint = this.g.getPaint();
- this.g.setPaint(CONDITIONAL_INDICATOR_COLOR);
- this.g.fill(conditionalIndicator);
- this.g.setPaint(originalPaint);
- this.g.setTransform(originalTransformation);
- }
-
- public void drawTask(TaskIconType icon, String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(id, name, graphicInfo);
- icon.drawIcon((int) graphicInfo.getX(), (int) graphicInfo.getY(), ICON_PADDING, this.g);
- }
-
- public void drawTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(id, name, graphicInfo, false);
- }
-
-
- public void drawPoolOrLane(String id, String name, GraphicInfo graphicInfo) {
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- this.g.drawRect(x, y, width, height);
- if (name != null && name.length() > 0) {
- int availableTextSpace = height - 6;
- AffineTransform transformation = new AffineTransform();
- transformation.setToIdentity();
- transformation.rotate(4.71238898038469D);
- Font currentFont = this.g.getFont();
- Font theDerivedFont = currentFont.deriveFont(transformation);
- this.g.setFont(theDerivedFont);
- String truncated = this.fitTextToWidth(name, availableTextSpace);
- int realWidth = this.fontMetrics.stringWidth(truncated);
- this.g.drawString(truncated, x + 2 + this.fontMetrics.getHeight(), 3 + y + availableTextSpace - (availableTextSpace - realWidth) / 2);
- this.g.setFont(currentFont);
- }
-
- this.g.setCurrentGroupId(id);
- }
-
- protected void drawTask(String id, String name, GraphicInfo graphicInfo, boolean thickBorder) {
- Paint originalPaint = this.g.getPaint();
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- this.g.setPaint(TASK_BOX_COLOR);
- int arcR = 6;
- if (thickBorder) {
- arcR = 3;
- }
-
- RoundRectangle2D rect = new RoundRectangle2D.Double((double) x, (double) y, (double) width, (double) height, (double) arcR, (double) arcR);
- this.g.fill(rect);
- this.g.setPaint(TASK_BORDER_COLOR);
- if (thickBorder) {
- Stroke originalStroke = this.g.getStroke();
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- this.g.draw(rect);
- this.g.setStroke(originalStroke);
- } else {
- this.g.draw(rect);
- }
-
- this.g.setPaint(originalPaint);
- if (name != null && name.length() > 0) {
- int boxWidth = width - 6;
- int boxHeight = height - 16 - ICON_PADDING - ICON_PADDING - 12 - 2 - 2;
- int boxX = x + width / 2 - boxWidth / 2;
- int boxY = y + height / 2 - boxHeight / 2 + ICON_PADDING + ICON_PADDING - 2 - 2;
- this.drawMultilineCentredText(name, boxX, boxY, boxWidth, boxHeight);
- }
-
- this.g.setCurrentGroupId(id);
- }
-
- protected void drawMultilineCentredText(String text, int x, int y, int boxWidth, int boxHeight) {
- this.drawMultilineText(text, x, y, boxWidth, boxHeight, true);
- }
-
- protected void drawMultilineAnnotationText(String text, int x, int y, int boxWidth, int boxHeight) {
- this.drawMultilineText(text, x, y, boxWidth, boxHeight, false);
- }
-
- protected void drawMultilineText(String text, int x, int y, int boxWidth, int boxHeight, boolean centered) {
- AttributedString attributedString = new AttributedString(text);
- attributedString.addAttribute(TextAttribute.FONT, this.g.getFont());
- attributedString.addAttribute(TextAttribute.FOREGROUND, Color.black);
- AttributedCharacterIterator characterIterator = attributedString.getIterator();
- int currentHeight = 0;
- List layouts = new ArrayList();
- String lastLine = null;
- LineBreakMeasurer measurer = new LineBreakMeasurer(characterIterator, this.g.getFontRenderContext());
-
- int currentY;
- int height;
- for (TextLayout layout = null; measurer.getPosition() < characterIterator.getEndIndex() && currentHeight <= boxHeight; currentHeight += height) {
- currentY = measurer.getPosition();
- layout = measurer.nextLayout((float) boxWidth);
- height = Float.valueOf(layout.getDescent() + layout.getAscent() + layout.getLeading()).intValue();
- if (currentHeight + height > boxHeight) {
- if (!layouts.isEmpty()) {
- layouts.remove(layouts.size() - 1);
- if (lastLine.length() >= 4) {
- lastLine = lastLine.substring(0, lastLine.length() - 4) + "...";
- }
-
- layouts.add(new TextLayout(lastLine, this.g.getFont(), this.g.getFontRenderContext()));
- } else {
- layouts.add(layout);
- currentHeight += height;
- }
- break;
- }
-
- layouts.add(layout);
- lastLine = text.substring(currentY, measurer.getPosition());
- }
-
- currentY = y + (centered ? (boxHeight - currentHeight) / 2 : 0);
-
-
- TextLayout textLayout;
- for (Iterator var16 = layouts.iterator(); var16.hasNext(); currentY = (int) ((float) currentY + textLayout.getDescent() + textLayout.getLeading())) {
- textLayout = (TextLayout) var16.next();
- currentY = (int) ((float) currentY + textLayout.getAscent());
- height = x + (centered ? (boxWidth - Double.valueOf(textLayout.getBounds().getWidth()).intValue()) / 2 : 0);
- textLayout.draw(this.g, (float) height, (float) currentY);
- }
-
- }
-
- protected String fitTextToWidth(String original, int width) {
- String text = original;
-
- for (int maxWidth = width - 10; this.fontMetrics.stringWidth(text + "...") > maxWidth && text.length() > 0; text = text.substring(0, text.length() - 1)) {
- }
-
- if (!text.equals(original)) {
- text = text + "...";
- }
-
- return text;
- }
-
- public void drawUserTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(USERTASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawScriptTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(SCRIPTTASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawServiceTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(SERVICETASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawReceiveTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(RECEIVETASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawSendTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(SENDTASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawManualTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(MANUALTASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawBusinessRuleTask(String id, String name, GraphicInfo graphicInfo) {
- this.drawTask(BUSINESS_RULE_TASK_IMAGE, id, name, graphicInfo);
- }
-
- public void drawExpandedSubProcess(String id, String name, GraphicInfo graphicInfo, Class> type) {
- RoundRectangle2D rect = new RoundRectangle2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight(), 8.0D, 8.0D);
- if (type.equals(EventSubProcess.class)) {
- Stroke originalStroke = this.g.getStroke();
- this.g.setStroke(EVENT_SUBPROCESS_STROKE);
- this.g.draw(rect);
- this.g.setStroke(originalStroke);
- } else if (type.equals(Transaction.class)) {
- RoundRectangle2D outerRect = new RoundRectangle2D.Double(graphicInfo.getX() - 3.0D, graphicInfo.getY() - 3.0D, graphicInfo.getWidth() + 6.0D, graphicInfo.getHeight() + 6.0D, 8.0D, 8.0D);
- Paint originalPaint = this.g.getPaint();
- this.g.setPaint(SUBPROCESS_BOX_COLOR);
- this.g.fill(outerRect);
- this.g.setPaint(SUBPROCESS_BORDER_COLOR);
- this.g.draw(outerRect);
- this.g.setPaint(SUBPROCESS_BOX_COLOR);
- this.g.fill(rect);
- this.g.setPaint(SUBPROCESS_BORDER_COLOR);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- } else {
- Paint originalPaint = this.g.getPaint();
- this.g.setPaint(SUBPROCESS_BOX_COLOR);
- this.g.fill(rect);
- this.g.setPaint(SUBPROCESS_BORDER_COLOR);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- }
-
- if (name != null && !name.isEmpty()) {
- String text = this.fitTextToWidth(name, (int) graphicInfo.getWidth());
- this.g.drawString(text, (int) graphicInfo.getX() + 10, (int) graphicInfo.getY() + 15);
- }
-
- this.g.setCurrentGroupId(id);
- }
-
- public void drawCollapsedSubProcess(String id, String name, GraphicInfo graphicInfo, Boolean isTriggeredByEvent) {
- this.drawCollapsedTask(id, name, graphicInfo, false);
- }
-
- public void drawCollapsedCallActivity(String id, String name, GraphicInfo graphicInfo) {
- this.drawCollapsedTask(id, name, graphicInfo, true);
- }
-
- protected void drawCollapsedTask(String id, String name, GraphicInfo graphicInfo, boolean thickBorder) {
- this.drawTask(id, name, graphicInfo, thickBorder);
- }
-
- public void drawCollapsedMarker(int x, int y, int width, int height) {
- int rectangleWidth = 12;
- int rectangleHeight = 12;
- Rectangle rect = new Rectangle(x + (width - rectangleWidth) / 2, y + height - rectangleHeight - 3, rectangleWidth, rectangleHeight);
- this.g.draw(rect);
- Line2D.Double line = new Line2D.Double(rect.getCenterX(), rect.getY() + 2.0D, rect.getCenterX(), rect.getMaxY() - 2.0D);
- this.g.draw(line);
- line = new Line2D.Double(rect.getMinX() + 2.0D, rect.getCenterY(), rect.getMaxX() - 2.0D, rect.getCenterY());
- this.g.draw(line);
- }
-
- public void drawActivityMarkers(int x, int y, int width, int height, boolean multiInstanceSequential, boolean multiInstanceParallel, boolean collapsed) {
- if (collapsed) {
- if (!multiInstanceSequential && !multiInstanceParallel) {
- this.drawCollapsedMarker(x, y, width, height);
- } else {
- this.drawCollapsedMarker(x - 6 - 2, y, width, height);
- if (multiInstanceSequential) {
- this.drawMultiInstanceMarker(true, x + 6 + 2, y, width, height);
- } else {
- this.drawMultiInstanceMarker(false, x + 6 + 2, y, width, height);
- }
- }
- } else if (multiInstanceSequential) {
- this.drawMultiInstanceMarker(true, x, y, width, height);
- } else if (multiInstanceParallel) {
- this.drawMultiInstanceMarker(false, x, y, width, height);
- }
-
- }
-
- public void drawGateway(GraphicInfo graphicInfo) {
- Polygon rhombus = new Polygon();
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- rhombus.addPoint(x, y + height / 2);
- rhombus.addPoint(x + width / 2, y + height);
- rhombus.addPoint(x + width, y + height / 2);
- rhombus.addPoint(x + width / 2, y);
- this.g.draw(rhombus);
- }
-
- public void drawParallelGateway(String id, GraphicInfo graphicInfo) {
- this.drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- Stroke orginalStroke = this.g.getStroke();
- this.g.setStroke(GATEWAY_TYPE_STROKE);
- Line2D.Double line = new Line2D.Double((double) (x + 10), (double) (y + height / 2), (double) (x + width - 10), (double) (y + height / 2));
- this.g.draw(line);
- line = new Line2D.Double((double) (x + width / 2), (double) (y + height - 10), (double) (x + width / 2), (double) (y + 10));
- this.g.draw(line);
- this.g.setStroke(orginalStroke);
- this.g.setCurrentGroupId(id);
- }
-
- public void drawExclusiveGateway(String id, GraphicInfo graphicInfo) {
- this.drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- int quarterWidth = width / 4;
- int quarterHeight = height / 4;
- Stroke orginalStroke = this.g.getStroke();
- this.g.setStroke(GATEWAY_TYPE_STROKE);
- Line2D.Double line = new Line2D.Double((double) (x + quarterWidth + 3), (double) (y + quarterHeight + 3), (double) (x + 3 * quarterWidth - 3), (double) (y + 3 * quarterHeight - 3));
- this.g.draw(line);
- line = new Line2D.Double((double) (x + quarterWidth + 3), (double) (y + 3 * quarterHeight - 3), (double) (x + 3 * quarterWidth - 3), (double) (y + quarterHeight + 3));
- this.g.draw(line);
- this.g.setStroke(orginalStroke);
- this.g.setCurrentGroupId(id);
- }
-
- public void drawInclusiveGateway(String id, GraphicInfo graphicInfo) {
- this.drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- int diameter = width / 2;
- Stroke orginalStroke = this.g.getStroke();
- this.g.setStroke(GATEWAY_TYPE_STROKE);
- Ellipse2D.Double circle = new Ellipse2D.Double((double) ((width - diameter) / 2 + x), (double) ((height - diameter) / 2 + y), (double) diameter, (double) diameter);
- this.g.draw(circle);
- this.g.setStroke(orginalStroke);
- this.g.setCurrentGroupId(id);
- }
-
- public void drawEventBasedGateway(String id, GraphicInfo graphicInfo) {
- this.drawGateway(graphicInfo);
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- double scale = 0.6D;
- GraphicInfo eventInfo = new GraphicInfo();
- eventInfo.setX((double) x + (double) width * (1.0D - scale) / 2.0D);
- eventInfo.setY((double) y + (double) height * (1.0D - scale) / 2.0D);
- eventInfo.setWidth((double) width * scale);
- eventInfo.setHeight((double) height * scale);
- this.drawCatchingEvent((String) null, eventInfo, true, (IconType) null, "eventGateway");
- double r = (double) width / 6.0D;
- int topX = (int) (0.95D * r);
- int topY = (int) (-0.31D * r);
- int bottomX = (int) (0.59D * r);
- int bottomY = (int) (0.81D * r);
- int[] xPoints = new int[]{0, topX, bottomX, -bottomX, -topX};
- int[] yPoints = new int[]{-((int) r), topY, bottomY, bottomY, topY};
- Polygon pentagon = new Polygon(xPoints, yPoints, 5);
- pentagon.translate(x + width / 2, y + width / 2);
- this.g.drawPolygon(pentagon);
- this.g.setCurrentGroupId(id);
- }
-
- public void drawMultiInstanceMarker(boolean sequential, int x, int y, int width, int height) {
- int rectangleWidth = 12;
- int rectangleHeight = 12;
- int lineX = x + (width - rectangleWidth) / 2;
- int lineY = y + height - rectangleHeight - 3;
- Stroke orginalStroke = this.g.getStroke();
- this.g.setStroke(MULTI_INSTANCE_STROKE);
- if (sequential) {
- this.g.draw(new Line2D.Double((double) lineX, (double) lineY, (double) (lineX + rectangleWidth), (double) lineY));
- this.g.draw(new Line2D.Double((double) lineX, (double) (lineY + rectangleHeight / 2), (double) (lineX + rectangleWidth), (double) (lineY + rectangleHeight / 2)));
- this.g.draw(new Line2D.Double((double) lineX, (double) (lineY + rectangleHeight), (double) (lineX + rectangleWidth), (double) (lineY + rectangleHeight)));
- } else {
- this.g.draw(new Line2D.Double((double) lineX, (double) lineY, (double) lineX, (double) (lineY + rectangleHeight)));
- this.g.draw(new Line2D.Double((double) (lineX + rectangleWidth / 2), (double) lineY, (double) (lineX + rectangleWidth / 2), (double) (lineY + rectangleHeight)));
- this.g.draw(new Line2D.Double((double) (lineX + rectangleWidth), (double) lineY, (double) (lineX + rectangleWidth), (double) (lineY + rectangleHeight)));
- }
-
- this.g.setStroke(orginalStroke);
- }
-
- public void drawHighLight(int x, int y, int width, int height) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
- this.g.setPaint(HIGHLIGHT_COLOR);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- RoundRectangle2D rect = new RoundRectangle2D.Double((double) x, (double) y, (double) width, (double) height, 5.0D, 5.0D);
- this.g.draw(rect);
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
-
- /**
- * Desc: 绘制正在执行中的节点红色高亮显示
- *
- * @param x x
- * @param y y
- * @param width width
- * @param height height
- * @author Fuxs
- */
- public void drawRunningActivityHighLight(int x, int y, int width, int height) {
- Paint originalPaint = this.g.getPaint();
- Stroke originalStroke = this.g.getStroke();
-
- this.g.setPaint(RUNNING_HIGHLIGHT_COLOR);
- this.g.setStroke(THICK_TASK_BORDER_STROKE);
- //todo 修改长方形弧度
- //RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
- RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 5, 5);
- this.g.draw(rect);
-
- this.g.setPaint(originalPaint);
- this.g.setStroke(originalStroke);
- }
-
- public void drawTextAnnotation(String id, String text, GraphicInfo graphicInfo) {
- int x = (int) graphicInfo.getX();
- int y = (int) graphicInfo.getY();
- int width = (int) graphicInfo.getWidth();
- int height = (int) graphicInfo.getHeight();
- Font originalFont = this.g.getFont();
- Stroke originalStroke = this.g.getStroke();
- this.g.setFont(ANNOTATION_FONT);
- Path2D path = new Path2D.Double();
- x = (int) ((double) x + 0.5D);
- int lineLength = 18;
- path.moveTo((double) (x + lineLength), (double) y);
- path.lineTo((double) x, (double) y);
- path.lineTo((double) x, (double) (y + height));
- path.lineTo((double) (x + lineLength), (double) (y + height));
- path.lineTo((double) (x + lineLength), (double) (y + height - 1));
- path.lineTo((double) (x + 1), (double) (y + height - 1));
- path.lineTo((double) (x + 1), (double) (y + 1));
- path.lineTo((double) (x + lineLength), (double) (y + 1));
- path.closePath();
- this.g.draw(path);
- int boxWidth = width - 14;
- int boxHeight = height - 14;
- int boxX = x + width / 2 - boxWidth / 2;
- int boxY = y + height / 2 - boxHeight / 2;
- if (text != null && !text.isEmpty()) {
- this.drawMultilineAnnotationText(text, boxX, boxY, boxWidth, boxHeight);
- }
-
- this.g.setFont(originalFont);
- this.g.setStroke(originalStroke);
- this.g.setCurrentGroupId(id);
- }
-
- public void drawLabel(String text, GraphicInfo graphicInfo) {
- this.drawLabel(text, graphicInfo, true);
- }
-
- /**
- * 绘制流程线名称
- * Desc:
- *
- * @param text
- * @param graphicInfo
- * @param centered
- * @author Fuxs
- */
- public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) {
+ public void drawLabel(boolean highLighted, String text, GraphicInfo graphicInfo, boolean centered) {
float interline = 1.0f;
+
// text
if (text != null && text.length() > 0) {
- Paint originalPaint = this.g.getPaint();
- Font originalFont = this.g.getFont();
-
- this.g.setPaint(LABEL_COLOR);
- this.g.setFont(LABEL_FONT);
+ Paint originalPaint = g.getPaint();
+ Font originalFont = g.getFont();
+ if (highLighted) {
+ g.setPaint(WorkflowConstants.COLOR_NORMAL);
+ } else {
+ g.setPaint(LABEL_COLOR);
+ }
+ g.setFont(new Font(labelFontName, Font.BOLD, 10));
int wrapWidth = 100;
- int textY = (int) (graphicInfo.getY() + graphicInfo.getHeight());
+ int textY = (int) graphicInfo.getY();
// TODO: use drawMultilineText()
AttributedString as = new AttributedString(text);
- as.addAttribute(TextAttribute.FOREGROUND, this.g.getPaint());
- as.addAttribute(TextAttribute.FONT, this.g.getFont());
+ as.addAttribute(TextAttribute.FOREGROUND, g.getPaint());
+ as.addAttribute(TextAttribute.FONT, g.getFont());
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = new FontRenderContext(null, true, false);
+ LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
- TextLayout tl;
- for (LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
- lbm.getPosition() < text.length();
- textY = (int) ((float) textY + tl.getDescent() + tl.getLeading() + (interline - 1.0F) * tl.getAscent())
- ) {
- tl = lbm.nextLayout((float) wrapWidth);
- textY = (int) ((float) textY + tl.getAscent());
+ while (lbm.getPosition() < text.length()) {
+ TextLayout tl = lbm.nextLayout(wrapWidth);
+ textY += tl.getAscent();
Rectangle2D bb = tl.getBounds();
double tX = graphicInfo.getX();
if (centered) {
- tX += (double) ((int) (graphicInfo.getWidth() / 2.0D - bb.getWidth() / 2.0D));
+ tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2);
}
-
- tl.draw(this.g, (float) tX, (float) textY);
+ tl.draw(g, (float) tX, textY);
+ textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent();
}
// restore originals
- this.g.setFont(originalFont);
- this.g.setPaint(originalPaint);
+ g.setFont(originalFont);
+ g.setPaint(originalPaint);
}
}
- /**
- * This method makes coordinates of connection flow better.
- *
- * @param sourceShapeType
- * @param targetShapeType
- * @param sourceGraphicInfo
- * @param targetGraphicInfo
- * @param graphicInfoList
- */
- public List connectionPerfectionizer(SHAPE_TYPE sourceShapeType,
- SHAPE_TYPE targetShapeType,
- GraphicInfo sourceGraphicInfo,
- GraphicInfo targetGraphicInfo,
- List graphicInfoList) {
- Shape shapeFirst = createShape(sourceShapeType, sourceGraphicInfo);
- Shape shapeLast = createShape(targetShapeType, targetGraphicInfo);
-
- if (graphicInfoList != null && graphicInfoList.size() > 0) {
- GraphicInfo graphicInfoFirst = graphicInfoList.get(0);
- GraphicInfo graphicInfoLast = graphicInfoList.get(graphicInfoList.size() - 1);
- if (shapeFirst != null) {
- graphicInfoFirst.setX(shapeFirst.getBounds2D().getCenterX());
- graphicInfoFirst.setY(shapeFirst.getBounds2D().getCenterY());
- }
- if (shapeLast != null) {
- graphicInfoLast.setX(shapeLast.getBounds2D().getCenterX());
- graphicInfoLast.setY(shapeLast.getBounds2D().getCenterY());
- }
-
- Point p = null;
-
- if (shapeFirst != null) {
- Line2D.Double lineFirst = new Line2D.Double(graphicInfoFirst.getX(), graphicInfoFirst.getY(), graphicInfoList.get(1).getX(), graphicInfoList.get(1).getY());
- p = getIntersection(shapeFirst, lineFirst);
- if (p != null) {
- graphicInfoFirst.setX(p.getX());
- graphicInfoFirst.setY(p.getY());
- }
- }
-
- if (shapeLast != null) {
- Line2D.Double lineLast = new Line2D.Double(graphicInfoLast.getX(), graphicInfoLast.getY(), graphicInfoList.get(graphicInfoList.size() - 2).getX(),
- graphicInfoList.get(graphicInfoList.size() - 2).getY());
- p = getIntersection(shapeLast, lineLast);
- if (p != null) {
- graphicInfoLast.setX(p.getX());
- graphicInfoLast.setY(p.getY());
- }
- }
+ @Override
+ public BufferedImage generateBufferedImage(String imageType) {
+ if (closed) {
+ throw new ActivitiImageException("ProcessDiagramGenerator already closed");
}
- return graphicInfoList;
+ // Try to remove white space
+ minX = (minX <= WorkflowConstants.PROCESS_PADDING) ? WorkflowConstants.PROCESS_PADDING : minX;
+ minY = (minY <= WorkflowConstants.PROCESS_PADDING) ? WorkflowConstants.PROCESS_PADDING : minY;
+ BufferedImage imageToSerialize = processDiagram;
+ if (minX >= 0 && minY >= 0) {
+ imageToSerialize = processDiagram.getSubimage(
+ minX - WorkflowConstants.PROCESS_PADDING,
+ minY - WorkflowConstants.PROCESS_PADDING,
+ canvasWidth - minX + WorkflowConstants.PROCESS_PADDING,
+ canvasHeight - minY + WorkflowConstants.PROCESS_PADDING);
+ }
+ return imageToSerialize;
}
- /**
- * This method creates shape by type and coordinates.
- *
- * @param shapeType
- * @param graphicInfo
- * @return Shape
- */
- private static Shape createShape(SHAPE_TYPE shapeType, GraphicInfo graphicInfo) {
- if (SHAPE_TYPE.Rectangle.equals(shapeType)) {
- // source is rectangle
- return new Rectangle2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight());
- } else if (SHAPE_TYPE.Rhombus.equals(shapeType)) {
- // source is rhombus
- Path2D.Double rhombus = new Path2D.Double();
- rhombus.moveTo(graphicInfo.getX(), graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2, graphicInfo.getY() + graphicInfo.getHeight());
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth(), graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.lineTo(graphicInfo.getX() + graphicInfo.getWidth() / 2, graphicInfo.getY());
- rhombus.lineTo(graphicInfo.getX(), graphicInfo.getY() + graphicInfo.getHeight() / 2);
- rhombus.closePath();
- return rhombus;
- } else {
- return DefaultProcessDiagramCanvas.SHAPE_TYPE.Ellipse.equals(shapeType) ? new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(), graphicInfo.getWidth(), graphicInfo.getHeight()) : null;
+ @Override
+ public void initialize(String imageType) {
+ this.processDiagram = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB);
+ this.g = processDiagram.createGraphics();
+
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setPaint(Color.black);
+
+ Font font = new Font(activityFontName, Font.BOLD, FONT_SIZE);
+ g.setFont(font);
+ this.fontMetrics = g.getFontMetrics();
+
+ LABEL_FONT = new Font(labelFontName, Font.ITALIC, 10);
+ ANNOTATION_FONT = new Font(annotationFontName, Font.PLAIN, FONT_SIZE);
+ //优化加载速度
+ if(flag) {
+ return;
+ }
+ try {
+ USERTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/userTask.png", customClassLoader));
+ SCRIPTTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/scriptTask.png", customClassLoader));
+ SERVICETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/serviceTask.png", customClassLoader));
+ RECEIVETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/receiveTask.png", customClassLoader));
+ SENDTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/sendTask.png", customClassLoader));
+ MANUALTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/manualTask.png", customClassLoader));
+ BUSINESS_RULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/businessRuleTask.png", customClassLoader));
+ SHELL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/shellTask.png", customClassLoader));
+ CAMEL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/camelTask.png", customClassLoader));
+ MULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/muleTask.png", customClassLoader));
+
+ TIMER_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/timer.png", customClassLoader));
+ COMPENSATE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/compensate-throw.png", customClassLoader));
+ COMPENSATE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/compensate.png", customClassLoader));
+ ERROR_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/error-throw.png", customClassLoader));
+ ERROR_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/error.png", customClassLoader));
+ MESSAGE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/message-throw.png", customClassLoader));
+ MESSAGE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/message.png", customClassLoader));
+ SIGNAL_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/signal-throw.png", customClassLoader));
+ SIGNAL_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/activiti/icons/signal.png", customClassLoader));
+/* String baseUrl = Thread.currentThread().getContextClassLoader().getResource("static/img/activiti/").getPath();
+ SCRIPTTASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"scriptTask.png"));
+ USERTASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"userTask.png"));
+ SERVICETASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"serviceTask.png"));
+ RECEIVETASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"receiveTask.png"));
+ SENDTASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"sendTask.png"));
+ MANUALTASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"manualTask.png"));
+ BUSINESS_RULE_TASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"businessRuleTask.png"));
+ SHELL_TASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"shellTask.png"));
+ CAMEL_TASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"camelTask.png"));
+ MULE_TASK_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"muleTask.png"));
+
+ TIMER_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"timer.png"));
+ COMPENSATE_THROW_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"compensate-throw.png"));
+ COMPENSATE_CATCH_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"compensate.png"));
+ ERROR_THROW_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"error-throw.png"));
+ ERROR_CATCH_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"error.png"));
+ MESSAGE_THROW_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"message-throw.png"));
+ MESSAGE_CATCH_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"message.png"));
+ SIGNAL_THROW_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"signal-throw.png"));
+ SIGNAL_CATCH_IMAGE = ImageIO.read(new FileInputStream(baseUrl+"signal.png"));*/
+ flag = true;
+ } catch (IOException e) {
+ flag = false;
+ LOGGER.warn("Could not load image for process diagram creation: {}", e.getMessage());
}
}
- /**
- * This method returns intersection point of shape border and line.
- *
- * @param shape
- * @param line
- * @return Point
- */
- private static Point getIntersection(Shape shape, Line2D.Double line) {
- if (shape instanceof Ellipse2D) {
- return getEllipseIntersection(shape, line);
- } else {
- return !(shape instanceof Rectangle2D) && !(shape instanceof Path2D) ? null : getShapeIntersection(shape, line);
- }
- }
- /**
- * This method calculates ellipse intersection with line
- *
- * @param shape Bounds of this shape used to calculate parameters of inscribed into this bounds ellipse.
- * @param line
- * @return Intersection point
- */
- private static Point getEllipseIntersection(Shape shape, Line2D.Double line) {
- double angle = Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
- double x = shape.getBounds2D().getWidth() / 2.0D * Math.cos(angle) + shape.getBounds2D().getCenterX();
- double y = shape.getBounds2D().getHeight() / 2.0D * Math.sin(angle) + shape.getBounds2D().getCenterY();
- Point p = new Point();
- p.setLocation(x, y);
- return p;
- }
-
- /**
- * This method calculates shape intersection with line.
- *
- * @param shape
- * @param line
- * @return Intersection point
- */
- private static Point getShapeIntersection(Shape shape, Line2D.Double line) {
- PathIterator it = shape.getPathIterator(null);
- double[] coords = new double[6];
- double[] pos = new double[2];
- Line2D.Double l = new Line2D.Double();
- while (!it.isDone()) {
- int type = it.currentSegment(coords);
- switch (type) {
- case PathIterator.SEG_MOVETO:
- pos[0] = coords[0];
- pos[1] = coords[1];
- break;
- case PathIterator.SEG_LINETO:
- l = new Line2D.Double(pos[0], pos[1], coords[0], coords[1]);
- if (line.intersectsLine(l)) {
- return getLinesIntersection(line, l);
- }
- pos[0] = coords[0];
- pos[1] = coords[1];
- break;
- case PathIterator.SEG_CLOSE:
- break;
- default:
- // whatever
- }
- it.next();
- }
- return null;
- }
-
- /**
- * This method calculates intersections of two lines.
- *
- * @param a Line 1
- * @param b Line 2
- * @return Intersection point
- */
- private static Point getLinesIntersection(Line2D a, Line2D b) {
- double d = (a.getX1() - a.getX2()) * (b.getY2() - b.getY1()) - (a.getY1() - a.getY2()) * (b.getX2() - b.getX1());
- double da = (a.getX1() - b.getX1()) * (b.getY2() - b.getY1()) - (a.getY1() - b.getY1()) * (b.getX2() - b.getX1());
- // double db = (a.getX1()-a.getX2())*(a.getY1()-b.getY1()) - (a.getY1()-a.getY2())*(a.getX1()-b.getX1());
- double ta = da / d;
- // double tb = db/d;
- Point p = new Point();
- p.setLocation(a.getX1() + ta * (a.getX2() - a.getX1()), a.getY1() + ta * (a.getY2() - a.getY1()));
- return p;
- }
-
-
-}
\ No newline at end of file
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramGenerator.java b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramGenerator.java
index bd192547..8d748bdb 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramGenerator.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/CustomProcessDiagramGenerator.java
@@ -1,395 +1,211 @@
package com.jero.modules.activiti.service.impl.image;
-import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
+import org.activiti.image.impl.DefaultProcessDiagramGenerator;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
-
-/**
- * Class to generate an image based the diagram interchange information in a BPMN 2.0 process.
- * 在 BPMN 2.0 流程中基于图表交换信息生成图像的类。
- *
- * @author Joram Barrez
- * @author Tijs Rademakers
- */
-@Slf4j
-public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGenerator {
-
- protected String ACTIVITY_FONT_NAME = "微软雅黑";
- protected String LABEL_FONT_NAME = "微软雅黑";
- protected String ANNOTATION_FONT_NAME = "微软雅黑";
-
- protected Map, ActivityDrawInstruction> activityDrawInstructions = new HashMap<>();
- protected Map, ArtifactDrawInstruction> artifactDrawInstructions = new HashMap<>();
-
- /**
- * The instructions on how to draw a certain construct is
- * created statically and stored in a map for performance.
- */
- public CustomProcessDiagramGenerator() {
- // start event
- activityDrawInstructions.put(StartEvent.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- StartEvent startEvent = (StartEvent) flowNode;
- if (startEvent.getEventDefinitions() != null && !startEvent.getEventDefinitions().isEmpty()) {
- EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
- if (eventDefinition instanceof TimerEventDefinition) {
- processDiagramCanvas.drawTimerStartEvent(flowNode.getId(), graphicInfo);
- } else if (eventDefinition instanceof ErrorEventDefinition) {
- processDiagramCanvas.drawErrorStartEvent(flowNode.getId(), graphicInfo);
- } else if (eventDefinition instanceof SignalEventDefinition) {
- processDiagramCanvas.drawSignalStartEvent(flowNode.getId(), graphicInfo);
- } else if (eventDefinition instanceof MessageEventDefinition) {
- processDiagramCanvas.drawMessageStartEvent(flowNode.getId(), graphicInfo);
- } else {
- processDiagramCanvas.drawNoneStartEvent(flowNode.getId(), graphicInfo);
- }
- } else {
- processDiagramCanvas.drawNoneStartEvent(flowNode.getId(), graphicInfo);
- }
- }
- });
-
- // signal catch
- activityDrawInstructions.put(IntermediateCatchEvent.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- IntermediateCatchEvent intermediateCatchEvent = (IntermediateCatchEvent) flowNode;
- if (intermediateCatchEvent.getEventDefinitions() != null && !intermediateCatchEvent
- .getEventDefinitions().isEmpty()) {
- if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
- } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
- processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
- } else if (intermediateCatchEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
- processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(), flowNode.getName(), graphicInfo, true);
- }
- }
- }
- });
-
- // signal throw
- activityDrawInstructions.put(ThrowEvent.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- ThrowEvent throwEvent = (ThrowEvent) flowNode;
- if (throwEvent.getEventDefinitions() != null && !throwEvent.getEventDefinitions().isEmpty()) {
- if (throwEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawThrowingSignalEvent(flowNode.getId(), graphicInfo);
- } else if (throwEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
- processDiagramCanvas.drawThrowingCompensateEvent(flowNode.getId(), graphicInfo);
- } else {
- processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(), graphicInfo);
- }
- } else {
- processDiagramCanvas.drawThrowingNoneEvent(flowNode.getId(), graphicInfo);
- }
- }
- });
-
- // end event
- activityDrawInstructions.put(EndEvent.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- EndEvent endEvent = (EndEvent) flowNode;
- if (endEvent.getEventDefinitions() != null && !endEvent.getEventDefinitions().isEmpty()) {
- if (endEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
- processDiagramCanvas.drawErrorEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
- } else {
- processDiagramCanvas.drawNoneEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- } else {
- processDiagramCanvas.drawNoneEndEvent(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- }
- });
-
- // task
- activityDrawInstructions.put(Task.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // user task
- activityDrawInstructions.put(UserTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawUserTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // script task
- activityDrawInstructions.put(ScriptTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawScriptTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // service task
- activityDrawInstructions.put(ServiceTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- ServiceTask serviceTask = (ServiceTask) flowNode;
- processDiagramCanvas.drawServiceTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // receive task
- activityDrawInstructions.put(ReceiveTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawReceiveTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // send task
- activityDrawInstructions.put(SendTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawSendTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // manual task
- activityDrawInstructions.put(ManualTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawManualTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // businessRuleTask task
- activityDrawInstructions.put(BusinessRuleTask.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawBusinessRuleTask(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // exclusive gateway
- activityDrawInstructions.put(ExclusiveGateway.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawExclusiveGateway(flowNode.getId(), graphicInfo);
- }
- });
-
- // inclusive gateway
- activityDrawInstructions.put(InclusiveGateway.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawInclusiveGateway(flowNode.getId(), graphicInfo);
- }
- });
-
- // parallel gateway
- activityDrawInstructions.put(ParallelGateway.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawParallelGateway(flowNode.getId(), graphicInfo);
- }
- });
-
- // event based gateway
- activityDrawInstructions.put(EventGateway.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawEventBasedGateway(flowNode.getId(), graphicInfo);
- }
- });
-
- // Boundary timer
- activityDrawInstructions.put(BoundaryEvent.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- BoundaryEvent boundaryEvent = (BoundaryEvent) flowNode;
- if (boundaryEvent.getEventDefinitions() != null && !boundaryEvent.getEventDefinitions().isEmpty()) {
- if (boundaryEvent.getEventDefinitions().get(0) instanceof TimerEventDefinition) {
- processDiagramCanvas.drawCatchingTimerEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof ErrorEventDefinition) {
- processDiagramCanvas.drawCatchingErrorEvent(flowNode.getId(), graphicInfo, boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof SignalEventDefinition) {
- processDiagramCanvas.drawCatchingSignalEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof MessageEventDefinition) {
- processDiagramCanvas.drawCatchingMessageEvent(flowNode.getId(), flowNode.getName(), graphicInfo, boundaryEvent.isCancelActivity());
- } else if (boundaryEvent.getEventDefinitions().get(0) instanceof CompensateEventDefinition) {
- processDiagramCanvas.drawCatchingCompensateEvent(flowNode.getId(), graphicInfo, boundaryEvent.isCancelActivity());
- }
- }
-
- }
- });
-
- // subprocess
- activityDrawInstructions.put(SubProcess.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
- processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, false);
- } else {
- processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, SubProcess.class);
- }
- }
- });
-
- // Event subprocess
- activityDrawInstructions.put(EventSubProcess.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (graphicInfo.getExpanded() != null && !graphicInfo.getExpanded()) {
- processDiagramCanvas.drawCollapsedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, false);
- } else {
- processDiagramCanvas.drawExpandedSubProcess(flowNode.getId(), flowNode.getName(), graphicInfo, Transaction.class);
- }
- }
- });
-
- // call activity
- activityDrawInstructions.put(CallActivity.class, new ActivityDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- processDiagramCanvas.drawCollapsedCallActivity(flowNode.getId(), flowNode.getName(), graphicInfo);
- }
- });
-
- // text annotation
- artifactDrawInstructions.put(TextAnnotation.class, new ArtifactDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
- TextAnnotation textAnnotation = (TextAnnotation) artifact;
- processDiagramCanvas.drawTextAnnotation(textAnnotation.getId(), textAnnotation.getText(), graphicInfo);
- }
- });
-
- // association
- artifactDrawInstructions.put(Association.class, new ArtifactDrawInstruction() {
- @Override
- public void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact) {
- Association association = (Association) artifact;
- String sourceRef = association.getSourceRef();
- String targetRef = association.getTargetRef();
-
- // source and target can be instance of FlowElement or Artifact
- BaseElement sourceElement = bpmnModel.getFlowElement(sourceRef);
- BaseElement targetElement = bpmnModel.getFlowElement(targetRef);
- if (sourceElement == null) {
- sourceElement = bpmnModel.getArtifact(sourceRef);
- }
- if (targetElement == null) {
- targetElement = bpmnModel.getArtifact(targetRef);
- }
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
- graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
- int[] xPoints = new int[graphicInfoList.size()];
- int[] yPoints = new int[graphicInfoList.size()];
- for (int i = 1; i < graphicInfoList.size(); i++) {
- GraphicInfo graphicInfo = graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
- if (i == 1) {
- xPoints[0] = (int) previousGraphicInfo.getX();
- yPoints[0] = (int) previousGraphicInfo.getY();
- }
- xPoints[i] = (int) graphicInfo.getX();
- yPoints[i] = (int) graphicInfo.getY();
- }
-
- AssociationDirection associationDirection = association.getAssociationDirection();
- processDiagramCanvas.drawAssociation(xPoints, yPoints, associationDirection, false);
- }
- });
+@Component
+public class CustomProcessDiagramGenerator extends DefaultProcessDiagramGenerator implements ICustomProcessDiagramGenerator{
+ //预初始化流程图绘制,大大提升了系统启动后首次查看流程图的速度
+ static {
+ new CustomProcessDiagramCanvas(10,10,0,0,"png", "宋体","宋体","宋体",null);
}
+ public CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType,
+ List highLightedActivities, List highLightedFlows, String activityFontName,
+ String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor,
+ Color[] colors, Set currIds) {
- protected CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel,
- List highLightedActivities, List runningActivityIdList, List highLightedFlows, List runningActivityFlowsIds,
- String activityFontName, String labelFontName, String annotationFontName) {
+ if(null == highLightedActivities) {
+ highLightedActivities = Collections.emptyList();
+ }
+ if(null == highLightedFlows) {
+ highLightedFlows = Collections.emptyList();
+ }
- CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, activityFontName, labelFontName, annotationFontName);
+ prepareBpmnModel(bpmnModel);
+
+ CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
// Draw pool shape, if process is participant in collaboration
for (Pool pool : bpmnModel.getPools()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- processDiagramCanvas.drawPoolOrLane(pool.getId(), pool.getName(), graphicInfo);
+ GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
+ processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo);
}
// Draw lanes
for (Process process : bpmnModel.getProcesses()) {
- for (Lane lane : process.getLanes()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
- processDiagramCanvas.drawPoolOrLane(lane.getId(), lane.getName(), graphicInfo);
- }
+ for (Lane lane : process.getLanes()) {
+ GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());
+ processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo);
+ }
}
// Draw activities and their sequence-flows
- /**
- * 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理
- */
- for (FlowNode flowNode : bpmnModel.getProcesses().get(0).findFlowElementsOfType(FlowNode.class)) {
- drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, runningActivityIdList,
- highLightedFlows, runningActivityFlowsIds);
+ for (Process process: bpmnModel.getProcesses()) {
+ List flowNodeList= process.findFlowElementsOfType(FlowNode.class);
+ for (FlowNode flowNode : flowNodeList) {
+ drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, colors, currIds);
+ }
}
// Draw artifacts
for (Process process : bpmnModel.getProcesses()) {
- for (Artifact artifact : process.getArtifacts()) {
- drawArtifact(processDiagramCanvas, bpmnModel, artifact);
+
+ for (Artifact artifact : process.getArtifacts()) {
+ drawArtifact(processDiagramCanvas, bpmnModel, artifact);
+ }
+
+ List subProcesses = process.findFlowElementsOfType(SubProcess.class, true);
+ if (subProcesses != null) {
+ for (SubProcess subProcess : subProcesses) {
+ for (Artifact subProcessArtifact : subProcess.getArtifacts()) {
+ drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);
+ }
}
+ }
}
return processDiagramCanvas;
}
- /**
- * Desc: 绘制流程图上的所有节点和流程线,对高亮显示的节点和流程线进行特殊处理
- *
- * @param processDiagramCanvas
- * @param bpmnModel
- * @param flowNode
- * @param highLightedActivities
- * @param highLightedFlows
- * @author Fuxs
- */
protected void drawActivity(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,
- List highLightedActivities, List runningActivityIdList, List highLightedFlows, List runningActivityFlowsIds) {
+ List highLightedActivities, List highLightedFlows, double scaleFactor, Color[] colors, Set currIds) {
+ ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
+ if (drawInstruction != null) {
+ drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
+
+ // Gather info on the multi instance marker
+ boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;
+ if (flowNode instanceof Activity) {
+ Activity activity = (Activity) flowNode;
+ MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
+ if (multiInstanceLoopCharacteristics != null) {
+ multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
+ multiInstanceParallel = !multiInstanceSequential;
+ }
+ }
+
+ // Gather info on the collapsed marker
+ GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
+ if (flowNode instanceof SubProcess) {
+ collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
+ } else if (flowNode instanceof CallActivity) {
+ collapsed = true;
+ }
+
+ if (scaleFactor == 1.0) {
+ // Actually draw the markers
+ processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(),(int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
+ multiInstanceSequential, multiInstanceParallel, collapsed);
+ }
+
+ // Draw highlighted activities
+ if (highLightedActivities.contains(flowNode.getId())) {
+ if(!CollectionUtils.isEmpty(currIds)
+ &&currIds.contains(flowNode.getId())
+ && !(flowNode instanceof Gateway)) {//非结束节点,并且是当前节点
+ drawHighLight((flowNode instanceof StartEvent), processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[1]);
+ }else {//普通节点
+ drawHighLight((flowNode instanceof StartEvent)||(flowNode instanceof EndEvent),processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[0]);
+ }
+ }
+
+ }
+
+ // Outgoing transitions of activity
+ for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
+ String flowId = sequenceFlow.getId();
+ boolean highLighted = (highLightedFlows.contains(flowId));
+ String defaultFlow = null;
+ if (flowNode instanceof Activity) {
+ defaultFlow = ((Activity) flowNode).getDefaultFlow();
+ } else if (flowNode instanceof Gateway) {
+ defaultFlow = ((Gateway) flowNode).getDefaultFlow();
+ }
+
+ boolean isDefault = false;
+ if (defaultFlow != null && defaultFlow.equalsIgnoreCase(flowId)) {
+ isDefault = true;
+ }
+// boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
+
+ String sourceRef = sequenceFlow.getSourceRef();
+ String targetRef = sequenceFlow.getTargetRef();
+ FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
+ FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
+ List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(flowId);
+ if (graphicInfoList != null && graphicInfoList.size() > 0) {
+ graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
+ int xPoints[]= new int[graphicInfoList.size()];
+ int yPoints[]= new int[graphicInfoList.size()];
+
+ for (int i=1; i= 5);
+// }
+ }
+ }
+
+ // Nested elements
+ if (flowNode instanceof FlowElementsContainer) {
+ for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
+ if (nestedFlowElement instanceof FlowNode) {
+ drawActivity_highOne(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, colors, currIds);
+ //drawActivity,这个是activiti自带的,子流程会出现多次高亮问题,改用 drawActivity_highOne
+ /*drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement,
+ highLightedActivities, highLightedFlows, scaleFactor);*/
+ }
+ }
+ }
+ }
+
+ /**
+ * 解决子流程多次高亮问题
+ */
+ protected void drawActivity_highOne(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode,
+ List highLightedActivities, List highLightedFlows, double scaleFactor, Color[] colors, Set currIds) {
ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
if (drawInstruction != null) {
drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
// Gather info on the multi instance marker
- boolean multiInstanceSequential = false;
- boolean multiInstanceParallel = false;
- boolean highLighted = false;
+ boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;
if (flowNode instanceof Activity) {
Activity activity = (Activity) flowNode;
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
@@ -399,39 +215,37 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
}
}
- // Gather info on the highLighted marker
+ // Gather info on the collapsed marker
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- if (!(flowNode instanceof SubProcess)) {
- if (flowNode instanceof CallActivity) {
- highLighted = true;
- }
- } else {
- highLighted = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
+ if (flowNode instanceof SubProcess) {
+ collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
+ } else if (flowNode instanceof CallActivity) {
+ collapsed = true;
}
- processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, highLighted);
-
+ if (scaleFactor == 1.0) {
+ // Actually draw the markers
+ processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(),(int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
+ multiInstanceSequential, multiInstanceParallel, collapsed);
+ }
// Draw highlighted activities
if (highLightedActivities.contains(flowNode.getId())) {
- /*
- * 如果节点为当前正在处理中的节点,则红色高亮显示
- */
- if (runningActivityIdList.contains(flowNode.getId())) {
- log.debug("[绘制]-当前正在处理中的节点-红色高亮显示节点[{}-{}]", flowNode.getId(), flowNode.getName());
- drawRunningActivityHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
- } else {
- log.debug("[绘制]-高亮显示节点[{}-{}]", flowNode.getId(), flowNode.getName());
- drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
+ if(!CollectionUtils.isEmpty(currIds)
+ &&currIds.contains(flowNode.getId())
+ && !(flowNode instanceof Gateway)) {//非结束节点,并且是当前节点
+ drawHighLight((flowNode instanceof StartEvent), processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[1]);
+ }else {//普通节点
+ drawHighLight((flowNode instanceof StartEvent)||(flowNode instanceof EndEvent),processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[0]);
}
}
+
}
- /*
- * 绘制当前节点的流程线
- */
+ // Outgoing transitions of activity
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
- boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
+ String flowId = sequenceFlow.getId();
+ boolean highLighted = (highLightedFlows.contains(flowId));
String defaultFlow = null;
if (flowNode instanceof Activity) {
defaultFlow = ((Activity) flowNode).getDefaultFlow();
@@ -440,26 +254,24 @@ public class CustomProcessDiagramGenerator implements ICustomProcessDiagramGener
}
boolean isDefault = false;
- if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
+ if (defaultFlow != null && defaultFlow.equalsIgnoreCase(flowId)) {
isDefault = true;
}
- boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null
- && !(flowNode instanceof Gateway);
+// boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
String sourceRef = sequenceFlow.getSourceRef();
String targetRef = sequenceFlow.getTargetRef();
FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
+ List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(flowId);
if (graphicInfoList != null && graphicInfoList.size() > 0) {
- graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement,
- targetElement, graphicInfoList);
- int[] xPoints = new int[graphicInfoList.size()];
- int[] yPoints = new int[graphicInfoList.size()];
+ graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
+ int xPoints[]= new int[graphicInfoList.size()];
+ int yPoints[]= new int[graphicInfoList.size()];
- for (int i = 1; i < graphicInfoList.size(); i++) {
+ for (int i=1; i= 5);
+// }
}
}
- // Nested elements
- if (flowNode instanceof FlowElementsContainer) {
- for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
- if (nestedFlowElement instanceof FlowNode) {
- drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement, highLightedActivities,
- runningActivityIdList, highLightedFlows, runningActivityFlowsIds);
- }
+ }
+
+ protected void drawHighLight(boolean isStartOrEnd, CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo, Color color) {
+ processDiagramCanvas.drawHighLight(isStartOrEnd, (int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), color);
+ }
+
+ protected static CustomProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType,
+ String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
+
+ // We need to calculate maximum values to know how big the image will be in its entirety
+ double minX = Double.MAX_VALUE;
+ double maxX = 0;
+ double minY = Double.MAX_VALUE;
+ double maxY = 0;
+
+ for (Pool pool : bpmnModel.getPools()) {
+ GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
+ minX = graphicInfo.getX();
+ maxX = graphicInfo.getX() + graphicInfo.getWidth();
+ minY = graphicInfo.getY();
+ maxY = graphicInfo.getY() + graphicInfo.getHeight();
}
- }
- }
- /**
- * This method makes coordinates of connection flow better.
- *
- * @param processDiagramCanvas
- * @param bpmnModel
- * @param sourceElement
- * @param targetElement
- * @param graphicInfoList
- * @return
- */
- protected static List connectionPerfectionizer(CustomProcessDiagramCanvas processDiagramCanvas,
- BpmnModel bpmnModel, BaseElement sourceElement, BaseElement targetElement,
- List graphicInfoList) {
- GraphicInfo sourceGraphicInfo = bpmnModel.getGraphicInfo(sourceElement.getId());
- GraphicInfo targetGraphicInfo = bpmnModel.getGraphicInfo(targetElement.getId());
+ List flowNodes = gatherAllFlowNodes(bpmnModel);
+ for (FlowNode flowNode : flowNodes) {
- CustomProcessDiagramCanvas.SHAPE_TYPE sourceShapeType = getShapeType(sourceElement);
- CustomProcessDiagramCanvas.SHAPE_TYPE targetShapeType = getShapeType(targetElement);
+ GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
- return processDiagramCanvas.connectionPerfectionizer(sourceShapeType, targetShapeType, sourceGraphicInfo,
- targetGraphicInfo, graphicInfoList);
- }
-
- /**
- * This method returns shape type of base element.
- * Each element can be presented as rectangle, rhombus, or ellipse.
- *
- * @param baseElement
- * @return CustomProcessDiagramCanvas.SHAPE_TYPE
- */
- protected static CustomProcessDiagramCanvas.SHAPE_TYPE getShapeType(BaseElement baseElement) {
- if (baseElement instanceof Task || baseElement instanceof Activity || baseElement instanceof TextAnnotation) {
- return CustomProcessDiagramCanvas.SHAPE_TYPE.Rectangle;
- } else if (baseElement instanceof Gateway) {
- return CustomProcessDiagramCanvas.SHAPE_TYPE.Rhombus;
- } else if (baseElement instanceof Event) {
- return CustomProcessDiagramCanvas.SHAPE_TYPE.Ellipse;
- } else {
- // unknown source element, just do not correct coordinates
- }
- return null;
- }
-
- protected static GraphicInfo getLineCenter(List graphicInfoList) {
- GraphicInfo gi = new GraphicInfo();
-
- int[] xPoints = new int[graphicInfoList.size()];
- int[] yPoints = new int[graphicInfoList.size()];
-
- double length = 0;
- double[] lengths = new double[graphicInfoList.size()];
- lengths[0] = 0;
- double m;
- for (int i = 1; i < graphicInfoList.size(); i++) {
- GraphicInfo graphicInfo = graphicInfoList.get(i);
- GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
-
- if (i == 1) {
- xPoints[0] = (int) previousGraphicInfo.getX();
- yPoints[0] = (int) previousGraphicInfo.getY();
- }
- xPoints[i] = (int) graphicInfo.getX();
- yPoints[i] = (int) graphicInfo.getY();
-
- length += Math.sqrt(Math.pow((int) graphicInfo.getX() - (int) previousGraphicInfo.getX(), 2) + Math.pow(
- (int) graphicInfo.getY() - (int) previousGraphicInfo.getY(), 2));
- lengths[i] = length;
- }
- m = length / 2;
- int p1 = 0, p2 = 1;
- for (int i = 1; i < lengths.length; i++) {
- double len = lengths[i];
- p1 = i - 1;
- p2 = i;
- if (len > m) {
- break;
- }
- }
-
- GraphicInfo graphicInfo1 = graphicInfoList.get(p1);
- GraphicInfo graphicInfo2 = graphicInfoList.get(p2);
-
- double AB = (int) graphicInfo2.getX() - (int) graphicInfo1.getX();
- double OA = (int) graphicInfo2.getY() - (int) graphicInfo1.getY();
- double OB = lengths[p2] - lengths[p1];
- double ob = m - lengths[p1];
- double ab = AB * ob / OB;
- double oa = OA * ob / OB;
-
- double mx = graphicInfo1.getX() + ab;
- double my = graphicInfo1.getY() + oa;
-
- gi.setX(mx);
- gi.setY(my);
- return gi;
- }
-
- protected void drawArtifact(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,
- Artifact artifact) {
-
- ArtifactDrawInstruction drawInstruction = artifactDrawInstructions.get(artifact.getClass());
- if (drawInstruction != null) {
- drawInstruction.draw(processDiagramCanvas, bpmnModel, artifact);
- }
- }
-
- private static void drawHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
- processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo
- .getWidth(), (int) graphicInfo.getHeight());
-
- }
-
- /**
- * Desc:绘制正在执行中的节点红色高亮显示
- *
- * @param processDiagramCanvas CustomProcessDiagramCanvas
- * @param graphicInfo GraphicInfo
- * @author Fuxs
- */
- private static void drawRunningActivityHighLight(CustomProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
- processDiagramCanvas.drawRunningActivityHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo
- .getWidth(), (int) graphicInfo.getHeight());
-
- }
-
- protected static CustomProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String activityFontName,
- String labelFontName, String annotationFontName) {
-
- // We need to calculate maximum values to know how big the image will be in its entirety
- double minX = 1.7976931348623157E308D;
- double maxX = 0.0D;
- double minY = 1.7976931348623157E308D;
- double maxY = 0.0D;
-
-
- for (Pool pool : bpmnModel.getPools()) {
- GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());
- minX = graphicInfo.getX();
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
- minY = graphicInfo.getY();
- maxY = graphicInfo.getY() + graphicInfo.getHeight();
- }
-
- List flowNodes = gatherAllFlowNodes(bpmnModel);
- for (FlowNode flowNode : flowNodes) {
-
- GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
-
- // width
- if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {
+ // width
+ if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {
maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth();
- }
- if (flowNodeGraphicInfo.getX() < minX) {
+ }
+ if (flowNodeGraphicInfo.getX() < minX) {
minX = flowNodeGraphicInfo.getX();
- }
- // height
- if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {
+ }
+ // height
+ if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {
maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight();
- }
- if (flowNodeGraphicInfo.getY() < minY) {
+ }
+ if (flowNodeGraphicInfo.getY() < minY) {
minY = flowNodeGraphicInfo.getY();
- }
+ }
- for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
+ for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
if (graphicInfoList != null) {
- for (GraphicInfo graphicInfo : graphicInfoList) {
- // width
- if (graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
- }
- if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
- }
- // height
- if (graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
- }
- if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
- }
- }
- }
- }
- }
-
- List artifacts = gatherAllArtifacts(bpmnModel);
- for (Artifact artifact : artifacts) {
-
- GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
-
- if (artifactGraphicInfo != null) {
- // width
- if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {
- maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();
- }
- if (artifactGraphicInfo.getX() < minX) {
- minX = artifactGraphicInfo.getX();
- }
- // height
- if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {
- maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();
- }
- if (artifactGraphicInfo.getY() < minY) {
- minY = artifactGraphicInfo.getY();
- }
- }
-
- List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
- if (graphicInfoList != null) {
- for (GraphicInfo graphicInfo : graphicInfoList) {
+ for (GraphicInfo graphicInfo : graphicInfoList) {
// width
if (graphicInfo.getX() > maxX) {
- maxX = graphicInfo.getX();
+ maxX = graphicInfo.getX();
}
if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
+ minX = graphicInfo.getX();
}
// height
if (graphicInfo.getY() > maxY) {
- maxY = graphicInfo.getY();
+ maxY = graphicInfo.getY();
}
- if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
+ if (graphicInfo.getY()< minY) {
+ minY = graphicInfo.getY();
}
+ }
}
+ }
}
- }
- int nrOfLanes = 0;
- for (Process process : bpmnModel.getProcesses()) {
- for (Lane l : process.getLanes()) {
+ List artifacts = gatherAllArtifacts(bpmnModel);
+ for (Artifact artifact : artifacts) {
+
+ GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());
+
+ if (artifactGraphicInfo != null) {
+ // width
+ if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {
+ maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();
+ }
+ if (artifactGraphicInfo.getX() < minX) {
+ minX = artifactGraphicInfo.getX();
+ }
+ // height
+ if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {
+ maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();
+ }
+ if (artifactGraphicInfo.getY() < minY) {
+ minY = artifactGraphicInfo.getY();
+ }
+ }
+
+ List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());
+ if (graphicInfoList != null) {
+ for (GraphicInfo graphicInfo : graphicInfoList) {
+ // width
+ if (graphicInfo.getX() > maxX) {
+ maxX = graphicInfo.getX();
+ }
+ if (graphicInfo.getX() < minX) {
+ minX = graphicInfo.getX();
+ }
+ // height
+ if (graphicInfo.getY() > maxY) {
+ maxY = graphicInfo.getY();
+ }
+ if (graphicInfo.getY()< minY) {
+ minY = graphicInfo.getY();
+ }
+ }
+ }
+ }
+
+ int nrOfLanes = 0;
+ for (Process process : bpmnModel.getProcesses()) {
+ for (Lane l : process.getLanes()) {
nrOfLanes++;
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(l.getId());
// // width
if (graphicInfo.getX() + graphicInfo.getWidth() > maxX) {
- maxX = graphicInfo.getX() + graphicInfo.getWidth();
+ maxX = graphicInfo.getX() + graphicInfo.getWidth();
}
if (graphicInfo.getX() < minX) {
- minX = graphicInfo.getX();
+ minX = graphicInfo.getX();
}
// height
if (graphicInfo.getY() + graphicInfo.getHeight() > maxY) {
- maxY = graphicInfo.getY() + graphicInfo.getHeight();
+ maxY = graphicInfo.getY() + graphicInfo.getHeight();
}
if (graphicInfo.getY() < minY) {
- minY = graphicInfo.getY();
+ minY = graphicInfo.getY();
}
+ }
}
- }
- // Special case, see http://jira.codehaus.org/browse/ACT-1431
- if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
- // Nothing to show
- minX = 0.0D;
- minY = 0.0D;
- }
- //width和height代表最大的长宽
- return new CustomProcessDiagramCanvas((int) maxX + 30, (int) maxY + 50, (int) minX, (int) minY, activityFontName, labelFontName, annotationFontName);
- }
-
- protected static List gatherAllArtifacts(BpmnModel bpmnModel) {
- List artifacts = new ArrayList();
- for (Process process : bpmnModel.getProcesses()) {
- artifacts.addAll(process.getArtifacts());
- }
- return artifacts;
- }
-
- protected static List gatherAllFlowNodes(BpmnModel bpmnModel) {
- List flowNodes = new ArrayList();
- for (Process process : bpmnModel.getProcesses()) {
- flowNodes.addAll(gatherAllFlowNodes(process));
- }
- return flowNodes;
- }
-
- protected static List gatherAllFlowNodes(FlowElementsContainer flowElementsContainer) {
- List flowNodes = new ArrayList();
- for (FlowElement flowElement : flowElementsContainer.getFlowElements()) {
- if (flowElement instanceof FlowNode) {
- flowNodes.add((FlowNode) flowElement);
- }
- if (flowElement instanceof FlowElementsContainer) {
- flowNodes.addAll(gatherAllFlowNodes((FlowElementsContainer) flowElement));
+ // Special case, see https://activiti.atlassian.net/browse/ACT-1431
+ if (flowNodes.isEmpty() && bpmnModel.getPools().isEmpty() && nrOfLanes == 0) {
+ // Nothing to show
+ minX = 0;
+ minY = 0;
}
+
+ return new CustomProcessDiagramCanvas((int) maxX + 10,(int) maxY + 10, (int) minX, (int) minY,
+ imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
+ }
+
+ @Override
+ public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities,
+ List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName,
+ ClassLoader customClassLoader, double scaleFactor, Color[] colors, Set currIds) {
+ CustomProcessDiagramCanvas customProcessDiagramCanvas = generateProcessDiagram(bpmnModel, imageType, highLightedActivities, highLightedFlows,
+ activityFontName, labelFontName, annotationFontName, customClassLoader, scaleFactor,colors, currIds);
+ BufferedImage bufferedImage = customProcessDiagramCanvas.generateBufferedImage(imageType);
+ ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ ImageOutputStream imOut;
+ try {
+ imOut = ImageIO.createImageOutputStream(bs);
+ ImageIO.write(bufferedImage, "PNG", imOut);
+ } catch (IOException e) {
+ e.printStackTrace();
}
- return flowNodes;
- }
- public Map, ActivityDrawInstruction> getActivityDrawInstructions() {
- return activityDrawInstructions;
+ InputStream is = new ByteArrayInputStream(bs.toByteArray());
+ return is;
}
-
- public void setActivityDrawInstructions(Map, ActivityDrawInstruction> activityDrawInstructions) {
- this.activityDrawInstructions = activityDrawInstructions;
- }
-
- public Map, ArtifactDrawInstruction> getArtifactDrawInstructions() {
- return artifactDrawInstructions;
- }
-
- public void setArtifactDrawInstructions(Map, ArtifactDrawInstruction> artifactDrawInstructions) {
- this.artifactDrawInstructions = artifactDrawInstructions;
- }
-
- protected interface ActivityDrawInstruction {
- void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode);
- }
-
- protected interface ArtifactDrawInstruction {
- void draw(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, Artifact artifact);
- }
-
- /**
- * Desc: 输入所有的参数,以获取图像
- *
- * @param bpmnModel
- * @param highLightedActivities
- * @param runningActivityIdList
- * @param highLightedFlows
- * @param activityFontName
- * @param labelFontName
- * @param annotationFontName
- * @return
- */
@Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- List runningActivityFlowsIds,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
- // TODO
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- runningActivityIdList,
- highLightedFlows,
- runningActivityFlowsIds,
- activityFontName,
- labelFontName,
- annotationFontName).generateImage();
+ public InputStream generateDiagram(BpmnModel bpmnModel, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
+ return generateDiagram(bpmnModel, imageType, Collections.emptyList(), Collections.emptyList(),
+ activityFontName, labelFontName, annotationFontName, customClassLoader, 1.0, new Color[] {Color.BLACK, Color.BLACK}, null);
}
- @Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- runningActivityIdList,
- highLightedFlows,
- Collections.emptyList(),
- activityFontName,
- labelFontName,
- annotationFontName).generateImage();
- }
-
- @Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName) {
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- Collections.emptyList(),
- highLightedFlows,
- Collections.emptyList(),
- activityFontName,
- labelFontName,
- annotationFontName).generateImage();
- }
-
- @Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- List runningActivityFlowsIds) {
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- runningActivityIdList,
- highLightedFlows,
- runningActivityFlowsIds,
- ACTIVITY_FONT_NAME,
- LABEL_FONT_NAME,
- ANNOTATION_FONT_NAME).generateImage();
- }
-
- @Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows) {
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- runningActivityIdList,
- highLightedFlows,
- Collections.emptyList(),
- ACTIVITY_FONT_NAME,
- LABEL_FONT_NAME,
- ANNOTATION_FONT_NAME).generateImage();
- }
-
- @Override
- public InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows) {
- return generateProcessDiagram(bpmnModel,
- highLightedActivities,
- Collections.emptyList(),
- highLightedFlows,
- Collections.emptyList(),
- ACTIVITY_FONT_NAME,
- LABEL_FONT_NAME,
- ANNOTATION_FONT_NAME).generateImage();
- }
}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/ICustomProcessDiagramGenerator.java b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/ICustomProcessDiagramGenerator.java
index 3075226d..f5687768 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/ICustomProcessDiagramGenerator.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/service/impl/image/ICustomProcessDiagramGenerator.java
@@ -1,61 +1,15 @@
package com.jero.modules.activiti.service.impl.image;
import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.image.ProcessDiagramGenerator;
+import java.awt.*;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
-/**
- * bpmnModel bpmn模型
- * activityFontName 活动字体
- * labelFontName 标签字体
- * annotationFontName 标注字体
- * highLightedActivities 高亮活动节点(绿色)
- * runningActivityIdList 正在运行的活动节点(红色)
- * highLightedFlows 高亮顺序流(绿色)
- * lastFlowIdList 最后一条执行的顺序流(红色) ——————未实现
- */
-public interface ICustomProcessDiagramGenerator{
-
- //指定字体
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- List runningActivityFlowsIds,
- String activityFontName,
- String labelFontName,
- String annotationFontName);
-
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName);
-
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows,
- String activityFontName,
- String labelFontName,
- String annotationFontName);
-
- //无指定字体,使用默认字体
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows,
- List runningActivityFlowsIds);
-
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List runningActivityIdList,
- List highLightedFlows);
-
- InputStream generateDiagramCustom(BpmnModel bpmnModel,
- List highLightedActivities,
- List highLightedFlows);
-
+public interface ICustomProcessDiagramGenerator extends ProcessDiagramGenerator {
+ InputStream generateDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities,
+ List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName,
+ ClassLoader customClassLoader, double scaleFactor, Color[] colors, Set currIds);
}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/util/CamundaTag.java b/laws-modules/src/main/java/com/jero/modules/activiti/util/CamundaTag.java
new file mode 100644
index 00000000..6f11a58c
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/util/CamundaTag.java
@@ -0,0 +1,58 @@
+package com.jero.modules.activiti.util;
+
+/**
+ * @author liJiaRao
+ * @date 2023-09-05 17:16
+ */
+public enum CamundaTag {
+ assignee("assignee", "camunda:assignee","activiti:assignee","指派人"),
+ candidateUsers("candidateUsers", "camunda:candidateUsers","activiti:candidateUsers","候选人"),
+ candidateGroups("candidateGroups", "camunda:candidateGroups","activiti:candidateGroups","候选组"),
+ exclusive("exclusive", "camunda:exclusive","activiti:exclusive","独家"),
+ taskListener("taskListener", "camunda:taskListener","activiti:taskListener","监听"),
+ ;
+ private String attribute;
+ private String camundaName;
+ private String activitiName;
+ private String note;
+
+
+ CamundaTag(String attribute, String camundaName, String activitiName, String note) {
+ this.attribute = attribute;
+ this.camundaName = camundaName;
+ this.activitiName = activitiName;
+ this.note = note;
+ }
+
+ public String getAttribute() {
+ return attribute;
+ }
+
+ public void setAttribute(String attribute) {
+ this.attribute = attribute;
+ }
+
+ public String getCamundaName() {
+ return camundaName;
+ }
+
+ public void setCamundaName(String camundaName) {
+ this.camundaName = camundaName;
+ }
+
+ public String getActivitiName() {
+ return activitiName;
+ }
+
+ public void setActivitiName(String activitiName) {
+ this.activitiName = activitiName;
+ }
+
+ public String getNote() {
+ return note;
+ }
+
+ public void setNote(String note) {
+ this.note = note;
+ }
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/util/ConversionUtil.java b/laws-modules/src/main/java/com/jero/modules/activiti/util/ConversionUtil.java
new file mode 100644
index 00000000..b8112076
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/util/ConversionUtil.java
@@ -0,0 +1,178 @@
+package com.jero.modules.activiti.util;
+
+import cn.hutool.core.io.FileUtil;
+import org.dom4j.*;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
+import org.dom4j.tree.AbstractAttribute;
+import org.dom4j.tree.DefaultAttribute;
+import org.dom4j.tree.DefaultElement;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.util.List;
+
+/**
+ * 作者 CG
+ * 时间 2021/4/12 14:21
+ * 备注 camunda 和 activiti xml 互相转换
+ * 参数
+ */
+public class ConversionUtil {
+ public static void main(String[] args) {
+ File file1 = new File("E:\\Data\\Downloads\\sign.bpmn");
+ camundaToActiviti(file1,true);
+ }
+
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 14:22
+ * 备注 判断文件名字是否是xml,不是xml转换为xml
+ * 参数
+ */
+ public static File isXml(File file) {
+// 判断是否为null
+ String name = FileUtil.mainName(file);
+ String parent = file.getParent();
+ boolean bpmn = FileUtil.pathEndsWith(file, "bpmn");
+ if (bpmn) {
+ //转换为xml
+ File xmlFile = FileUtil.file(parent, name + ".xml");
+ File copy = FileUtil.copy(file, xmlFile, true);
+ return copy;
+ }
+ return file;
+ }
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 15:57
+ * 备注 属性转换
+ * 参数 [file, flag camunda->activiti=true activiti->camunda=false]
+ */
+ public static void camundaToActiviti(File file, Boolean flag) {
+ //判断文件后缀名是否正确
+ try {
+ File xml = isXml(file);
+ //转换为文档
+ SAXReader reader = new SAXReader();
+// 转换为Document
+ Document doc = reader.read(xml);
+ //获取根节点
+ Element rootElement = doc.getRootElement();
+ //获取命名空间
+ //flag camunda->activiti=true activiti->camunda=false
+ NamespaceHandler(rootElement, flag);
+ //处理userTask
+ Element process = rootElement.element("process");
+ List userTask = process.elements("userTask");
+ CamundaTag[] values = CamundaTag.values();
+ if (!CollectionUtils.isEmpty(userTask)) {
+ for (CamundaTag value : values) {
+ userTask(userTask, value, flag);
+ }
+ //处理监听
+ userTaskListener(userTask, flag);
+ }
+ //保存文档
+ saveDocument(doc, file);
+ } catch (DocumentException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 17:45
+ * 备注 处理命名空间
+ * 参数 [rootElement, flag]
+ */
+ public static void NamespaceHandler(Element rootElement, Boolean flag) {
+ NamespaceName camundaNamespace = NamespaceName.camunda;
+ NamespaceName activitiNamespace = NamespaceName.activiti;
+ Namespace activiti = rootElement.getNamespaceForPrefix(flag ? camundaNamespace.getName() : activitiNamespace.getName());
+ if (activiti != null) {
+ //删除camunda命名空间
+ rootElement.remove(activiti);
+ //添加activiti命名空间
+ Namespace namespace = new Namespace(flag ? activitiNamespace.getName() : camundaNamespace.getName(), flag ? activitiNamespace.getUrl() : camundaNamespace.getUrl());
+ rootElement.add(namespace);
+ }
+ }
+
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 15:36
+ * 备注 userTask 参数转换
+ * 参数 [userTask 要处理的集合, camundaTag 要处理的参数类型, flag camunda->activiti=true activiti->camunda=false]
+ */
+ public static void userTask(List userTask, CamundaTag camundaTag, Boolean flag) {
+ for (Element element : userTask) {
+ Attribute assignee = element.attribute(camundaTag.getAttribute());
+ if (assignee != null) {
+ element.remove(assignee);
+ AbstractAttribute abstractAttribute = new AbstractAttribute() {
+ @Override
+ public QName getQName() {
+ QName qName = new QName(flag ? camundaTag.getActivitiName() : camundaTag.getCamundaName());
+ return qName;
+ }
+
+ @Override
+ public String getValue() {
+ return assignee.getValue();
+ }
+ };
+ element.add(abstractAttribute);
+ }
+ }
+ }
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 15:36
+ * 备注 userTask 参数转换
+ * 参数 [userTask 要处理的集合, camundaTag 要处理的参数类型, flag camunda->activiti=true activiti->camunda=false]
+ */
+ public static void userTaskListener(List userTask, Boolean flag) {
+ CamundaTag listener = CamundaTag.taskListener;
+ for (Element element : userTask) {
+ Element extensionElements = element.element("extensionElements");
+ if (extensionElements!=null){
+ //是否有监听
+ Element taskListener = extensionElements.element(listener.getAttribute());
+ if (taskListener!=null){
+ //获取节点所有参数
+ List attributes = taskListener.attributes();
+ DefaultElement defaultElement = new DefaultElement(flag?listener.getActivitiName():listener.getCamundaName());
+ //将参数拷贝到新的节点
+ for (Attribute attribute : attributes) {
+ DefaultAttribute defaultAttribute = new DefaultAttribute(attribute.getName(), attribute.getValue());
+ defaultElement.add(defaultAttribute);
+ }
+ //删除原有节点
+ extensionElements.remove(taskListener);
+ //添加新构建的节点
+ extensionElements.add(defaultElement);
+ }
+
+ }
+ }
+ }
+ /**
+ * 作者 CG
+ * 时间 2021/4/12 15:45
+ * 备注 文档保存
+ * 参数 [document, xmlFile]
+ */
+ public static void saveDocument(Document document, File xmlFile) throws IOException {
+ Writer osWrite = new OutputStreamWriter(new FileOutputStream(xmlFile));//创建输出流
+ OutputFormat format = OutputFormat.createPrettyPrint(); //获取输出的指定格式
+ format.setEncoding("UTF-8");//设置编码 ,确保解析的xml为UTF-8格式
+ XMLWriter writer = new XMLWriter(osWrite, format);//XMLWriter 指定输出文件以及格式
+ writer.write(document);//把document写入xmlFile指定的文件(可以为被解析的文件或者新创建的文件)
+ writer.flush();
+ writer.close();
+ }
+}
+
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/util/NamespaceName.java b/laws-modules/src/main/java/com/jero/modules/activiti/util/NamespaceName.java
new file mode 100644
index 00000000..28ef255b
--- /dev/null
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/util/NamespaceName.java
@@ -0,0 +1,34 @@
+package com.jero.modules.activiti.util;
+
+/**
+ * @author liJiaRao
+ * @date 2023-09-05 17:16
+ */
+public enum NamespaceName {
+ activiti("activiti","http://activiti.org/bpmn"),
+ camunda("camunda","http://camunda.org/schema/1.0/bpmn"),
+ ;
+ private String name;
+ public String url;
+
+ NamespaceName(String name, String url) {
+ this.name = name;
+ this.url = url;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+}
diff --git a/laws-modules/src/main/resources/bpmn/企标制修订流程.bpmn b/laws-modules/src/main/resources/bpmn/企标制修订流程.bpmn
new file mode 100644
index 00000000..28bf2b93
--- /dev/null
+++ b/laws-modules/src/main/resources/bpmn/企标制修订流程.bpmn
@@ -0,0 +1,457 @@
+
+
+
+
+ Flow_0ln2zen
+
+
+
+ Flow_0ln2zen
+ Flow_1dmfby6
+
+
+
+
+ Flow_0hkyh3o
+ Flow_0dlfvoz
+ Flow_0iw6bki
+
+
+ Flow_0iw6bki
+ Flow_0rw7rph
+
+
+
+ Flow_1dmfby6
+ Flow_0hkyh3o
+
+ ${nrOfInstances== nrOfCompletedInstances}
+
+
+
+ Flow_0rw7rph
+ Flow_0dlfvoz
+ Flow_07x6x68
+
+
+
+ ${!pass}
+
+
+ ${pass}
+
+
+ Flow_07x6x68
+ Flow_1gc5b6z
+
+
+ Flow_1gc5b6z
+ Flow_0lxhrf3
+ Flow_0s3et9m
+
+
+
+ Flow_0s3et9m
+ Flow_1ts1npj
+ Flow_1yn3bo0
+
+
+
+ ${open}
+
+
+
+
+
+ Flow_14y4j6o
+ Flow_1x9nrbh
+
+ ${nrOfInstances== nrOfCompletedInstances}
+
+
+
+ Flow_1ts1npj
+ Flow_14y4j6o
+
+
+
+ Flow_1x9nrbh
+ Flow_0b6hwpr
+ Flow_1jfhrkk
+
+
+
+ Flow_1jfhrkk
+ Flow_0n3oqju
+
+ ${nrOfInstances== nrOfCompletedInstances}
+
+
+
+ Flow_0n3oqju
+ Flow_0b6hwpr
+ Flow_0viypc1
+
+
+
+ ${!pass}
+
+
+ ${pass}
+
+
+
+ Flow_0viypc1
+ Flow_0lxhrf3
+
+
+
+ Flow_0114fp7
+ Flow_15vlua6
+
+ ${nrOfInstances== nrOfCompletedInstances}
+
+
+
+ Flow_1uaxx7p
+ Flow_02wh2wo
+
+
+
+ ${pass}
+
+
+ Flow_15vlua6
+ Flow_1uaxx7p
+ Flow_1k4inp1
+
+
+
+ ${!pass}
+
+
+ Flow_02wh2wo
+ Flow_0v50urt
+ Flow_0rkg4il
+
+
+
+ ${pass}
+
+
+ ${!pass}
+
+
+ Flow_1cg7p7q
+ Flow_0jc597n
+ Flow_03b0vp0
+
+
+
+ ${pass}
+
+
+ ${!pass}
+
+
+ Flow_0jc597n
+ Flow_093us1v
+
+ ${nrOfInstances== nrOfCompletedInstances}
+
+
+
+ Flow_0v50urt
+ Flow_1cg7p7q
+
+
+
+ Flow_093us1v
+ Flow_09gf9nd
+
+
+
+ Flow_09gf9nd
+ Flow_0r1lb59
+
+
+ Flow_1yn3bo0
+ Flow_1k4inp1
+ Flow_0rkg4il
+ Flow_03b0vp0
+ Flow_0114fp7
+
+
+ Flow_0r1lb59
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/laws-single-startup/src/main/java/com/jero/JeroSystemSingleApplication.java b/laws-single-startup/src/main/java/com/jero/JeroSystemSingleApplication.java
index 052f3615..979e44da 100644
--- a/laws-single-startup/src/main/java/com/jero/JeroSystemSingleApplication.java
+++ b/laws-single-startup/src/main/java/com/jero/JeroSystemSingleApplication.java
@@ -2,7 +2,9 @@ package com.jero;
import com.jero.common.util.oConvertUtils;
import lombok.extern.slf4j.Slf4j;
+import org.activiti.spring.boot.SecurityAutoConfiguration;
import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -21,7 +23,8 @@ import java.net.UnknownHostException;
@Slf4j
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
- org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class})
+ SecurityAutoConfiguration.class,
+ ManagementWebSecurityAutoConfiguration.class})
public class JeroSystemSingleApplication extends SpringBootServletInitializer {
@Override
diff --git a/pom.xml b/pom.xml
index 7e8a6703..b8d3c3ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,7 +45,7 @@
1.6.1
7.4.0
2.15.0
- 7.1.0.M1
+ 6.0.0