1 /*
2 * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.openjdk.asmtools.jdis;
24
25 import java.io.DataInputStream;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.*;
29
30 import org.openjdk.asmtools.common.Module;
31 import org.openjdk.asmtools.common.Tool;
32 import org.openjdk.asmtools.jasm.JasmTokens;
33
34 import static org.openjdk.asmtools.jdis.Main.i18n;
35
36 /**
37 * The module attribute data.
38 */
39 public class ModuleData {
40
41 // internal references
42 private final Tool tool;
43
44 private ConstantPool pool;
45 private PrintWriter out;
46 private Module module;
47
48 public ModuleData(ClassData clsData) {
49 this.tool = clsData.tool;
50 this.pool = clsData.pool;
51 this.out = clsData.out;
52 }
53
54 public String getModuleName() {
55 return module == null ? "N/A" : module.getModuleName();
56 }
57
58 public String getModuleVersion() { return module.getModuleVersion(); }
59
60 public String getModuleHeader() {
61 if ( module == null ) {
62 return "N/A";
63 } else {
64 StringBuilder sb = new StringBuilder(module.getModuleFlags());
65 sb.append(JasmTokens.Token.MODULE.parseKey()).append(" ");
66 sb.append(module.getModuleName());
67 if (module.getModuleVersion() != null)
68 sb.append("// @").append(module.getModuleVersion());
69 return sb.toString();
70 }
71 }
72
73 /**
74 * Reads and resolve the method's attribute data called from ClassData.
75 */
76 public void read(DataInputStream in) throws IOException {
77 int index, moduleFlags, versionIndex;
78 String moduleName, version;
79 Module.Builder builder;
80 try {
81 // u2 module_name_index;
82 index = in.readUnsignedShort();
83 moduleName = pool.getModule(index);
84 // u2 module_flags;
85 moduleFlags = in.readUnsignedShort();
86 // u2 module_version_index;
87 versionIndex = in.readUnsignedShort();
88 version = pool.getString(versionIndex);
89 builder = new Module.Builder(moduleName, moduleFlags, version);
90 } catch (IOException ioe) {
91 tool.error(i18n.getString("jdis.error.invalid_header"));
92 throw ioe;
93 }
94
95 try {
96 int requires_count = in.readUnsignedShort();
97 for (int i = 0; i < requires_count; i++) {
98 index = in.readUnsignedShort();
99 int requiresFlags = in.readUnsignedShort();
100 versionIndex = in.readUnsignedShort();
101
102 moduleName = pool.getModule(index);
103 version = pool.getString(versionIndex);
104 builder.require(moduleName, requiresFlags, version);
105 }
106 } catch (IOException ioe) {
107 tool.error(i18n.getString("jdis.error.invalid_requires"));
108 throw ioe;
109 }
110
111 try {
112 int exports_count = in.readUnsignedShort();
113 if (exports_count > 0) {
114 for (int i = 0; i < exports_count; i++) {
115 index = in.readUnsignedShort();
116 String packageName = pool.getPackage(index);
117 int exportsFlags = in.readUnsignedShort();
118 int exports_to_count = in.readUnsignedShort();
119 if (exports_to_count > 0) {
120 Set<String> targets = new HashSet<>(exports_to_count);
121 for (int j = 0; j < exports_to_count; j++) {
122 int exports_to_index = in.readUnsignedShort();
123 targets.add(pool.getModule(exports_to_index));
124 }
125 builder.exports(packageName, exportsFlags, targets);
126 } else {
127 builder.exports(packageName, exportsFlags);
128 }
129 }
130 }
131 } catch (IOException ioe) {
132 tool.error(i18n.getString("jdis.error.invalid_exports"));
133 throw ioe;
134 }
135
136 try {
137 int opens_count = in.readUnsignedShort();
138 if (opens_count > 0) {
139 for (int i = 0; i < opens_count; i++) {
140 index = in.readUnsignedShort();
141 String packageName = pool.getPackage(index);
142 int opensFlags = in.readUnsignedShort();
143 int opens_to_count = in.readUnsignedShort();
144 if (opens_to_count > 0) {
145 Set<String> targets = new HashSet<>(opens_to_count);
146 for (int j = 0; j < opens_to_count; j++) {
147 int opens_to_index = in.readUnsignedShort();
148 targets.add(pool.getModule(opens_to_index));
149 }
150 builder.opens(packageName, opensFlags, targets);
151 } else {
152 builder.opens(packageName, opensFlags);
153 }
154 }
155 }
156 } catch (IOException ioe) {
157 tool.error(i18n.getString("jdis.error.invalid_opens"));
158 throw ioe;
159 }
160
161 try {
162 int uses_count = in.readUnsignedShort();
163 if (uses_count > 0) {
164 for (int i = 0; i < uses_count; i++) {
165 index = in.readUnsignedShort();
166 String serviceName = pool.getClassName(index);
167 builder.uses(serviceName);
168 }
169 }
170 } catch (IOException ioe) {
171 tool.error(i18n.getString("jdis.error.invalid_uses"));
172 throw ioe;
173 }
174
175 try {
176 int provides_count = in.readUnsignedShort();
177 if (provides_count > 0) {
178 for (int i = 0; i < provides_count; i++) {
179 index = in.readUnsignedShort();
180 String serviceName = pool.getClassName(index);
181 int provides_with_count = in.readUnsignedShort();
182 Set<String> implNames = new HashSet<>(provides_with_count);
183 for (int j = 0; j < provides_with_count; j++) {
184 int provides_with_index = in.readUnsignedShort();
185 implNames.add(pool.getClassName(provides_with_index));
186 }
187 builder.provides(serviceName, implNames);
188 }
189 }
190 } catch (IOException ioe) {
191 tool.error(i18n.getString("jdis.error.invalid_provides"));
192 throw ioe;
193 }
194 module = builder.build();
195 }
196
197 /* Print Methods */
198 public void print() {
199 if (module != null)
200 out.println(module.toString());
201 }
202 }