All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yaoqiang.graph.io.bpmn.BPMNCodecUtils Maven / Gradle / Ivy

There is a newer version: 2.2.18
Show newest version
package org.yaoqiang.graph.io.bpmn;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.yaoqiang.bpmn.model.BPMNModelUtils;
import org.yaoqiang.bpmn.model.elements.XMLAttribute;
import org.yaoqiang.bpmn.model.elements.XMLCollection;
import org.yaoqiang.bpmn.model.elements.XMLComplexElement;
import org.yaoqiang.bpmn.model.elements.XMLElement;
import org.yaoqiang.bpmn.model.elements.XMLExtensionElement;
import org.yaoqiang.bpmn.model.elements.activities.Activity;
import org.yaoqiang.bpmn.model.elements.activities.CallActivity;
import org.yaoqiang.bpmn.model.elements.activities.SubProcess;
import org.yaoqiang.bpmn.model.elements.activities.Task;
import org.yaoqiang.bpmn.model.elements.artifacts.Association;
import org.yaoqiang.bpmn.model.elements.artifacts.Group;
import org.yaoqiang.bpmn.model.elements.artifacts.TextAnnotation;
import org.yaoqiang.bpmn.model.elements.bpmndi.BPMNDiagram;
import org.yaoqiang.bpmn.model.elements.bpmndi.BPMNEdge;
import org.yaoqiang.bpmn.model.elements.bpmndi.BPMNShape;
import org.yaoqiang.bpmn.model.elements.bpmndi.Bounds;
import org.yaoqiang.bpmn.model.elements.bpmndi.Waypoint;
import org.yaoqiang.bpmn.model.elements.choreography.Choreography;
import org.yaoqiang.bpmn.model.elements.choreography.GlobalChoreographyTask;
import org.yaoqiang.bpmn.model.elements.choreographyactivities.CallChoreography;
import org.yaoqiang.bpmn.model.elements.choreographyactivities.ChoreographyActivity;
import org.yaoqiang.bpmn.model.elements.choreographyactivities.ChoreographyTask;
import org.yaoqiang.bpmn.model.elements.choreographyactivities.SubChoreography;
import org.yaoqiang.bpmn.model.elements.collaboration.Collaboration;
import org.yaoqiang.bpmn.model.elements.collaboration.MessageFlow;
import org.yaoqiang.bpmn.model.elements.collaboration.Participant;
import org.yaoqiang.bpmn.model.elements.conversations.CallConversation;
import org.yaoqiang.bpmn.model.elements.conversations.Conversation;
import org.yaoqiang.bpmn.model.elements.conversations.ConversationLink;
import org.yaoqiang.bpmn.model.elements.conversations.ConversationNode;
import org.yaoqiang.bpmn.model.elements.conversations.GlobalConversation;
import org.yaoqiang.bpmn.model.elements.conversations.SubConversation;
import org.yaoqiang.bpmn.model.elements.core.common.BPMNError;
import org.yaoqiang.bpmn.model.elements.core.common.CallableElement;
import org.yaoqiang.bpmn.model.elements.core.common.FlowElement;
import org.yaoqiang.bpmn.model.elements.core.common.FlowElementsContainer;
import org.yaoqiang.bpmn.model.elements.core.common.FlowNode;
import org.yaoqiang.bpmn.model.elements.core.common.Message;
import org.yaoqiang.bpmn.model.elements.core.common.SequenceFlow;
import org.yaoqiang.bpmn.model.elements.core.foundation.BaseElement;
import org.yaoqiang.bpmn.model.elements.core.foundation.RootElements;
import org.yaoqiang.bpmn.model.elements.core.infrastructure.Definitions;
import org.yaoqiang.bpmn.model.elements.core.service.Interface;
import org.yaoqiang.bpmn.model.elements.core.service.Operation;
import org.yaoqiang.bpmn.model.elements.data.DataAssociation;
import org.yaoqiang.bpmn.model.elements.data.DataInput;
import org.yaoqiang.bpmn.model.elements.data.DataInputAssociation;
import org.yaoqiang.bpmn.model.elements.data.DataObjectReference;
import org.yaoqiang.bpmn.model.elements.data.DataOutput;
import org.yaoqiang.bpmn.model.elements.data.DataOutputAssociation;
import org.yaoqiang.bpmn.model.elements.data.DataStoreReference;
import org.yaoqiang.bpmn.model.elements.events.BoundaryEvent;
import org.yaoqiang.bpmn.model.elements.events.CatchEvent;
import org.yaoqiang.bpmn.model.elements.events.CompensateEventDefinition;
import org.yaoqiang.bpmn.model.elements.events.EndEvent;
import org.yaoqiang.bpmn.model.elements.events.Event;
import org.yaoqiang.bpmn.model.elements.events.IntermediateCatchEvent;
import org.yaoqiang.bpmn.model.elements.events.IntermediateThrowEvent;
import org.yaoqiang.bpmn.model.elements.events.StartEvent;
import org.yaoqiang.bpmn.model.elements.events.ThrowEvent;
import org.yaoqiang.bpmn.model.elements.gateways.ComplexGateway;
import org.yaoqiang.bpmn.model.elements.gateways.ExclusiveGateway;
import org.yaoqiang.bpmn.model.elements.gateways.Gateway;
import org.yaoqiang.bpmn.model.elements.gateways.InclusiveGateway;
import org.yaoqiang.bpmn.model.elements.process.BPMNProcess;
import org.yaoqiang.bpmn.model.elements.process.Lane;
import org.yaoqiang.bpmn.model.elements.process.LaneSet;
import org.yaoqiang.graph.model.GraphModel;
import org.yaoqiang.graph.util.GraphUtils;
import org.yaoqiang.graph.view.Graph;
import org.yaoqiang.util.Constants;

