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.ModuleReader; 32 import java.lang.module.ModuleReference; 33 import java.io.IOException; 34 import java.io.UncheckedIOException; 35 import java.nio.ByteBuffer; 36 import java.util.Collection; 37 import java.util.HashSet; 38 import java.util.Map; 39 import java.util.Optional; 40 import java.util.Set; 41 import java.util.stream.Collectors; 42 import jdk.tools.jlink.plugin.PluginException; 43 import jdk.tools.jlink.plugin.ResourcePool; 44 import jdk.tools.jlink.plugin.ResourcePoolEntry; 45 import jdk.tools.jlink.plugin.ResourcePoolModule; 46 47 final class ResourcePoolConfiguration { 48 private ResourcePoolConfiguration() {} 49 50 private static ModuleDescriptor descriptorOf(ResourcePoolModule mod) { 51 ModuleDescriptor md = mod.descriptor(); 52 53 // drop hashes 54 ModuleDescriptor.Builder builder = ModuleDescriptor.module(md.name()); 55 md.requires().stream() 56 .forEach(builder::requires); 57 md.exports().stream() 58 .forEach(builder::exports); 59 md.opens().stream() 60 .forEach(builder::opens); 61 md.uses().stream() 62 .forEach(builder::uses); 63 md.provides().stream() 64 .forEach(builder::provides); 65 66 // build the proper concealed packages 67 Set<String> concealed = new HashSet<>(mod.packages()); 68 md.exports().stream().map(ModuleDescriptor.Exports::source).forEach(concealed::remove); 69 md.opens().stream().map(ModuleDescriptor.Opens::source).forEach(concealed::remove); 70 concealed.stream().forEach(builder::contains); 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 @Override 84 public ModuleReader open() { 85 throw new UnsupportedOperationException(); 86 } 87 }; 88 } 89 90 private static Map<String, ModuleReference> allModRefs(ResourcePool pool) { 91 return pool.moduleView().modules(). 92 collect(Collectors.toMap(ResourcePoolModule::name, 93 m -> moduleReference(descriptorOf(m)))); 94 } 95 96 private static void checkPackages(ResourcePool pool) { 97 // check that each resource pool module's packages() 98 // returns a set that is consistent with the module 99 // descriptor of that module. 100 101 pool.moduleView().modules().forEach(m -> { 102 ModuleDescriptor desc = m.descriptor(); 103 if (!desc.packages().equals(m.packages())) { 104 throw new RuntimeException("Module " + m.name() + 105 "'s descriptor returns inconsistent package set"); 106 } 107 }); 108 } 109 110 static Configuration validate(ResourcePool pool) { 111 checkPackages(pool); 112 final Map<String, ModuleReference> nameToModRef = allModRefs(pool); 113 final Set<ModuleReference> allRefs = new HashSet<>(nameToModRef.values()); 114 115 final ModuleFinder finder = new ModuleFinder() { 116 @Override 117 public Optional<ModuleReference> find(String name) { 118 return Optional.ofNullable(nameToModRef.get(name)); 119 } 120 121 @Override 122 public Set<ModuleReference> findAll() { 123 return allRefs; 124 } 125 }; 126 127 return Configuration.empty().resolveRequires( 128 finder, ModuleFinder.of(), nameToModRef.keySet()); 129 } 130 }