18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.tools.jlink.internal; 26 27 import java.lang.module.ModuleDescriptor; 28 import java.nio.ByteBuffer; 29 import java.nio.ByteOrder; 30 import java.util.HashSet; 31 import java.util.LinkedHashMap; 32 import java.util.Map; 33 import java.util.Objects; 34 import java.util.Optional; 35 import java.util.Set; 36 import java.util.stream.Stream; 37 import jdk.internal.jimage.decompressor.CompressedResourceHeader; 38 import jdk.internal.loader.ResourceHelper; 39 import jdk.tools.jlink.plugin.ResourcePool; 40 import jdk.tools.jlink.plugin.ResourcePoolBuilder; 41 import jdk.tools.jlink.plugin.ResourcePoolEntry; 42 import jdk.tools.jlink.plugin.ResourcePoolModule; 43 import jdk.tools.jlink.plugin.ResourcePoolModuleView; 44 import jdk.tools.jlink.plugin.PluginException; 45 46 /** 47 * A manager for pool of resources. 48 */ 49 public class ResourcePoolManager { 50 // utility to read ModuleDescriptor of the given ResourcePoolModule 51 static ModuleDescriptor readModuleDescriptor(ResourcePoolModule mod) { 52 String p = "/" + mod.name() + "/module-info.class"; 53 Optional<ResourcePoolEntry> content = mod.findEntry(p); 54 if (!content.isPresent()) { 55 throw new PluginException("module-info.class not found for " + 56 mod.name() + " module"); 57 } 58 ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes()); 59 try { 60 return ModuleDescriptor.read(bb); 61 } catch (RuntimeException re) { 62 throw new RuntimeException("module descriptor cannot be read for " + mod.name(), re); 63 } 64 } 65 66 /** 67 * Returns true if a resource has an effective package. 68 */ 69 public static boolean isNamedPackageResource(String path) { 70 return (path.endsWith(".class") && !path.endsWith("module-info.class")) || 71 !ResourceHelper.isSimpleResource(path); 72 } 73 74 class ResourcePoolModuleImpl implements ResourcePoolModule { 75 76 final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>(); 77 // lazily initialized 78 private ModuleDescriptor descriptor; 79 final String name; 80 81 private ResourcePoolModuleImpl(String name) { 82 this.name = name; 83 } 84 85 @Override 86 public String name() { 87 return name; 88 } 89 90 @Override 91 public Optional<ResourcePoolEntry> findEntry(String path) { 92 if (!path.startsWith("/")) { 93 path = "/" + path; 94 } 95 if (!path.startsWith("/" + name + "/")) { 96 path = "/" + name + path; // path already starts with '/' 97 } 98 return Optional.ofNullable(moduleContent.get(path)); 99 } 100 101 @Override 102 public ModuleDescriptor descriptor() { 103 if (descriptor == null) { 104 descriptor = readModuleDescriptor(this); 105 } 106 return descriptor; 107 } 108 109 @Override 110 public Set<String> packages() { 111 Set<String> pkgs = new HashSet<>(); 112 moduleContent.values().stream() 113 .filter(m -> m.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE) 114 .forEach(res -> { 115 String name = ImageFileCreator.resourceName(res.path()); 116 if (isNamedPackageResource(name)) { 117 String pkg = ImageFileCreator.toPackage(name); 118 if (!pkg.isEmpty()) { 119 pkgs.add(pkg); 120 } 121 } 122 }); 123 return pkgs; 124 } 125 126 @Override 127 public String toString() { 128 return name(); 129 } | 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.tools.jlink.internal; 26 27 import java.lang.module.ModuleDescriptor; 28 import java.nio.ByteBuffer; 29 import java.nio.ByteOrder; 30 import java.util.HashSet; 31 import java.util.LinkedHashMap; 32 import java.util.Map; 33 import java.util.Objects; 34 import java.util.Optional; 35 import java.util.Set; 36 import java.util.stream.Stream; 37 import jdk.internal.jimage.decompressor.CompressedResourceHeader; 38 import jdk.internal.module.Resources; 39 import jdk.internal.module.ModuleInfo; 40 import jdk.internal.module.ModuleInfo.Attributes; 41 import jdk.internal.module.ModuleTarget; 42 import jdk.tools.jlink.plugin.ResourcePool; 43 import jdk.tools.jlink.plugin.ResourcePoolBuilder; 44 import jdk.tools.jlink.plugin.ResourcePoolEntry; 45 import jdk.tools.jlink.plugin.ResourcePoolModule; 46 import jdk.tools.jlink.plugin.ResourcePoolModuleView; 47 import jdk.tools.jlink.plugin.PluginException; 48 49 /** 50 * A manager for pool of resources. 51 */ 52 public class ResourcePoolManager { 53 // utility to read Module Attributes of the given ResourcePoolModule 54 static Attributes readModuleAttributes(ResourcePoolModule mod) { 55 String p = "/" + mod.name() + "/module-info.class"; 56 Optional<ResourcePoolEntry> content = mod.findEntry(p); 57 if (!content.isPresent()) { 58 throw new PluginException("module-info.class not found for " + 59 mod.name() + " module"); 60 } 61 ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes()); 62 try { 63 return ModuleInfo.read(bb, null); 64 } catch (RuntimeException re) { 65 throw new RuntimeException("module info cannot be read for " + mod.name(), re); 66 } 67 } 68 69 /** 70 * Returns true if a resource has an effective package. 71 */ 72 public static boolean isNamedPackageResource(String path) { 73 return (path.endsWith(".class") && !path.endsWith("module-info.class")) || 74 Resources.canEncapsulate(path); 75 } 76 77 class ResourcePoolModuleImpl implements ResourcePoolModule { 78 79 final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>(); 80 // lazily initialized 81 private ModuleDescriptor descriptor; 82 private ModuleTarget target; 83 84 final String name; 85 86 private ResourcePoolModuleImpl(String name) { 87 this.name = name; 88 } 89 90 @Override 91 public String name() { 92 return name; 93 } 94 95 @Override 96 public Optional<ResourcePoolEntry> findEntry(String path) { 97 if (!path.startsWith("/")) { 98 path = "/" + path; 99 } 100 if (!path.startsWith("/" + name + "/")) { 101 path = "/" + name + path; // path already starts with '/' 102 } 103 return Optional.ofNullable(moduleContent.get(path)); 104 } 105 106 @Override 107 public ModuleDescriptor descriptor() { 108 initModuleAttributes(); 109 return descriptor; 110 } 111 112 @Override 113 public String osName() { 114 initModuleAttributes(); 115 return target != null? target.osName() : null; 116 } 117 118 @Override 119 public String osArch() { 120 initModuleAttributes(); 121 return target != null? target.osArch() : null; 122 } 123 124 private void initModuleAttributes() { 125 if (this.descriptor == null) { 126 Attributes attr = readModuleAttributes(this); 127 this.descriptor = attr.descriptor(); 128 this.target = attr.target(); 129 } 130 } 131 132 @Override 133 public Set<String> packages() { 134 Set<String> pkgs = new HashSet<>(); 135 moduleContent.values().stream() 136 .filter(m -> m.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE) 137 .forEach(res -> { 138 String name = ImageFileCreator.resourceName(res.path()); 139 if (isNamedPackageResource(name)) { 140 String pkg = ImageFileCreator.toPackage(name); 141 if (!pkg.isEmpty()) { 142 pkgs.add(pkg); 143 } 144 } 145 }); 146 return pkgs; 147 } 148 149 @Override 150 public String toString() { 151 return name(); 152 } |