import com.mxgraph.io.mxCodec;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxGraphModel;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxCellState;

/**
 * BPMNCodecUtils
 * 
 * @author Shi Yaoqiang([email protected])
 */
public class BPMNCodecUtils {

	public static mxCell generateNodeParent(Graph graph, Map bpmnElementMap, BPMNShape shape) {
		String parentId = null;
		XMLElement bpmnElement = bpmnElementMap.get(shape.getBpmnElement());
		if (bpmnElement instanceof BoundaryEvent) {
			parentId = ((BoundaryEvent) bpmnElement).getAttachedToRef();
		} else if (bpmnElement instanceof Participant) {
			String bandKind = shape.getParticipantBandKind();
			if (bandKind.length() != 0) {
				XMLElement pShape = bpmnElementMap.get(shape.getChoreographyActivityShape());
				parentId = ((BPMNShape) pShape).getBpmnElement() + "_act";
			}
		} else {
			XMLElement parent = bpmnElement.getParent().getParent();
			if (parent instanceof Collaboration) {

			} else if (parent instanceof LaneSet) {
				parent = parent.getParent();
				if (parent instanceof Lane) {
					parentId = ((Lane) parent).getId();
				} else {
					parent = parent.getParent();
					if (parent instanceof Lane) {
						parentId = ((Lane) parent).getId();
					} else if (parent instanceof BPMNProcess) {
						String processId = ((BPMNProcess) parent).getId();
						parent = parent.getParent().getParent();
						Participant participant = BPMNModelUtils.getParticipantByProcessId(processId, (Definitions) parent);
						if (participant != null) {
							parentId = participant.getId();
						}
					}
				}
			} else if (parent instanceof BPMNProcess) {
				if (bpmnElement instanceof FlowElement) {
					String nodeId = ((FlowElement) bpmnElement).getId();
					if (((BPMNProcess) parent).getLanes().isEmpty()) {
						String processId = ((BPMNProcess) parent).getId();
						parent = parent.getParent().getParent();
						Participant participant = BPMNModelUtils.getParticipantByProcessId(processId, (Definitions) parent);
						if (participant != null) {
							parentId = participant.getId();
						}
					} else {
						for (XMLElement lane : ((BPMNProcess) parent).getLanes()) {
							for (XMLElement flownode : ((Lane) lane).getFlowNodeList()) {
								if (nodeId.equals(flownode.toValue())) {
									parentId = ((Lane) lane).getId();
									break;
								}
							}
							if (parentId != null) {
								break;
							}
						}
					}
				}
			} else if (parent instanceof SubProcess) {
				parentId = ((SubProcess) parent).getId();
			} else if (parent instanceof SubChoreography) {
				parentId = ((SubChoreography) parent).getId();
			}
		}

		if (parentId == null || parentId.length() == 0 || graph.getModel().getCell(parentId) == null) {
			return (mxCell) graph.getModel().getChildAt(graph.getModel().getRoot(), 0);
		}
		return (mxCell) graph.getModel().getCell(parentId);
	}

