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 }