1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.bcel.classfile;
19
20 import java.io.DataInput;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 import java.util.Arrays;
24
25 import org.apache.bcel.Const;
26
27
28
29
30
31
32
33
34 public final class Module extends Attribute {
35
36
37
38
39
40
41 public static final String EXTENSION = ".jmod";
42
43 private final int moduleNameIndex;
44 private final int moduleFlags;
45 private final int moduleVersionIndex;
46
47 private ModuleRequires[] requiresTable;
48 private ModuleExports[] exportsTable;
49 private ModuleOpens[] opensTable;
50 private final int usesCount;
51 private final int[] usesIndex;
52 private ModuleProvides[] providesTable;
53
54
55
56
57
58
59
60
61
62
63 Module(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
64 super(Const.ATTR_MODULE, nameIndex, length, constantPool);
65
66 moduleNameIndex = input.readUnsignedShort();
67 moduleFlags = input.readUnsignedShort();
68 moduleVersionIndex = input.readUnsignedShort();
69
70 final int requiresCount = input.readUnsignedShort();
71 requiresTable = new ModuleRequires[requiresCount];
72 for (int i = 0; i < requiresCount; i++) {
73 requiresTable[i] = new ModuleRequires(input);
74 }
75
76 final int exportsCount = input.readUnsignedShort();
77 exportsTable = new ModuleExports[exportsCount];
78 for (int i = 0; i < exportsCount; i++) {
79 exportsTable[i] = new ModuleExports(input);
80 }
81
82 final int opensCount = input.readUnsignedShort();
83 opensTable = new ModuleOpens[opensCount];
84 for (int i = 0; i < opensCount; i++) {
85 opensTable[i] = new ModuleOpens(input);
86 }
87
88 usesCount = input.readUnsignedShort();
89 usesIndex = new int[usesCount];
90 for (int i = 0; i < usesCount; i++) {
91 usesIndex[i] = input.readUnsignedShort();
92 }
93
94 final int providesCount = input.readUnsignedShort();
95 providesTable = new ModuleProvides[providesCount];
96 for (int i = 0; i < providesCount; i++) {
97 providesTable[i] = new ModuleProvides(input);
98 }
99 }
100
101
102
103
104
105
106
107 @Override
108 public void accept(final Visitor v) {
109 v.visitModule(this);
110 }
111
112
113
114
115
116
117 @Override
118 public Attribute copy(final ConstantPool constantPool) {
119 final Module c = (Module) clone();
120
121 c.requiresTable = new ModuleRequires[requiresTable.length];
122 Arrays.setAll(c.requiresTable, i -> requiresTable[i].copy());
123
124 c.exportsTable = new ModuleExports[exportsTable.length];
125 Arrays.setAll(c.exportsTable, i -> exportsTable[i].copy());
126
127 c.opensTable = new ModuleOpens[opensTable.length];
128 Arrays.setAll(c.opensTable, i -> opensTable[i].copy());
129
130 c.providesTable = new ModuleProvides[providesTable.length];
131 Arrays.setAll(c.providesTable, i -> providesTable[i].copy());
132
133 c.setConstantPool(constantPool);
134 return c;
135 }
136
137
138
139
140
141
142
143 @Override
144 public void dump(final DataOutputStream file) throws IOException {
145 super.dump(file);
146
147 file.writeShort(moduleNameIndex);
148 file.writeShort(moduleFlags);
149 file.writeShort(moduleVersionIndex);
150
151 file.writeShort(requiresTable.length);
152 for (final ModuleRequires entry : requiresTable) {
153 entry.dump(file);
154 }
155
156 file.writeShort(exportsTable.length);
157 for (final ModuleExports entry : exportsTable) {
158 entry.dump(file);
159 }
160
161 file.writeShort(opensTable.length);
162 for (final ModuleOpens entry : opensTable) {
163 entry.dump(file);
164 }
165
166 file.writeShort(usesIndex.length);
167 for (final int entry : usesIndex) {
168 file.writeShort(entry);
169 }
170
171 file.writeShort(providesTable.length);
172 for (final ModuleProvides entry : providesTable) {
173 entry.dump(file);
174 }
175 }
176
177
178
179
180
181 public ModuleExports[] getExportsTable() {
182 return exportsTable;
183 }
184
185
186
187
188
189 public ModuleOpens[] getOpensTable() {
190 return opensTable;
191 }
192
193
194
195
196
197 public ModuleProvides[] getProvidesTable() {
198 return providesTable;
199 }
200
201
202
203
204
205 public ModuleRequires[] getRequiresTable() {
206 return requiresTable;
207 }
208
209
210
211
212 @Override
213 public String toString() {
214 final ConstantPool cp = super.getConstantPool();
215 final StringBuilder buf = new StringBuilder();
216 buf.append("Module:\n");
217 buf.append(" name: ").append(Utility.pathToPackage(cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module))).append("\n");
218 buf.append(" flags: ").append(String.format("%04x", moduleFlags)).append("\n");
219 final String version = moduleVersionIndex == 0 ? "0" : cp.getConstantString(moduleVersionIndex, Const.CONSTANT_Utf8);
220 buf.append(" version: ").append(version).append("\n");
221
222 buf.append(" requires(").append(requiresTable.length).append("):\n");
223 for (final ModuleRequires module : requiresTable) {
224 buf.append(" ").append(module.toString(cp)).append("\n");
225 }
226
227 buf.append(" exports(").append(exportsTable.length).append("):\n");
228 for (final ModuleExports module : exportsTable) {
229 buf.append(" ").append(module.toString(cp)).append("\n");
230 }
231
232 buf.append(" opens(").append(opensTable.length).append("):\n");
233 for (final ModuleOpens module : opensTable) {
234 buf.append(" ").append(module.toString(cp)).append("\n");
235 }
236
237 buf.append(" uses(").append(usesIndex.length).append("):\n");
238 for (final int index : usesIndex) {
239 final String className = cp.getConstantString(index, Const.CONSTANT_Class);
240 buf.append(" ").append(Utility.compactClassName(className, false)).append("\n");
241 }
242
243 buf.append(" provides(").append(providesTable.length).append("):\n");
244 for (final ModuleProvides module : providesTable) {
245 buf.append(" ").append(module.toString(cp)).append("\n");
246 }
247
248 return buf.substring(0, buf.length() - 1);
249 }
250 }