	public static mxGeometry generateNodeGeometry(GraphModel model, mxCell parent, BPMNShape shape, XMLComplexElement bpmnElement) {
		Bounds bounds = shape.getBounds();
		if (bounds.getX() == -1 && bounds.getY() == -1 && !(bpmnElement instanceof BoundaryEvent)) {
			bounds.setX(20);
			bounds.setY(200);
			if (bounds.getWidth() == -1 && bounds.getHeight() == -1 && (bpmnElement instanceof SubProcess)) {
				bounds.setWidth(150);
				bounds.setHeight(200);
			}
		}
		if (bpmnElement instanceof Event) {
			String width = "";
			String height = "";
			if (bpmnElement instanceof StartEvent) {
				width = Constants.SETTINGS.getProperty("style_startEvent_size", "32");
				height = Constants.SETTINGS.getProperty("style_startEvent_size", "32");
			} else if (bpmnElement instanceof EndEvent) {
				width = Constants.SETTINGS.getProperty("style_endEvent_size", "32");
				height = Constants.SETTINGS.getProperty("style_endEvent_size", "32");
			} else {
				width = Constants.SETTINGS.getProperty("style_intermediateEvent_size", "32");
				height = Constants.SETTINGS.getProperty("style_intermediateEvent_size", "32");
			}
			bounds.setWidth(Integer.parseInt(width));
			bounds.setHeight(Integer.parseInt(height));
		} else if (bpmnElement instanceof Gateway) {
			String width = Constants.SETTINGS.getProperty("style_gateway_size", "42");
			String height = Constants.SETTINGS.getProperty("style_gateway_size", "42");
			bounds.setWidth(Integer.parseInt(width));
			bounds.setHeight(Integer.parseInt(height));
		} else if (bpmnElement instanceof DataObjectReference || bpmnElement instanceof DataInput || bpmnElement instanceof DataOutput) {
			String width = Constants.SETTINGS.getProperty("style_dataobject_width", "29");
			String height = Constants.SETTINGS.getProperty("style_dataobject_height", "38");
			bounds.setWidth(Integer.parseInt(width));
			bounds.setHeight(Integer.parseInt(height));
		} else if (bpmnElement instanceof DataStoreReference) {
			String width = Constants.SETTINGS.getProperty("style_datastore_width", "35");
			String height = Constants.SETTINGS.getProperty("style_datastore_height", "30");
			bounds.setWidth(Integer.parseInt(width));
			bounds.setHeight(Integer.parseInt(height));
		} else if (bpmnElement instanceof ConversationNode) {
			String width = Constants.SETTINGS.getProperty("style_conversation_width", "40");
			String height = Constants.SETTINGS.getProperty("style_conversation_height", "35");
			bounds.setWidth(Integer.parseInt(width));
			bounds.setHeight(Integer.parseInt(height));
		} else if (bpmnElement instanceof Activity) {
			String width = Constants.SETTINGS.getProperty("style_task_width", "85");
			String height = Constants.SETTINGS.getProperty("style_task_height", "55");
			if (bounds.getWidth() < Integer.parseInt(width)) {
				bounds.setWidth(Integer.parseInt(width));
			}
			if (bounds.getHeight() < Integer.parseInt(height)) {
				bounds.setHeight(Integer.parseInt(height));
			}
		} else if (bpmnElement instanceof Participant) {
			String bandKind = shape.getParticipantBandKind();
			if (bandKind.length() != 0) {
				if (((Participant) bpmnElement).getMultiplicity() > 1 || ((Participant) bpmnElement).getMultiplicity() == -1) {
					bounds.setHeight(Constants.PARTICIPANT_HEIGHT * 1.75);
				} else {
					bounds.setHeight(Constants.PARTICIPANT_HEIGHT);
				}
			}
		}

		mxGeometry pgeo = new mxGeometry();
		mxCell tmp = parent;
		while (tmp != null && tmp.getGeometry() != null) {
			pgeo.setX(pgeo.getX() + tmp.getGeometry().getX());
			pgeo.setY(pgeo.getY() + tmp.getGeometry().getY());
			tmp = (mxCell) model.getParent(tmp);
		}

		mxGeometry geometry = new mxGeometry(bounds.getX() - pgeo.getX() + 50, bounds.getY() - pgeo.getY() + 50, bounds.getWidth(), bounds.getHeight());
		if ((model.isPool(parent) || model.isLane(parent)) && bounds.getX() == 20 && bounds.getY() == 200) {
			geometry.setX(50);
			geometry.setY(parent.getGeometry().getHeight() / 2 - bounds.getWidth() / 2);
		}
		if (bpmnElement instanceof SubProcess) {
			mxRectangle rect = new mxRectangle(geometry.getX(), geometry.getY(), 85, 55);
			if (!shape.isExpanded()) {
				rect.setWidth(400);
				rect.setHeight(250);
			}
			geometry.setAlternateBounds(rect);
		} else if (bpmnElement instanceof BoundaryEvent) {
			geometry.setOffset(new mxPoint(geometry.getX(), geometry.getY()));
			geometry.setX(0);
			geometry.setY(0);
			geometry.setRelative(true);
			if (bounds.getX() == -1 && bounds.getY() == -1) {
				geometry.setX(0);
				geometry.setY(1);
				geometry.setOffset(new mxPoint(parent.getGeometry().getWidth() * 0.15 + 32, -32 / 2));
			}
		}

		if (!"2.0".equals(BPMNModelUtils.getDefinitions(bpmnElement).getExporterVersion())) {
			Bounds labelBounds = shape.getLabelBounds();
			if (bpmnElement instanceof BoundaryEvent) {
				if (labelBounds.getX() < -1 || labelBounds.getY() < -1) {
					geometry.setOffset(new mxPoint(labelBounds.getX(), labelBounds.getY()));
					geometry.setX(labelBounds.getHeight());
					geometry.setY(labelBounds.getWidth());
				}
			} else {
				geometry.setOffset(new mxPoint(labelBounds.getX(), labelBounds.getY()));
			}
		}

		return geometry;
	}

