
org.yaoqiang.graph.io.vdx.VdxCodec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yaoqiang-bpmn-editor Show documentation
Show all versions of yaoqiang-bpmn-editor Show documentation
an Open Source BPMN 2.0 Modeler
package org.yaoqiang.graph.io.vdx;
import java.util.ArrayList;
import java.util.HashMap;
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.graph.swing.GraphComponent;
import org.yaoqiang.graph.view.Graph;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxPoint;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxConnectionConstraint;
/**
* VdxCodec
*
* @author Shi Yaoqiang([email protected])
*/
public class VdxCodec {
public static String stencilType;
private Map mastersMap = new HashMap();
private Map vertexMap = new HashMap();
private Map edgeShapeMap = new HashMap();
private Map vertexShapeMap = new HashMap();
private mxGraphComponent graphComponent;
private Graph graph;
private Document document;
private int pageNumber = 0;
private double pageHeight = 0;
private double actualPageHeight = 0;
public VdxCodec(GraphComponent graphComponent, Document document) {
this.graphComponent = graphComponent;
this.graph = graphComponent.getGraph();
this.document = document;
}
public void decode() {
setStencilType(document);
initMasters(document);
graph.clearBpmnModel();
graph.getModel().clear();
graphComponent.zoomTo(0.7, true);
graph.getModel().beginUpdate();
NodeList vdxPages = document.getElementsByTagName(VdxConstants.PAGES);
if (vdxPages.getLength() > 0) {
Element pages = (Element) vdxPages.item(0);
NodeList pageList = pages.getElementsByTagName(VdxConstants.PAGE);
if (pageList.getLength() > 0) {
for (int p = 0; p < pageList.getLength(); p++) {
Element page = (Element) pageList.item(p);
String back = page.getAttribute(VdxConstants.BACKGROUND);
if (back == null || back.length() == 0 || back.equals(VdxConstants.FALSE)) {
pageNumber++;
actualPageHeight = getPageDimentions(page).getY();
pageHeight += actualPageHeight;
importPage(page);
}
}
}
}
graph.getModel().setHorizontalPageCount(1);
graph.getModel().setPageCount(pageNumber);
graph.getModel().endUpdate();
cleanMaps();
}
private void setStencilType(Document document) {
Element documentSheet = (Element) document.getElementsByTagName(VdxConstants.DOCUMENT_SHEET).item(0);
NodeList userList = documentSheet.getElementsByTagName(VdxConstants.USER);
for (int i = 0; i < userList.getLength(); i++) {
Element user = (Element) userList.item(i);
if (VdxConstants.USER_NAME_ITP.equals(user.getAttribute(VdxConstants.NAME_U))) {
stencilType = VdxConstants.STENCIL_TYPE_ITP;
return;
}
}
NodeList propList = documentSheet.getElementsByTagName(VdxConstants.PROP);
if (propList != null && propList.getLength() > 0) {
Element prop = (Element) propList.item(0);
if (VdxConstants.PROP_NAME_STENCIL_VERSION.equals(prop.getAttribute(VdxConstants.NAME_U))) {
stencilType = VdxConstants.STENCIL_TYPE_TRISOTECH;
return;
}
}
}
private void initMasters(Document document) {
NodeList vdxMasters = document.getElementsByTagName(VdxConstants.MASTERS);
if (vdxMasters.getLength() > 0) {
Element masters = (Element) vdxMasters.item(0);
NodeList masterList = masters.getElementsByTagName(VdxConstants.MASTER);
int masterLength = masterList.getLength();
for (int i = 0; i < masterLength; i++) {
Element master = (Element) masterList.item(i);
String masterId = master.getAttribute(VdxConstants.ID);
String masterNameU = master.getAttribute(VdxConstants.NAME_U);
mastersMap.put(masterId, masterNameU);
}
}
}
private void importPage(Element page) {
NodeList shapesList = page.getElementsByTagName(VdxConstants.SHAPES);
List vdxAttachedMessageShapes = new ArrayList();
if (shapesList.getLength() > 0) {
Element shapes = (Element) shapesList.item(0);
NodeList shapeList = shapes.getChildNodes();
List vdxShapes = new ArrayList();
List vdxSwimlaneShapes = new ArrayList();
List vdxAttachedEventShapes = new ArrayList();
List shpList = VdxCodecUtils.nodeListTags(shapeList, VdxConstants.SHAPE);
int shapeLength = shpList.size();
for (int j = 0; j < shapeLength; j++) {
Element shp = shpList.get(j);
VdxShape shape = new VdxShape(shp, mastersMap);
String id = shape.getId();
if (shape.isVertexShape()) {
vdxShapes.add(shape);
vertexShapeMap.put(id, shape);
} else {
edgeShapeMap.put(id, shape);
}
}
for (VdxShape shape : vdxShapes) {
if (shape.isPoolShape()) {
vdxSwimlaneShapes.add(0, shape);
} else if (shape.isLaneShape()) {
vdxSwimlaneShapes.add(shape);
} else if (shape.isAttachedEventShape()) {
vdxAttachedEventShapes.add(shape);
} else if (shape.isAttachedMessageShape()) {
vdxAttachedMessageShapes.add(shape);
}
}
for (VdxShape shape : vdxSwimlaneShapes) {
addShapeToGraph(graph, shape);
}
for (VdxShape shape : vdxShapes) {
if (shape.isPoolShape() || shape.isLaneShape() || shape.isAttachedMessageShape()) {
continue;
}
addShapeToGraph(graph, shape);
}
// for (VdxShape shape : vdxAttachedEventShapes) {
// addShapeToGraph(graph, shape);
// }
}
NodeList connectsList = page.getElementsByTagName(VdxConstants.CONNECTS);
if (connectsList.getLength() > 0) {
Element connects = (Element) connectsList.item(0);
NodeList connectList = connects.getElementsByTagName(VdxConstants.CONNECT);
List list = VdxCodecUtils.copyNodeList(connectList);
for (int j = 0; j < list.size(); j++) {
Element connect = (Element) list.get(j);
Element sigConnect = findSigConnect(list, connect, j);
if (sigConnect == null) {
continue;
}
list.remove(sigConnect);
addEdgeToGraph(graph, connect, sigConnect);
}
for (VdxShape shape : vdxAttachedMessageShapes) {
addShapeToGraph(graph, shape);
}
}
}
private Object addEdgeToGraph(Graph graph, Element connect, Element sigConnect) {
mxCell edge = null;
String shapeConnect = connect.getAttribute(VdxConstants.FROM_SHEET);
VdxShape edgeShape = edgeShapeMap.get(shapeConnect);
edgeShapeMap.remove(shapeConnect);
if (edgeShape != null) {
Object parent = null;
String textLabel = edgeShape.getText();
String from = connect.getAttribute(VdxConstants.TO_SHEET);
mxCell source = vertexMap.get(from);
if (source == null) {
return null;
}
String to = sigConnect.getAttribute(VdxConstants.TO_SHEET);
mxCell target = vertexMap.get(to);
if (target == null) {
return null;
}
if (source.getParent() == target.getParent()) {
parent = source.getParent();
} else {
parent = graph.getModel().getNearestCommonAncestor(source, target);
}
if (parent == null) {
parent = graph.getDefaultParent();
}
edge = (mxCell) graph.insertEdge(parent, null, textLabel, source, target, edgeShape.getStyleFromEdgeShape());
double parentHeight = pageHeight;
// mxCell parentCell = (mxCell) parent;
// if (parentCell != null) {
// mxGeometry parentGeometry = parentCell.getGeometry();
// if (parentGeometry != null) {
// parentHeight = parentGeometry.getHeight();
// parentHeight += pageHeight - actualPageHeight;
// }
// }
mxPoint beginXY = edgeShape.getBeginXY(parentHeight);
beginXY = calculateAbsolutePoint((mxCell) parent, beginXY);
mxPoint endXY = edgeShape.getEndXY(parentHeight);
endXY = calculateAbsolutePoint((mxCell) parent, endXY);
VdxShape fromShape = vertexShapeMap.get(from);
mxPoint dimentionFrom = fromShape.getDimentions();
mxPoint originFrom = fromShape.getOriginPoint(parentHeight);
mxPoint absOriginFrom = calculateAbsolutePoint(
graph.getModel().isBoundaryEvent(source) ? (mxCell) source.getParent().getParent() : (mxCell) source.getParent(), originFrom);
mxPoint fromConstraint = new mxPoint((beginXY.getX() - absOriginFrom.getX()) / dimentionFrom.getX(), (beginXY.getY() - absOriginFrom.getY())
/ dimentionFrom.getY());
VdxShape toShape = vertexShapeMap.get(to);
mxPoint dimentionTo = toShape.getDimentions();
mxPoint originTo = toShape.getOriginPoint(parentHeight);
mxPoint absOriginTo = calculateAbsolutePoint((mxCell) target.getParent(), originTo);
mxPoint toConstraint = new mxPoint((endXY.getX() - absOriginTo.getX()) / dimentionTo.getX(), (endXY.getY() - absOriginTo.getY())
/ dimentionTo.getY());
fromConstraint = VdxCodecUtils.adjustConstraint(fromConstraint);
toConstraint = VdxCodecUtils.adjustConstraint(toConstraint);
graph.setConnectionConstraint(edge, source, true, new mxConnectionConstraint(fromConstraint, false));
graph.setConnectionConstraint(edge, target, false, new mxConnectionConstraint(toConstraint, false));
List pointList = edgeShape.getRoutingPoints(parentHeight);
mxGeometry edgeGeometry = edge.getGeometry();
edgeGeometry.setPoints(pointList);
edgeGeometry.setSourcePoint(beginXY);
edgeGeometry.setTargetPoint(endXY);
}
return edge;
}
private mxCell addShapeToGraph(Graph graph, VdxShape shape) {
mxPoint cordenates = shape.getOriginPoint(pageHeight);
mxPoint dimentions = shape.getDimentions();
String textLabel = shape.getText();
String style = shape.getStyleFromShape(stencilType);
if ("whiteSpace=wrap;".equals(style)) {
return null;
}
String attachedTo = shape.getAttachedToShape();
mxCell parent = null;
mxCell pCell = vertexMap.get(VdxCodecUtils.getShapeIdByNameU(vertexShapeMap, attachedTo));
if (pCell != null) {
parent = pCell;
} else {
mxCell target = (mxCell) graphComponent.getCellAt((int) (cordenates.getX() * graph.getView().getScale()),
(int) (cordenates.getY() / graph.getView().getScale() + dimentions.getY() / 2));
if (target == null) {
target = (mxCell) graphComponent.getCellAt((int) (cordenates.getX()),
(int) (cordenates.getY() / graph.getView().getScale() + dimentions.getY() / 2));
}
if (target == null) {
target = (mxCell) graphComponent.getCellAt((int) (cordenates.getX() / graph.getView().getScale()),
(int) (cordenates.getY() / graph.getView().getScale() + dimentions.getY() / 2));
}
if (target != null && (graph.getModel().isPool(target) && !graph.isLaneByStyle(target) || graph.getModel().isSubProcess(target) && !graph.getModel().isCollapsedSubProcess(target))) {
parent = target;
}
}
mxCell v1 = (mxCell) graph.createVertex(parent, null, textLabel, cordenates.getX(), cordenates.getY(), dimentions.getX(), dimentions.getY(), style);
if (parent != null) {
v1.getGeometry().setX(v1.getGeometry().getX() - parent.getGeometry().getX());
v1.getGeometry().setY(v1.getGeometry().getY() - parent.getGeometry().getY());
}
VdxCodecUtils.adjustCellDimentions(graph, v1);
if (pCell != null) {
mxGeometry geo = v1.getGeometry();
geo.setOffset(new mxPoint(geo.getX(), geo.getY()));
geo.setX(0);
geo.setY(0);
geo.setRelative(true);
}
graph.addCell(v1, parent);
String id = shape.getId();
vertexMap.put(id, v1);
return v1;
}
private mxPoint calculateAbsolutePoint(mxCell cellParent, mxPoint point) {
if (cellParent != null) {
mxCellState state = graph.getView().getState(cellParent);
if (state != null) {
point.setX(point.getX() + state.getX());
point.setY(point.getY() + state.getY());
}
}
return point;
}
private mxPoint getPageDimentions(Element page) {
Element pHeight = (Element) page.getElementsByTagName(VdxConstants.PAGE_HEIGHT).item(0);
double pageH = Double.valueOf(pHeight.getTextContent()) * VdxCodecUtils.conversionFactor();
Element pageWidth = (Element) page.getElementsByTagName(VdxConstants.PAGE_WIDTH).item(0);
double pageW = Double.valueOf(pageWidth.getTextContent()) * VdxCodecUtils.conversionFactor();
return new mxPoint(pageW, pageH);
}
private Element findSigConnect(List connectList, Element connect, int index) {
int length = connectList.size();
String shapeConn1 = connect.getAttribute(VdxConstants.FROM_SHEET);
Element sigConnect = null;
boolean end = false;
for (int i = index + 1; (i < length) && (!end); i++) {
sigConnect = (Element) connectList.get(i);
String shapeConn2 = sigConnect.getAttribute(VdxConstants.FROM_SHEET);
if (shapeConn1.equals(shapeConn2)) {
end = true;
} else {
sigConnect = null;
}
}
return sigConnect;
}
private void cleanMaps() {
mastersMap.clear();
vertexMap.clear();
edgeShapeMap.clear();
vertexShapeMap.clear();
pageNumber = 0;
pageHeight = 0;
actualPageHeight = 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy