39 import jdk.internal.org.objectweb.asm.Attribute; 40 import jdk.internal.org.objectweb.asm.ClassReader; 41 import jdk.internal.org.objectweb.asm.ClassVisitor; 42 import jdk.internal.org.objectweb.asm.ClassWriter; 43 import jdk.internal.org.objectweb.asm.Opcodes; 44 45 import static jdk.internal.module.ClassFileAttributes.*; 46 47 /** 48 * Utility class to extend a module-info.class with additional attributes. 49 */ 50 51 public final class ModuleInfoExtender { 52 53 // the input stream to read the original module-info.class 54 private final InputStream in; 55 56 // the packages in the ModulePackages attribute 57 private Set<String> packages; 58 59 // the value of the module_version in Module attribute 60 private Version version; 61 62 // the value of the ModuleMainClass attribute 63 private String mainClass; 64 65 // the values for the ModuleTarget attribute 66 private String osName; 67 private String osArch; 68 private String osVersion; 69 70 // the hashes for the ModuleHashes attribute 71 private ModuleHashes hashes; 72 73 // the value of the ModuleResolution attribute 74 private ModuleResolution moduleResolution; 75 76 private ModuleInfoExtender(InputStream in) { 77 this.in = in; 78 } 79 80 /** 81 * Sets the set of packages for the ModulePackages attribute 82 */ 83 public ModuleInfoExtender packages(Set<String> packages) { 84 this.packages = Collections.unmodifiableSet(packages); 85 return this; 86 } 87 88 /** 89 * Sets the value of the module_version in Module attribute. 90 */ 91 public ModuleInfoExtender version(Version version) { 92 this.version = version; 93 return this; 94 } 95 96 /** 97 * Sets the value of the ModuleMainClass attribute. 98 */ 99 public ModuleInfoExtender mainClass(String mainClass) { 100 this.mainClass = mainClass; 101 return this; 102 } 103 104 /** 105 * Sets the values for the ModuleTarget attribute. 106 */ 107 public ModuleInfoExtender targetPlatform(String osName, 108 String osArch, 109 String osVersion) { 110 this.osName = osName; 111 this.osArch = osArch; 112 this.osVersion = osVersion; 113 return this; 114 } 115 116 /** 117 * The ModuleHashes attribute will be emitted to the module-info with 118 * the hashes encapsulated in the given {@code ModuleHashes} 119 * object. 120 */ 121 public ModuleInfoExtender hashes(ModuleHashes hashes) { 122 this.hashes = hashes; 123 return this; 124 } 125 126 /** 127 * Sets the value for the ModuleResolution attribute. 128 */ 129 public ModuleInfoExtender moduleResolution(ModuleResolution mres) { 130 this.moduleResolution = mres; 131 return this; 132 } 133 134 /** 135 * A ClassVisitor that supports adding class file attributes. If an 136 * attribute already exists then the first occurence of the attribute 137 * is replaced. 138 */ 139 private static class AttributeAddingClassVisitor extends ClassVisitor { 140 private Map<String, Attribute> attrs = new HashMap<>(); 141 142 AttributeAddingClassVisitor(int api, ClassVisitor cv) { 143 super(api, cv); 144 } 145 146 void addAttribute(Attribute attr) { 147 attrs.put(attr.type, attr); 148 } 149 150 @Override 151 public void visitAttribute(Attribute attr) { 152 String name = attr.type; 153 Attribute replacement = attrs.get(name); 154 if (replacement != null) { 155 attr = replacement; 156 attrs.remove(name); | 39 import jdk.internal.org.objectweb.asm.Attribute; 40 import jdk.internal.org.objectweb.asm.ClassReader; 41 import jdk.internal.org.objectweb.asm.ClassVisitor; 42 import jdk.internal.org.objectweb.asm.ClassWriter; 43 import jdk.internal.org.objectweb.asm.Opcodes; 44 45 import static jdk.internal.module.ClassFileAttributes.*; 46 47 /** 48 * Utility class to extend a module-info.class with additional attributes. 49 */ 50 51 public final class ModuleInfoExtender { 52 53 // the input stream to read the original module-info.class 54 private final InputStream in; 55 56 // the packages in the ModulePackages attribute 57 private Set<String> packages; 58 59 // the value for the module version in the Module attribute 60 private Version version; 61 62 // the value of the ModuleMainClass attribute 63 private String mainClass; 64 65 // the values for the ModuleTarget attribute 66 private String osName; 67 private String osArch; 68 private String osVersion; 69 70 // the hashes for the ModuleHashes attribute 71 private ModuleHashes hashes; 72 73 // the value of the ModuleResolution attribute 74 private ModuleResolution moduleResolution; 75 76 private ModuleInfoExtender(InputStream in) { 77 this.in = in; 78 } 79 80 /** 81 * Sets the packages for the ModulePackages attribute 82 * 83 * @apiNote This method does not check that the package names are legal 84 * package names or that the set of packages is a super set of the 85 * packages in the module. 86 */ 87 public ModuleInfoExtender packages(Set<String> packages) { 88 this.packages = Collections.unmodifiableSet(packages); 89 return this; 90 } 91 92 /** 93 * Sets the value for the module version in the Module attribute 94 */ 95 public ModuleInfoExtender version(Version version) { 96 this.version = version; 97 return this; 98 } 99 100 /** 101 * Sets the value of the ModuleMainClass attribute. 102 * 103 * @apiNote This method does not check that the main class is a legal 104 * class name in a named package. 105 */ 106 public ModuleInfoExtender mainClass(String mainClass) { 107 this.mainClass = mainClass; 108 return this; 109 } 110 111 /** 112 * Sets the values for the ModuleTarget attribute. 113 */ 114 public ModuleInfoExtender targetPlatform(String osName, 115 String osArch, 116 String osVersion) { 117 this.osName = osName; 118 this.osArch = osArch; 119 this.osVersion = osVersion; 120 return this; 121 } 122 123 /** 124 * The ModuleHashes attribute will be emitted to the module-info with 125 * the hashes encapsulated in the given {@code ModuleHashes} 126 * object. 127 */ 128 public ModuleInfoExtender hashes(ModuleHashes hashes) { 129 this.hashes = hashes; 130 return this; 131 } 132 133 /** 134 * Sets the value for the ModuleResolution attribute. 135 */ 136 public ModuleInfoExtender moduleResolution(ModuleResolution mres) { 137 this.moduleResolution = mres; 138 return this; 139 } 140 141 /** 142 * A ClassVisitor that supports adding class file attributes. If an 143 * attribute already exists then the first occurrence of the attribute 144 * is replaced. 145 */ 146 private static class AttributeAddingClassVisitor extends ClassVisitor { 147 private Map<String, Attribute> attrs = new HashMap<>(); 148 149 AttributeAddingClassVisitor(int api, ClassVisitor cv) { 150 super(api, cv); 151 } 152 153 void addAttribute(Attribute attr) { 154 attrs.put(attr.type, attr); 155 } 156 157 @Override 158 public void visitAttribute(Attribute attr) { 159 String name = attr.type; 160 Attribute replacement = attrs.get(name); 161 if (replacement != null) { 162 attr = replacement; 163 attrs.remove(name); |