Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.yaoqiang.graph.util.GraphUtils Maven / Gradle / Ivy
package org.yaoqiang.graph.util;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.ImageIcon;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.yaoqiang.bpmn.model.elements.XMLExtensionElement;
import org.yaoqiang.bpmn.model.elements.core.foundation.BaseElement;
import org.yaoqiang.graph.model.GraphModel;
import org.yaoqiang.graph.swing.GraphComponent;
import org.yaoqiang.graph.view.Graph;
import org.yaoqiang.util.Constants;
import org.yaoqiang.util.Resources;
import com.mxgraph.canvas.mxImageCanvas;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxDomUtils;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxGraphView;
import com.mxgraph.view.mxTemporaryCellStates;
/**
* Utils
*
* @author Shi Yaoqiang([email protected] )
*/
public class GraphUtils {
public static boolean isWSDL11File(String importType) {
if (importType.equals("http://schemas.xmlsoap.org/wsdl/")) {
return true;
}
return false;
}
public static boolean isWSDL20File(String importType) {
if (importType.equals("http://www.w3.org/TR/wsdl20/")) {
return true;
}
return false;
}
public static Cursor getConnectCursor(mxGraphComponent graphComponent) {
ImageIcon curIc = new ImageIcon(GraphUtils.class.getResource("/org/yaoqiang/graph/images/arrow.gif"));
Point hotSpot = new Point(curIc.getIconWidth(), curIc.getIconHeight());
if (!Constants.OS.startsWith("Windows")) {
hotSpot = new Point(curIc.getIconWidth() / 2, curIc.getIconHeight() / 2);
}
Cursor cursor = graphComponent.getToolkit().createCustomCursor(curIc.getImage(), hotSpot, "ConnectCursor");
return cursor;
}
public static boolean hasSwimlane(final Graph graph, final boolean vertical) {
Collection pools = mxGraphModel.filterDescendants(graph.getModel(), new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return graph.isAutoPool(cell) && (vertical ? graph.isVerticalSwimlane(cell) : !graph.isVerticalSwimlane(cell));
}
});
return pools.size() > 0;
}
public static Set getOutgoingCells(Graph graph, Object cell, Object edge, Object parent) {
Set outgoingCells = new HashSet();
outgoingCells.add(cell);
for (Object e : graph.getOutgoingEdges(cell, parent)) {
if (e == edge) {
continue;
}
Object next = graph.getModel().getTerminal(e, false);
outgoingCells.add(e);
outgoingCells.add(next);
outgoingCells.addAll(getIncomingCells(graph, next, e, parent));
outgoingCells.addAll(getOutgoingCells(graph, next, null, parent));
}
return outgoingCells;
}
public static Set getIncomingCells(Graph graph, Object cell, Object edge, Object parent) {
Set incomingCells = new HashSet();
incomingCells.add(cell);
for (Object e : graph.getIncomingEdges(cell, parent)) {
if (e == edge) {
continue;
}
Object previous = graph.getModel().getTerminal(e, true);
incomingCells.add(e);
incomingCells.add(previous);
incomingCells.addAll(getOutgoingCells(graph, previous, e, parent));
incomingCells.addAll(getIncomingCells(graph, previous, null, parent));
}
return incomingCells;
}
public static List getAllAssociations(Graph graph) {
List associations = new ArrayList();
GraphModel model = graph.getModel();
Object[] edges = mxGraphModel.getChildEdges(model, graph.getDefaultParent());
if (edges != null) {
for (Object edge : edges) {
if (model.isAssociation(edge)) {
associations.add((mxCell) edge);
}
}
}
return associations;
}
public static void getAllVerticesInOrder(Graph graph, Object parent, List vertices, List callActivities) {
Object[] children = mxGraphModel.getChildVertices(graph.getModel(), parent);
if (children != null) {
vertices.addAll(Arrays.asList(children));
for (Object v : children) {
// TODO:
// if (graph.isCallActivityProcess(v)) {
// boolean add = false;
// Object[] cells = mxGraphModel.getChildVertices(graph.getModel(), v);
// if (cells != null) {
// for (Object c : cells) {
// if (graph.getModel().isBoundaryEvent(c)) {
// vertices.add(c);
// } else {
// add = true;
// }
// }
// }
// if (add) {
// callActivities.add(v);
// }
// continue;
// } else if (graph.getModel().isBoundaryEvent(v) && graph.isCallActivityProcess(parent)) {
// vertices.remove(v);
// }
getAllVerticesInOrder(graph, v, vertices, callActivities);
}
}
}
public static List getAllGroups(Graph graph) {
List groups = new ArrayList();
for (Object cell : graph.getChildVertices(graph.getDefaultParent())) {
mxCell group = (mxCell) cell;
if (graph.getModel().isGroupArtifact(group) && group.getValue().toString().length() != 0) {
groups.add(group);
}
}
return groups;
}
public static List getAllPools(Graph graph, boolean auto) {
GraphModel model = graph.getModel();
List pools = new ArrayList();
Object[] cells = model.getCells().values().toArray();
for (int i = 0; i < cells.length; i++) {
if (model.isPool(cells[i])) {
if (auto) {
if (mxUtils.isTrue(graph.getCellStyle(cells[i]), Constants.STYLE_AUTO, true)) {
pools.add(cells[i]);
}
} else {
pools.add(cells[i]);
}
}
}
return pools;
}
public static mxCell getChoreographyActivity(Graph graph, Object parent) {
GraphModel model = graph.getModel();
Object[] partCells = mxGraphModel.getChildVertices(model, parent);
Object act = null;
for (int i = 0; i < partCells.length; i++) {
if (model.isChoreographyTask(partCells[i]) || model.isChoreographySubprocess(partCells[i])) {
act = partCells[i];
}
}
return (mxCell) act;
}
public static void arrangeChoreography(Graph graph, Object cell, boolean fold) {
GraphModel model = graph.getModel();
mxGeometry geo = model.getGeometry(cell);
Object act = getChoreographyActivity(graph, cell);
if (act == null) {
return;
}
mxGeometry ageo = model.getGeometry(act);
double partHeight = 0;
Object[] partCells = mxGraphModel.getChildVertices(graph.getModel(), cell);
// arrange width
for (Object part : partCells) {
if (model.isChoreographyParticipant(part)) {
mxGeometry pgeo = model.getGeometry(part);
if (fold) {
pgeo.setWidth(ageo.getWidth());
} else {
pgeo.setWidth(geo.getWidth());
}
partHeight += pgeo.getHeight();
model.setGeometry(part, pgeo);
}
}
if (fold) {
// arrange parent size
geo.setHeight(partHeight + ageo.getHeight());
geo.setWidth(ageo.getWidth());
model.setGeometry(cell, geo);
} else {
// arrange activity size
ageo.setWidth(geo.getWidth());
ageo.setHeight(geo.getHeight() - partHeight);
model.setGeometry(act, ageo);
}
List partList = new ArrayList();
partList.addAll(Arrays.asList(partCells));
Collections.sort(partList, new Comparator() {
public int compare(Object o1, Object o2) {
mxGeometry geo1 = ((mxCell) o1).getGeometry();
mxGeometry geo2 = ((mxCell) o2).getGeometry();
return (int) (geo1.getY() - geo2.getY());
}
});
Iterator it = partList.iterator();
Object upper = it.next();
while (it.hasNext()) {
Object part = it.next();
mxGeometry tmp = model.getGeometry(part);
tmp.setY(model.getGeometry(upper).getY() + model.getGeometry(upper).getHeight());
model.setGeometry(part, tmp);
upper = part;
}
}
public static void rotateSwimlane(final GraphComponent graphComponent) {
final Graph graph = graphComponent.getGraph();
final GraphModel model = graph.getModel();
List pools = GraphUtils.getAllPools(graph, true);
if (pools.isEmpty()) {
return;
}
List swimlanes = new ArrayList(pools);
List children = new ArrayList();
for (Object pool : pools) {
swimlanes.addAll(mxGraphModel.filterDescendants(model, new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return model.isLane(cell);
}
}, pool));
children.addAll(mxGraphModel.filterDescendants(model, new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return !graph.isSwimlane(cell);
}
}, pool));
}
double tmp = 0;
for (Object swimlane : swimlanes) {
mxGeometry geo = ((mxCell) swimlane).getGeometry();
tmp = geo.getHeight();
geo.setHeight(geo.getWidth());
geo.setWidth(tmp);
boolean vertical = graph.isVerticalSwimlane(swimlane);
if (vertical) {
geo.setY(geo.getX());
model.setStyle(swimlane, (model.isPool(swimlane) ? "p" : "l") + model.getStyle(swimlane).substring(9));
} else {
geo.setX(geo.getY());
model.setStyle(swimlane, "vertical" + (model.isPool(swimlane) ? "P" : "L") + model.getStyle(swimlane).substring(1));
}
}
Set edges = new HashSet();
for (Object child : children) {
mxGeometry geo = ((mxCell) child).getGeometry();
if (model.isEdge(child)) {
edges.add(child);
List points = geo.getPoints();
if (points != null && !points.isEmpty()) {
geo.setPoints(null);
}
} else {
tmp = geo.getX();
geo.setX(geo.getY());
geo.setY(tmp);
}
graph.extendParent(child);
}
for (Object pool : pools) {
GraphUtils.arrangeSwimlaneLength(graph, pool, true, false);
}
GraphUtils.arrangeSwimlanePosition(graphComponent);
for (Object e : edges) {
mxGeometry geo = ((mxCell) e).getGeometry();
geo.setX(0);
geo.setY(0);
}
graph.clearSelection();
graph.refresh();
}
public static void arrangeAllSwimlaneLength(final Graph graph, boolean auto) {
List pools = getAllPools(graph, auto);
for (Object pool : pools) {
arrangeSwimlaneLength(graph, pool, true, false);
}
}
public static void manualArrangeSwimlaneLength(final Graph graph, Object cell) {
if (!graph.isManualPool(cell)) {
return;
}
mxGraphModel model = graph.getModel();
Collection childlanes = mxGraphModel.filterDescendants(model, new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return graph.isSwimlane(cell);
}
}, cell);
if (childlanes.size() > 1) {
childlanes.remove(cell);
for (Object lane : childlanes) {
arrangeSwimlaneLength(graph, lane, false, false);
}
}
}
public static void arrangeSwimlaneLength(final Graph graph, Object cell, boolean child, boolean fold) {
if (graph.isManualPool(cell)) {
return;
}
mxGraphModel model = graph.getModel();
mxCell swimlane = (mxCell) cell;
mxGeometry geo = swimlane.getGeometry();
double width = 0;
// arrange parent swimlanes
Object parent = model.getParent(swimlane);
while (graph.isSwimlane(parent)) {
if (!fold) {
arrangeSwimlaneLength(graph, parent, false, false);
}
parent = model.getParent(parent);
}
parent = model.getParent(swimlane);
if (graph.isSwimlane(parent)) {
if (graph.isVerticalSwimlane(swimlane)) {
width = model.getGeometry(parent).getHeight() - Constants.SWIMLANE_NAME_WIDTH;
geo.setHeight(width);
} else {
width = model.getGeometry(parent).getWidth() - Constants.SWIMLANE_NAME_WIDTH;
geo.setWidth(width);
}
} else {
if (graph.isVerticalSwimlane(swimlane)) {
geo.setHeight(Constants.SWIMLANE_HEIGHT);
} else {
geo.setWidth(Constants.SWIMLANE_WIDTH);
}
}
if (graph.isPlane(model.getParent(swimlane))) {
if (graph.isVerticalSwimlane(swimlane)) {
geo.setY(Constants.SWIMLANE_START_POINT);
} else {
geo.setX(Constants.SWIMLANE_START_POINT);
}
} else {
if (graph.isVerticalSwimlane(swimlane)) {
geo.setY(Constants.SWIMLANE_NAME_WIDTH + 1);
} else {
geo.setX(Constants.SWIMLANE_NAME_WIDTH + 1);
}
}
model.setGeometry(swimlane, geo);
// arrange child swimlanes
if (child) {
Collection childlanes = mxGraphModel.filterDescendants(model, new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return graph.isSwimlane(cell);
}
}, swimlane);
if (childlanes.size() > 1) {
childlanes.remove(swimlane);
for (Object lane : childlanes) {
arrangeSwimlaneLength(graph, lane, false, false);
}
}
}
}
public static void arrangeSwimlaneSize(final Graph graph, Object cell, boolean other, boolean fold, boolean remove) {
final GraphModel model = graph.getModel();
mxCell swimlane = (mxCell) cell;
Set movedlanes = new HashSet();
movedlanes.add(swimlane);
// arrange folded swimlanes
if (graph.isCollapsedSwimlane(swimlane)) {
mxGeometry geo = model.getGeometry(swimlane);
if (graph.isVerticalSwimlane(cell)) {
geo.setWidth(Constants.SWIMLANE_SIZE / 3);
} else {
geo.setHeight(Constants.SWIMLANE_SIZE / 3);
}
model.setGeometry(swimlane, geo);
}
// arrange moved swimlanes
Object parent = model.getParent(swimlane);
if (other && !fold) {
parent = swimlane;
}
while (graph.isSwimlane(parent)) {
double size = 0;
Object[] cells = mxGraphModel.getChildVertices(model, parent);
for (int i = 0; i < cells.length; i++) {
if (other && !graph.isSwimlane(cells[i]))
break;
if (graph.isVerticalSwimlane(cell)) {
size += model.getGeometry(cells[i]).getWidth();
} else {
size += model.getGeometry(cells[i]).getHeight();
}
movedlanes.add(cells[i]);
}
mxGeometry geo = model.getGeometry(parent);
if (size > 0) {
if (graph.isVerticalSwimlane(cell)) {
geo.setWidth(size);
} else {
geo.setHeight(size);
}
}
model.setGeometry(parent, geo);
movedlanes.add(parent);
parent = model.getParent(parent);
}
// arrange other swimlanes
if (!other && !fold && !remove) {
Collection swimlanes = mxGraphModel.filterDescendants(model, new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return !model.isCollapsed(model.getParentPool(cell)) && (graph.hasChildNonLane(cell) || graph.isEmptySwimlane(cell));
}
});
swimlanes.removeAll(movedlanes);
for (Object lane : swimlanes) {
arrangeSwimlaneSize(graph, lane, true, false, false);
}
}
}
public static void arrangeSwimlanePosition(final GraphComponent graphComponent) {
final Graph graph = graphComponent.getGraph();
Collection pools = mxGraphModel.filterDescendants(graph.getModel(), new mxGraphModel.Filter() {
public boolean filter(Object cell) {
return graph.isAutoPool(cell);
}
});
List poolList = new ArrayList();
poolList.addAll(pools);
Collections.sort(poolList, new Comparator() {
public int compare(Object o1, Object o2) {
mxGeometry geo1 = ((mxCell) o1).getGeometry();
mxGeometry geo2 = ((mxCell) o2).getGeometry();
if (graph.isVerticalSwimlane(o1)) {
return (int) (geo1.getX() - geo2.getX());
} else {
return (int) (geo1.getY() - geo2.getY());
}
}
});
for (Object pool : poolList) {
if (graph.isVerticalSwimlane(pool)) {
arrangePoolXOffset(graphComponent, pool);
arrangeLaneXOffset(graph, pool);
} else {
arrangePoolYOffset(graphComponent, pool);
arrangeLaneYOffset(graph, pool);
}
}
}
public static void arrangePoolYOffset(final GraphComponent graphComponent, Object cell) {
final Graph graph = graphComponent.getGraph();
if (graph.isManualPool(cell)) {
return;
}
GraphModel model = graph.getModel();
mxGeometry geo = model.getGeometry(cell);
mxCellState state = graph.getView().getState(cell);
Rectangle rect = state == null ? geo.getRectangle() : state.getRectangle();
double yOffset = Constants.POOL_SPACING;
Object pool = graphComponent.getCellAt(Constants.SWIMLANE_WIDTH / 4, rect.y - Constants.POOL_SPACING / 2);
if (pool == null) {
pool = graphComponent.getCellAt(Constants.SWIMLANE_WIDTH / 4, rect.y - 1);
}
if (pool == null) {
pool = graphComponent.getCellAt(Constants.SWIMLANE_WIDTH / 4, rect.y - Constants.POOL_SPACING);
}
if (model.isLane(pool)) {
pool = model.getParentPool(pool);
}
if (pool != cell && model.isPool(pool)) {
mxGeometry tmp = model.getGeometry(pool);
yOffset += tmp.getY() + tmp.getHeight();
geo.setY(yOffset);
model.setGeometry(cell, geo);
} else if (pool == null && model.isPool(cell)) {
mxGeometry tmp = model.getGeometry(cell);
if (tmp.getY() < 50) {
geo.setY(Constants.SWIMLANE_START_POINT);
}
model.setGeometry(cell, geo);
}
}
public static void arrangePoolXOffset(final GraphComponent graphComponent, Object cell) {
final Graph graph = graphComponent.getGraph();
if (graph.isManualPool(cell)) {
return;
}
GraphModel model = graph.getModel();
mxGeometry geo = model.getGeometry(cell);
mxCellState state = graph.getView().getState(cell);
Rectangle rect = state == null ? geo.getRectangle() : state.getRectangle();
double xOffset = Constants.POOL_SPACING;
Object pool = graphComponent.getCellAt(rect.x - Constants.POOL_SPACING / 2, Constants.SWIMLANE_WIDTH / 4);
if (pool == null) {
pool = graphComponent.getCellAt(rect.x - 1, Constants.SWIMLANE_WIDTH / 4);
}
if (pool == null) {
pool = graphComponent.getCellAt(rect.x - Constants.POOL_SPACING, Constants.SWIMLANE_WIDTH / 4);
}
if (model.isLane(pool)) {
pool = model.getParentPool(pool);
}
if (pool != cell && graph.isAutoPool(pool)) {
mxGeometry tmp = model.getGeometry(pool);
xOffset += tmp.getX() + tmp.getWidth();
geo.setX(xOffset);
model.setGeometry(cell, geo);
} else if (pool == null && model.isPool(cell)) {
mxGeometry tmp = model.getGeometry(cell);
if (tmp.getX() < 50) {
geo.setX(Constants.SWIMLANE_START_POINT);
}
model.setGeometry(cell, geo);
}
}
public static void arrangeLaneYOffset(final Graph graph, Object cell) {
if (graph.hasChildLane(cell)) {
GraphModel model = graph.getModel();
double yOffset = 0;
int laneCount = model.getChildCount(cell);
for (int i = 0; i < laneCount; i++) {
Object lane = model.getChildAt(cell, i);
if (model.isLane(lane)) {
mxGeometry geo = model.getGeometry(lane);
geo.setY(yOffset);
model.setGeometry(lane, geo);
yOffset += model.getGeometry(lane).getHeight();
arrangeLaneYOffset(graph, lane);
}
}
}
}
public static void arrangeLaneXOffset(final Graph graph, Object cell) {
if (graph.hasChildLane(cell)) {
GraphModel model = graph.getModel();
double xOffset = 0;
int laneCount = model.getChildCount(cell);
for (int i = 0; i < laneCount; i++) {
Object lane = model.getChildAt(cell, i);
if (model.isLane(lane)) {
mxGeometry geo = model.getGeometry(lane);
geo.setX(xOffset);
model.setGeometry(lane, geo);
xOffset += model.getGeometry(lane).getWidth();
arrangeLaneXOffset(graph, lane);
}
}
}
}
public static String setEdgeStyle(Graph graph, Object cell) {
Object src = graph.getModel().getTerminal(cell, true);
Object tgt = graph.getModel().getTerminal(cell, false);
String style = graph.adjustEdgeStyle(src, tgt, cell);
graph.getModel().setStyle(cell, style);
return style;
}
public static void moveLableToTop(Graph graph, Object[] cells) {
graph.setCellStyles(mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_CENTER, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_TOP, cells);
graph.setCellStyles(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_CENTER, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_BOTTOM, cells);
graph.setSelectionCells(cells);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_LABEL_POSITION, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_LABEL_POSITION,
(String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_ALIGN), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_ALIGN), null);
}
public static void moveLableToLeft(Graph graph, Object[] cells) {
graph.setCellStyles(mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_LEFT, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE, cells);
graph.setCellStyles(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_RIGHT, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE, cells);
graph.setSelectionCells(cells);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_LABEL_POSITION, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_LABEL_POSITION,
(String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_ALIGN), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_ALIGN), null);
}
public static void moveLableToRight(Graph graph, Object[] cells) {
graph.setCellStyles(mxConstants.STYLE_LABEL_POSITION, mxConstants.ALIGN_RIGHT, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_MIDDLE, cells);
graph.setCellStyles(mxConstants.STYLE_ALIGN, mxConstants.ALIGN_LEFT, cells);
graph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE, cells);
graph.setSelectionCells(cells);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_LABEL_POSITION, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_LABEL_POSITION,
(String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_LABEL_POSITION), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_ALIGN), null);
GraphUtils.setElementStyles(graph, mxConstants.STYLE_VERTICAL_ALIGN, (String) graph.getCellStyle(cells[0]).get(mxConstants.STYLE_VERTICAL_ALIGN), null);
}
public static BufferedImage generateDiagram(mxGraphComponent graphComponent) {
return generateDiagram(graphComponent, null, 1, null, null, null);
}
public static BufferedImage generateDiagram(mxGraphComponent graphComponent, List highLightedActivityIds) {
return generateDiagram(graphComponent, null, 1, highLightedActivityIds, "#00FF00", "#FFFF00");
}
public static BufferedImage generateDiagram(mxGraphComponent graphComponent, Color background, double scale, List highLightedActivityIds,
String highlightStrokeColor, String highlightFillColor) {
mxImageCanvas canvas = null;
mxGraph graph = graphComponent.getGraph();
mxGraphModel model = (mxGraphModel) graph.getModel();
mxGraphView view = graph.getView();
boolean eventsEnabled = view.isEventsEnabled();
view.setEventsEnabled(false);
if (highLightedActivityIds != null) {
for (String id : highLightedActivityIds) {
Object cell = model.getCell(id);
if (cell != null) {
if (highlightStrokeColor != null) {
model.setStyle(cell, model.getStyle(cell) + ";strokeWidth=3;strokeColor=" + highlightStrokeColor);
}
if (highlightFillColor != null) {
Color tmp = mxUtils.parseColor(highlightFillColor);
String gradientColor = "#"
+ mxUtils.getHexColorString(
new Color(Math.max(tmp.getRed() - 48, 0), Math.max(tmp.getGreen() - 48, 0), Math.max(tmp.getBlue() - 48, 0)))
.substring(2);
model.setStyle(cell, model.getStyle(cell) + ";fillColor=" + highlightFillColor + ";gradientColor=" + gradientColor);
}
}
}
}
Object[] cells = new Object[] { model.getRoot() };
mxTemporaryCellStates temp = new mxTemporaryCellStates(view, scale, cells);
try {
mxRectangle clip = graph.getBoundsForCells(cells, false, true, true);
if (clip != null && clip.getWidth() > 0 && clip.getHeight() > 0) {
clip.grow(1);
Rectangle rect = clip.getRectangle();
canvas = new mxImageCanvas(graphComponent.getCanvas(), rect.width + 1, rect.height + 1, background, graphComponent.isAntiAlias());
if (canvas != null) {
double previousScale = canvas.getScale();
Point previousTranslate = canvas.getTranslate();
try {
canvas.setTranslate(-rect.x, -rect.y);
canvas.setScale(view.getScale());
for (int i = 0; i < cells.length; i++) {
graph.drawCell(canvas, cells[i]);
}
} finally {
canvas.setScale(previousScale);
canvas.setTranslate(previousTranslate.x, previousTranslate.y);
}
}
}
} finally {
temp.destroy();
view.setEventsEnabled(eventsEnabled);
}
return (canvas != null) ? canvas.destroy() : null;
}
public static mxCell generateOrganizationCell(String style, String name) {
mxCell orgCell = null;
List objectClass = null;
Map attrs = new HashMap();
if ("organizationRoot".equals(style)) {
objectClass = Arrays.asList("dcObject", "organization");
attrs.put("dc", name);
attrs.put("o", name);
} else if ("organization".equals(style)) {
objectClass = Arrays.asList("organization", "top");
attrs.put("o", name);
} else if ("organizationalUnit".equals(style)) {
objectClass = Arrays.asList("organizationalUnit", "top");
attrs.put("ou", name);
} else if ("organizationalRole".equals(style)) {
objectClass = Arrays.asList("organizationalRole", "top");
attrs.put("cn", name);
} else if ("organizationalPerson".equals(style)) {
objectClass = Arrays.asList("inetOrgPerson", "organizationalPerson", "person", "top");
attrs.put("cn", name);
attrs.put("sn", name);
} else if ("groupOfNames".equals(style)) {
objectClass = Arrays.asList("groupOfNames", "top");
attrs.put("cn", name);
}
Document doc = mxDomUtils.createDocument();
Element value = doc.createElement("entry");
for (Entry e : attrs.entrySet()) {
value.setAttribute(e.getKey(), e.getValue());
}
Element el = null;
for (String c : objectClass) {
el = doc.createElement("objectClass");
el.setAttribute("name", c);
value.appendChild(el);
}
orgCell = new mxCell(value, new mxGeometry(), style);
orgCell.setVertex(true);
return orgCell;
}
public static void setElementStyles(Graph graph, String name, String value, Object cell) {
BaseElement el = null;
Object[] cells = null;
if (cell != null) {
cells = new Object[] { cell };
} else {
cells = graph.getSelectionCells();
}
for (Object c : cells) {
if (graph.isChoreography(c) || graph.isSubChoreography(c)) {
c = GraphUtils.getChoreographyActivity(graph, c);
}
el = (BaseElement) graph.getModel().getValue(c);
if (el != null) {
XMLExtensionElement parent = el.getExtensionElements();
XMLExtensionElement styleElement = parent.getChildElement("yaoqiang:style");
if (name == null) {
if (styleElement != null) {
parent.removeChildElement(styleElement);
}
} else {
if (styleElement == null) {
styleElement = new XMLExtensionElement(parent, "yaoqiang:style");
parent.addChildElement(styleElement);
}
styleElement.setAttribute(name, (String) graph.getCellStyle(c).get(name));
}
}
}
}
public static String validateEdge(Graph graph, Object edge, Object source, Object target) {
StringBuffer error = new StringBuffer();
String style = graph.adjustEdgeStyle(source, target, edge);
GraphModel model = graph.getModel();
Object srcParent = model.getParent(source);
if (graph.isSwimlane(source)) {
srcParent = source;
}
if (model.isBoundaryEvent(source) || graph.isChoreography(srcParent) || graph.isSubChoreography(srcParent)) {
srcParent = model.getParent(srcParent);
}
Object tgtParent = model.getParent(target);
if (graph.isSwimlane(target)) {
tgtParent = target;
}
if (model.isBoundaryEvent(target) || graph.isChoreography(tgtParent) || graph.isSubChoreography(tgtParent)) {
tgtParent = model.getParent(tgtParent);
}
if (model.isAncestor(source, target) || model.isAncestor(target, source)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
if (model.isEdge(source)) {
if (!style.equals(Constants.EDGE_TYPE_ASSOCIATION) && !style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)
|| model.getTerminal(source, true) == target || model.getTerminal(source, false) == target) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
}
if (model.isEdge(target)) {
if (!style.equals(Constants.EDGE_TYPE_ASSOCIATION) && !style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)
|| model.getTerminal(target, true) == source || model.getTerminal(target, false) == source) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
}
if (model.isBoundaryEvent(target) && model.isNoneEvent(target)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
if (graph.isOrganizationRoot(target)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
if ((model.isGroupArtifact(source) || model.isGroupArtifact(target)) && (!model.isAnnotation(source) && !model.isAnnotation(target))) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
// for (Object e: graph.getOutgoingEdges(target)) {
// if (graph.isSequenceFlow(e)) {
// if (model.getTerminal(e, false) == source) {
// error.append(mxResources.get("WarningInvalidConnection") + "\n");
// }
// }
// }
if (model.isSubProcess(srcParent) || model.isSubProcess(tgtParent)) {
if (model.hasSameParentPool(srcParent, tgtParent) && srcParent != tgtParent && !style.equals(Constants.EDGE_TYPE_ASSOCIATION)
&& !style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
}
// Choreography Participant
if (model.isChoreographyParticipant(source)) {
if (model.isEvent(target) || model.isGateway(target) || model.isChoreographyParticipant(target) || model.isChoreographyTask(target)
|| model.isChoreographySubprocess(target)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
}
if (model.isChoreographyParticipant(target)) {
if (model.isEvent(source) || model.isGateway(source) || model.isChoreographyParticipant(source) || model.isChoreographyTask(source)
|| model.isChoreographySubprocess(source)) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
}
if (style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)
&& (model.isChoreographyTask(source) || model.isChoreographySubprocess(source) || model.isChoreographyTask(target) || model
.isChoreographySubprocess(target))) {
error.append(Resources.get("WarningInvalidConnection") + "\n");
}
// Start/Link Event P283, Intermediate Event P297 ,Instantiate Event Gateway P337
if ((graph.isLinkEvent(target, false) || model.isBoundaryEvent(target) || model.isInstantiateReceiveTask(target)
|| model.isInstantiateEventGateway(target) || model.isStartEvent(target))
&& style.equals(Constants.EDGE_TYPE_SEQUENCE_FLOW)) {
if (model.isStartEvent(target)) {
error.append(Resources.get("WarningStartEventMustNotHaveAnyIncomingSequenceFlows") + "\n");
} else if (graph.isLinkEvent(target, false)) {
error.append(Resources.get("WarningTargetLinkEventMustNotHaveAnyIncomingSequenceFlows") + "\n");
} else if (model.isBoundaryEvent(target)) {
error.append(Resources.get("WarningAttachedIntermediateEventMustNotHaveAnyIncomingSequenceFlows") + "\n");
} else if (model.isInstantiateEventGateway(target)) {
error.append(Resources.get("WarningInstantiateEventGatewayMustNotHaveAnyIncomingSequenceFlows") + "\n");
} else if (model.isInstantiateReceiveTask(target)) {
error.append(Resources.get("WarningInstantiateReceiveTaskMustNotHaveAnyIncomingSequenceFlows") + "\n");
}
}
// Start Event P283
if (model.isStartEvent(source) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningStartEventMustNotHaveAnyOutgoingMessageFlows") + "\n");
}
// End Event P287
if (model.isEndEvent(target) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningEndEventMustNotHaveAnyIncomingMessageFlows") + "\n");
}
if (model.isEndEvent(source) && !model.isMessageEvent(source) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningOnlyMessageEndEventMayHaveOutgoingMessageFlows") + "\n");
}
if (model.isReceiveTask(source) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningReceiveTaskMustNotHaveAnyOutgoingMessageFlows") + "\n");
}
if (model.isSendTask(target) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningSendTaskMustNotHaveAnyIncomingMessageFlows") + "\n");
}
// Intermediate Event P298
if ((model.isIntermediateEvent(source) && !model.isMessageIntermediateEvent(source) || model.isIntermediateEvent(target)
&& !model.isMessageIntermediateEvent(target))
&& style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningOnlyMessageIntermediateEventMayHaveOneIncomingOrOutgoingMessageFlow") + "\n");
}
// End/Link Event P287
if ((graph.isLinkEvent(source, true) || model.isEndEvent(source)) && style.equals(Constants.EDGE_TYPE_SEQUENCE_FLOW)) {
if (model.isEndEvent(source)) {
error.append(Resources.get("WarningEndEventMustNotHaveAnyOutgoingSequenceFlows") + "\n");
} else if (graph.isLinkEvent(source, true)) {
error.append(Resources.get("WarningSourceLinkEventMustNotHaveAnyOutgoingSequenceFlows") + "\n");
}
}
// Event Sub-Process P212
if ((model.isEventSubProcess(source) || model.isEventSubProcess(target)) && style.equals(Constants.EDGE_TYPE_SEQUENCE_FLOW)) {
error.append(Resources.get("WarningEventSubProcessMustNotHaveAnyIncomingOrOutgoingSequenceFlows") + "\n");
}
// Gateway P74
if ((model.isGateway(source) || model.isGateway(target)) && style.startsWith(Constants.EDGE_TYPE_MESSAGE_FLOW)) {
error.append(Resources.get("WarningGatewayMustNotHaveAnyIncomingOrOutgoingMessageFlows") + "\n");
}
// Event Gateway P336
if (model.isEventGateway(source)) {
if (!model.isIntermediateEvent(target) && !model.isReceiveTask(target) && !model.isChoreographyTask(target)
&& !model.isChoreographySubprocess(target)) {
error.append(Resources.get("WarningEventGatewayOutgoingSequenceFlowTargetMustBeAnIntermediateEventOrAReceiveTask") + "\n");
}
}
if (model.isCompensationActivity(source) || model.isCompensationActivity(target)) {
if (!style.equals(Constants.EDGE_TYPE_COMPENSATION_ASSOCIATION)) {
error.append(Resources.get("WarningCompensationActivityMustNotHaveAnyIncomingOrOutgoingSequenceFlow") + "\n");
}
}
// Data Object
if ((model.isDataObject(source) || model.isDataStore(source)) && (model.isDataObject(target) || model.isDataStore(target))) {
error.append(Resources.get("WarningADataAssociationMustNotConnectTwoDataObjectsOrDataStores") + "\n");
}
if ((model.isSubProcess(source) || model.isSubProcess(target)) && style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningSubProcessMustNotHaveAnyIncomingOrOutgoingDataAssociations") + "\n");
}
if (model.isDataOutput(source) && style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningDataOutputMustNotHaveAnyOutgoingDataAssociations") + "\n");
}
if (model.isDataInput(target) && style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningDataInputMustNotHaveAnyIncomingDataAssociations") + "\n");
}
if (model.isEvent(source) && model.isDataStore(target) || model.isEvent(target) && model.isDataStore(source)) {
error.append(Resources.get("WarningSourceOrTargetOfDataAssociationToDataStoreMustBeActivity") + "\n");
}
if (model.isCatchEvent(target) && (model.isDataObject(source) || model.isDataInput(source))) {
error.append(Resources.get("WarningCatchEventMustNotHaveAnyIncomingDataAssociations") + "\n");
}
if (model.isThrowEvent(source) && (model.isDataObject(target) || model.isDataOutput(target))) {
error.append(Resources.get("WarningThrowEventMustNotHaveAnyOutgoingDataAssociations") + "\n");
}
if (model.isGateway(source) && (model.isDataObject(target) || model.isDataStore(target)) && style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningGatewayMustNotBeTheSourceOfADataAssociation") + "\n");
}
if (model.isGateway(target) && (model.isDataObject(source) || model.isDataStore(source)) && style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningGatewayMustNotBeTheTargetOfADataAssociation") + "\n");
}
if ((model.isChoreographyTask(source) || model.isChoreographySubprocess(source)) && (model.isDataOutput(target) || model.isDataStore(target))
&& style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningChoreographyActivityMustNotBeTheSourceOfADataAssociation") + "\n");
}
if ((model.isChoreographyTask(target) || model.isChoreographySubprocess(target)) && (model.isDataInput(source) || model.isDataStore(source))
&& style.equals(Constants.EDGE_TYPE_DATA_ASSOCIATION)) {
error.append(Resources.get("WarningChoreographyActivityMustNotBeTheTargetOfADataAssociation") + "\n");
}
return (error.length() > 0) ? error.toString() : null;
}
public static String validateCell(Graph graph, Object cell) {
StringBuffer error = new StringBuffer("");
GraphModel model = graph.getModel();
Object parent = model.getParent(cell);
// Gateway
if (model.isGateway(cell)) {
int outEdgeCount = 0;
for (Object edge : graph.getOutgoingEdges(cell)) {
if (model.isSequenceFlow(edge)) {
outEdgeCount++;
}
}
int inEdgeCount = 0;
for (Object edge : graph.getIncomingEdges(cell)) {
if (model.isSequenceFlow(edge)) {
inEdgeCount++;
}
}
if (outEdgeCount < 2 && inEdgeCount < 2) {
error.append(Resources.get("WarningGatewayMustHaveEitherMultipleOSFsOrMultipleISFs") + "\n");
}
}
// Conditional Sequence Flow P127
if (model.hasConditionalSequenceFlow(cell)) {
boolean otherEdge = false;
for (Object edge : graph.getOutgoingEdges(cell)) {
if (!model.isConditionalSequenceFlow(edge)) {
otherEdge = true;
break;
}
}
if (!otherEdge) {
error.append(Resources.get("WarningActivityMustHaveOtherOutgoingSequenceFlow") + "\n");
}
}
if (model.isCompensationActivity(cell)) {
for (Object edge : graph.getConnections(cell)) {
if (!graph.isCompensationAssociation(edge)) {
error.append(Resources.get("WarningCompensationActivityMustNotHaveAnyIncomingOrOutgoingSequenceFlow") + "\n");
break;
}
}
}
// Start/Link Event
if (graph.isLinkEvent(cell, false) || model.isIntermediateEvent(cell) && !graph.isLinkEvent(cell, true) || model.isStartEvent(cell)) {
Object[] edges = graph.getOutgoingEdges(cell);
boolean hasEdge = false;
for (int i = 0; i < edges.length; i++) {
if (model.isSequenceFlow(edges[i])) {
hasEdge = true;
break;
}
}
if (!hasEdge) {
if (model.isStartEvent(cell)) {
error.append(Resources.get("WarningStartEventMustHaveOutgoingSequenceFlows") + "\n");
} else if (graph.isLinkEvent(cell, false)) {
error.append(Resources.get("WarningTargetLinkEventMustHaveOutgoingSequenceFlows") + "\n");
} else if (model.isIntermediateEvent(cell)) {
if (model.isCompensationIntermediateEvent(cell) && model.isBoundaryEvent(cell)) {
if (graph.getOutgoingEdges(cell).length == 0) {
error.append(Resources.get("WarningAttachedCompensationIntermediateEventMustHaveOutgoingAssociation") + "\n");
}
} else {
error.append(Resources.get("WarningIntermediateEventMustHaveOutgoingSequenceFlows") + "\n");
}
}
}
}
// End/Link Event , Intermediate Event P297
if (graph.isLinkEvent(cell, true) || model.isIntermediateEvent(cell) && !model.isBoundaryEvent(cell) && !graph.isLinkEvent(cell, false)
|| model.isEndEvent(cell)) {
Object[] edges = graph.getIncomingEdges(cell);
boolean hasEdge = false;
for (int i = 0; i < edges.length; i++) {
if (model.isSequenceFlow(edges[i])) {
hasEdge = true;
break;
}
}
if (!hasEdge) {
if (model.isEndEvent(cell)) {
error.append(Resources.get("WarningEndEventMustHaveIncomingSequenceFlows") + "\n");
} else if (graph.isLinkEvent(cell, true)) {
error.append(Resources.get("WarningSourceLinkEventMustHaveIncomingSequenceFlows") + "\n");
} else if (model.isIntermediateEvent(cell)) {
error.append(Resources.get("WarningIntermediateEventMustHaveIncomingSequenceFlows") + "\n");
}
}
}
// Data Object
if (model.isDataObject(cell) || model.isDataStore(cell)) {
Object[] edges = graph.getEdges(cell);
boolean hasEdge = false;
for (int i = 0; i < edges.length; i++) {
if (model.isDataAssociation(edges[i])) {
hasEdge = true;
break;
}
}
if (!hasEdge) {
error.append(Resources.get("WarningADataObjectOrDataStoreMustHaveAtLeastOneConnectedDataAssociation") + "\n");
}
}
// Start Event P276 , Link Event P298
if (graph.isPlane(cell) || model.isSubProcess(cell)) {
if (graph.hasEndEvent(cell) && !graph.hasStartEvent(cell)) {
error.append(Resources.get("WarningIfThereIsAnEndEventThenThereMustBeAtLeastOneStartEvent") + "\n");
}
Object[] srcLinks = graph.getLinkEvent(cell, true, null);
if (srcLinks != null && srcLinks.length > 0) {
for (int i = 0; i < srcLinks.length; i++) {
String srcName = ((mxCell) srcLinks[i]).getValue().toString();
Object[] tgtLinks = graph.getLinkEvent(cell, false, srcName);
if (tgtLinks == null || tgtLinks.length <= 0) {
error.append(Resources.get("WarningIfThereIsASourceLinkThereMustBeAMatchingTargetLink") + "\n");
} else if (tgtLinks.length > 1) {
error.append(Resources.get("WarningThereMustNotBeMultipleTargetLinksForASingleSourceLink") + "\n");
}
}
}
}
// End Event P284
if (graph.isPlane(cell) || model.isSubProcess(cell)) {
if (graph.hasStartEvent(cell) && !graph.hasEndEvent(cell)) {
error.append(Resources.get("WarningIfThereIsAStartEventThenThereMustBeAtLeastOneEndEvent") + "\n");
}
}
// Intermediate Event
if (model.isMessageIntermediateEvent(cell)) {
Object[] edges = graph.getEdges(cell);
boolean hasMessageFlow = false;
for (int i = 0; i < edges.length; i++) {
if (model.isMessageFlow(edges[i])) {
if (hasMessageFlow) {
error.append(Resources.get("WarningMessageIntermediateEventMayHaveOnlyOneIncomingOrOutgoingMessageFlow") + "\n");
break;
} else {
hasMessageFlow = true;
}
}
}
}
// Event Sub-Process P212
if (model.isEventSubProcess(cell)) {
if (!graph.hasStartEvent(cell)) {
error.append(Resources.get("WarningEventSubProcessMustHaveOneAndOnlyOneStartEvent") + "\n");
}
}
if (model.isStartEvent(cell) && model.isEventSubProcess(parent)) {
if (model.isNoneEvent(cell)) {
error.append(Resources.get("WarningStartEventOfEventSubProcessMustHaveTrigger") + "\n");
}
}
if (model.isAdhocSubProcess(parent)) {
if (model.isStartEvent(cell)) {
error.append(Resources.get("WarningStartEventMustNotBeUsedInAdHocSubProcess") + "\n");
}
if (model.isEndEvent(cell)) {
error.append(Resources.get("WarningEndEventMustNotBeUsedInAdHocSubProcess") + "\n");
}
}
if (model.isStartEvent(cell) && model.isSubProcess(parent) && !model.isAdhocSubProcess(parent) && !model.isEventSubProcess(parent)) {
if (!model.isNoneEvent(cell)) {
error.append(Resources.get("WarningASubProcessMustNotHaveAnyNonEmptyStartEvents") + "\n");
}
}
if (model.isBoundaryEvent(cell) && model.isNoneEvent(cell)) {
error.append(Resources.get("WarningNoneIntermediateEventMayNotBeUsedOnBoundaryOfActivity") + "\n");
}
// Attached Cancel Intermediate Event P297
if (model.isCancelBoundaryEvent(cell) && !model.isTransactionSubProcess(parent)) {
error.append(Resources.get("WarningCancelIntermediateEventMustBeAttachedToATransactionSubProcess") + "\n");
}
if (model.isCancelEndEvent(cell) && !model.isTransactionSubProcess(parent)) {
error.append(Resources.get("WarningCancelEndEventCanOnlyBeUsedWithinTranSubProcess") + "\n");
}
// Event Gateway P335
if (model.isEventGateway(cell)) {
Object[] edges = graph.getOutgoingEdges(cell);
int count = 0;
boolean hasEvent = false;
boolean hasTask = false;
for (int i = 0; i < edges.length; i++) {
if (model.isSequenceFlow(edges[i])) {
Object targetCell = model.getTerminal(edges[i], false);
if (model.isMessageIntermediateEvent(targetCell)) {
hasEvent = true;
} else if (model.isReceiveTask(targetCell)) {
hasTask = true;
}
count++;
}
}
if (count < 2) {
error.append(Resources.get("WarningEventGatewayMustHaveTwoOrMoreOutgoingSequenceFlows") + "\n");
}
if (hasEvent && hasTask) {
error.append(Resources.get("WarningEventGatewayOutgoingSequenceFlowTargetMayHaveOnlyMessageIntermediateEventOrReceiveTask") + "\n");
}
}
if (model.isReceiveTask(cell) || model.isIntermediateEvent(cell)) {
Object[] edges = graph.getIncomingEdges(cell);
if (edges.length > 1) {
boolean isEventGatewayTarget = false;
int eventGatewayCount = 0;
boolean hasAdditionalIncomingSequenceFlows = false;
for (int i = 0; i < edges.length; i++) {
if (model.isSequenceFlow(edges[i])) {
if (model.isEventGateway(model.getTerminal(edges[i], true))) {
isEventGatewayTarget = true;
eventGatewayCount++;
} else {
hasAdditionalIncomingSequenceFlows = true;
}
}
}
if (isEventGatewayTarget && (hasAdditionalIncomingSequenceFlows || eventGatewayCount > 1)) {
error.append(Resources.get("WarningEventGatewayTargetMustNotHaveAnyAdditionalIncomingSequenceFlows") + "\n");
}
} else if (edges.length == 1 && model.isEventGateway(model.getTerminal(edges[0], true)) && model.isReceiveTask(cell)) {
if (model.getChildCount(cell) > 0 && model.isBoundaryEvent(mxGraphModel.getChildVertices(model, cell)[0])) {
error.append(Resources.get("WarningReceiveTasksUsedInEventGatewayMustNotHaveAnyAttachedIntermediateEvents") + "\n");
}
}
}
if (error.length() > 6) {
return error.append("").toString();
} else {
return null;
}
}
}