2 * JavaInspect - Utility to visualize java software
3 * Copyright (C) 2013-2014, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 3 of the GNU Lesser General Public License
7 * or later as published by the Free Software Foundation.
10 package eu.svjatoslav.inspector.java.structure;
13 import java.io.IOException;
14 import java.io.PrintWriter;
15 import java.util.HashMap;
18 import eu.svjatoslav.commons.file.CommonPathResolver;
19 import eu.svjatoslav.inspector.java.methods.Clazz;
20 import eu.svjatoslav.inspector.java.methods.ProjectScanner;
22 public class ClassGraph {
24 public static void render(final String graphName, final Class... classes) {
25 final ClassGraph classGraph = new ClassGraph(classes);
27 classGraph.generateGraph(graphName);
31 * Maps class fully qualified names to class descriptors.
33 private final Map<String, ClassDescriptor> fullyQualifiedNameToClassMap = new HashMap<String, ClassDescriptor>();
35 private Filter filter = new Filter();
42 * classes that shall be added to graph
44 public ClassGraph(final Class<? extends Object>... classes) {
45 for (final Class<? extends Object> clazz : classes)
51 * objects that shall be added to graph
53 public ClassGraph(final Object... objects) {
54 for (final Object object : objects)
55 addClass(object.getClass());
60 * class that shall be added to graph
62 public ClassDescriptor addClass(final Class<? extends Object> clazz) {
67 final String className = clazz.getName();
69 if (fullyQualifiedNameToClassMap.containsKey(className))
70 return fullyQualifiedNameToClassMap.get(className);
72 return new ClassDescriptor(clazz, this);
77 * object that shall be added to graph
79 public ClassDescriptor addObject(final Object object) {
80 return addClass(object.getClass());
85 * path to recursively scan for java source code could be
86 * relative to current project or absolute
88 public void addProject(final String path) {
89 final ProjectScanner projectScanner = new ProjectScanner(new File(path));
90 for (final Clazz clazz : projectScanner.getAllClasses())
92 System.out.println("Class full name: " + clazz.getFullName());
93 final Class c = this.getClass().forName(clazz.getFullName());
95 } catch (final Exception exception) {
96 System.out.println("cannot add class: "
97 + exception.getMessage());
102 * @param resultFileName
103 * file name for the generated graph. Existing file with the same
104 * name will be overwritten.
106 public void generateGraph(final String resultFileName) {
107 generateGraph(resultFileName, false);
111 * @param resultFileName
112 * file name for the generated graph. File extension will be
113 * added automatically. Existing file with the same name will be
117 * if set to <code>true</code> then intermediary GraphViz DOT
121 public void generateGraph(final String resultFileName,
122 final boolean keepDotFile) {
124 final String desktopPath = CommonPathResolver.getDesktopDirectory()
125 .getAbsolutePath() + "/";
127 generateGraph(desktopPath, resultFileName, keepDotFile);
131 * @param targetDirectory
132 * target directory name
134 * @param resultFileName
135 * file name for the generated graph. File extension will be
136 * added automatically. Existing file with the same name will be
140 * if set to <code>true</code> then intermediary GraphViz DOT
144 public void generateGraph(String targetDirectory,
145 final String resultFileName, final boolean keepDotFile) {
147 if (!targetDirectory.endsWith("/"))
148 targetDirectory += "/";
150 final String dotFilePath = targetDirectory + resultFileName + ".dot";
151 final String imageFilePath = targetDirectory + resultFileName + ".png";
153 System.out.println("Dot file path:" + dotFilePath);
156 // write DOT file to disk
157 final PrintWriter out = new PrintWriter(dotFilePath);
161 // execute GraphViz to visualize graph
164 .exec(new String[] { "dot", "-Tpng", dotFilePath, "-o",
165 imageFilePath }).waitFor();
166 } catch (final InterruptedException e) {
172 final File dotFile = new File(dotFilePath);
175 } catch (final IOException e) {
176 System.err.println(e);
181 private String getDot() {
182 final StringBuffer result = new StringBuffer();
184 result.append("digraph Java {\n");
185 result.append("graph [rankdir=LR, overlap = false, concentrate=true];\n");
187 for (final Map.Entry<String, ClassDescriptor> entry : fullyQualifiedNameToClassMap
189 result.append(entry.getValue().getDot());
191 result.append("}\n");
193 final String resultStr = result.toString();
197 public Filter getFilter() {
202 * Hide orphaned class that have no references
204 public void hideOrphanedClasses() {
206 for (final ClassDescriptor classDescriptor : fullyQualifiedNameToClassMap
208 classDescriptor.hideClassIfNoReferences();
212 public void registerClass(final String classFullyQualifiedName,
213 final ClassDescriptor classDescriptor) {
214 fullyQualifiedNameToClassMap.put(classFullyQualifiedName,
218 public void setFilter(final Filter filter) {
219 this.filter = filter;