/*
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package jdk.internal.module;

import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
import java.lang.module.ModuleDescriptor.Provides;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleDescriptor.Version;
import java.util.List;
import java.util.Set;

import jdk.internal.misc.JavaLangModuleAccess;
import jdk.internal.misc.SharedSecrets;

This builder is optimized for reconstituting the ModuleDescriptors for system modules. The validation should be done at jlink time. 1. skip name validation 2. ignores dependency hashes. 3. ModuleDescriptor skips the defensive copy and directly uses the sets/maps created in this Builder. SystemModules should contain modules for the boot layer.
/** * This builder is optimized for reconstituting the {@code ModuleDescriptor}s * for system modules. The validation should be done at jlink time. * * 1. skip name validation * 2. ignores dependency hashes. * 3. ModuleDescriptor skips the defensive copy and directly uses the * sets/maps created in this Builder. * * SystemModules should contain modules for the boot layer. */
final class Builder { private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); // Static cache of the most recently seen Version to cheaply deduplicate // most Version objects. JDK modules have the same version. static Version cachedVersion;
Returns a Requires for a dependence on a module with the given (and possibly empty) set of modifiers, and optionally the version recorded at compile time.
/** * Returns a {@link Requires} for a dependence on a module with the given * (and possibly empty) set of modifiers, and optionally the version * recorded at compile time. */
public static Requires newRequires(Set<Requires.Modifier> mods, String mn, String compiledVersion) { Version version = null; if (compiledVersion != null) { // use the cached version if the same version string Version ver = cachedVersion; if (ver != null && compiledVersion.equals(ver.toString())) { version = ver; } else { version = Version.parse(compiledVersion); } } return JLMA.newRequires(mods, mn, version); }
Returns a Requires for a dependence on a module with the given (and possibly empty) set of modifiers, and optionally the version recorded at compile time.
/** * Returns a {@link Requires} for a dependence on a module with the given * (and possibly empty) set of modifiers, and optionally the version * recorded at compile time. */
public static Requires newRequires(Set<Requires.Modifier> mods, String mn) { return newRequires(mods, mn, null); }
Returns a Exports for a qualified export, with the given (and possibly empty) set of modifiers, to a set of target modules.
/** * Returns a {@link Exports} for a qualified export, with * the given (and possibly empty) set of modifiers, * to a set of target modules. */
public static Exports newExports(Set<Exports.Modifier> ms, String pn, Set<String> targets) { return JLMA.newExports(ms, pn, targets); }
Returns an Opens for an unqualified open with a given set of modifiers.
/** * Returns an {@link Opens} for an unqualified open with a given set of * modifiers. */
public static Opens newOpens(Set<Opens.Modifier> ms, String pn) { return JLMA.newOpens(ms, pn); }
Returns an Opens for a qualified opens, with the given (and possibly empty) set of modifiers, to a set of target modules.
/** * Returns an {@link Opens} for a qualified opens, with * the given (and possibly empty) set of modifiers, * to a set of target modules. */
public static Opens newOpens(Set<Opens.Modifier> ms, String pn, Set<String> targets) { return JLMA.newOpens(ms, pn, targets); }
Returns a Exports for an unqualified export with a given set of modifiers.
/** * Returns a {@link Exports} for an unqualified export with a given set * of modifiers. */
public static Exports newExports(Set<Exports.Modifier> ms, String pn) { return JLMA.newExports(ms, pn); }
Returns a Provides for a service with a given list of implementation classes.
/** * Returns a {@link Provides} for a service with a given list of * implementation classes. */
public static Provides newProvides(String st, List<String> pcs) { return JLMA.newProvides(st, pcs); } final String name; boolean open, synthetic, mandated; Set<Requires> requires; Set<Exports> exports; Set<Opens> opens; Set<String> packages; Set<String> uses; Set<Provides> provides; Version version; String mainClass; Builder(String name) { this.name = name; this.requires = Set.of(); this.exports = Set.of(); this.opens = Set.of(); this.provides = Set.of(); this.uses = Set.of(); } Builder open(boolean value) { this.open = value; return this; } Builder synthetic(boolean value) { this.synthetic = value; return this; } Builder mandated(boolean value) { this.mandated = value; return this; }
Sets module exports.
/** * Sets module exports. */
public Builder exports(Exports[] exports) { this.exports = Set.of(exports); return this; }
Sets module opens.
/** * Sets module opens. */
public Builder opens(Opens[] opens) { this.opens = Set.of(opens); return this; }
Sets module requires.
/** * Sets module requires. */
public Builder requires(Requires[] requires) { this.requires = Set.of(requires); return this; }
Adds a set of (possible empty) packages.
/** * Adds a set of (possible empty) packages. */
public Builder packages(Set<String> packages) { this.packages = packages; return this; }
Sets the set of service dependences.
/** * Sets the set of service dependences. */
public Builder uses(Set<String> uses) { this.uses = uses; return this; }
Sets module provides.
/** * Sets module provides. */
public Builder provides(Provides[] provides) { this.provides = Set.of(provides); return this; }
Sets the module version.
Throws:
  • IllegalArgumentException – if v is null or cannot be parsed as a version string
See Also:
/** * Sets the module version. * * @throws IllegalArgumentException if {@code v} is null or cannot be * parsed as a version string * * @see Version#parse(String) */
public Builder version(String v) { Version ver = cachedVersion; if (ver != null && v.equals(ver.toString())) { version = ver; } else { cachedVersion = version = Version.parse(v); } return this; }
Sets the module main class.
/** * Sets the module main class. */
public Builder mainClass(String mc) { mainClass = mc; return this; }
Returns an immutable set of the module modifiers derived from the flags.
/** * Returns an immutable set of the module modifiers derived from the flags. */
private Set<ModuleDescriptor.Modifier> modifiers() { int n = 0; if (open) n++; if (synthetic) n++; if (mandated) n++; if (n == 0) { return Set.of(); } else { ModuleDescriptor.Modifier[] mods = new ModuleDescriptor.Modifier[n]; if (open) mods[--n] = ModuleDescriptor.Modifier.OPEN; if (synthetic) mods[--n] = ModuleDescriptor.Modifier.SYNTHETIC; if (mandated) mods[--n] = ModuleDescriptor.Modifier.MANDATED; return Set.of(mods); } }
Builds a ModuleDescriptor from the components.
/** * Builds a {@code ModuleDescriptor} from the components. */
public ModuleDescriptor build(int hashCode) { assert name != null; return JLMA.newModuleDescriptor(name, version, modifiers(), requires, exports, opens, uses, provides, packages, mainClass, hashCode); } }