1 /* 2 * Copyright (c) 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 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 26 package jdk.tools.jlink.internal; 27 28 import java.lang.module.Configuration; 29 import java.lang.module.ModuleDescriptor; 30 import java.lang.module.ModuleFinder; 31 import java.lang.module.ModuleReference; 32 import java.io.IOException; 33 import java.io.UncheckedIOException; 34 import java.nio.ByteBuffer; 35 import java.util.Collection; 36 import java.util.HashSet; 37 import java.util.Map; 38 import java.util.Optional; 39 import java.util.Set; 40 import java.util.stream.Collectors; 41 import jdk.tools.jlink.plugin.PluginException; 42 import jdk.tools.jlink.plugin.ResourcePool; 43 import jdk.tools.jlink.plugin.ResourcePoolEntry; 44 import jdk.tools.jlink.plugin.ResourcePoolModule; 45 46 final class ResourcePoolConfiguration { 47 private ResourcePoolConfiguration() {} 48 49 private static ModuleDescriptor descriptorOf(ResourcePoolModule mod) { 50 ModuleDescriptor md = mod.descriptor(); 51 52 // drop hashes 53 ModuleDescriptor.Builder builder = new ModuleDescriptor.Builder(md.name()); 54 md.requires().stream() 55 .forEach(builder::requires); 56 md.exports().stream() 57 .forEach(builder::exports); 58 md.uses().stream() 59 .forEach(builder::uses); 60 md.provides().values().stream() 61 .forEach(builder::provides); 62 63 // build the proper concealed packages 64 Set<String> exps = md.exports().stream() 65 .map(ModuleDescriptor.Exports::source) 66 .collect(Collectors.toSet()); 67 68 mod.packages().stream() 69 .filter(pn -> !exps.contains(pn)) 70 .forEach(builder::conceals); 71 72 md.version().ifPresent(builder::version); 73 md.mainClass().ifPresent(builder::mainClass); 74 md.osName().ifPresent(builder::osName); 75 md.osArch().ifPresent(builder::osArch); 76 md.osVersion().ifPresent(builder::osVersion); 77 78 return builder.build(); 79 } 80 81 private static ModuleReference moduleReference(ModuleDescriptor desc) { 82 return new ModuleReference(desc, null, () -> { 83 IOException ioe = new IOException("<module reader unsupported>"); 84 throw new UncheckedIOException(ioe); 85 }); 86 } 87 88 private static Map<String, ModuleReference> allModRefs(ResourcePool pool) { 89 return pool.moduleView().modules(). 90 collect(Collectors.toMap(ResourcePoolModule::name, 91 m -> moduleReference(descriptorOf(m)))); 92 } 93 94 private static void checkPackages(ResourcePool pool) { 95 // check that each resource pool module's packages() 96 // returns a set that is consistent with the module 97 // descriptor of that module. 98 99 pool.moduleView().modules().forEach(m -> { 100 ModuleDescriptor desc = m.descriptor(); 101 if (!desc.packages().equals(m.packages())) { 102 throw new RuntimeException("Module " + m.name() + 103 "'s descriptor returns inconsistent package set"); 104 } 105 }); 106 } 107 108 static Configuration validate(ResourcePool pool) { 109 checkPackages(pool); 110 final Map<String, ModuleReference> nameToModRef = allModRefs(pool); 111 final Set<ModuleReference> allRefs = new HashSet<>(nameToModRef.values()); 112 113 final ModuleFinder finder = new ModuleFinder() { 114 @Override 115 public Optional<ModuleReference> find(String name) { 116 return Optional.ofNullable(nameToModRef.get(name)); 117 } 118 119 @Override 120 public Set<ModuleReference> findAll() { 121 return allRefs; 122 } 123 }; 124 125 return Configuration.empty().resolveRequires( 126 finder, ModuleFinder.of(), nameToModRef.keySet()); 127 } 128 }