From c508bf97e017675b49df989b7f5a64cbd31d9aa3 Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Tue, 3 Mar 2015 22:25:13 +0200 Subject: [PATCH] Refactoring. API simplifications. Documentation updates. --- doc/index.html | 167 +++++++++++++----- doc/index.org | 85 ++++++--- .../inspector/java/structure/ClassGraph.java | 64 +++---- .../structure/example/RenderDemoClasses.java | 2 +- .../structure/example/RenderJavaInspect.java | 13 +- 5 files changed, 211 insertions(+), 120 deletions(-) diff --git a/doc/index.html b/doc/index.html index 958f4ef..ea10bb8 100644 --- a/doc/index.html +++ b/doc/index.html @@ -4,7 +4,7 @@ JavaInspect - Utility to visualize java software - + @@ -144,13 +144,16 @@ for the JavaScript code in this tag.
@@ -188,43 +191,51 @@ automatically visualizing its structure.

-JavaInspect is a Java library that you can embed into your Java -project with a few lines of Maven configuration and then visualize any -part of your Java program structure with few simple JavaInspect API -calls at application runtime. +JavaInspect is a Java library that primarily uses Java reflection to +discover and visualize any part of Java program provided that +classes to be visualised are available in the classpath.

-JavaInspect uses Java reflection to discover class relations and -structure and produces GraphViz dot file that describes your -application. Then launches GraphViz to generate bitmap graph in PNG -format on your Desktop directory. +JavaInspect currently has no GUI, configuration files, embedded +scripting support, direct Maven or Ant integration. The only way to +instuct Javainspect what to do is by using its Java API.

- - -
-

2 Current status

-

-This is simple utility, quickly written. Tested on GNU Linux (can be -relatively simply ported to other operating systems too). So far I -used it for my own needs. There might be bugs and missing -features. Feedback and code contributions are welcome. +To get JavaInspect into same classpath with your projecs I so far came +up with 2 solutions:

-
-
-
-

3 Example graphs