	public static String generateNodeStyle(Graph graph, mxCell parent, Map bpmnElementMap, BPMNShape shape) {
		String style = "";
		XMLElement bpmnElement = bpmnElementMap.get(shape.getBpmnElement());
		if (graph.isChoreography(parent)) {
			parent = (mxCell) parent.getParent();
		}

		if (bpmnElement instanceof Lane) {
			String collapsed = "";
			if (shape.isHorizontal()) {
				if (!shape.isExpanded()) {
					collapsed = ";horizontal=1";
				}
				style = "lane" + collapsed;
			} else {
				if (!shape.isExpanded()) {
					collapsed = ";horizontal=0";
				}
				style = "verticalLane" + collapsed;
			}
		} else if (bpmnElement instanceof Activity) {
			if (bpmnElement instanceof Task) {
				style = "task";
			} else if (bpmnElement instanceof SubProcess) {
				style = "subprocess";
			} else if (bpmnElement instanceof CallActivity) {
				String calledElementId = ((CallActivity) bpmnElement).getCalledElement();
				CallableElement calledElement = (CallableElement) bpmnElementMap.get(calledElementId);
				if (calledElement == null || calledElement instanceof BPMNProcess) {
					style = "callProcess";
				} else {
					style = "callTask";
				}
			}
			style += ";whiteSpace=wrap";
		} else if (bpmnElement instanceof Gateway) {
			if (bpmnElement instanceof ExclusiveGateway) {
				if (shape.isMarkerVisible()) {
					style = "exclusiveGatewayWithIndicator";
				} else {
					style = "exclusiveGateway";
				}
			} else {
				style = "gateway";
			}
		} else if (bpmnElement instanceof Event) {
			if (bpmnElement instanceof CatchEvent) {
				if (bpmnElement instanceof StartEvent) {
					StartEvent event = (StartEvent) bpmnElement;
					List eventDefs = event.getEventDefinitionList();
					eventDefs.addAll(event.getRefEventDefinitionList());
					if (eventDefs.size() > 1) {
						if (event.isParallelMultiple()) {
							style = "startParallelMultipleEvent";
						} else {
							style = "startMultipleEvent";
						}
					} else {
						style = "startEvent";
					}
				} else if (bpmnElement instanceof IntermediateCatchEvent) {
					IntermediateCatchEvent event = (IntermediateCatchEvent) bpmnElement;
					List eventDefs = event.getEventDefinitionList();
					eventDefs.addAll(event.getRefEventDefinitionList());
					if (eventDefs.size() > 1) {
						if (event.isParallelMultiple()) {
							style = "intermediateParallelMultipleEvent";
						} else {
							style = "intermediateMultipleEvent";
						}
					} else {
						style = "intermediateEvent";
					}
				} else if (bpmnElement instanceof BoundaryEvent) {
					BoundaryEvent event = (BoundaryEvent) bpmnElement;
					List eventDefs = event.getEventDefinitionList();
					eventDefs.addAll(event.getRefEventDefinitionList());
					if (eventDefs.size() > 1) {
						if (event.isParallelMultiple()) {
							style = "intermediateParallelMultipleEvent";
						} else {
							style = "intermediateMultipleEvent";
						}
					} else {
						style = "intermediateEvent";
					}
				}
			} else if (bpmnElement instanceof ThrowEvent) {
				if (bpmnElement instanceof EndEvent) {
					EndEvent event = (EndEvent) bpmnElement;
					List eventDefs = event.getEventDefinitionList();
					eventDefs.addAll(event.getRefEventDefinitionList());
					if (eventDefs.size() > 1) {
						style = "endMultipleEvent";
					} else {
						style = "endEvent";
					}
				} else if (bpmnElement instanceof IntermediateThrowEvent) {
					IntermediateThrowEvent event = (IntermediateThrowEvent) bpmnElement;
					List eventDefs = event.getEventDefinitionList();
					if (eventDefs.size() > 1) {
						style = "intermediateMultipleThrowEvent";
					} else {
						style = "intermediateEvent";
					}
				}
			}
		} else if (bpmnElement instanceof ConversationNode) {
			if (bpmnElement instanceof Conversation) {
				style = "conversation";
			} else if (bpmnElement instanceof SubConversation) {
				style = "subConversation";
			} else if (bpmnElement instanceof CallConversation) {
				XMLElement collaboration = bpmnElementMap.get(((CallConversation) bpmnElement).getCalledCollaboratioinRef());
				if (collaboration instanceof GlobalConversation) {
					style = "callConversation";
				} else if (collaboration == null || collaboration instanceof Collaboration) {
					style = "callCollaboration";
				}
			}
		} else if (bpmnElement instanceof ChoreographyActivity) {
			if (bpmnElement instanceof ChoreographyTask) {
				style = "choreography";
			} else if (bpmnElement instanceof SubChoreography) {
				style = "subChoreography";
			} else if (bpmnElement instanceof CallChoreography) {
				CallChoreography callC = (CallChoreography) bpmnElement;
				XMLElement choreography = bpmnElementMap.get(callC.getCalledChoreographyRef());
				if (choreography == null && callC.getId().endsWith("_CT") || choreography instanceof GlobalChoreographyTask) {
					style = "callChoreographyTask";
				} else if (choreography == null || choreography instanceof Choreography) {
					style = "callChoreography";
				}
			}
		} else if (bpmnElement instanceof Participant) {
			String bandKind = shape.getParticipantBandKind();
			Bounds bounds = shape.getBounds();
			XMLElement pShape = bpmnElementMap.get(shape.getChoreographyActivityShape());
			if (bandKind.length() == 0) {
				String auto = "";
				String collapsed = "";
				if (bounds.getY() != 0 && bounds.getX() != 0) {
					auto = ";auto=0";
				}
				if (shape.isHorizontal()) {
					if (!shape.isExpanded()) {
						collapsed = ";horizontal=1";
					}
					style = "pool" + auto + collapsed;
				} else {
					if (!shape.isExpanded()) {
						collapsed = ";horizontal=0";
					}
					style = "verticalPool" + auto + collapsed;
				}
			} else if (pShape != null && bandKind.length() != 0) {
				Object act = graph.getModel().getCell(((BPMNShape) pShape).getBpmnElement());
				mxGeometry ageo = graph.getModel().getGeometry(act);
				ageo.setHeight(ageo.getHeight() - bounds.getHeight());
				if (bandKind.equals("middle_initiating") || bandKind.equals("middle_non_initiating")) {
					if (bounds.getY() > ageo.getY()) {
						style = "participantAdditionalBottom";
					} else {
						ageo.setY(ageo.getY() + bounds.getHeight());
						style = "participantAdditionalTop";
					}
				} else if (bandKind.equals("top_initiating") || bandKind.equals("top_non_initiating")) {
					ageo.setY(ageo.getY() + bounds.getHeight());
					style = "participantTop";
				} else if (bandKind.equals("bottom_initiating") || bandKind.equals("bottom_non_initiating")) {
					style = "participantBottom";
				}
				graph.getModel().setGeometry(act, ageo);
				if (graph.getModel().isCallChoreographyActivity(act)) {
					style += ";call=1;strokeWidth=3";
				}
			}
		} else if (bpmnElement instanceof TextAnnotation) {
			style = "annotation";
		} else if (bpmnElement instanceof Message) {
			style = "initiatingMessage";
			XMLExtensionElement styleElement = ((BaseElement) bpmnElement).getExtensionElements().getChildElement("yaoqiang:style");
			if (styleElement != null) {
				if ("0".equals(styleElement.getAttribute("init").toValue())) {
					style = "nonInitiatingMessage";
				}
			}
		} else if (bpmnElement instanceof Group) {
			style = "group";
		} else if (bpmnElement instanceof DataStoreReference) {
			style = "dataStore";
		} else if (bpmnElement instanceof DataObjectReference || bpmnElement instanceof DataInput || bpmnElement instanceof DataOutput) {
			style = "dataObject";
		}
		XMLExtensionElement styleElement = ((BaseElement) bpmnElement).getExtensionElements().getChildElement("yaoqiang:style");
		if (styleElement != null) {
			for (XMLElement el : styleElement.toElements()) {
				style += ";" + ((XMLAttribute) el).toName() + "=" + ((XMLAttribute) el).toValue();
			}
		}
		return style;
	}

