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;
+/**
+ * This class acts as a commandline interface for JavaInspect.
+ */
public class Main {
- public static void main(String[] args) {
- if (args.length == 0) {
- System.err.println("usage: javainspect [PROJECT_DIR] [PACKAGE_GLOB] [GRAPH_NAME]");
- System.exit(1);
- }
-
- String projectDir = args[0];
- String packageGlob = args[1];
- String graphName = args[2];
-
- ClassGraph cg = new ClassGraph();
- cg.setTargetDirectoryPath(getProperty("user.dir") + separator);
-
- cg.addProject(projectDir);
- cg.whitelistClassPattern(packageGlob);
- cg.setKeepDotFile(true);
- cg.generateGraph(graphName);
-
- System.exit(0);
- }
+ public static void main(String[] args) throws IOException, ClassNotFoundException {
+ CommandlineConfiguration configuration = new CommandlineConfiguration(args);
+
+ List<File> jarFiles = configuration.jarFiles.getValue();
+
+ URLClassLoader classLoader = new URLClassLoader(
+ getFileUrls(jarFiles),
+ configuration.getClass().getClassLoader());
+
+ ClassGraph classGraph = new ClassGraph();
+ classGraph.setTargetDirectoryPath(getProperty("user.dir") + separator);
+ classGraph.setKeepDotFile(true);
+
+ for (File jarFile : jarFiles)
+ addJarToGraph(jarFile, classLoader, classGraph, configuration);
+
+ classGraph.generateGraph(configuration.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('.'));
+ }
}