/** * $Id: mxGraphMlGraph.java,v 1.1 2012/11/15 13:26:45 gaudenz Exp $ * Copyright (c) 2010 David Benson, Gaudenz Alder */ package com.mxgraph.io.graphml; import com.mxgraph.model.mxCell; import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxConnectionConstraint; import com.mxgraph.view.mxGraph; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Represents a Graph element in the GML Structure. */ public class mxGraphMlGraph { /** * Map with the vertex cells added in the addNode method. */ private static HashMap<String, Object> cellsMap = new HashMap<String, Object>(); private String id = ""; private String edgedefault = ""; private List<mxGraphMlNode> nodes = new ArrayList<mxGraphMlNode>(); private List<mxGraphMlEdge> edges = new ArrayList<mxGraphMlEdge>(); /** * Constructs a graph with id and edge default direction. * @param id Graph's ID * @param edgedefault Edge Default direction.("directed" or "undirected") */ public mxGraphMlGraph(String id, String edgedefault) { this.id = id; this.edgedefault = edgedefault; } /** * Constructs an empty graph. */ public mxGraphMlGraph() { } /** * Constructs a graph from a xml graph element. * @param graphElement Xml graph element. */ public mxGraphMlGraph(Element graphElement) { this.id = graphElement.getAttribute(mxGraphMlConstants.ID); this.edgedefault = graphElement .getAttribute(mxGraphMlConstants.EDGE_DEFAULT); //Adds node elements List<Element> nodeElements = mxGraphMlUtils.childsTags(graphElement, mxGraphMlConstants.NODE); for (Element nodeElem : nodeElements) { mxGraphMlNode node = new mxGraphMlNode(nodeElem); nodes.add(node); } //Adds edge elements List<Element> edgeElements = mxGraphMlUtils.childsTags(graphElement, mxGraphMlConstants.EDGE); for (Element edgeElem : edgeElements) { mxGraphMlEdge edge = new mxGraphMlEdge(edgeElem); if (edge.getEdgeDirected().equals("")) { if (edgedefault.equals(mxGraphMlConstants.EDGE_DIRECTED)) { edge.setEdgeDirected("true"); } else if (edgedefault.equals(mxGraphMlConstants.EDGE_UNDIRECTED)) { edge.setEdgeDirected("false"); } } edges.add(edge); } } /** * Adds the elements represented for this graph model into the given graph. * @param graph Graph where the elements will be located * @param parent Parent of the cells to be added. */ public void addGraph(mxGraph graph, Object parent) { List<mxGraphMlNode> nodeList = getNodes(); for (mxGraphMlNode node : nodeList) { addNode(graph, parent, node); } List<mxGraphMlEdge> edgeList = getEdges(); for (mxGraphMlEdge edge : edgeList) { addEdge(graph, parent, edge); } } /** * Checks if the node has data elements inside. * @param node Gml node element. * @return Returns <code>true</code> if the node has data elements inside. */ public static boolean hasData(mxGraphMlNode node) { boolean ret = false; if (node.getNodeDataMap() == null) { ret = false; } else { ret = true; } return ret; } /** * Returns the data element inside the node that references to the key element * with name = KEY_NODE_NAME. * @param node Gml Node element. * @return The required data. null if not found. */ public static mxGraphMlData dataNodeKey(mxGraphMlNode node) { String keyId = ""; HashMap<String, mxGraphMlKey> keyMap = mxGraphMlKeyManager.getInstance() .getKeyMap(); for (mxGraphMlKey key : keyMap.values()) { if (key.getKeyName().equals(mxGraphMlConstants.KEY_NODE_NAME)) { keyId = key.getKeyId(); } } mxGraphMlData data = null; HashMap<String, mxGraphMlData> nodeDataMap = node.getNodeDataMap(); data = nodeDataMap.get(keyId); return data; } /** * Returns the data element inside the edge that references to the key element * with name = KEY_EDGE_NAME. * @param edge Gml Edge element. * @return The required data. null if not found. */ public static mxGraphMlData dataEdgeKey(mxGraphMlEdge edge) { String keyId = ""; HashMap<String, mxGraphMlKey> keyMap = mxGraphMlKeyManager.getInstance() .getKeyMap(); for (mxGraphMlKey key : keyMap.values()) { if (key.getKeyName().equals(mxGraphMlConstants.KEY_EDGE_NAME)) { keyId = key.getKeyId(); } } mxGraphMlData data = null; HashMap<String, mxGraphMlData> nodeDataMap = edge.getEdgeDataMap(); data = nodeDataMap.get(keyId); return data; } /** * Adds the vertex represented for the gml node into the graph with the given parent. * @param graph Graph where the vertex will be added. * @param parent Parent's cell. * @param node Gml Node * @return The inserted Vertex cell. */ private mxCell addNode(mxGraph graph, Object parent, mxGraphMlNode node) { mxCell v1; String id = node.getNodeId(); mxGraphMlData data = dataNodeKey(node); if (data != null && data.getDataShapeNode() != null) { Double x = Double.valueOf(data.getDataShapeNode().getDataX()); Double y = Double.valueOf(data.getDataShapeNode().getDataY()); Double h = Double.valueOf(data.getDataShapeNode().getDataHeight()); Double w = Double.valueOf(data.getDataShapeNode().getDataWidth()); String label = data.getDataShapeNode().getDataLabel(); String style = data.getDataShapeNode().getDataStyle(); v1 = (mxCell) graph.insertVertex(parent, id, label, x, y, w, h, style); } else { v1 = (mxCell) graph.insertVertex(parent, id, "", 0, 0, 100, 100); } cellsMap.put(id, v1); List<mxGraphMlGraph> graphs = node.getNodeGraph(); for (mxGraphMlGraph gmlGraph : graphs) { gmlGraph.addGraph(graph, v1); } return v1; } /** * Returns the point represented for the port name. * The specials names North, NorthWest, NorthEast, East, West, South, SouthEast and SouthWest. * are accepted. Else, the values acepted follow the pattern "double,double". * where double must be in the range 0..1 * @param source Port Name. * @return point that represent the port value. */ private static mxPoint portValue(String source) { mxPoint fromConstraint = null; if (source != null && !source.equals("")) { if (source.equals("North")) { fromConstraint = new mxPoint(0.5, 0); } else if (source.equals("South")) { fromConstraint = new mxPoint(0.5, 1); } else if (source.equals("East")) { fromConstraint = new mxPoint(1, 0.5); } else if (source.equals("West")) { fromConstraint = new mxPoint(0, 0.5); } else if (source.equals("NorthWest")) { fromConstraint = new mxPoint(0, 0); } else if (source.equals("SouthWest")) { fromConstraint = new mxPoint(0, 1); } else if (source.equals("SouthEast")) { fromConstraint = new mxPoint(1, 1); } else if (source.equals("NorthEast")) { fromConstraint = new mxPoint(1, 0); } else { try { String[] s = source.split(","); Double x = Double.valueOf(s[0]); Double y = Double.valueOf(s[1]); fromConstraint = new mxPoint(x, y); } catch (Exception e) { e.printStackTrace(); } } } return fromConstraint; } /** * Adds the edge represented for the gml edge into the graph with the given parent. * @param graph Graph where the vertex will be added. * @param parent Parent's cell. * @param edge Gml Edge * @return The inserted edge cell. */ private static mxCell addEdge(mxGraph graph, Object parent, mxGraphMlEdge edge) { //Get source and target vertex mxPoint fromConstraint = null; mxPoint toConstraint = null; Object source = cellsMap.get(edge.getEdgeSource()); Object target = cellsMap.get(edge.getEdgeTarget()); String sourcePort = edge.getEdgeSourcePort(); String targetPort = edge.getEdgeTargetPort(); fromConstraint = portValue(sourcePort); toConstraint = portValue(targetPort); mxGraphMlData data = dataEdgeKey(edge); String style = ""; String label = ""; if (data != null) { mxGraphMlShapeEdge shEdge = data.getDataShapeEdge(); style = shEdge.getStyle(); label = shEdge.getText(); } else { style = edge.getEdgeStyle(); } //Insert new edge. mxCell e = (mxCell) graph.insertEdge(parent, null, label, source, target, style); graph.setConnectionConstraint(e, source, true, new mxConnectionConstraint(fromConstraint, false)); graph.setConnectionConstraint(e, target, false, new mxConnectionConstraint(toConstraint, false)); return e; } public String getEdgedefault() { return edgedefault; } public void setEdgedefault(String edgedefault) { this.edgedefault = edgedefault; } public String getId() { return id; } public void setId(String id) { this.id = id; } public List<mxGraphMlNode> getNodes() { return nodes; } public void setNodes(List<mxGraphMlNode> node) { this.nodes = node; } public List<mxGraphMlEdge> getEdges() { return edges; } public void setEdges(List<mxGraphMlEdge> edge) { this.edges = edge; } /** * Checks if the graph has child nodes or edges. * @return Returns <code>true</code> if the graph hasn't child nodes or edges. */ public boolean isEmpty() { return nodes.size() == 0 && edges.size() == 0; } /** * Generates a Key Element from this class. * @param document Document where the key Element will be inserted. * @return Returns the generated Elements. */ public Element generateElement(Document document) { Element graph = document.createElement(mxGraphMlConstants.GRAPH); if (!id.equals("")) { graph.setAttribute(mxGraphMlConstants.ID, id); } if (!edgedefault.equals("")) { graph.setAttribute(mxGraphMlConstants.EDGE_DEFAULT, edgedefault); } for (mxGraphMlNode node : nodes) { Element nodeElement = node.generateElement(document); graph.appendChild(nodeElement); } for (mxGraphMlEdge edge : edges) { Element edgeElement = edge.generateElement(document); graph.appendChild(edgeElement); } return graph; } }