	public static String generateEdgeStyle(GraphModel model, Map bpmnElementMap, XMLComplexElement bpmnElement, mxCell source, mxCell target) {
		String style = "";
		if (bpmnElement instanceof SequenceFlow) {
			style = Constants.EDGE_TYPE_SEQUENCE_FLOW;
		} else if (bpmnElement instanceof MessageFlow) {
			if (model.isChoreographyParticipant(source)) {
				style = "messageFlow;startArrow=none";
			} else if (model.isChoreographyParticipant(target)) {
				style = "messageFlow;endArrow=none";
			} else {
				if (model.getParentPool(source) != null && model.getStyle(model.getParentPool(source)).startsWith("vertical")
						|| model.getParentPool(target) != null && model.getStyle(model.getParentPool(target)).startsWith("vertical")) {
					style = "messageFlow;elbow=horizontal";
				} else {
					style = Constants.EDGE_TYPE_MESSAGE_FLOW;
				}
			}
		} else if (bpmnElement instanceof DataAssociation) {
			style = Constants.EDGE_TYPE_DATA_ASSOCIATION;
		} else if (bpmnElement instanceof Association) {
			if (bpmnElementMap.get(bpmnElement.get("sourceRef").toValue()) instanceof BoundaryEvent) {
				style = Constants.EDGE_TYPE_COMPENSATION_ASSOCIATION;
			} else {
				style = Constants.EDGE_TYPE_ASSOCIATION;
			}
		} else if (bpmnElement instanceof ConversationLink) {
			style = Constants.EDGE_TYPE_CONVERSATION_LINK;
		}

		XMLExtensionElement styleElement = ((BaseElement) bpmnElement).getExtensionElements().getChildElement("yaoqiang:style");
		if (styleElement != null) {
			for (XMLElement el : styleElement.toElements()) {
				style += ";" + ((XMLAttribute) el).toName() + "=" + ((XMLAttribute) el).toValue();
			}
		}

		return style;
	}

	public static mxCell getEdgeTerminal(mxGraphModel model, XMLComplexElement bpmnElement, boolean isSource) {
		if (bpmnElement.get("sourceRef") == null || bpmnElement.get("targetRef") == null) {
			return null;
		}
		String sourceId = bpmnElement.get("sourceRef").toValue();
		String targetId = bpmnElement.get("targetRef").toValue();
		if (bpmnElement instanceof DataInputAssociation) {
			sourceId = ((DataInputAssociation) bpmnElement).getSourceRef();
			FlowElement target = (FlowElement) bpmnElement.getParent().getParent();
			targetId = target.getId();
		} else if (bpmnElement instanceof DataOutputAssociation) {
			FlowElement source = (FlowElement) bpmnElement.getParent().getParent();
			sourceId = source.getId();
			targetId = ((DataOutputAssociation) bpmnElement).getTargetRef();
		}
		if (sourceId.equals("_1") || sourceId.equals("_0")) {
			sourceId = "_" + sourceId;
			bpmnElement.set("sourceRef", sourceId);
		}
		if (targetId.equals("_1") || targetId.equals("_0")) {
			targetId = "_" + targetId;
			bpmnElement.set("targetRef", targetId);
		}
		if (isSource) {
			return (mxCell) model.getCell(sourceId);
		} else {
			return (mxCell) model.getCell(targetId);
		}
	}

	public static Object insertChoreography(mxCodec codec, mxGraphModel model, String loopType, String id, mxCell parent, Object value, mxGeometry geometry,
			String style) {
		parent.setValue(null);

		mxCell cell = new mxCell(value, geometry, style);
		cell.setId(id);
		cell.setVertex(true);
		cell.setParent(parent);
		codec.insertIntoGraph(cell);
		model.getCells().put(cell.getId(), cell);
		return cell;
	}

	public static List convertTomxPointList(List points, mxGeometry geo) {
		List mxPointList = new ArrayList();
		if (points == null) {
			return mxPointList;
		} else {
			if (!points.isEmpty()) {
				for (int i = 0; i < points.size(); i++) {
					Point p = points.get(i);
					mxPointList.add(new mxPoint(p.getX() - geo.getX() + 50, p.getY() - geo.getY() + 50));
				}
			}
		}
		return mxPointList;
	}

