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 = ModuleDescriptor.module(md.name()); 54 md.requires().stream() 55 .forEach(builder::requires); 56 md.exports().stream() 57 .forEach(builder::exports); 58 md.opens().stream() 59 .forEach(builder::opens); 60 md.uses().stream() 61 .forEach(builder::uses); 62 md.provides().stream() 63 .forEach(builder::provides); 64 65 // build the proper concealed packages 66 Set<String> concealed = new HashSet<>(mod.packages()); 67 md.exports().stream().map(ModuleDescriptor.Exports::source).forEach(concealed::remove); 68 md.opens().stream().map(ModuleDescriptor.Opens::source).forEach(concealed::remove); 69 concealed.stream().forEach(builder::contains); 70 71 md.version().ifPresent(builder::version); 72 md.mainClass().ifPresent(builder::mainClass); 73 md.osName().ifPresent(builder::osName); 74 md.osArch().ifPresent(builder::osArch); 75 md.osVersion().ifPresent(builder::osVersion); 76 77 return builder.build(); 78 } 79 80 private static ModuleReference moduleReference(ModuleDescriptor desc) { 81 return new ModuleReference(desc, null, () -> { 82 IOException ioe = new IOException("<module reader unsupported>"); 83 throw new UncheckedIOException(ioe); 84 }); 85 } 86 87 private static Map<String, ModuleReference> allModRefs(ResourcePool pool) { 88 return pool.moduleView().modules(). 89 collect(Collectors.toMap(ResourcePoolModule::name, 90 m -> moduleReference(descriptorOf(m)))); 91 } 92 93 private static void checkPackages(ResourcePool pool) { 94 // check that each resource pool module's packages() 95 // returns a set that is consistent with the module 96 // descriptor of that module. 97 98 pool.moduleView().modules().forEach(m -> { 99 ModuleDescriptor desc = m.descriptor(); 100 if (!desc.packages().equals(m.packages())) { 101 throw new RuntimeException("Module " + m.name() + 102 "'s descriptor returns inconsistent package set"); 103 } 104 }); 105 } 106 107 static Configuration validate(ResourcePool pool) { 108 checkPackages(pool); 109 final Map<String, ModuleReference> nameToModRef = allModRefs(pool); 110 final Set<ModuleReference> allRefs = new HashSet<>(nameToModRef.values()); 111 112 final ModuleFinder finder = new ModuleFinder() { 113 @Override 114 public Optional<ModuleReference> find(String name) { 115 return Optional.ofNullable(nameToModRef.get(name)); 116 } 117 118 @Override 119 public Set<ModuleReference> findAll() { 120 return allRefs; 121 } 122 }; 123 124 return Configuration.empty().resolveRequires( 125 finder, ModuleFinder.of(), nameToModRef.keySet()); 126 } 127 }