Added all important commandline options. Updated documentation.
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Tue, 26 Dec 2017 21:32:44 +0000 (23:32 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Tue, 26 Dec 2017 21:32:44 +0000 (23:32 +0200)
commandline launcher/javainspect
doc/index.html
doc/index.org
javainspect.iml
pom.xml
src/main/java/eu/svjatoslav/inspector/java/CommandlineConfiguration.java [deleted file]
src/main/java/eu/svjatoslav/inspector/java/Main.java
src/main/java/eu/svjatoslav/inspector/java/commandline/CommandlineConfiguration.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/inspector/java/commandline/TargetImageTypeParameter.java [new file with mode: 0644]
src/main/java/eu/svjatoslav/inspector/java/structure/ClassGraph.java
src/main/java/eu/svjatoslav/inspector/java/structure/TargetImageType.java

index 162f317..66c02c4 100755 (executable)
@@ -4,10 +4,4 @@
 #    http://www2.svjatoslav.eu/gitbrowse/javainspect/doc/
 #
 
-# Commandline parameters:
-# [JAR_FILE_PATH] [GRAPH_NAME] [[OPTIONS] ...]
-#
-#
-
-
-java -jar /opt/javainspect/javainspect.jar $@
+java -jar /opt/javainspect/javainspect.jar "$@"
index f011ad8..a9ae900 100644 (file)
@@ -2,7 +2,7 @@
 <html lang="en">
 <head>
 <title>JavaInspect - Utility to visualize java software</title>
-<!-- 2017-11-29 Wed 23:51 -->
+<!-- 2017-12-26 Tue 23:30 -->
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="generator" content="Org-mode">
@@ -206,10 +206,10 @@ it under the terms of version 3 of the <a href="https://www.gnu.org/licenses/lgp
 License</a> or later as published by the Free Software Foundation.
 </li>
 
-<li>Program author:
+<li>Program authors:
 <ul class="org-ul">
 <li>Svjatoslav Agejenko
-</li>
+<ul class="org-ul">
 <li>Homepage: <a href="http://svjatoslav.eu">http://svjatoslav.eu</a>
 </li>
 <li>Email: <a href="mailto://svjatoslav@svjatoslav.eu">mailto://svjatoslav@svjatoslav.eu</a>
@@ -217,6 +217,16 @@ License</a> or later as published by the Free Software Foundation.
 </ul>
 </li>
 
+<li>Tony Bargnesi
+<ul class="org-ul">
+<li>GitHub fork for the project:
+<a href="https://github.com/abargnesi/javainspect">https://github.com/abargnesi/javainspect</a>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+
 <li><a href="http://www.svjatoslav.eu/programs.jsp">other applications hosted at svjatoslav.eu</a>
 </li>
 </ul>
@@ -230,38 +240,27 @@ automatically visualizing its structure.
 </p>
 
 <p>
-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 is a Java library/commandline utility that primarily uses
+Java reflection to discover and visualize any part of Java program.
 </p>
 
 <p>
 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.
+scripting support, direct Maven or Ant integration. See <a href="#sec-3">usage</a> to learn
+how to instuct Javainspect what to do.
 </p>
 
-<p>
-To get JavaInspect into same classpath with your projecs I so far came
-up with 2 solutions:
-</p>
-
-<ol class="org-ol">
-<li>Add JavaInspect library in your project as a dependency.
-</li>
-<li>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.
-</li>
-</ol>
-
 <p>
 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.
+bitmap graph in PNG or SVG format.
+</p>
+
+<p>
+By default on your Desktop directory when operated in library mode or
+current working directory when operated as standalone commandline
+application.
 </p>
 
 <p>
@@ -300,12 +299,93 @@ Graph legend:
 </div>
 
 <div id="outline-container-sec-3" class="outline-2">
-<h2 id="sec-3"><span class="section-number-2">3</span> Usage</h2>
+<h2 id="sec-3"><a id="ID-2ad2889e-6c95-4662-b3f4-2c341fc74522" name="ID-2ad2889e-6c95-4662-b3f4-2c341fc74522"></a><span class="section-number-2">3</span> Usage</h2>
 <div class="outline-text-2" id="text-3">
 <p>
-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
+JavaInspect can be controlled in 2 different ways:
+</p>
+<ul class="org-ul">
+<li><a href="#sec-3-1">as standalone commandline utility</a>
+</li>
+<li><a href="#sec-3-2">as embedded Java library via Java API</a>
+</li>
+</ul>
+</div>
+
+<div id="outline-container-sec-3-1" class="outline-3">
+<h3 id="sec-3-1"><a id="ID-acf1896a-74b4-4914-acf6-a77075e07f25" name="ID-acf1896a-74b4-4914-acf6-a77075e07f25"></a><span class="section-number-3">3.1</span> usage as commandline utility</h3>
+<div class="outline-text-3" id="text-3-1">
+<p>
+To enable commandline support, (study and) execute script:
+</p>
+<pre class="example">
+commandline launcher/install
+</pre>
+
+<p>
+Warning: It was tested only on Debian Stretch linux.
+</p>
+
+<p>
+Available commandline arguments:
+</p>
+<p class="verse">
+-j (existing files)&#x2026;<br >
+&#xa0;&#xa0;&#xa0;&#xa0;JAR file(s) to render.<br >
+<br >
+-n (mandatory, string)<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Graph name.<br >
+<br >
+&#x2013;debug<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Show debug info.<br >
+<br >
+-k<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Keep dot file.<br >
+<br >
+-h<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Hide orphaned classes.<br >
+<br >
+-w (one to many strings)&#x2026;<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Whitelist glob(s).<br >
+<br >
+-b (one to many strings)&#x2026;<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Blacklist glob(s).<br >
+<br >
+-d (existingdirectory)<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Target directory. Default is current directory.<br >
+<br >
+-t (options: png, svg)<br >
+&#xa0;&#xa0;&#xa0;&#xa0;Target image type. Default is: svg.<br >
+</p>
+</div>
+</div>
+<div id="outline-container-sec-3-2" class="outline-3">
+<h3 id="sec-3-2"><a id="ID-bbeeffc8-3767-440d-8d93-ec9124dd60ee" name="ID-bbeeffc8-3767-440d-8d93-ec9124dd60ee"></a><span class="section-number-3">3.2</span> usage via Java API</h3>
+<div class="outline-text-3" id="text-3-2">
+<p>
+Requires that classes to be visualised are available in the classpath.
+</p>
+
+<p>
+To get JavaInspect into same classpath with your projecs I so far came
+up with 2 solutions:
+</p>
+
+<ol class="org-ol">
+<li>Add JavaInspect library in your project as a dependency.
+</li>
+
+<li>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.
+</li>
+</ol>
+
+<p>
+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.
 </p>
@@ -352,9 +432,9 @@ files. (Default is user desktop directory)
 </div>
 
 
-<div id="outline-container-sec-3-1" class="outline-3">
-<h3 id="sec-3-1"><span class="section-number-3">3.1</span> example 1: individually picked objects</h3>
-<div class="outline-text-3" id="text-3-1">
+<div id="outline-container-sec-3-2-1" class="outline-4">
+<h4 id="sec-3-2-1"><span class="section-number-4">3.2.1</span> example 1: individually picked objects</h4>
+<div class="outline-text-4" id="text-3-2-1">
 <p>
 This example demonstrates generating of class graph from hand picked
 classes and visualizing GraphViz itself.
@@ -404,9 +484,9 @@ Result:
 </div>
 </div>
 
-<div id="outline-container-sec-3-2" class="outline-3">
-<h3 id="sec-3-2"><span class="section-number-3">3.2</span> example 2: scan java code, apply filters</h3>
-<div class="outline-text-3" id="text-3-2">
+<div id="outline-container-sec-3-2-2" class="outline-4">
+<h4 id="sec-3-2-2"><span class="section-number-4">3.2.2</span> example 2: scan java code, apply filters</h4>
+<div class="outline-text-4" id="text-3-2-2">
 <div class="org-src-container">
 
 <pre class="src src-java"><span style="color: #8C8C8C;">// </span><span style="color: #8C8C8C;">Create graph</span>
@@ -437,9 +517,9 @@ Result:
 </div>
 </div>
 
-<div id="outline-container-sec-3-3" class="outline-3">
-<h3 id="sec-3-3"><span class="section-number-3">3.3</span> example 3: GraphViz embedded in another project</h3>
-<div class="outline-text-3" id="text-3-3">
+<div id="outline-container-sec-3-2-3" class="outline-4">
+<h4 id="sec-3-2-3"><span class="section-number-4">3.2.3</span> example 3: GraphViz embedded in another project</h4>
+<div class="outline-text-4" id="text-3-2-3">
 <ol class="org-ol">
 <li>Download project Sixth <a href="http://www2.svjatoslav.eu/gitweb/?p=sixth.git;a=snapshot;h=HEAD;sf=tgz">code snapshot</a>.
 </li>
@@ -448,11 +528,10 @@ Result:
 </ol>
 </div>
 </div>
-</div>
 
-<div id="outline-container-sec-4" class="outline-2">
-<h2 id="sec-4"><span class="section-number-2">4</span> Embedding JavaInspect in your Maven project</h2>
-<div class="outline-text-2" id="text-4">
+<div id="outline-container-sec-3-2-4" class="outline-4">
+<h4 id="sec-3-2-4"><span class="section-number-4">3.2.4</span> Embedding JavaInspect in your Maven project</h4>
+<div class="outline-text-4" id="text-3-2-4">
 <p>
 Declare JavaInspect as dependency:
 </p>
@@ -489,10 +568,12 @@ Add Maven repository to retrieve artifact from:
 </div>
 </div>
 </div>
+</div>
+</div>
 
-<div id="outline-container-sec-5" class="outline-2">
-<h2 id="sec-5"><span class="section-number-2">5</span> Requirements</h2>
-<div class="outline-text-2" id="text-5">
+<div id="outline-container-sec-4" class="outline-2">
+<h2 id="sec-4"><span class="section-number-2">4</span> Requirements</h2>
+<div class="outline-text-2" id="text-4">
 <p>
 <a href="http://www.graphviz.org/">GraphViz</a> - shall be installed on the computer.
 </p>
@@ -507,38 +588,121 @@ On Ubuntu/Debian use:
 </div>
 </div>
 </div>
-<div id="outline-container-sec-6" class="outline-2">
-<h2 id="sec-6"><span class="section-number-2">6</span> TO DO</h2>
-<div class="outline-text-2" id="text-6">
+<div id="outline-container-sec-5" class="outline-2">
+<h2 id="sec-5"><span class="section-number-2">5</span> TO DO</h2>
+<div class="outline-text-2" id="text-5">
+<p>
+Note: Because this is side project (and I have many of them) I can
+only contribute few hours per year at average. Any help is welcome.  A
+LOT of cool ideas could be implemented. For intstance:
+</p>
+
+<ul class="org-ul">
+<li>BUG: Should not hide references if there are too many of them to
+classes if referring classes are not visible anyway because of
+blacklist/whitelist rules. Basically reference counting should
+exclude not visible classes.
+</li>
+
+<li>BUG: Orphaned class removal does not work always. There are many
+bugs and corner cases to find and fix still.
+</li>
+
+<li>BUG: Code is not very readable. Document and refactor for better
+maintainability.
+</li>
+
+<li>FEATURE: Create installable DEB package.
+<ul class="org-ul">
+<li>Submit it to some Debian developer for integration or become
+Debian package maintainer.
+</li>
+</ul>
+</li>
+
+<li>FEATURE: Make it modular. That is: central part, an application
+model could be standalone and serializable.
+
 <ul class="org-ul">
-<li>BUG: Should not hide references if there are too many of them to classes if
-referring classes are not visible anyway because of blacklist/whitelist rules.
-Basically reference counting should exclude not visible classes.
+<li>There could be multiple ways to acquire model:
+<ul class="org-ul">
+<li>By introspecting application via Java reflections (current mode
+of operation).
+</li>
+<li>By parsing java source. (unfinished)
+</li>
+</ul>
+</li>
+
+<li>There could be ways to manipulate model:
+<ul class="org-ul">
+<li>Store/load/compare.
+</li>
+<li>Trim uninteresting parts.
+</li>
+<li>Highlight important parts.
+</li>
+</ul>
+</li>
+
+<li>There could be multiple ways to render model:
+<ul class="org-ul">
+<li>PNG/SVG (currently implemented)
+</li>
+<li>PlantUML (TODO)
+</li>
+<li>Interactive 3D visualization (TODO)
+</li>
+</ul>
 </li>
-<li>FEATURE: integarte with <a href="http://plantuml.com/class-diagram">PlantUML</a>.
+</ul>
 </li>
-<li>FEATURE: add dark theme
+
+<li>FEATURE: Replace internal java parser in package
+eu.svjatoslav.inspector.java.methods with: <a href="https://javaparser.org/">https://javaparser.org/</a>
 </li>
-<li>FEATURE: sort Class fields by alphabet
+
+<li>FEATURE: Integarte with <a href="http://plantuml.com/class-diagram">PlantUML</a>.
 </li>
-<li>FEATURE: visualize also concrete field values so it could be used as
-ultra cool runtime logging framework
+
+<li>FEATURE: Add dark theme for generated graphs.
 </li>
-<li>FEATURE: possibility to visualize structure and data from JVM
-snapshot
+
+<li>FEATURE: Sort Class fields by alphabet.
+</li>
+
+<li>FEATURE: Visualize also concrete field values so it could be used as
+ultra cool runtime logging/debugging framework.
 </li>
-<li>FEATURE: possibility to attach to remote process to visualize
+
+<li>FEATURE: Possibility to visualize structure and data from JVM
+snapshot.
+</li>
+
+<li>FEATURE: Possibility to attach to remote process to visualize
 data/structure using JVM debug port and mechanism.
 </li>
-<li>FEATURE: possibility to attach to JVM using JVM agent
+
+<li>FEATURE: Possibility to attach to JVM using JVM agent.
+</li>
+
+<li>FEATURE: Possibility to inspect graphs in 3D using <a href="http://www2.svjatoslav.eu/gitbrowse/sixth-3d/doc/index.html">Sixth 3D engine</a>.
 </li>
-<li>FEATURE: possibility to script javainspect behavior
+
+<li>FEATURE: Possibility to select classes/fields/values to be
+visualized in some graph query language. For greater flexibility in
+comparison to currently supported glob syntax.
 </li>
-<li>FEATURE: possibility to select classes/fields/values to be
-visualized in SQL like syntax
+
+<li>FEATURE: Add option to control JavaInspect via JSON or XML config
+file. For example different graphs for given project could be
+defined once in plain text config, possibly with the aid of some
+interactive utility. Then defined graphs could be updated as part of
+project build or release process.
 </li>
-<li>FEATURE: configurable maven plugin to generate graphs as part of the
-project build/release process
+
+<li>FEATURE: Configurable maven plugin to generate graphs as part of the
+project build/release process.
 </li>
 </ul>
 </div>
@@ -550,21 +714,19 @@ project build/release process
 <li><a href="#sec-2">2. Example graphs</a></li>
 <li><a href="#sec-3">3. Usage</a>
 <ul class="nav">
-<li><a href="#sec-3-1">3.1. example 1: individually picked objects</a></li>
-<li><a href="#sec-3-2">3.2. example 2: scan java code, apply filters</a></li>
-<li><a href="#sec-3-3">3.3. example 3: GraphViz embedded in another project</a></li>
+<li><a href="#sec-3-1">3.1. usage as commandline utility</a></li>
+<li><a href="#sec-3-2">3.2. usage via Java API</a></li>
 </ul>
 </li>
-<li><a href="#sec-4">4. Embedding JavaInspect in your Maven project</a></li>
-<li><a href="#sec-5">5. Requirements</a></li>
-<li><a href="#sec-6">6. TO DO</a></li>
+<li><a href="#sec-4">4. Requirements</a></li>
+<li><a href="#sec-5">5. TO DO</a></li>
 </ul>
 </div>
 </nav>
 </div></div></div>
 <footer id="postamble" class="">
 <div><p class="author">Author: Svjatoslav Agejenko</p>
-<p class="date">Created: 2017-11-29 Wed 23:51</p>
+<p class="date">Created: 2017-12-26 Tue 23:30</p>
 <p class="creator"><a href="http://www.gnu.org/software/emacs/">Emacs</a> 25.1.1 (<a href="http://orgmode.org">Org-mode</a> 8.2.10)</p>
 </div>
 </footer>
index 09f1266..eb25b72 100644 (file)
 Goal: simplify/speed up understanding the computer program code by
 automatically visualizing its structure.
 
-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 is a Java library/commandline utility that primarily uses
+Java reflection to discover and visualize any part of Java program.
 
 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.
-
-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.
+scripting support, direct Maven or Ant integration. See [[id:2ad2889e-6c95-4662-b3f4-2c341fc74522][usage]] to learn
+how to instuct Javainspect what to do.
 
 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.
+bitmap graph in PNG or SVG format.
+
+By default on your Desktop directory when operated in library mode or
+current working directory when operated as standalone commandline
+application.
 
 Note: GraphViz is developed and tested so far only on GNU/Linux.
 
@@ -69,9 +62,70 @@ Note: GraphViz is developed and tested so far only on GNU/Linux.
 + Example visualization of [[http://www2.svjatoslav.eu/gitbrowse/sixth-3d/doc/][Sixth 3D]] project: [[http://www2.svjatoslav.eu/gitbrowse/sixth-3d/doc/codeGraph/][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
+  :PROPERTIES:
+  :ID:       2ad2889e-6c95-4662-b3f4-2c341fc74522
+  :END:
+JavaInspect can be controlled in 2 different ways:
++ [[id:acf1896a-74b4-4914-acf6-a77075e07f25][as standalone commandline utility]]
++ [[id:bbeeffc8-3767-440d-8d93-ec9124dd60ee][as embedded Java library via Java API]]
+
+** usage as commandline utility
+   :PROPERTIES:
+   :ID:       acf1896a-74b4-4914-acf6-a77075e07f25
+   :END:
+To enable commandline support, (study and) execute script:
+: commandline launcher/install
+
+Warning: It was tested only on Debian Stretch linux.
+
+Available commandline arguments:
+#+BEGIN_VERSE
+-j (existing files)...
+    JAR file(s) to render.
+
+-n (mandatory, string)
+    Graph name.
+
+--debug
+    Show debug info.
+
+-k
+    Keep dot file.
+
+-h
+    Hide orphaned classes.
+
+-w (one to many strings)...
+    Whitelist glob(s).
+
+-b (one to many strings)...
+    Blacklist glob(s).
+
+-d (existingdirectory)
+    Target directory. Default is current directory.
+
+-t (options: png, svg)
+    Target image type. Default is: svg.
+#+END_VERSE
+** usage via Java API
+   :PROPERTIES:
+   :ID:       bbeeffc8-3767-440d-8d93-ec9124dd60ee
+   :END:
+Requires that classes to be visualised are available in the classpath.
+
+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.
+
+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.
 
@@ -97,7 +151,7 @@ Control code in general does the following:
 5. Render graph.
 
 
-** example 1: individually picked objects
+*** example 1: individually picked objects
 This example demonstrates generating of class graph from hand picked
 classes and visualizing GraphViz itself.
 
@@ -133,7 +187,7 @@ Result:
     - Generated DOT file: [[file:JavaInspect.dot][JavaInspect.dot]]
     - Generated PNG image: [[file:JavaInspect.png][JavaInspect.png]]
 
-** example 2: scan java code, apply filters
+*** example 2: scan java code, apply filters
 #+BEGIN_SRC java
 // Create graph
 final ClassGraph graph = new ClassGraph();
@@ -155,11 +209,11 @@ graph.generateGraph("JavaInspect full project");
 Result:
     - Generated PNG image: [[file:JavaInspect%20full%20project.png][JavaInspect full project.png]]
 
-** example 3: GraphViz embedded in another project
+*** example 3: GraphViz embedded in another project
 1. Download project Sixth [[http://www2.svjatoslav.eu/gitweb/?p=sixth.git;a=snapshot;h=HEAD;sf=tgz][code snapshot]].
 2. Inspect and run *DataGraph.java*.
 
-* Embedding JavaInspect in your Maven project
+*** Embedding JavaInspect in your Maven project
 
 Declare JavaInspect as dependency:
 #+BEGIN_SRC xml
@@ -196,23 +250,74 @@ On Ubuntu/Debian use:
 sudo apt-get install graphviz
 #+END_SRC
 * TO DO
-- BUG: Should not hide references if there are too many of them to classes if
-  referring classes are not visible anyway because of blacklist/whitelist rules.
-  Basically reference counting should exclude not visible classes.
-- FEATURE: replace internal java parser in package
+Note: Because this is side project (and I have many of them) I can
+only contribute few hours per year at average. Any help is welcome.  A
+LOT of cool ideas could be implemented. For intstance:
+
+- BUG: Should not hide references if there are too many of them to
+  classes if referring classes are not visible anyway because of
+  blacklist/whitelist rules. Basically reference counting should
+  exclude not visible classes.
+
+- BUG: Orphaned class removal does not work always. There are many
+  bugs and corner cases to find and fix still.
+
+- BUG: Code is not very readable. Document and refactor for better
+  maintainability.
+
+- FEATURE: Create installable DEB package.
+  - Submit it to some Debian developer for integration or become
+    Debian package maintainer.
+
+- FEATURE: Make it modular. That is: central part, an application
+  model could be standalone and serializable.
+
+  - There could be multiple ways to acquire model:
+    - By introspecting application via Java reflections (current mode
+      of operation).
+    - By parsing java source. (unfinished)
+
+  - There could be ways to manipulate model:
+    - Store/load/compare.
+    - Trim uninteresting parts.
+    - Highlight important parts.
+
+  - There could be multiple ways to render model:
+    - PNG/SVG (currently implemented)
+    - PlantUML (TODO)
+    - Interactive 3D visualization (TODO)
+
+- FEATURE: Replace internal java parser in package
   eu.svjatoslav.inspector.java.methods with: https://javaparser.org/
-- FEATURE: integarte with [[http://plantuml.com/class-diagram][PlantUML]].
-- FEATURE: add dark theme
-- FEATURE: sort Class fields by alphabet
-- FEATURE: visualize also concrete field values so it could be used as
-  ultra cool runtime logging framework
-- FEATURE: possibility to visualize structure and data from JVM
-  snapshot
-- FEATURE: possibility to attach to remote process to visualize
+
+- FEATURE: Integarte with [[http://plantuml.com/class-diagram][PlantUML]].
+
+- FEATURE: Add dark theme for generated graphs.
+
+- FEATURE: Sort Class fields by alphabet.
+
+- FEATURE: Visualize also concrete field values so it could be used as
+  ultra cool runtime logging/debugging framework.
+
+- FEATURE: Possibility to visualize structure and data from JVM
+  snapshot.
+
+- FEATURE: Possibility to attach to remote process to visualize
   data/structure using JVM debug port and mechanism.
-- FEATURE: possibility to attach to JVM using JVM agent
-- FEATURE: possibility to script javainspect behavior
-- FEATURE: possibility to select classes/fields/values to be
-  visualized in SQL like syntax
-- FEATURE: configurable maven plugin to generate graphs as part of the
-  project build/release process
+
+- FEATURE: Possibility to attach to JVM using JVM agent.
+
+- FEATURE: Possibility to inspect graphs in 3D using [[http://www2.svjatoslav.eu/gitbrowse/sixth-3d/doc/index.html][Sixth 3D engine]].
+
+- FEATURE: Possibility to select classes/fields/values to be
+  visualized in some graph query language. For greater flexibility in
+  comparison to currently supported glob syntax.
+
+- FEATURE: Add option to control JavaInspect via JSON or XML config
+  file. For example different graphs for given project could be
+  defined once in plain text config, possibly with the aid of some
+  interactive utility. Then defined graphs could be updated as part of
+  project build or release process.
+
+- FEATURE: Configurable maven plugin to generate graphs as part of the
+  project build/release process.
index 43da783..854d268 100644 (file)
@@ -11,6 +11,6 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="Maven: eu.svjatoslav:svjatoslavcommons:1.7-SNAPSHOT" level="project" />
+    <orderEntry type="library" name="Maven: eu.svjatoslav:svjatoslavcommons:1.7" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6614ca1..0a9bf25 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         <dependency>
             <groupId>eu.svjatoslav</groupId>
             <artifactId>svjatoslavcommons</artifactId>
-            <version>1.7-SNAPSHOT</version>
+            <version>1.7</version>
         </dependency>
     </dependencies>
 
diff --git a/src/main/java/eu/svjatoslav/inspector/java/CommandlineConfiguration.java b/src/main/java/eu/svjatoslav/inspector/java/CommandlineConfiguration.java
deleted file mode 100644 (file)
index cb9e4fc..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package eu.svjatoslav.inspector.java;
-
-import eu.svjatoslav.commons.commandline.parameterparser.Parser;
-import eu.svjatoslav.commons.commandline.parameterparser.parameter.FileParameters;
-import eu.svjatoslav.commons.commandline.parameterparser.parameter.NullParameter;
-import eu.svjatoslav.commons.commandline.parameterparser.parameter.StringParameter;
-import eu.svjatoslav.commons.commandline.parameterparser.parameter.StringParameters;
-
-public class CommandlineConfiguration {
-
-    public FileParameters jarFiles;
-    public StringParameter graphName;
-    private NullParameter showDebug;
-
-    public CommandlineConfiguration(String args[]) {
-        Parser parser = buildCommandlineParameterParser();
-        if (!parser.parse(args)) {
-            parser.showHelp();
-        }
-
-    }
-
-    public boolean isDebug() {
-        return showDebug.isSpecified();
-    }
-
-    public Parser buildCommandlineParameterParser() {
-        Parser parser = new Parser();
-
-        jarFiles = parser.add(
-                new FileParameters("JAR file(s)"))
-                .mustExist()
-                .addAliases("-j");
-
-        graphName = parser.add(
-                new StringParameter("graph name"))
-                .setMandatory()
-                .addAliases("-n");
-
-        showDebug = parser.add(
-                new NullParameter("show debug info"))
-                .addAliases("-d");
-
-        parser.add(
-                new StringParameters("whitelist glob"))
-                .addAliases("-w");
-
-        parser.add(
-                new StringParameters("blacklist glob"))
-                .addAliases("-b");
-
-        return parser;
-    }
-
-}
index 4f6bfbf..9b706d3 100644 (file)
@@ -1,5 +1,6 @@
 package eu.svjatoslav.inspector.java;
 
+import eu.svjatoslav.inspector.java.commandline.CommandlineConfiguration;
 import eu.svjatoslav.inspector.java.structure.ClassGraph;
 
 import java.io.File;
@@ -22,7 +23,16 @@ import static java.lang.System.getProperty;
 public class Main {
     public static void main(String[] args) throws IOException, ClassNotFoundException {
         CommandlineConfiguration configuration = new CommandlineConfiguration(args);
+        if (!configuration.configurationOk)
+            System.exit(1);
+            
+        getClassGraph(configuration).generateGraph(configuration.graphName.getValue());
 
+        if (configuration.isDebug())
+            System.out.println("Graph ready.");
+    }
+
+    private static ClassGraph getClassGraph(CommandlineConfiguration configuration) throws IOException, ClassNotFoundException {
         List<File> jarFiles = configuration.jarFiles.getValue();
 
         URLClassLoader classLoader = new URLClassLoader(
@@ -30,16 +40,32 @@ public class Main {
                 configuration.getClass().getClassLoader());
 
         ClassGraph classGraph = new ClassGraph();
-        classGraph.setTargetDirectoryPath(getProperty("user.dir") + separator);
-        classGraph.setKeepDotFile(true);
+
+        classGraph.setTargetDirectory(getTargetDirectory(configuration));
+
+        if (configuration.targetImageType.isSpecified())
+            classGraph.setTargetImageType(configuration.targetImageType.getValue());
+
+        classGraph.setKeepDotFile(configuration.keepDotFile.getValue());
 
         for (File jarFile : jarFiles)
             addJarToGraph(jarFile, classLoader, classGraph, configuration);
 
-        classGraph.generateGraph(configuration.graphName.getValue());
+        configuration.blacklistGlob.getValue().forEach(classGraph::blacklistClassGlob);
+        configuration.whitelistGlob.getValue().forEach(classGraph::whitelistClassGlob);
 
-        if (configuration.isDebug())
-            System.out.println("Graph ready.");
+        if (configuration.hideOrphanedClasses.getValue())
+            classGraph.hideOrphanedClasses();
+
+        return classGraph;
+    }
+
+    private static File getTargetDirectory(CommandlineConfiguration configuration) {
+        if (configuration.targetDirectory.isSpecified())
+            return configuration.targetDirectory.getValue();
+
+        // default to current directory
+        return new File(getProperty("user.dir") + separator);
     }
 
     private static URL[] getFileUrls(List<File> jarFiles) {
diff --git a/src/main/java/eu/svjatoslav/inspector/java/commandline/CommandlineConfiguration.java b/src/main/java/eu/svjatoslav/inspector/java/commandline/CommandlineConfiguration.java
new file mode 100644 (file)
index 0000000..933a95d
--- /dev/null
@@ -0,0 +1,72 @@
+package eu.svjatoslav.inspector.java.commandline;
+
+import eu.svjatoslav.commons.commandline.parameterparser.Parser;
+import eu.svjatoslav.commons.commandline.parameterparser.parameter.*;
+
+public class CommandlineConfiguration {
+
+    public FileParameters jarFiles;
+    public StringParameter graphName;
+    private NullParameter showDebug;
+    public StringParameters whitelistGlob;
+    public StringParameters blacklistGlob;
+    public TargetImageTypeParameter targetImageType;
+    public NullParameter keepDotFile;
+    public DirectoryParameter targetDirectory;
+    public final boolean configurationOk;
+    public NullParameter hideOrphanedClasses;
+
+    public CommandlineConfiguration(String args[]) {
+        Parser parser = buildCommandlineParameterParser();
+        configurationOk = parser.parse(args);
+        if (!configurationOk)
+            parser.showHelp();
+    }
+
+    public boolean isDebug() {
+        return showDebug.isSpecified();
+    }
+
+    public Parser buildCommandlineParameterParser() {
+        Parser parser = new Parser();
+
+        jarFiles = parser.add(
+                new FileParameters("JAR file(s) to render."))
+                .mustExist()
+                .addAliases("-j");
+
+        graphName = parser.add(
+                new StringParameter("Graph name."))
+                .setMandatory()
+                .addAliases("-n");
+
+        showDebug = parser.add(
+                new NullParameter("Show debug info."))
+                .addAliases("--debug");
+
+        keepDotFile = parser.add(
+                new NullParameter("Keep dot file."))
+                .addAliases("-k");
+
+        hideOrphanedClasses = parser.add(
+                new NullParameter("Hide orphaned classes."))
+                .addAliases("-h");
+
+        whitelistGlob = parser.add(
+                new StringParameters("Whitelist glob(s)."))
+                .addAliases("-w");
+
+        blacklistGlob = parser.add(
+                new StringParameters("Blacklist glob(s)."))
+                .addAliases("-b");
+
+        targetDirectory = parser.add(new DirectoryParameter("Target directory. " +
+                "Default is current directory.").mustExist())
+                .addAliases("-d");
+
+        targetImageType = parser.add(new TargetImageTypeParameter()).addAliases("-t");
+
+        return parser;
+    }
+
+}
diff --git a/src/main/java/eu/svjatoslav/inspector/java/commandline/TargetImageTypeParameter.java b/src/main/java/eu/svjatoslav/inspector/java/commandline/TargetImageTypeParameter.java
new file mode 100644 (file)
index 0000000..7151b8a
--- /dev/null
@@ -0,0 +1,43 @@
+package eu.svjatoslav.inspector.java.commandline;
+
+import eu.svjatoslav.commons.commandline.parameterparser.ArgumentCount;
+import eu.svjatoslav.commons.commandline.parameterparser.Parameter;
+import eu.svjatoslav.commons.string.String2;
+import eu.svjatoslav.inspector.java.structure.TargetImageType;
+
+import java.util.Arrays;
+
+public class TargetImageTypeParameter extends Parameter<TargetImageType, TargetImageTypeParameter> {
+
+    public TargetImageTypeParameter(){
+        super("Target image type. Default is: svg.", ArgumentCount.SINGLE);
+    }
+
+    @Override
+    public String describeFormat() {
+        String2 result = new String2("");
+
+        Arrays.stream(TargetImageType.values())
+                .forEach(targetImageType -> result.addSuffix(", ", targetImageType.fileExtension));
+
+        result.addPrefix("options: ");
+
+        return result.toString();
+    }
+
+    @Override
+    public TargetImageType getValue() {
+        return TargetImageType.valueOf(arguments.get(0).toUpperCase());
+    }
+
+    @Override
+    public boolean validate(String value) {
+        try {
+            TargetImageType.valueOf(value.toUpperCase());
+        } catch (final IllegalArgumentException exception) {
+            return false;
+        }
+
+        return true;
+    }
+}
index 1747614..ce22d26 100755 (executable)
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Map;
 
 import static eu.svjatoslav.inspector.java.methods.JavaFile.UTF_8;
-import static java.io.File.separator;
 
 public class ClassGraph {
 
@@ -36,8 +35,7 @@ public class ClassGraph {
 
     private final List<String> whitelistClassGlobs = new ArrayList<>();
     TargetImageType targetImageType = TargetImageType.SVG;
-    private String targetDirectoryPath = CommonPathResolver.getDesktopDirectory()
-            .getAbsolutePath() + separator;
+    private File targetDirectory = CommonPathResolver.getDesktopDirectory();
     private boolean keepDotFile;
 
     public ClassGraph() {
@@ -96,27 +94,30 @@ public class ClassGraph {
 
     public void generateGraph(final String resultFileName) {
 
-        final String dotFilePath = targetDirectoryPath + resultFileName + ".dot";
-        final String imageFilePath = targetDirectoryPath + resultFileName + "." + targetImageType.fileExtension;
+        final File dotFile = new File(targetDirectory, resultFileName + ".dot");
+        final File imageFile = new File(targetDirectory, resultFileName + "." + targetImageType.fileExtension);
 
         try {
             // write DOT file to disk
-            final PrintWriter out = new PrintWriter(dotFilePath, UTF_8);
+            final PrintWriter out = new PrintWriter(dotFile, UTF_8);
             out.write(getDot());
             out.close();
 
             // execute GraphViz to visualize graph
             try {
                 Runtime.getRuntime()
-                        .exec(new String[]{"dot", "-T" + targetImageType.fileExtension, dotFilePath, "-o",
-                                imageFilePath}).waitFor();
+                        .exec(new String[]{"dot",
+                                "-T" + targetImageType.fileExtension,
+                                dotFile.getAbsolutePath(),
+                                "-o",
+                                imageFile.getAbsolutePath()}).waitFor();
             } catch (final InterruptedException ignored) {
             }
 
             if (!keepDotFile)
                 // delete dot file
-                if (!new File(dotFilePath).delete())
-                    throw new RuntimeException("Cannot delete file: " + dotFilePath);
+                if (!dotFile.delete())
+                    throw new RuntimeException("Cannot delete file: " + dotFile.getAbsolutePath());
 
         } catch (final IOException e) {
             throw new RuntimeException("Unable to generate graph: " + e.getMessage(), e);
@@ -199,12 +200,8 @@ public class ClassGraph {
         return this;
     }
 
-    public ClassGraph setTargetDirectoryPath(String directoryPath) {
-        if (!directoryPath.endsWith(separator))
-            directoryPath += separator;
-
-        targetDirectoryPath = directoryPath;
-
+    public ClassGraph setTargetDirectory(File targetDirectory) {
+        this.targetDirectory = targetDirectory;
         return this;
     }
 
index c1baf93..53f9690 100644 (file)
@@ -9,4 +9,5 @@ public enum TargetImageType {
     TargetImageType(String fileExtension) {
         this.fileExtension = fileExtension;
     }
+
 }