	public static void setBounds(Graph graph, mxCell cell, Element bounds) {
		GraphModel model = graph.getModel();
		mxCell pCell = (mxCell) model.getParent(cell);
		mxGeometry pgeo = new mxGeometry();
		while (pCell != null && pCell.getGeometry() != null) {
			pgeo.setX(pgeo.getX() + pCell.getGeometry().getX());
			pgeo.setY(pgeo.getY() + pCell.getGeometry().getY());
			pCell = (mxCell) model.getParent(pCell);
		}

		mxGeometry geo = (mxGeometry) model.getGeometry(cell).clone();
		if (model.isBoundaryEvent(cell)) {
			geo.setX(pgeo.getX() - 50);
			geo.setY(pgeo.getY() - 50);
		} else if (model.isAttachedMessage(cell)) {
			mxPoint offset = geo.getOffset();
			geo.setX(offset.getX());
			geo.setY(offset.getY());
		} else {
			geo.setX(geo.getX() + pgeo.getX() - 50);
			geo.setY(geo.getY() + pgeo.getY() - 50);
		}

		bounds.setAttribute("height", Double.toString(geo.getHeight()));
		bounds.setAttribute("width", Double.toString(geo.getWidth()));
		if (model.isBoundaryEvent(cell)) {
			mxGeometry cellgeo = model.getGeometry(cell);
			mxGeometry parentgeo = model.getGeometry(model.getParent(cell));
			mxPoint offset = cellgeo.getOffset();
			if (cellgeo.getX() == 0) {
				geo.setX(geo.getX() + offset.getX());
			} else if (cellgeo.getX() == 1) {
				geo.setX(geo.getX() + parentgeo.getWidth() + offset.getX());
			}
			if (cellgeo.getY() == 0) {
				geo.setY(geo.getY() + offset.getY());
			} else if (cellgeo.getY() == 1) {
				geo.setY(geo.getY() + parentgeo.getHeight() + offset.getY());
			}
			bounds.setAttribute("x", Double.toString(geo.getX()));
			bounds.setAttribute("y", Double.toString(geo.getY()));
		} else {
			bounds.setAttribute("x", Double.toString(geo.getX()));
			bounds.setAttribute("y", Double.toString(geo.getY()));
		}
	}

	public static void setLabelBounds(Graph graph, mxCell cell, Element bounds) {
		mxRectangle labelBounds = new mxRectangle();
		mxGeometry geo = graph.getModel().getGeometry(cell);
		if (geo.getOffset() != null) {
			labelBounds.setX(geo.getOffset().getX());
			labelBounds.setY(geo.getOffset().getY());
		}

		if (graph.getModel().isBoundaryEvent(cell)) {
			labelBounds.setWidth(geo.getY());
			labelBounds.setHeight(geo.getX());
		} else {
			mxCellState state = graph.getView().getState(cell);
			if (state != null && state.getLabelBounds() != null) {
				labelBounds.setWidth(geo.getWidth());
				labelBounds.setHeight(geo.getHeight());
			}
		}

		bounds.setAttribute("x", Double.toString(labelBounds.getX()));
		bounds.setAttribute("y", Double.toString(labelBounds.getY()));
		bounds.setAttribute("height", Double.toString(labelBounds.getHeight()));
		bounds.setAttribute("width", Double.toString(labelBounds.getWidth()));
	}

	public static Element generateEdgeElement(Graph graph, mxCell cell, Element plane, String bpmndiPrefix, String dcPrefix, String diPrefix) {
		Element el = plane.getOwnerDocument().createElement(bpmndiPrefix + "BPMNEdge");
		Element label = plane.getOwnerDocument().createElement(bpmndiPrefix + "BPMNLabel");
		Element bounds = plane.getOwnerDocument().createElement(dcPrefix + "Bounds");

		mxGeometry geo = graph.getModel().getGeometry(cell);
		mxPoint offset = geo.getOffset();
		if (offset == null) {
			offset = new mxPoint();
		}

		bounds.setAttribute("x", Double.toString(geo.getX()));
		bounds.setAttribute("y", Double.toString(geo.getY()));
		bounds.setAttribute("width", Double.toString(offset.getX()));
		bounds.setAttribute("height", Double.toString(offset.getY()));
		label.appendChild(bounds);

		BPMNCodecUtils.generateWaypoints(diPrefix, el, graph, cell);
		el.appendChild(label);
		String id = cell.getId();
		// if (id.startsWith("__1")) {
		// id = id.substring(1);
		// }
		String sid = cell.getSource().getId();
		// if (sid.startsWith("__1")) {
		// sid = sid.substring(1);
		// }
		String tid = cell.getTarget().getId();
		// if (tid.startsWith("__1")) {
		// tid = tid.substring(1);
		// }
		el.setAttribute("id", "Yaoqiang-" + id);
		el.setAttribute("bpmnElement", id);
		el.setAttribute("sourceElement", sid);
		el.setAttribute("targetElement", tid);
		return el;
	}

	public static void generateWaypoints(String prefix, Element edge, Graph graph, mxCell cell) {
		mxGeometry geo = graph.getModel().getGeometry(cell);
		mxCell pCell = (mxCell) graph.getModel().getParent(cell);
		mxGeometry pgeo = new mxGeometry();
		while (pCell != null && pCell.getGeometry() != null) {
			pgeo.setX(pgeo.getX() + pCell.getGeometry().getX());
			pgeo.setY(pgeo.getY() + pCell.getGeometry().getY());
			pCell = (mxCell) graph.getModel().getParent(pCell);
		}

		mxCellState state = graph.getView().getState(cell);
		List abps = null;
		double scale = graph.getView().getScale();
		List points = new ArrayList();
		if (state == null) {
			Object srcCell = graph.getModel().getTerminal(cell, true);
			mxGeometry srcGeo = graph.getModel().getGeometry(srcCell);
			mxPoint src = new mxPoint(srcGeo.getCenterX() + pgeo.getX() - 50, srcGeo.getCenterY() + pgeo.getY() - 50);
			points.add(src);
		} else {
			abps = state.getAbsolutePoints();
			mxPoint src = (mxPoint) abps.get(0).clone();
			src.setX(src.getX() / scale - graph.getView().getTranslate().getX() - 50);
			src.setY(src.getY() / scale - graph.getView().getTranslate().getY() - 50);
			points.add(src);
		}

		if (geo.getPoints() != null) {
			mxPoint cp = null;
			for (mxPoint p : geo.getPoints()) {
				cp = new mxPoint(p.getX() + pgeo.getX() - 50, p.getY() + pgeo.getY() - 50);
				points.add(cp);
			}
		}

		if (state == null) {
			Object tgtCell = graph.getModel().getTerminal(cell, false);
			mxGeometry tgtGeo = graph.getModel().getGeometry(tgtCell);
			mxPoint tgt = new mxPoint(tgtGeo.getCenterX() + pgeo.getX() - 50, tgtGeo.getCenterY() + pgeo.getY() - 50);
			points.add(tgt);
		} else {
			mxPoint tgt = (mxPoint) abps.get(abps.size() - 1).clone();
			tgt.setX(tgt.getX() / scale - graph.getView().getTranslate().getX() - 50);
			tgt.setY(tgt.getY() / scale - graph.getView().getTranslate().getY() - 50);
			points.add(tgt);
		}
		Element waypoint = null;
		for (mxPoint p : points) {
			waypoint = edge.getOwnerDocument().createElement(prefix + "waypoint");
			generateWaypoint(edge, waypoint, p);
		}
	}

