View Javadoc

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