package de.tu_darmstadt.informatik.tk.scopviz.io; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import org.graphstream.graph.Graph; import org.graphstream.stream.file.FileSinkGraphML; import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug; import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyEdge; import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyGraph; import de.tu_darmstadt.informatik.tk.scopviz.graphs.MyNode; public class MyFileSinkGraphML extends FileSinkGraphML { public boolean isWritingMultigraph = false; private void print(String format, Object... args) throws IOException { output.write(String.format(format, args)); } @Override protected void exportGraph(Graph g) { try { int attribute = 0; HashMap nodeAttributes = new HashMap(); HashMap edgeAttributes = new HashMap(); HashMap graphAttributes = new HashMap(); for (String j : g.getAttributeKeySet()) { if (!isWritingMultigraph && (j.equals("layer") || j.equals("ui.stylesheet"))) { continue; } if (!graphAttributes.containsKey(j)) { Object gValue = g.getAttribute(j); String gType; if (gValue == null) continue; String gId = String.format("attr%04X", attribute++); if (gValue instanceof Boolean) gType = "boolean"; else if (gValue instanceof Long) gType = "long"; else if (gValue instanceof Integer) gType = "int"; else if (gValue instanceof Double) gType = "double"; else if (gValue instanceof Float) gType = "float"; else gType = "string"; graphAttributes.put(j, gId); print("\t\n", gId, escapeXmlString(j), gType); } } for (MyNode n : g.getEachNode()) { for (String k : n.getAttributeKeySet()) { // AttributeFiltering if (k.equals("ui.j2dsk") || k.equals("ui.class") || k.equals("ui.pie-values") || k.equalsIgnoreCase("originalgraph")) { continue; } Class c = n.getAttribute(k).getClass(); if (!c.isPrimitive() && !(c == String.class) && !(c == Character.class) && !(c == Boolean.class) && !(c == Integer.class) && !(c == Long.class) && !(c == Short.class) && !(c == Byte.class) && !(c == Float.class) && !(c == Double.class)) { Debug.out("Could not parse an Attribute because it is not Primitive or a String \n\t" + "(Attribute: " + k + ", Value: " + n.getAttribute(k) + ", from Node: " + n + ", Type: " + c + ") ", 2); continue; } if (!nodeAttributes.containsKey(k)) { Object value = n.getAttribute(k); String type; if (value == null) continue; String id = String.format("attr%04X", attribute++); if (value instanceof Boolean) type = "boolean"; else if (value instanceof Long) type = "long"; else if (value instanceof Integer) type = "int"; else if (value instanceof Double) type = "double"; else if (value instanceof Float) type = "float"; else type = "string"; nodeAttributes.put(k, id); print("\t\n", id, escapeXmlString(k), type); } } } for (MyEdge n : g.getEachEdge()) { for (String k : n.getAttributeKeySet()) { // AttributeFiltering if (k.equals("ui.j2dsk")) { continue; } Class c = n.getAttribute(k).getClass(); if (!c.isPrimitive() && !(c == String.class) && !(c == Character.class) && !(c == Boolean.class) && !(c == Integer.class) && !(c == Long.class) && !(c == Short.class) && !(c == Byte.class) && !(c == Float.class) && !(c == Double.class)) { Debug.out("Could not parse an Attribute because it is not Primitive or a String \n\t" + "(Attribute: " + k + ", Value: " + n.getAttribute(k) + ", from Edge: " + n + ", Type: " + c + ") ", 2); continue; } if (!edgeAttributes.containsKey(k)) { Object value = n.getAttribute(k); String type; if (value == null) continue; String id = String.format("attr%04X", attribute++); if (value instanceof Boolean) type = "boolean"; else if (value instanceof Long) type = "long"; else if (value instanceof Integer) type = "int"; else if (value instanceof Double) type = "double"; else if (value instanceof Float) type = "float"; else type = "string"; edgeAttributes.put(k, id); print("\t\n", id, escapeXmlString(k), type); } } } print("\t\n", escapeXmlString(g.getId())); for (String k : g.getAttributeKeySet()) { if (!isWritingMultigraph && (k.equals("layer") || k.equals("ui.stylesheet"))) { continue; } print("\t\t\t%s\n", graphAttributes.get(k), escapeXmlString(g.getAttribute(k).toString())); } for (MyNode n : g.getEachNode()) { print("\t\t\n", n.getId()); for (String k : n.getAttributeKeySet()) { if (k.equals("ui.j2dsk") || k.equals("ui.class") || k.equals("ui.pie-values") || k.equalsIgnoreCase("originalgraph")) { continue; } Class c = n.getAttribute(k).getClass(); if (!c.isPrimitive() && !(c == String.class) && !(c == Character.class) && !(c == Boolean.class) && !(c == Integer.class) && !(c == Long.class) && !(c == Short.class) && !(c == Byte.class) && !(c == Float.class) && !(c == Double.class)) { continue; } print("\t\t\t%s\n", nodeAttributes.get(k), escapeXmlString(n.getAttribute(k).toString())); } print("\t\t\n"); } for (MyEdge e : g.getEachEdge()) { print("\t\t\n", e.getId(), e.getSourceNode().getId(), e.getTargetNode().getId(), e.isDirected()); for (String k : e.getAttributeKeySet()) { if (k.equals("ui.j2dsk") || k.equals("ui.class") || k.equals("ui.pie-values")) { continue; } Class c = e.getAttribute(k).getClass(); if (!c.isPrimitive() && !(c == String.class) && !(c == Character.class) && !(c == Boolean.class) && !(c == Integer.class) && !(c == Long.class) && !(c == Short.class) && !(c == Byte.class) && !(c == Float.class) && !(c == Double.class)) { continue; } print("\t\t\t%s\n", edgeAttributes.get(k), escapeXmlString(e.getAttribute(k).toString())); } print("\t\t\n"); } print("\t\n"); } catch (IOException e) { e.printStackTrace(); } } private static String escapeXmlString(String s) { // why do you make me do this graphstream??? return s.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """).replace("'", "'"); } /** * * @param graphs */ public void exportGraphs(LinkedList graphs, String fileName) { Iterator graphIter = graphs.iterator(); while (graphIter.hasNext()) { if (graphIter.next().isComposite()) { graphIter.remove(); } } try { begin(fileName); isWritingMultigraph = true; for (MyGraph g : graphs) { exportGraph(g); } isWritingMultigraph = false; end(); } catch (IOException e) { e.printStackTrace(); } } }