| // |
| // ======================================================================== |
| // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. |
| // ------------------------------------------------------------------------ |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // and Apache License v2.0 which accompanies this distribution. |
| // |
| // The Eclipse Public License is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // The Apache License v2.0 is available at |
| // http://www.opensource.org/licenses/apache2.0.php |
| // |
| // You may elect to redistribute this code under either of these licenses. |
| // ======================================================================== |
| // |
| |
| package org.eclipse.jetty.deploy.graph; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.text.CollationKey; |
| import java.text.Collator; |
| import java.util.Comparator; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.eclipse.jetty.util.IO; |
| |
| /** |
| * Output the Graph in GraphViz Dot format. |
| */ |
| public class GraphOutputDot |
| { |
| private GraphOutputDot() |
| { |
| } |
| |
| private static final String TOPNODE = "undeployed"; |
| |
| /** |
| * Comparator that makes the 'undeployed' node the first node in the sort list. |
| * |
| * This makes the 'undeployed' node show up at the top of the generated graph. |
| */ |
| private static class TopNodeSort implements Comparator<Node> |
| { |
| private Collator collator = Collator.getInstance(); |
| |
| public int compare(Node o1, Node o2) |
| { |
| if (o1.getName().equals(TOPNODE)) |
| { |
| return -1; |
| } |
| |
| if (o2.getName().equals(TOPNODE)) |
| { |
| return 1; |
| } |
| |
| CollationKey key1 = toKey(o1); |
| CollationKey key2 = toKey(o2); |
| return key1.compareTo(key2); |
| } |
| |
| private CollationKey toKey(Node node) |
| { |
| return collator.getCollationKey(node.getName()); |
| } |
| } |
| |
| public static void write(Graph graph, File outputFile) throws IOException |
| { |
| FileWriter writer = null; |
| PrintWriter out = null; |
| |
| try |
| { |
| writer = new FileWriter(outputFile); |
| out = new PrintWriter(writer); |
| |
| out.println("// Autogenerated by " + GraphOutputDot.class.getName()); |
| out.println("digraph Graf {"); |
| |
| writeGraphDefaults(out); |
| writeNodeDefaults(out); |
| writeEdgeDefaults(out); |
| |
| Set<Node> nodes = new TreeSet<Node>(new TopNodeSort()); |
| nodes.addAll(graph.getNodes()); |
| |
| for (Node node : nodes) |
| { |
| writeNode(out,node); |
| } |
| |
| for (Edge edge : graph.getEdges()) |
| { |
| writeEdge(out,edge); |
| } |
| |
| out.println("}"); |
| } |
| finally |
| { |
| IO.close(out); |
| IO.close(writer); |
| } |
| } |
| |
| private static void writeEdge(PrintWriter out, Edge edge) |
| { |
| out.println(); |
| out.println(" // Edge"); |
| out.printf(" \"%s\" -> \"%s\" [%n",toId(edge.getFrom()),toId(edge.getTo())); |
| out.println(" arrowtail=none,"); |
| out.println(" arrowhead=normal"); |
| out.println(" ];"); |
| } |
| |
| private static void writeNode(PrintWriter out, Node node) |
| { |
| out.println(); |
| out.println(" // Node"); |
| out.printf(" \"%s\" [%n",toId(node)); |
| out.printf(" label=\"%s\",%n",node.getName()); |
| if (node.getName().endsWith("ed")) |
| { |
| out.println(" color=\"#ddddff\","); |
| out.println(" style=filled,"); |
| } |
| out.println(" shape=box"); |
| out.println(" ];"); |
| } |
| |
| private static CharSequence toId(Node node) |
| { |
| StringBuilder buf = new StringBuilder(); |
| |
| for (char c : node.getName().toCharArray()) |
| { |
| if (Character.isLetter(c)) |
| { |
| buf.append(c); |
| continue; |
| } |
| |
| if (Character.isDigit(c)) |
| { |
| buf.append(c); |
| continue; |
| } |
| |
| if ((c == ' ') || (c == '-') || (c == '_')) |
| { |
| buf.append(c); |
| continue; |
| } |
| } |
| |
| return buf; |
| } |
| |
| private static void writeEdgeDefaults(PrintWriter out) |
| { |
| out.println(); |
| out.println(" // Edge Defaults "); |
| out.println(" edge ["); |
| out.println(" arrowsize=\"0.8\","); |
| out.println(" fontsize=\"11\""); |
| out.println(" ];"); |
| } |
| |
| private static void writeGraphDefaults(PrintWriter out) |
| { |
| out.println(); |
| out.println(" // Graph Defaults "); |
| out.println(" graph ["); |
| out.println(" bgcolor=\"#ffffff\","); |
| out.println(" fontname=\"Helvetica\","); |
| out.println(" fontsize=\"11\","); |
| out.println(" label=\"Graph\","); |
| out.println(" labeljust=\"l\","); |
| out.println(" rankdir=\"TD\""); |
| out.println(" ];"); |
| } |
| |
| private static void writeNodeDefaults(PrintWriter out) |
| { |
| out.println(); |
| out.println(" // Node Defaults "); |
| out.println(" node ["); |
| out.println(" fontname=\"Helvetica\","); |
| out.println(" fontsize=\"11\","); |
| out.println(" shap=\"box\""); |
| out.println(" ];"); |
| } |
| } |