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

org.yaoqiang.graph.io.vdx.VdxCodec Maven / Gradle / Ivy

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 int decode() {

		setStencilType(document);
		if (stencilType == null) {
			return -1;
		}
		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();
		return 0;
	}

	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 - 2024 Weber Informatics LLC | Privacy Policy