Path: blob/master/src/java.base/share/classes/jdk/internal/module/Builder.java
41159 views
/*1* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package jdk.internal.module;2526import java.lang.module.ModuleDescriptor;27import java.lang.module.ModuleDescriptor.Exports;28import java.lang.module.ModuleDescriptor.Opens;29import java.lang.module.ModuleDescriptor.Provides;30import java.lang.module.ModuleDescriptor.Requires;31import java.lang.module.ModuleDescriptor.Version;32import java.util.List;33import java.util.Set;3435import jdk.internal.access.JavaLangModuleAccess;36import jdk.internal.access.SharedSecrets;3738/**39* This builder is optimized for reconstituting the {@code ModuleDescriptor}s40* for system modules. The validation should be done at jlink time.41*42* 1. skip name validation43* 2. ignores dependency hashes.44* 3. ModuleDescriptor skips the defensive copy and directly uses the45* sets/maps created in this Builder.46*47* SystemModules should contain modules for the boot layer.48*/49final class Builder {50private static final JavaLangModuleAccess JLMA =51SharedSecrets.getJavaLangModuleAccess();5253// Static cache of the most recently seen Version to cheaply deduplicate54// most Version objects. JDK modules have the same version.55static Version cachedVersion;5657/**58* Returns a {@link Requires} for a dependence on a module with the given59* (and possibly empty) set of modifiers, and optionally the version60* recorded at compile time.61*/62public static Requires newRequires(Set<Requires.Modifier> mods,63String mn,64String compiledVersion)65{66Version version = null;67if (compiledVersion != null) {68// use the cached version if the same version string69Version ver = cachedVersion;70if (ver != null && compiledVersion.equals(ver.toString())) {71version = ver;72} else {73version = Version.parse(compiledVersion);74}75}76return JLMA.newRequires(mods, mn, version);77}7879/**80* Returns a {@link Requires} for a dependence on a module with the given81* (and possibly empty) set of modifiers, and optionally the version82* recorded at compile time.83*/84public static Requires newRequires(Set<Requires.Modifier> mods,85String mn)86{87return newRequires(mods, mn, null);88}8990/**91* Returns a {@link Exports} for a qualified export, with92* the given (and possibly empty) set of modifiers,93* to a set of target modules.94*/95public static Exports newExports(Set<Exports.Modifier> ms,96String pn,97Set<String> targets) {98return JLMA.newExports(ms, pn, targets);99}100101/**102* Returns an {@link Opens} for an unqualified open with a given set of103* modifiers.104*/105public static Opens newOpens(Set<Opens.Modifier> ms, String pn) {106return JLMA.newOpens(ms, pn);107}108109/**110* Returns an {@link Opens} for a qualified opens, with111* the given (and possibly empty) set of modifiers,112* to a set of target modules.113*/114public static Opens newOpens(Set<Opens.Modifier> ms,115String pn,116Set<String> targets) {117return JLMA.newOpens(ms, pn, targets);118}119120/**121* Returns a {@link Exports} for an unqualified export with a given set122* of modifiers.123*/124public static Exports newExports(Set<Exports.Modifier> ms, String pn) {125return JLMA.newExports(ms, pn);126}127128/**129* Returns a {@link Provides} for a service with a given list of130* implementation classes.131*/132public static Provides newProvides(String st, List<String> pcs) {133return JLMA.newProvides(st, pcs);134}135136final String name;137boolean open, synthetic, mandated;138Set<Requires> requires;139Set<Exports> exports;140Set<Opens> opens;141Set<String> packages;142Set<String> uses;143Set<Provides> provides;144Version version;145String mainClass;146147Builder(String name) {148this.name = name;149this.requires = Set.of();150this.exports = Set.of();151this.opens = Set.of();152this.provides = Set.of();153this.uses = Set.of();154}155156Builder open(boolean value) {157this.open = value;158return this;159}160161Builder synthetic(boolean value) {162this.synthetic = value;163return this;164}165166Builder mandated(boolean value) {167this.mandated = value;168return this;169}170171/**172* Sets module exports.173*/174public Builder exports(Exports[] exports) {175this.exports = Set.of(exports);176return this;177}178179/**180* Sets module opens.181*/182public Builder opens(Opens[] opens) {183this.opens = Set.of(opens);184return this;185}186187/**188* Sets module requires.189*/190public Builder requires(Requires[] requires) {191this.requires = Set.of(requires);192return this;193}194195/**196* Adds a set of (possible empty) packages.197*/198public Builder packages(Set<String> packages) {199this.packages = packages;200return this;201}202203/**204* Sets the set of service dependences.205*/206public Builder uses(Set<String> uses) {207this.uses = uses;208return this;209}210211/**212* Sets module provides.213*/214public Builder provides(Provides[] provides) {215this.provides = Set.of(provides);216return this;217}218219/**220* Sets the module version.221*222* @throws IllegalArgumentException if {@code v} is null or cannot be223* parsed as a version string224*225* @see Version#parse(String)226*/227public Builder version(String v) {228Version ver = cachedVersion;229if (ver != null && v.equals(ver.toString())) {230version = ver;231} else {232cachedVersion = version = Version.parse(v);233}234return this;235}236237/**238* Sets the module main class.239*/240public Builder mainClass(String mc) {241mainClass = mc;242return this;243}244245/**246* Returns an immutable set of the module modifiers derived from the flags.247*/248private Set<ModuleDescriptor.Modifier> modifiers() {249int n = 0;250if (open) n++;251if (synthetic) n++;252if (mandated) n++;253if (n == 0) {254return Set.of();255} else {256ModuleDescriptor.Modifier[] mods = new ModuleDescriptor.Modifier[n];257if (open) mods[--n] = ModuleDescriptor.Modifier.OPEN;258if (synthetic) mods[--n] = ModuleDescriptor.Modifier.SYNTHETIC;259if (mandated) mods[--n] = ModuleDescriptor.Modifier.MANDATED;260return Set.of(mods);261}262}263264/**265* Builds a {@code ModuleDescriptor} from the components.266*/267public ModuleDescriptor build(int hashCode) {268assert name != null;269return JLMA.newModuleDescriptor(name,270version,271modifiers(),272requires,273exports,274opens,275uses,276provides,277packages,278mainClass,279hashCode);280}281}282283284