	public static void generateWaypoint(Element edge, Element waypoint, mxPoint point) {
		waypoint.setAttribute("x", Double.toString(point.getX()));
		waypoint.setAttribute("y", Double.toString(point.getY()));
		edge.appendChild(waypoint);
	}

	public static void moveDiagram(BPMNDiagram diagram, Point offset) {
		List shapes = diagram.getBPMNPlane().getBPMNShapes();
		for (XMLElement s : shapes) {
			BPMNShape shape = (BPMNShape) s;
			moveShape(shape, offset);
		}

		List edges = diagram.getBPMNPlane().getBPMNEdges();
		for (XMLElement e : edges) {
			BPMNEdge edge = (BPMNEdge) e;
			moveEdge(edge, offset);
		}
	}

	public static void moveShape(BPMNShape shape, Point offset) {
		Bounds bounds = shape.getBounds();
		bounds.setX(bounds.getX() + offset.getX());
		bounds.setY(bounds.getY() + offset.getY());
		if ("2.0".equals(BPMNModelUtils.getDefinitions(shape).getExporterVersion())) {
			bounds = shape.getBPMNLabel().getBounds();
			bounds.setX(0);
			bounds.setY(0);
		}
	}

	public static void moveEdge(BPMNEdge edge, Point offset) {
		List waypoints = ((XMLCollection) edge.get("Waypoints")).getXMLElements();
		for (XMLElement wp : waypoints) {
			Waypoint waypoint = (Waypoint) wp;
			waypoint.setX(waypoint.getX() + offset.getX());
			waypoint.setY(waypoint.getY() + offset.getY());
		}
	}

	public static void mergeModel(Graph graph, Definitions fragment, Map fragElementMap, Object target) {
		Definitions bpmnModel = graph.getBpmnModel();
		Map bpmnElementMap = graph.getBpmnElementMap();
		BPMNDiagram diagram = fragment.getFirstBPMNDiagram();
		if (!fragElementMap.isEmpty()) {
			int num = 1;
			boolean ok = false;
			while (!ok) {
				boolean has = false;
				for (String id : fragElementMap.keySet()) {
					String newId = "F" + num + id;
					if (bpmnElementMap.containsKey(newId)) {
						has = true;
						break;
					}
				}
				if (has) {
					num++;
				} else {
					ok = true;
				}
			}
			String prefix = "F" + num;

			for (XMLElement el : fragElementMap.values()) {
				XMLComplexElement bpmnEl = (XMLComplexElement) el;
				String id = bpmnEl.get("id").toValue();
				XMLComplexElement shapeEl = diagram.getShapeByBpmnElement(id);
				if (shapeEl != null) {
					shapeEl.set("bpmnElement", prefix + id);
				}
				if (shapeEl instanceof BPMNEdge) {
					shapeEl.set("sourceElement", prefix + shapeEl.get("sourceElement").toValue());
					shapeEl.set("targetElement", prefix + shapeEl.get("targetElement").toValue());
					if (bpmnEl instanceof SequenceFlow) {
						SequenceFlow sequenceFlow = (SequenceFlow) bpmnEl;
						sequenceFlow.setSourceRef(prefix + sequenceFlow.getSourceRef());
						sequenceFlow.setTargetRef(prefix + sequenceFlow.getTargetRef());
					} else if (bpmnEl instanceof Association) {
						Association association = (Association) bpmnEl;
						association.setSourceRef(prefix + association.getSourceRef());
						association.setTargetRef(prefix + association.getTargetRef());
					} else {
						// TODO:
					}
				} else {
					if (bpmnEl instanceof FlowNode) {
						FlowNode flowNode = (FlowNode) bpmnEl;
						for (XMLElement incoming : flowNode.getIncomings().getXMLElements()) {
							flowNode.getIncomings().remove(incoming.toValue());
							incoming.setValue(prefix + incoming.toValue());
							flowNode.getIncomings().add(incoming);
						}
						for (XMLElement outgoing : flowNode.getOutgoings().getXMLElements()) {
							flowNode.getOutgoings().remove(outgoing.toValue());
							outgoing.setValue(prefix + outgoing.toValue());
							flowNode.getOutgoings().add(outgoing);
						}
						if (flowNode instanceof Activity || flowNode instanceof ExclusiveGateway || flowNode instanceof InclusiveGateway
								|| flowNode instanceof ComplexGateway) {
							if (flowNode.get("default").toValue().length() != 0) {
								flowNode.set("default", prefix + flowNode.get("default").toValue());
							}
						} else if (flowNode instanceof ThrowEvent) {
							for (XMLElement ed : ((ThrowEvent) flowNode).getEventDefinitionList()) {
								if (ed instanceof CompensateEventDefinition) {
									CompensateEventDefinition ced = (CompensateEventDefinition) ed;
									if (ced.getActivityRef().length() != 0) {
										ced.setActivityRef(prefix + ced.getActivityRef());
									}
								}
							}
						} else if (flowNode instanceof BoundaryEvent) {
							BoundaryEvent event = (BoundaryEvent) flowNode;
							event.setAttachedToRef(prefix + event.getAttachedToRef());
						}
					}
				}
				bpmnEl.set("id", prefix + id);
				if (bpmnEl.getParent() instanceof XMLCollection) {
					((XMLCollection) bpmnEl.getParent()).remove(id);
					((XMLCollection) bpmnEl.getParent()).add(bpmnEl);
				}
				bpmnElementMap.put(prefix + id, bpmnEl);
			}

			// TODO:
			BPMNProcess fragProcess = BPMNModelUtils.getDefaultProcess(fragment);
			if (fragProcess != null) {
				GraphModel model = graph.getModel();
				FlowElementsContainer container = null;
				if (target == null) {
					if (graph.getCurrentRoot() == null) {
						container = BPMNModelUtils.getDefaultProcess(bpmnModel);
					} else if (model.getValue(graph.getCurrentRoot()) instanceof FlowElementsContainer) {
						container = (FlowElementsContainer) model.getValue(graph.getCurrentRoot());
					}
				} else {
					if (model.getValue(target) instanceof FlowElementsContainer) {
						container = (FlowElementsContainer) model.getValue(target);
					} else if (model.getValue(target) instanceof Participant) {
						Participant participant = (Participant) model.getValue(target);
						container = bpmnModel.getProcess(participant.getProcessRef());
						if (container == null) {
							participant.setProcessRef(fragProcess.getId());
						}
					} else if (model.getValue(target) instanceof Lane) {
						container = BPMNModelUtils.getParentFlowElementsContainer((XMLElement) model.getValue(target));
						for (FlowNode flowNode : fragProcess.getFlowNodes()) {
							((Lane) model.getValue(target)).addFlowNodeRef(flowNode.getId());
						}
					}
				}

				if (container == null) {
					bpmnModel.addRootElement(fragProcess);
				} else {
					container.addFlowElements(fragProcess.getFlowElements());
					container.addArtifacts(fragProcess.getArtifacts());
				}
			}

		}
	}

