Removed half-baked java source code parser.
[javainspect.git] / src / main / java / eu / svjatoslav / inspector / java / commandline / Main.java
1 package eu.svjatoslav.inspector.java.commandline;
2
3 import eu.svjatoslav.inspector.java.structure.ClassGraph;
4
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.net.MalformedURLException;
9 import java.net.URL;
10 import java.net.URLClassLoader;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.jar.JarEntry;
14 import java.util.jar.JarInputStream;
15
16 /**
17  * This class acts as a commandline interface for JavaInspect.
18  */
19 public class Main {
20     public static void main(String[] args) throws IOException, ClassNotFoundException {
21         CommandlineConfiguration configuration = new CommandlineConfiguration(args);
22         if (!configuration.configurationOk)
23             System.exit(1);
24             
25         getClassGraph(configuration).generateGraph(configuration.graphName.getValue());
26
27         if (configuration.isDebug())
28             System.out.println("Graph ready.");
29     }
30
31     private static ClassGraph getClassGraph(CommandlineConfiguration configuration) throws IOException, ClassNotFoundException {
32         List<File> jarFiles = configuration.jarFiles.getValue();
33
34         URLClassLoader classLoader = new URLClassLoader(
35                 getFileUrls(jarFiles),
36                 configuration.getClass().getClassLoader());
37
38         ClassGraph classGraph = new ClassGraph();
39
40         if (configuration.targetDirectory.isSpecified())
41             classGraph.setTargetDirectory(configuration.targetDirectory.getValue());
42
43         if (configuration.targetImageType.isSpecified())
44             classGraph.setTargetImageType(configuration.targetImageType.getValue());
45
46         classGraph.setKeepDotFile(configuration.keepDotFile.getValue());
47
48         for (File jarFile : jarFiles)
49             addJarToGraph(jarFile, classLoader, classGraph, configuration);
50
51         configuration.blacklistGlob.getValue().forEach(classGraph::blacklistClassGlob);
52         configuration.whitelistGlob.getValue().forEach(classGraph::whitelistClassGlob);
53
54         if (configuration.hideOrphanedClasses.getValue())
55             classGraph.hideOrphanedClasses();
56
57         return classGraph;
58     }
59
60     private static URL[] getFileUrls(List<File> jarFiles) {
61         List<URL> urls = new ArrayList<>();
62         jarFiles.forEach((File file) -> {
63             try {
64                 urls.add(file.toURI().toURL());
65             } catch (MalformedURLException e) {
66                 throw new RuntimeException(e);
67             }
68         });
69
70         return urls.toArray(new URL[urls.size()]);
71     }
72
73     private static void addJarToGraph(
74             File jarFile, URLClassLoader classLoader, ClassGraph classGraph, CommandlineConfiguration configuration)
75             throws IOException, ClassNotFoundException {
76
77         for (String className : getClassNamesFromJar(jarFile)) {
78             if (configuration.isDebug())
79                 System.out.println("Adding class to graph: " + className);
80
81             classGraph.add(loadClassByName(classLoader, className));
82         }
83     }
84
85     private static Class loadClassByName(URLClassLoader classLoader, String className) throws ClassNotFoundException {
86         return Class.forName(className, true, classLoader);
87     }
88
89     public static List<String> getClassNamesFromJar(File jarFile) throws IOException {
90         List<String> result = new ArrayList<>();
91         try (
92                 JarInputStream jarInputStream = new JarInputStream(new FileInputStream(jarFile))
93         ) {
94             while (true) {
95                 JarEntry jarEntry = jarInputStream.getNextJarEntry();
96                 if (jarEntry == null)
97                     break;
98
99                 if (isClassFile(jarEntry))
100                     result.add(getClassNameFromFileName(jarEntry));
101             }
102
103             return result;
104         }
105     }
106
107     private static boolean isClassFile(JarEntry jarEntry) {
108         return jarEntry.getName().endsWith(".class");
109     }
110
111     private static String getClassNameFromFileName(JarEntry jarEntry) {
112         String result = jarEntry.getName().replaceAll("/", "\\.");
113         return result.substring(0, result.lastIndexOf('.'));
114     }
115 }