mxVsdxPage.java 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. package com.mxgraph.io.vsdx;
  2. import java.util.HashMap;
  3. import java.util.LinkedHashMap;
  4. import java.util.Map;
  5. import org.w3c.dom.Document;
  6. import org.w3c.dom.Element;
  7. import org.w3c.dom.Node;
  8. import org.w3c.dom.NodeList;
  9. import com.mxgraph.io.mxVsdxCodec;
  10. import com.mxgraph.util.mxPoint;
  11. public class mxVsdxPage {
  12. /**
  13. * Unique ID of the element within its parent element
  14. */
  15. protected Integer Id = null;
  16. protected boolean isBackground = false;
  17. protected Integer backPageId = null;
  18. protected mxVsdxPage backPage = null;
  19. protected Element pageElement = null;
  20. protected Element pageSheet = null;
  21. protected mxVsdxModel model = null;
  22. protected Map<Integer, VsdxShape> shapes = new LinkedHashMap<Integer, VsdxShape>();
  23. protected Map<Integer, mxVsdxConnect> connects = new LinkedHashMap<Integer, mxVsdxConnect>();
  24. // cell in the PageSheet
  25. protected Map<String, Element> cellElements = new HashMap<String, Element>();
  26. public mxVsdxPage(Element pageElem, mxVsdxModel model) {
  27. this.model = model;
  28. this.pageElement = pageElem;
  29. String backGround = pageElem.getAttribute(mxVsdxConstants.BACKGROUND);
  30. this.isBackground = (backGround != null && backGround.equals(mxVsdxConstants.TRUE)) ? true : false;
  31. String back = pageElem.getAttribute(mxVsdxConstants.BACK_PAGE);
  32. if (!isBackground && back != null && back.length() > 0)
  33. {
  34. this.backPageId = Integer.valueOf(back);
  35. }
  36. this.Id = Integer.valueOf(pageElem.getAttribute(mxVsdxConstants.ID));
  37. parseNodes(pageElem, model, "pages");
  38. Node child = pageElem.getFirstChild();
  39. while (child != null)
  40. {
  41. if (child instanceof Element && ((Element)child).getTagName().equals("PageSheet"))
  42. {
  43. Node childNode = child.getFirstChild();
  44. while (childNode != null)
  45. {
  46. if (childNode instanceof Element && ((Element)childNode).getTagName().equals("Cell"))
  47. {
  48. Element childElem = (Element) childNode;
  49. String n = childElem.getAttribute("N");
  50. cellElements.put(n, childElem);
  51. }
  52. childNode = childNode.getNextSibling();
  53. }
  54. break;
  55. }
  56. child = child.getNextSibling();
  57. }
  58. }
  59. /**
  60. * Parses the child nodes of the given element
  61. * @param pageElem the parent whose children to parse
  62. * @param model the model of the vsdx file
  63. * @param pageName page information is split across pages.xml and pageX.xml where X is any number. We have to know which we're currently parsing to use the correct relationships file.
  64. */
  65. protected void parseNodes(Node pageElem, mxVsdxModel model, String pageName)
  66. {
  67. Node pageChild = pageElem.getFirstChild();
  68. while (pageChild != null)
  69. {
  70. if (pageChild instanceof Element)
  71. {
  72. Element pageChildElem = (Element) pageChild;
  73. String childName = pageChildElem.getNodeName();
  74. if (childName.equals("Rel"))
  75. {
  76. resolveRel(pageChildElem, model, pageName);
  77. }
  78. else if (childName.equals("Shapes"))
  79. {
  80. this.shapes = parseShapes(pageChildElem, null, false);
  81. }
  82. else if (childName.equals("Connects"))
  83. {
  84. NodeList connectList = pageChildElem.getElementsByTagName(mxVsdxConstants.CONNECT);
  85. Node connectNode = (connectList != null && connectList.getLength() > 0) ? connectList.item(0) : null;
  86. //mxVdxConnect currentConnect = null;
  87. while (connectNode != null)
  88. {
  89. if (connectNode instanceof Element)
  90. {
  91. Element connectElem = (Element) connectNode;
  92. mxVsdxConnect connect = new mxVsdxConnect(connectElem);
  93. Integer fromSheet = connect.getFromSheet();
  94. mxVsdxConnect previousConnect = (fromSheet != null && fromSheet > -1) ? connects.get(fromSheet) : null;
  95. if (previousConnect != null)
  96. {
  97. previousConnect.addConnect(connectElem);
  98. }
  99. else
  100. {
  101. connects.put(connect.getFromSheet(), connect);
  102. }
  103. }
  104. connectNode = connectNode.getNextSibling();
  105. }
  106. }
  107. else if (childName.equals("PageSheet"))
  108. {
  109. this.pageSheet = pageChildElem;
  110. }
  111. }
  112. pageChild = pageChild.getNextSibling();
  113. }
  114. }
  115. /**
  116. *
  117. * @param relNode
  118. * @param model
  119. * @param pageName
  120. */
  121. protected void resolveRel(Element relNode, mxVsdxModel model, String pageName)
  122. {
  123. Element relElem = model.getRelationship(relNode.getAttribute("r:id"), mxVsdxCodec.vsdxPlaceholder + "/pages/" + "_rels/" + pageName + ".xml.rels");
  124. String target = relElem.getAttribute("Target");
  125. String type = relElem.getAttribute("Type");
  126. if (String.valueOf(type).endsWith("page"))
  127. {
  128. Document pageDoc = null;
  129. if (type != null && type.endsWith("page"))
  130. {
  131. pageDoc = model.getXmlDoc(mxVsdxCodec.vsdxPlaceholder + "/pages/" + target);
  132. }
  133. if (pageDoc != null)
  134. {
  135. Node child = pageDoc.getFirstChild();
  136. while (child != null)
  137. {
  138. if (child instanceof Element && ((Element)child).getTagName().equals("PageContents"))
  139. {
  140. int index = target.indexOf('.');
  141. if (index != -1)
  142. {
  143. parseNodes(child, model, target.substring(0, index));
  144. }
  145. break;
  146. }
  147. child = child.getNextSibling();
  148. }
  149. }
  150. }
  151. }
  152. public Map<Integer, VsdxShape> parseShapes(Element shapesElement, mxVsdxMaster master, boolean recurse)
  153. {
  154. Map<Integer, VsdxShape> shapes = new LinkedHashMap<Integer, VsdxShape>();
  155. NodeList shapeList = shapesElement.getElementsByTagName(mxVsdxConstants.SHAPE);
  156. Node shapeNode = (shapeList != null && shapeList.getLength() > 0) ? shapeList.item(0) : null;
  157. while (shapeNode != null)
  158. {
  159. if (shapeNode instanceof Element)
  160. {
  161. Element shapeElem = (Element) shapeNode;
  162. mxVsdxMaster masterTmp = master;
  163. // Work out node type
  164. if (masterTmp == null)
  165. {
  166. //If the shape has the Master attribute the master shape is the first
  167. //shape of the master element.
  168. String masterId = shapeElem.getAttribute(mxVsdxConstants.MASTER);
  169. if (masterId != null && !masterId.equals(""))
  170. {
  171. masterTmp = model.getMaster(masterId);
  172. }
  173. else
  174. {
  175. masterId = shapeElem.getAttribute(mxVsdxConstants.MASTER_SHAPE);
  176. if (masterId != null && !masterId.equals(""))
  177. {
  178. masterTmp = model.getMaster(masterId);
  179. }
  180. }
  181. }
  182. boolean isEdge = isEdge(shapeElem);
  183. //String type = mxVdxShape.getType(shapeElem);
  184. // If the master of the shape has an xform1D, it's an edge
  185. if (!isEdge && masterTmp != null)
  186. {
  187. isEdge = isEdge(masterTmp.getMasterElement());
  188. }
  189. VsdxShape shape = this.createCell(shapeElem, !isEdge, masterTmp);
  190. shapes.put(shape.getId(), shape);
  191. }
  192. shapeNode = shapeNode.getNextSibling();
  193. }
  194. return shapes;
  195. }
  196. protected VsdxShape createCell(Element shapeElem, boolean vertex, mxVsdxMaster masterTmp)
  197. {
  198. return new VsdxShape(this, shapeElem, vertex, this.model.getMasterShapes(), masterTmp, this.model);
  199. }
  200. protected boolean isEdge(Element shape)
  201. {
  202. if (shape != null)
  203. {
  204. NodeList children = shape.getChildNodes();
  205. if (children != null)
  206. {
  207. Node childNode = children.item(0);
  208. while (childNode != null)
  209. {
  210. if (childNode instanceof Element)
  211. {
  212. Element childElem = (Element) childNode;
  213. if (childElem.getNodeName().equals("Cell"))
  214. {
  215. String n = childElem.getAttribute("N");
  216. if (n.equals("BeginX") || n.equals("BeginY") || n.equals("EndY") || n.equals("EndX"))
  217. {
  218. return true;
  219. }
  220. }
  221. }
  222. childNode = childNode.getNextSibling();
  223. }
  224. }
  225. }
  226. return false;
  227. }
  228. /**
  229. * Returns the width and height of a Page expressed as an mxPoint.
  230. * @return mxPoint that represents the dimensions of the shape
  231. */
  232. public mxPoint getPageDimensions()
  233. {
  234. double pageH = 0;
  235. double pageW = 0;
  236. Element height = cellElements.get("PageHeight");
  237. Element width = cellElements.get("PageWidth");
  238. if (height != null)
  239. {
  240. pageH = Double.valueOf(height.getAttribute("V")) * mxVsdxUtils.conversionFactor;
  241. pageH = Math.round(pageH * 100.0) / 100.0;
  242. }
  243. if (width != null)
  244. {
  245. pageW = Double.valueOf(width.getAttribute("V")) * mxVsdxUtils.conversionFactor;
  246. pageW = Math.round(pageW * 100.0) / 100.0;
  247. }
  248. return new mxPoint(pageW, pageH);
  249. }
  250. public Integer getId()
  251. {
  252. return this.Id;
  253. }
  254. public Map<Integer, VsdxShape> getShapes()
  255. {
  256. return this.shapes;
  257. }
  258. public Map<Integer, mxVsdxConnect> getConnects()
  259. {
  260. return this.connects;
  261. }
  262. public boolean isBackground()
  263. {
  264. return this.isBackground;
  265. }
  266. public Integer getBackPageId()
  267. {
  268. return this.backPageId;
  269. }
  270. public void setBackPage(mxVsdxPage page)
  271. {
  272. this.backPage = page;
  273. }
  274. }