	public static void generateInterfaceForWSDL(Document document, Definitions bpmnModel, String type, String nsName) {
		String interfaceName = null;
		if (GraphUtils.isWSDL11File(type)) {
			interfaceName = "portType";
		} else if (GraphUtils.isWSDL20File(type)) {
			interfaceName = "interface";
		}
		NodeList ifNodes = document.getDocumentElement().getChildNodes();
		for (int i = 0; i < ifNodes.getLength(); i++) {
			Node ifNode = ifNodes.item(i);
			if (ifNode.getLocalName() != null && ifNode.getLocalName().equals(interfaceName)) {
				Interface _interface = (Interface) bpmnModel.generateRootElement(RootElements.TYPE_INTERFACE);
				_interface.setName(((Element) ifNode).getAttribute("name"));
				_interface.setImplementationRef(nsName + ":" + _interface.getName());
				bpmnModel.addRootElement(_interface);
				NodeList opNodes = ifNode.getChildNodes();
				for (int j = 0; j < opNodes.getLength(); j++) {
					Node opNode = opNodes.item(j);
					if (opNode.getLocalName() != null && opNode.getLocalName().equals("operation")) {
						Operation op = (Operation) _interface.getOperations().generateNewElement();
						op.setName(((Element) opNode).getAttribute("name"));
						op.setImplementationRef(nsName + ":" + op.getName());
						_interface.getOperations().add(op);
						NodeList ioNodes = opNode.getChildNodes();
						for (int k = 0; k < ioNodes.getLength(); k++) {
							Node ioNode = ioNodes.item(k);
							String nodeName = ioNode.getLocalName();
							if (nodeName != null) {
								String msg = ((Element) ioNode).getAttribute("message");
								if (msg.length() == 0) {
									msg = ((Element) ioNode).getAttribute("element");
									if (msg.length() == 0) {
										String ref = ((Element) ioNode).getAttribute("ref");
										if (ref.length() == 0) {
											continue;
										} else {
											int index = ref.indexOf(":");
											if (index != -1) {
												ref = ref.substring(index + 1);
											}
											NodeList faultNodes = ifNode.getChildNodes();
											for (int l = 0; l < faultNodes.getLength(); l++) {
												Node fNode = faultNodes.item(l);
												if (fNode.getLocalName() != null && fNode.getLocalName().equals("fault")) {
													if (ref.equals(((Element) fNode).getAttribute("name"))) {
														msg = ((Element) fNode).getAttribute("element");
														break;
													}
												}
											}
										}
									}
								}

								if (msg.length() != 0) {
									int index = msg.indexOf(":");
									if (index != -1) {
										msg = msg.substring(index + 1);
									}
									msg = nsName + ":" + msg;
									Message message = BPMNModelUtils.getMessageByStructure(msg, bpmnModel);
									if (nodeName.equals("input")) {
										op.setInMessageRef(message.getId());
									} else if (nodeName.equals("output")) {
										op.setOutMessageRef(message.getId());
									} else {
										BPMNError error = BPMNModelUtils.getErrorByStructure(msg, bpmnModel);
										if (error == null) {
											error = (BPMNError) bpmnModel.generateRootElement(RootElements.TYPE_ERROR);
											error.setName("Error " + error.getId().substring(4));
											error.setStructureRef(BPMNModelUtils.getItemDefinitionByStructure(msg, bpmnModel).getId());
											bpmnModel.addRootElement(error);
										}
										op.addErrorRef(error.getId());
									}
								}
							}
						}
					}
				}
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy