Possibility to visualize multiple JAR files.
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / Main.java
index d651d2e..58963ff 100644 (file)
@@ -3,9 +3,15 @@ package eu.svjatoslav.inspector.java;
 import eu.svjatoslav.inspector.java.structure.ClassGraph;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
 
 import static java.io.File.separator;
 import static java.lang.System.getProperty;
@@ -14,26 +20,81 @@ import static java.lang.System.getProperty;
  * This class acts as a commandline interface for JavaInspect.
  */
 public class Main {
-       public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
-        CommandlineConfiguration commandlineConfiguration = new CommandlineConfiguration(args);
-        System.out.println("Commandline config validated");
+    public static void main(String[] args) throws IOException, ClassNotFoundException {
+        CommandlineConfiguration configuration = new CommandlineConfiguration(args);
 
-        File jarFile = commandlineConfiguration.jarFile.getValue();
+        List<File> jarFiles = configuration.jarFiles.getValue();
 
         URLClassLoader classLoader = new URLClassLoader(
-                new URL[]{jarFile.toURL()},
-                commandlineConfiguration.getClass().getClassLoader());
+                getFileUrls(jarFiles),
+                configuration.getClass().getClassLoader());
 
-        Class classToLoad = Class.forName("eu.svjatoslav.sixth.e3d.gui.GuiComponent", true, classLoader);
+        ClassGraph classGraph = new ClassGraph();
+        classGraph.setTargetDirectoryPath(getProperty("user.dir") + separator);
+        classGraph.setKeepDotFile(true);
 
+        for (File jarFile : jarFiles)
+            addJarToGraph(jarFile, classLoader, classGraph, configuration);
 
-               ClassGraph cg = new ClassGraph();
-               cg.setTargetDirectoryPath(getProperty("user.dir") + separator);
+        classGraph.generateGraph(configuration.graphName.getValue());
 
-//             cg.addProject(projectDir);
-//             cg.whitelistClassGlob(packageGlob);
-               cg.setKeepDotFile(true);
-               cg.add(classToLoad);
-               cg.generateGraph(commandlineConfiguration.graphName.getValue());
-       }
+        if (configuration.isDebug())
+            System.out.println("Graph ready.");
+    }
+
+    private static URL[] getFileUrls(List<File> jarFiles) {
+        List<URL> urls = new ArrayList<>();
+        jarFiles.forEach((File file) -> {
+            try {
+                urls.add(file.toURI().toURL());
+            } catch (MalformedURLException e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        return urls.toArray(new URL[urls.size()]);
+    }
+
+    private static void addJarToGraph(
+            File jarFile, URLClassLoader classLoader, ClassGraph classGraph, CommandlineConfiguration configuration)
+            throws IOException, ClassNotFoundException {
+
+        for (String className : getClassNamesFromJar(jarFile)) {
+            if (configuration.isDebug())
+                System.out.println("Adding class to graph: " + className);
+
+            classGraph.add(loadClassByName(classLoader, className));
+        }
+    }
+
+    private static Class loadClassByName(URLClassLoader classLoader, String className) throws ClassNotFoundException {
+        return Class.forName(className, true, classLoader);
+    }
+
+    public static List<String> getClassNamesFromJar(File jarFile) throws IOException {
+        List<String> result = new ArrayList<>();
+        try (
+                JarInputStream jarInputStream = new JarInputStream(new FileInputStream(jarFile));
+        ) {
+            while (true) {
+                JarEntry jarEntry = jarInputStream.getNextJarEntry();
+                if (jarEntry == null)
+                    break;
+
+                if (isClassFile(jarEntry))
+                    result.add(getClassNameFromFileName(jarEntry));
+            }
+
+            return result;
+        }
+    }
+
+    private static boolean isClassFile(JarEntry jarEntry) {
+        return jarEntry.getName().endsWith(".class");
+    }
+
+    private static String getClassNameFromFileName(JarEntry jarEntry) {
+        String result = jarEntry.getName().replaceAll("/", "\\.");
+        return result.substring(0, result.lastIndexOf('.'));
+    }
 }