-
+
    +
  1. Add JavaInspect library in your project as a dependency. +
  2. +
  3. Create new Java project for the purpose visualizing your other +projects and include JavaInspect and your projecs binary artifacts +(Jar's) into new project classpath. Built binary Jar's (with no +source code) are sufficient because JavaInspect operates via +reflection. +
  4. +
+

-Example visualization of Sixth project: architecture graphs. +After discovering application structure and optionally filtering out +unimportant parts, JavaInspect produces GraphViz dot file that +describes data to be visualized. Then launches GraphViz to generate +bitmap graph in PNG format. By default on your Desktop directory.

-A very simple example: +Note: GraphViz is developed and tested so far only on GNU Linux.

+
+
+ +
+

2 Example graphs

+
+
    +
  • A very simple example:
    @@ -232,7 +243,6 @@ A very simple example:

    -

    Graph legend:

    @@ -242,12 +252,70 @@ Graph legend:

    legend.png

+ + +
  • Example visualization of Sixth project: architecture graphs. +
  • +
    -
    -

    4 Usage example 1

    -
    +
    +

    3 Usage

    +
    +

    +Currently the only way to control JavaInspect is by using Java +API. Simple Java based control/configuration code needs to be written +for each project. I usually put such code into directories devoted for +JUnit tests. Because it needs not to be compiled/embedded into final +product or project artifact I'm just willing to visualize. +

    + +

    +Control code in general does the following: +

    +
      +
    1. Create graph object. +
    2. +
    3. Java reflection/classloaders does not provide mechanism for +discovering all classes under given package. Therefore you need to +declare at least some classes to be added to the graph by: +
        +
      • Manually adding individual classes to the graph. +
      • +
      • and/or: Let GraphViz recursively scan and parse specified +directories with Java source code files to discover class names. +
      • +
      • For every class added to the graph, GraphViz will recursively +inspect it and add all referecned classes to the graph as well. +
      • +
      +
    4. +
    5. Graphs easilly get very big and complex so optionally we filter +important code using classname wildcards patterns based blacklist +and/or whitelist. +
    6. +
    7. Optionally we can tune some rendering parameters like: +
        +
      • Possibility to remove orphaned classes (classes with no +references) from the graph. +
      • +
      • Specify target directory for generated visualization +files. (Default is user desktop directory) +
      • +
      • Keep intermediate GraphViz dot file for later inspection. +
      • +
      +
    8. +
    9. Render graph. +
    10. +
    +
    + + +
    +

    3.1 example 1

    +

    This example demonstrates generating of class graph from hand picked classes. @@ -288,9 +356,9 @@ Result:

    -
    -

    5 Usage example 2

    -
    +
    +

    3.2 example 2

    +

    Recursively scan current directory for Java source code and attempt to detect class names from there to be added to the graph. @@ -321,10 +389,11 @@ Result:

    +
    -
    -

    6 Embedding JavaInspect in your Maven project

    -
    +
    +

    4 Embedding JavaInspect in your Maven project

    +

    Declare JavaInspect as dependency:

    @@ -362,9 +431,9 @@ Add Maven repository to retrieve artifact from:
    -
    -

    7 Requirements

    -
    +
    +

    5 Requirements

    +

    GraphViz - shall be installed on the computer.

    @@ -377,9 +446,9 @@ sudo apt-get install graphviz
    -
    -

    8 TODO

    -
    +
    +

    6 TODO

    +
    • BUG: Should not hide references if there are too many of them to classes if referring classes are not visible anyway because of @@ -419,7 +488,7 @@ project build/release process

    Author: Svjatoslav Agejenko

    -

    Created: 2015-02-03 Tue 20:39

    +

    Created: 2015-03-03 Tue 22:24

    Emacs 24.4.1 (Org mode 8.2.10)

    Validate

    diff --git a/doc/index.org b/doc/index.org index 1751f8d..873b0dd 100644 --- a/doc/index.org +++ b/doc/index.org @@ -18,35 +18,72 @@ Goal: simplify/speed up understanding the computer program code by automatically visualizing its structure. -JavaInspect is a Java library that you can embed into your Java -project with a few lines of Maven configuration and then visualize any -part of your Java program structure with few simple JavaInspect API -calls at application runtime. - -JavaInspect uses Java reflection to discover class relations and -structure and produces GraphViz dot file that describes your -application. Then launches GraphViz to generate bitmap graph in PNG -format on your Desktop directory. - -* Current status -This is simple utility, quickly written. Tested on GNU Linux (can be -relatively simply ported to other operating systems too). So far I -used it for my own needs. There might be bugs and missing -features. Feedback and code contributions are welcome. +JavaInspect is a Java library that primarily uses Java reflection to +discover and visualize any part of Java program provided that +classes to be visualised are available in the classpath. -* Example graphs -Example visualization of [[http://www2.svjatoslav.eu/gitbrowse/sixth/doc/][Sixth]] project: [[http://www2.svjatoslav.eu/projects/sixth/codegraphs/][architecture graphs]]. - -A very simple example: +JavaInspect currently has no GUI, configuration files, embedded +scripting support, direct Maven or Ant integration. The only way to +instuct Javainspect what to do is by using its Java API. -[[file:example.png][file:example.resized.png]] +To get JavaInspect into same classpath with your projecs I so far came +up with 2 solutions: +1. Add JavaInspect library in your project as a dependency. +2. Create new Java project for the purpose visualizing your other + projects and include JavaInspect and your projecs binary artifacts + (Jar's) into new project classpath. Built binary Jar's (with no + source code) are sufficient because JavaInspect operates via + reflection. -Graph legend: +After discovering application structure and optionally filtering out +unimportant parts, JavaInspect produces GraphViz dot file that +describes data to be visualized. Then launches GraphViz to generate +bitmap graph in PNG format. By default on your Desktop directory. -file:legend.png +Note: GraphViz is developed and tested so far only on GNU Linux. -* Usage example 1 +* Example graphs ++ A very simple example: + + [[file:example.png][file:example.resized.png]] + + Graph legend: + + file:legend.png + ++ Example visualization of [[http://www2.svjatoslav.eu/gitbrowse/sixth/doc/][Sixth]] project: [[http://www2.svjatoslav.eu/projects/sixth/codegraphs/][architecture graphs]]. + +* Usage +Currently the only way to control JavaInspect is by using Java +API. Simple Java based control/configuration code needs to be written +for each project. I usually put such code into directories devoted for +JUnit tests. Because it needs not to be compiled/embedded into final +product or project artifact I'm just willing to visualize. + +Control code in general does the following: +1. Create graph object. +2. Java reflection/classloaders does not provide mechanism for + discovering all classes under given package. Therefore you need to + declare at least some classes to be added to the graph by: + + Manually adding individual classes to the graph. + + and/or: Let GraphViz recursively scan and parse specified + directories with Java source code files to discover class names. + + For every class added to the graph, GraphViz will recursively + inspect it and add all referecned classes to the graph as well. +3. Graphs easilly get very big and complex so optionally we filter + important code using classname wildcards patterns based blacklist + and/or whitelist. +4. Optionally we can tune some rendering parameters like: + + Possibility to remove orphaned classes (classes with no + references) from the graph. + + Specify target directory for generated visualization + files. (Default is user desktop directory) + + Keep intermediate GraphViz dot file for later inspection. +5. Render graph. + + +** example 1 This example demonstrates generating of class graph from hand picked classes. @@ -75,7 +112,7 @@ Result: - Generated DOT file: [[file:JavaInspect.dot][JavaInspect.dot]] - Generated PNG image: [[file:JavaInspect.png][JavaInspect.png]] -* Usage example 2 +** example 2 Recursively scan current directory for Java source code and attempt to detect class names from there to be added to the graph. diff --git a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java index cee1ee4..f3afd80 100755 --- a/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java +++ b/src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java @@ -33,6 +33,11 @@ public class ClassGraph { private final List whitelistClassPatterns = new ArrayList(); + private String targetDirectory = CommonPathResolver.getDesktopDirectory() + .getAbsolutePath() + "/"; + + private boolean keepDotFile; + public ClassGraph() { } @@ -78,35 +83,6 @@ public class ClassGraph { blacklistClassPatterns.add(pattern); } - /** - * @param resultFileName - * file name for the generated graph. Existing file with the same - * name will be overwritten. - */ - public void generateGraph(final String resultFileName) { - generateGraph(resultFileName, false); - } - - /** - * @param resultFileName - * file name for the generated graph. File extension will be - * added automatically. Existing file with the same name will be - * overwritten. - * - * @param keepDotFile - * if set to true then intermediary GraphViz DOT - * file will be kept. - */ - - public void generateGraph(final String resultFileName, - final boolean keepDotFile) { - - final String desktopPath = CommonPathResolver.getDesktopDirectory() - .getAbsolutePath() + "/"; - - generateGraph(desktopPath, resultFileName, keepDotFile); - } - /** * @param targetDirectory * target directory name @@ -121,11 +97,7 @@ public class ClassGraph { * file will be kept. */ - public void generateGraph(String targetDirectory, - final String resultFileName, final boolean keepDotFile) { - - if (!targetDirectory.endsWith("/")) - targetDirectory += "/"; + public void generateGraph(final String resultFileName) { final String dotFilePath = targetDirectory + resultFileName + ".dot"; final String imageFilePath = targetDirectory + resultFileName + ".png"; @@ -149,8 +121,7 @@ public class ClassGraph { if (!keepDotFile) { // delete dot file - final File dotFile = new File(dotFilePath); - dotFile.delete(); + new File(dotFilePath).delete(); } } catch (final IOException e) { System.err.println(e); @@ -210,7 +181,7 @@ public class ClassGraph { } - public boolean isClassShown(final String className) { + protected boolean isClassShown(final String className) { for (final String pattern : blacklistClassPatterns) if (WildCardMatcher.match(className, pattern)) return false; @@ -225,8 +196,25 @@ public class ClassGraph { return true; } - public void whitelistClassPattern(final String pattern) { + public ClassGraph setKeepDotFile(final boolean keepDotFile) { + this.keepDotFile = keepDotFile; + + return this; + } + + public ClassGraph setTargetDirectory(String directoryPath) { + if (!directoryPath.endsWith("/")) + directoryPath += "/"; + + targetDirectory = directoryPath; + + return this; + } + + public ClassGraph whitelistClassPattern(final String pattern) { whitelistClassPatterns.add(pattern); + + return this; } } diff --git a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java index 50f9c7e..a3f83ec 100755 --- a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java +++ b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderDemoClasses.java @@ -18,7 +18,7 @@ public class RenderDemoClasses { public static void main(final String[] args) { new ClassGraph().add(SampleClass.class, SampleClass2.class) - .generateGraph("example", false); + .generateGraph("example"); } } diff --git a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java index 2bfd560..181ac09 100755 --- a/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java +++ b/src/test/java/eu/svjatoslav/inspector/java/structure/example/RenderJavaInspect.java @@ -37,25 +37,22 @@ public class RenderJavaInspect { private static void handpickClassesExample() { /* * This example demonstrates generating of class graph from hand picked - * classes. + * classes and visualizing GraphViz itself. */ // Create graph final ClassGraph graph = new ClassGraph(); - // While classes and objects can be immediately passed to ClassGraph - // constructor as arguments, it is also possible to add then one by one - // as in the following example. - - // Add some object to the graph. + // Add some random object to the graph. GraphViz will detect Class from + // the object. graph.add(graph); - // Add some class to the graph. + // Add some random class to the graph. graph.add(Utils.class); // Produce bitmap image titled "JavaInspect.png" to the user Desktop // directory and keep intermediary GraphViz DOT file for reference. - graph.generateGraph("JavaInspect", true); + graph.setKeepDotFile(true).generateGraph("JavaInspect"); } public static void main(final String[] args) throws FileNotFoundException { -- 2.20.1