1 package org.codehaus.plexus.languages.java.jpms;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.util.jar.JarEntry;
27 import java.util.jar.JarFile;
28 import java.util.jar.Manifest;
29
30 import org.codehaus.plexus.languages.java.version.JavaVersion;
31
32 abstract class AbstractBinaryModuleInfoParser implements ModuleInfoParser {
33 @Override
34 public JavaModuleDescriptor getModuleDescriptor(Path modulePath) throws IOException {
35 return getModuleDescriptor(modulePath, JavaVersion.JAVA_SPECIFICATION_VERSION);
36 }
37
38 @Override
39 public JavaModuleDescriptor getModuleDescriptor(Path modulePath, JavaVersion jdkVersion) throws IOException {
40 JavaModuleDescriptor descriptor;
41 if (Files.isDirectory(modulePath)) {
42 try (InputStream in = Files.newInputStream(modulePath.resolve("module-info.class"))) {
43 descriptor = parse(in);
44 }
45 } else {
46 try (JarFile jarFile = new JarFile(modulePath.toFile())) {
47 JarEntry moduleInfo;
48 if (modulePath.toString().toLowerCase().endsWith(".jmod")) {
49 moduleInfo = jarFile.getJarEntry("classes/module-info.class");
50 } else {
51 moduleInfo = jarFile.getJarEntry("module-info.class");
52
53 if (moduleInfo == null) {
54 Manifest manifest = jarFile.getManifest();
55
56 if (manifest != null
57 && "true"
58 .equalsIgnoreCase(
59 manifest.getMainAttributes().getValue("Multi-Release"))) {
60 int javaVersion =
61 Integer.parseInt(jdkVersion.asMajor().getValue(1));
62
63 for (int version = javaVersion; version >= 9; version--) {
64 String resource = "META-INF/versions/" + version + "/module-info.class";
65 JarEntry entry = jarFile.getJarEntry(resource);
66 if (entry != null) {
67 moduleInfo = entry;
68 break;
69 }
70 }
71 }
72 }
73 }
74
75 if (moduleInfo != null) {
76 descriptor = parse(jarFile.getInputStream(moduleInfo));
77 } else {
78 descriptor = null;
79 }
80 }
81 }
82 return descriptor;
83 }
84
85 abstract JavaModuleDescriptor parse(InputStream in) throws IOException;
86 }