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.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashSet;
27 import java.util.LinkedHashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import org.objectweb.asm.ClassReader;
32 import org.objectweb.asm.ClassVisitor;
33 import org.objectweb.asm.ModuleVisitor;
34 import org.objectweb.asm.Opcodes;
35
36
37
38
39
40
41
42
43 class AsmModuleInfoParser extends AbstractBinaryModuleInfoParser {
44 @Override
45 JavaModuleDescriptor parse(InputStream in) throws IOException {
46 final JavaModuleDescriptorWrapper wrapper = new JavaModuleDescriptorWrapper();
47
48 ClassReader reader = new ClassReader(in);
49 reader.accept(
50 new ClassVisitor(Opcodes.ASM9) {
51 @Override
52 public ModuleVisitor visitModule(String name, int arg1, String arg2) {
53 wrapper.builder = JavaModuleDescriptor.newModule(name);
54
55 return new ModuleVisitor(Opcodes.ASM9) {
56 @Override
57 public void visitRequire(String module, int access, String version) {
58 if ((access & (Opcodes.ACC_STATIC_PHASE | Opcodes.ACC_TRANSITIVE)) != 0) {
59 Set<JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers =
60 new LinkedHashSet<>();
61 if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
62 modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC);
63 }
64 if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
65 modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE);
66 }
67
68 wrapper.builder.requires(modifiers, module);
69 } else {
70 wrapper.builder.requires(module);
71 }
72 }
73
74 @Override
75 public void visitExport(String pn, int ms, String... targets) {
76 if (targets == null || targets.length == 0) {
77 wrapper.builder.exports(pn.replace('/', '.'));
78 } else {
79 wrapper.builder.exports(
80 pn.replace('/', '.'), new HashSet<>(Arrays.asList(targets)));
81 }
82 }
83
84 @Override
85 public void visitUse(String service) {
86 wrapper.builder.uses(service.replace('/', '.'));
87 }
88
89 @Override
90 public void visitProvide(String service, String... providers) {
91 List<String> renamedProvides = new ArrayList<>(providers.length);
92 for (String provider : providers) {
93 renamedProvides.add(provider.replace('/', '.'));
94 }
95 wrapper.builder.provides(service.replace('/', '.'), renamedProvides);
96 }
97 };
98 }
99 },
100 0);
101 return wrapper.builder.build();
102 }
103
104 private static class JavaModuleDescriptorWrapper {
105 private JavaModuleDescriptor.Builder builder;
106 }
107 }