Advertisement
Guest User

Untitled

a guest
May 30th, 2016
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.74 KB | None | 0 0
  1. From 9b60aa3fb32c6c63757ebe748e0a115e804e8678 Mon Sep 17 00:00:00 2001
  2. From: Uli Schlachter <uli.schlachter@informatik.uni-oldenburg.de>
  3. Date: Mon, 30 May 2016 17:31:48 +0200
  4. Subject: [PATCH] WIP: Implement GraphvizLayout
  5.  
  6. Signed-off-by: Uli Schlachter <uli.schlachter@informatik.uni-oldenburg.de>
  7. ---
  8. .../uniol/aptgui/editor/layout/GraphvizLayout.java | 168 +++++++++++++++++++++
  9. .../uniol/aptgui/mainwindow/menu/MenuViewImpl.java | 4 +
  10. .../aptgui/swing/actions/GraphvizLayoutAction.java | 61 ++++++++
  11. 3 files changed, 233 insertions(+)
  12. create mode 100644 src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
  13. create mode 100644 src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
  14.  
  15. diff --git a/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java b/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
  16. new file mode 100644
  17. index 0000000..248f2f9
  18. --- /dev/null
  19. +++ b/src/main/java/uniol/aptgui/editor/layout/GraphvizLayout.java
  20. @@ -0,0 +1,168 @@
  21. +/*-
  22. + * APT - Analysis of Petri Nets and labeled Transition systems
  23. + * Copyright (C) 2016 Jonas Prellberg
  24. + * Copyright (C) 2016 Uli Schlachter
  25. + *
  26. + * This program is free software; you can redistribute it and/or modify
  27. + * it under the terms of the GNU General Public License as published by
  28. + * the Free Software Foundation; either version 2 of the License, or
  29. + * (at your option) any later version.
  30. + *
  31. + * This program is distributed in the hope that it will be useful,
  32. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. + * GNU General Public License for more details.
  35. + *
  36. + * You should have received a copy of the GNU General Public License along
  37. + * with this program; if not, write to the Free Software Foundation, Inc.,
  38. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  39. + */
  40. +
  41. +package uniol.aptgui.editor.layout;
  42. +
  43. +import java.io.*;
  44. +import java.nio.charset.StandardCharsets;
  45. +
  46. +import java.awt.Point;
  47. +
  48. +import org.apache.commons.collections4.BidiMap;
  49. +import org.apache.commons.collections4.bidimap.DualHashBidiMap;
  50. +
  51. +import uniol.apt.adt.IGraph;
  52. +import uniol.apt.adt.IEdge;
  53. +
  54. +import uniol.aptgui.editor.document.Document;
  55. +import uniol.aptgui.editor.document.graphical.GraphicalElement;
  56. +import uniol.aptgui.editor.document.graphical.nodes.GraphicalNode;
  57. +
  58. +/**
  59. + * Simple layout algorithm that uses Graphviz to layout items.
  60. + * randomly scatters nodes across the layout area.
  61. + */
  62. +public class GraphvizLayout implements Layout {
  63. +
  64. + private static final String nodeProperties = "fixedsize=true, width=60, height=60";
  65. +
  66. + private static BidiMap<GraphicalNode, String> collectNodes(Document<?> document) {
  67. + int counter = 0;
  68. + BidiMap<GraphicalNode, String> nodes = new DualHashBidiMap<>();
  69. + for (GraphicalElement elem : document.getGraphicalElements()) {
  70. + // Only nodes are positioned directly.
  71. + if (elem instanceof GraphicalNode) {
  72. + GraphicalNode node = (GraphicalNode) elem;
  73. + String id = String.format("s%d", counter++);
  74. + nodes.put(node, id);
  75. + }
  76. + }
  77. + return nodes;
  78. + }
  79. +
  80. + private static void writeDot(Writer writer, Document document, IGraph<?, ?, ?> graph, BidiMap<GraphicalNode, String> nodes) throws IOException {
  81. + writer.append("digraph G {\nnode [" + nodeProperties + "];\n");
  82. + // Write out all IDs of nodes
  83. + for (String node : nodes.values()) {
  84. + System.out.println(String.format("Printing node %s (%s) to graphviz", nodes.getKey(node), node));
  85. + writer.append("\"");
  86. + writer.append(node);
  87. + writer.append("\";\n");
  88. + }
  89. + // Write out all edges
  90. + for (IEdge<?, ?, ?> edge : graph.getEdges()) {
  91. + String source = nodes.get(document.getGraphicalExtension(edge.getSource()));
  92. + String target = nodes.get(document.getGraphicalExtension(edge.getTarget()));
  93. + if (source != null && target != null) {
  94. + System.out.println(String.format("Printing edge %s to graphviz", edge));
  95. + writer.append("\"");
  96. + writer.append(source);
  97. + writer.append("\" -> \"");
  98. + writer.append(target);
  99. + writer.append("\";\n");
  100. + }
  101. + else
  102. + System.out.println(String.format("Skipping edge %s because %s %s %s %s", edge, edge.getSource(), source, edge.getTarget(), target));
  103. + }
  104. + // Done!
  105. + writer.append("}");
  106. + }
  107. +
  108. + private static void doLayout(Document<?> document, BidiMap<GraphicalNode, String> nodes) throws IOException {
  109. + Process graphviz = new ProcessBuilder("dot", "-Tplain").start();
  110. + try {
  111. + IGraph<?, ?, ?> graph = (IGraph<?, ?, ?>) document.getModel();
  112. + try (OutputStream stream = graphviz.getOutputStream();
  113. + Writer osw = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
  114. + Writer buf = new BufferedWriter(osw)) {
  115. + writeDot(buf, document, graph, nodes);
  116. + buf.close();
  117. + }
  118. + try (InputStream stream = graphviz.getInputStream();
  119. + Reader isr = new InputStreamReader(stream, StandardCharsets.UTF_8);
  120. + BufferedReader buf = new BufferedReader(isr)) {
  121. + String line;
  122. + do {
  123. + line = buf.readLine();
  124. + if (line != null)
  125. + System.out.println("read a line: " + line);
  126. + else
  127. + line = "stop";
  128. + String[] words = line.split(" ");
  129. + if (words.length >= 4 && words[0].equals("node")) {
  130. + String node = words[1];
  131. + double x, y;
  132. + try {
  133. + x = Double.parseDouble(words[2]);
  134. + y = Double.parseDouble(words[3]);
  135. + } catch (NumberFormatException e) {
  136. + // TODO: Should I do something nice here?
  137. + throw e;
  138. + }
  139. + GraphicalNode graphical = nodes.getKey(node);
  140. + if (graphical != null)
  141. + {
  142. + System.out.println(String.format("Setting %s %s to %d %d", node, graphical, (int)x, (int)y));
  143. + graphical.setCenter(new Point((int) x, (int) y));
  144. + }
  145. + }
  146. + } while (line != null && !line.equals("stop"));
  147. + System.out.println("done");
  148. + }
  149. + try (InputStream stream = graphviz.getErrorStream();
  150. + Reader isr = new InputStreamReader(stream, StandardCharsets.UTF_8);
  151. + BufferedReader buf = new BufferedReader(isr)) {
  152. + String line;
  153. + do {
  154. + line = buf.readLine();
  155. + if (line != null)
  156. + System.out.println("read an error line: " + line);
  157. + } while (line != null && !line.equals("stop"));
  158. + System.out.println("done");
  159. + }
  160. + } finally {
  161. + graphviz.destroy();
  162. + try {
  163. + graphviz.waitFor();
  164. + } catch (InterruptedException e) {
  165. + // Just re-interrupt the thread and return
  166. + Thread.currentThread().interrupt();
  167. + }
  168. + }
  169. + }
  170. +
  171. + @Override
  172. + public void applyTo(Document<?> document, int x0, int y0, int x1, int y1) {
  173. + try {
  174. + doLayout(document, collectNodes(document));
  175. + } catch (IOException e) {
  176. + // TODO
  177. + throw new RuntimeException(e);
  178. + }
  179. + }
  180. +
  181. + @Override
  182. + public String getName() {
  183. + return "Graphviz";
  184. + }
  185. +
  186. +}
  187. +
  188. +// vim: ft=java:noet:sw=8:sts=8:ts=8:tw=120
  189. diff --git a/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java b/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
  190. index 641d5da..19b5a2a 100644
  191. --- a/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
  192. +++ b/src/main/java/uniol/aptgui/mainwindow/menu/MenuViewImpl.java
  193. @@ -45,6 +45,7 @@ import uniol.aptgui.swing.actions.NewPetriNetAction;
  194. import uniol.aptgui.swing.actions.NewTransitionSystemAction;
  195. import uniol.aptgui.swing.actions.OpenAction;
  196. import uniol.aptgui.swing.actions.RandomLayoutAction;
  197. +import uniol.aptgui.swing.actions.GraphvizLayoutAction;
  198. import uniol.aptgui.swing.actions.RedoAction;
  199. import uniol.aptgui.swing.actions.RenameDocumentAction;
  200. import uniol.aptgui.swing.actions.SaveAction;
  201. @@ -88,6 +89,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
  202. private final JMenu documentMenu;
  203. private final JMenuItem renameDocument;
  204. private final JMenuItem layoutRandom;
  205. + private final JMenuItem layoutGraphviz;
  206.  
  207. private final JMenu moduleMenu;
  208. private final JMenuItem moduleBrowser;
  209. @@ -134,6 +136,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
  210. documentMenu = new JMenu("Document");
  211. renameDocument = new JMenuItem(injector.getInstance(RenameDocumentAction.class));
  212. layoutRandom = new JMenuItem(injector.getInstance(RandomLayoutAction.class));
  213. + layoutGraphviz = new JMenuItem(injector.getInstance(GraphvizLayoutAction.class));
  214.  
  215. // Modules
  216. moduleMenu = new JMenu("Modules");
  217. @@ -203,6 +206,7 @@ public class MenuViewImpl extends JMenuBarView<MenuPresenter> implements MenuVie
  218.  
  219. documentMenu.add(renameDocument);
  220. documentMenu.add(layoutRandom);
  221. + documentMenu.add(layoutGraphviz);
  222.  
  223. }
  224.  
  225. diff --git a/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java b/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
  226. new file mode 100644
  227. index 0000000..9f3e468
  228. --- /dev/null
  229. +++ b/src/main/java/uniol/aptgui/swing/actions/GraphvizLayoutAction.java
  230. @@ -0,0 +1,61 @@
  231. +/*-
  232. + * APT - Analysis of Petri Nets and labeled Transition systems
  233. + * Copyright (C) 2016 Jonas Prellberg
  234. + * Copyright (C) 2016 Uli Schlachter
  235. + *
  236. + * This program is free software; you can redistribute it and/or modify
  237. + * it under the terms of the GNU General Public License as published by
  238. + * the Free Software Foundation; either version 2 of the License, or
  239. + * (at your option) any later version.
  240. + *
  241. + * This program is distributed in the hope that it will be useful,
  242. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  243. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  244. + * GNU General Public License for more details.
  245. + *
  246. + * You should have received a copy of the GNU General Public License along
  247. + * with this program; if not, write to the Free Software Foundation, Inc.,
  248. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  249. + */
  250. +
  251. +package uniol.aptgui.swing.actions;
  252. +
  253. +import java.awt.event.ActionEvent;
  254. +import java.awt.event.KeyEvent;
  255. +
  256. +import com.google.common.eventbus.EventBus;
  257. +import com.google.inject.Inject;
  258. +
  259. +import uniol.aptgui.Application;
  260. +import uniol.aptgui.commands.ApplyLayoutCommand;
  261. +import uniol.aptgui.editor.document.Document;
  262. +import uniol.aptgui.editor.layout.GraphvizLayout;
  263. +import uniol.aptgui.swing.Resource;
  264. +import uniol.aptgui.swing.actions.base.DocumentAction;
  265. +
  266. +@SuppressWarnings("serial")
  267. +public class GraphvizLayoutAction extends DocumentAction {
  268. +
  269. + @Inject
  270. + public GraphvizLayoutAction(Application app, EventBus eventBus) {
  271. + super(app, eventBus);
  272. + String name = "Graphviz Layout";
  273. + putValue(NAME, name);
  274. + putValue(SHORT_DESCRIPTION, name);
  275. + putValue(SMALL_ICON, Resource.getIconLayout());
  276. + putValue(MNEMONIC_KEY, KeyEvent.VK_R);
  277. + setEnabled(false);
  278. + eventBus.register(this);
  279. + }
  280. +
  281. + @Override
  282. + public void actionPerformed(ActionEvent e) {
  283. + Document<?> document = app.getActiveDocument();
  284. + if (document != null) {
  285. + app.getHistory().execute(new ApplyLayoutCommand(document, new GraphvizLayout()));
  286. + }
  287. + }
  288. +
  289. +}
  290. +
  291. +// vim: ft=java:noet:sw=8:sts=8:ts=8:tw=120
  292. --
  293. 2.5.5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement