View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.deploy.graph;
20  
21  import java.io.File;
22  import java.io.FileWriter;
23  import java.io.IOException;
24  import java.io.PrintWriter;
25  import java.text.CollationKey;
26  import java.text.Collator;
27  import java.util.Comparator;
28  import java.util.Set;
29  import java.util.TreeSet;
30  
31  import org.eclipse.jetty.util.IO;
32  
33  /**
34   * Output the Graph in GraphViz Dot format.
35   */
36  public class GraphOutputDot
37  {
38      private GraphOutputDot()
39      {
40      }
41  
42      private static final String TOPNODE = "undeployed";
43  
44      /**
45       * Comparator that makes the 'undeployed' node the first node in the sort list.
46       * 
47       * This makes the 'undeployed' node show up at the top of the generated graph.
48       */
49      private static class TopNodeSort implements Comparator<Node>
50      {
51          private Collator collator = Collator.getInstance();
52  
53          public int compare(Node o1, Node o2)
54          {
55              if (o1.getName().equals(TOPNODE))
56              {
57                  return -1;
58              }
59  
60              if (o2.getName().equals(TOPNODE))
61              {
62                  return 1;
63              }
64  
65              CollationKey key1 = toKey(o1);
66              CollationKey key2 = toKey(o2);
67              return key1.compareTo(key2);
68          }
69  
70          private CollationKey toKey(Node node)
71          {
72              return collator.getCollationKey(node.getName());
73          }
74      }
75  
76      public static void write(Graph graph, File outputFile) throws IOException
77      {
78          FileWriter writer = null;
79          PrintWriter out = null;
80  
81          try
82          {
83              writer = new FileWriter(outputFile);
84              out = new PrintWriter(writer);
85  
86              out.println("// Autogenerated by " + GraphOutputDot.class.getName());
87              out.println("digraph Graf {");
88  
89              writeGraphDefaults(out);
90              writeNodeDefaults(out);
91              writeEdgeDefaults(out);
92  
93              Set<Node> nodes = new TreeSet<Node>(new TopNodeSort());
94              nodes.addAll(graph.getNodes());
95  
96              for (Node node : nodes)
97              {
98                  writeNode(out,node);
99              }
100 
101             for (Edge edge : graph.getEdges())
102             {
103                 writeEdge(out,edge);
104             }
105 
106             out.println("}");
107         }
108         finally
109         {
110             IO.close(out);
111             IO.close(writer);
112         }
113     }
114 
115     private static void writeEdge(PrintWriter out, Edge edge)
116     {
117         out.println();
118         out.println("  // Edge");
119         out.printf("  \"%s\" -> \"%s\" [%n",toId(edge.getFrom()),toId(edge.getTo()));
120         out.println("    arrowtail=none,");
121         out.println("    arrowhead=normal");
122         out.println("  ];");
123     }
124 
125     private static void writeNode(PrintWriter out, Node node)
126     {
127         out.println();
128         out.println("  // Node");
129         out.printf("  \"%s\" [%n",toId(node));
130         out.printf("    label=\"%s\",%n",node.getName());
131         if (node.getName().endsWith("ed"))
132         {
133             out.println("    color=\"#ddddff\",");
134             out.println("    style=filled,");
135         }
136         out.println("    shape=box");
137         out.println("  ];");
138     }
139 
140     private static CharSequence toId(Node node)
141     {
142         StringBuilder buf = new StringBuilder();
143 
144         for (char c : node.getName().toCharArray())
145         {
146             if (Character.isLetter(c))
147             {
148                 buf.append(c);
149                 continue;
150             }
151 
152             if (Character.isDigit(c))
153             {
154                 buf.append(c);
155                 continue;
156             }
157 
158             if ((c == ' ') || (c == '-') || (c == '_'))
159             {
160                 buf.append(c);
161                 continue;
162             }
163         }
164 
165         return buf;
166     }
167 
168     private static void writeEdgeDefaults(PrintWriter out)
169     {
170         out.println();
171         out.println("  // Edge Defaults ");
172         out.println("  edge [");
173         out.println("    arrowsize=\"0.8\",");
174         out.println("    fontsize=\"11\"");
175         out.println("  ];");
176     }
177 
178     private static void writeGraphDefaults(PrintWriter out)
179     {
180         out.println();
181         out.println("  // Graph Defaults ");
182         out.println("  graph [");
183         out.println("    bgcolor=\"#ffffff\",");
184         out.println("    fontname=\"Helvetica\",");
185         out.println("    fontsize=\"11\",");
186         out.println("    label=\"Graph\",");
187         out.println("    labeljust=\"l\",");
188         out.println("    rankdir=\"TD\"");
189         out.println("  ];");
190     }
191 
192     private static void writeNodeDefaults(PrintWriter out)
193     {
194         out.println();
195         out.println("  // Node Defaults ");
196         out.println("  node [");
197         out.println("    fontname=\"Helvetica\",");
198         out.println("    fontsize=\"11\",");
199         out.println("    shap=\"box\"");
200         out.println("  ];");
201     }
202 }