36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.EnumSet;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.LinkedHashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.Optional;
46 import java.util.Set;
47 import java.util.function.Supplier;
48 import java.util.stream.Collectors;
49 import java.util.stream.Stream;
50
51 import static jdk.internal.module.Checks.*;
52 import static java.util.Objects.*;
53
54 import jdk.internal.module.Checks;
55 import jdk.internal.module.ModuleHashes;
56
57
58 /**
59 * A module descriptor.
60 *
61 * <p> A {@code ModuleDescriptor} is typically created from the binary form
62 * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
63 * class can be used to create a {@code ModuleDescriptor} from its components.
64 * The {@link #module module}, {@link #openModule openModule}, and {@link
65 * #automaticModule automaticModule} methods create builders for building
66 * different kinds of modules. </p>
67 *
68 * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
69 * multiple concurrent threads.</p>
70 *
71 * @since 9
72 * @see java.lang.reflect.Module
73 */
74
75 public class ModuleDescriptor
975 // Indicates if synthesised for a JAR file found on the module path
976 private final boolean automatic;
977
978 // Not generated from a module-info.java
979 private final boolean synthetic;
980
981 private final Set<Requires> requires;
982 private final Set<Exports> exports;
983 private final Set<Opens> opens;
984 private final Set<String> uses;
985 private final Set<Provides> provides;
986
987 // "Extended" information, added post-compilation by tools
988 private final Version version;
989 private final String mainClass;
990 private final String osName;
991 private final String osArch;
992 private final String osVersion;
993 private final Set<String> packages;
994 private final ModuleHashes hashes;
995
996
997 private ModuleDescriptor(String name,
998 boolean open,
999 boolean automatic,
1000 boolean synthetic,
1001 Set<Requires> requires,
1002 Set<Exports> exports,
1003 Set<Opens> opens,
1004 Set<String> uses,
1005 Set<Provides> provides,
1006 Version version,
1007 String mainClass,
1008 String osName,
1009 String osArch,
1010 String osVersion,
1011 Set<String> packages,
1012 ModuleHashes hashes)
1013 {
1014
1015 this.name = name;
1016 this.open = open;
1017 this.automatic = automatic;
1018 this.synthetic = synthetic;
1019
1020 assert (requires.stream().map(Requires::name).distinct().count()
1021 == requires.size());
1022 this.requires = emptyOrUnmodifiableSet(requires);
1023
1024 this.exports = emptyOrUnmodifiableSet(exports);
1025 this.opens = emptyOrUnmodifiableSet(opens);
1026 this.uses = emptyOrUnmodifiableSet(uses);
1027 this.provides = emptyOrUnmodifiableSet(provides);
1028 this.version = version;
1029 this.mainClass = mainClass;
1030 this.osName = osName;
1031 this.osArch = osArch;
1032 this.osVersion = osVersion;
1033 this.hashes = hashes;
1034 this.packages = emptyOrUnmodifiableSet(packages);
1035 }
1036
1037 /**
1038 * Clones the given module descriptor with an augmented set of packages
1039 */
1040 ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1041 this.name = md.name;
1042 this.open = md.open;
1043 this.automatic = md.automatic;
1044 this.synthetic = md.synthetic;
1045
1046 this.requires = md.requires;
1047 this.exports = md.exports;
1048 this.opens = md.opens;
1049 this.uses = md.uses;
1050 this.provides = md.provides;
1051
1052 this.version = md.version;
1053 this.mainClass = md.mainClass;
1054 this.osName = md.osName;
1055 this.osArch = md.osArch;
1056 this.osVersion = md.osVersion;
1057 this.hashes = null; // need to ignore
1058
1059 Set<String> packages = new HashSet<>(md.packages);
1060 packages.addAll(pkgs);
1061 this.packages = emptyOrUnmodifiableSet(packages);
1062 }
1063
1064 /**
1065 * Creates a module descriptor from its components.
1066 * The arguments are pre-validated and sets are unmodifiable sets.
1067 */
1068 ModuleDescriptor(String name,
1069 boolean open,
1070 boolean automatic,
1071 boolean synthetic,
1072 Set<Requires> requires,
1073 Set<Exports> exports,
1074 Set<Opens> opens,
1075 Set<String> uses,
1076 Set<Provides> provides,
1077 Version version,
1078 String mainClass,
1079 String osName,
1080 String osArch,
1081 String osVersion,
1082 Set<String> packages,
1083 ModuleHashes hashes,
1084 int hashCode,
1085 boolean unused) {
1086 this.name = name;
1087 this.open = open;
1088 this.automatic = automatic;
1089 this.synthetic = synthetic;
1090 this.requires = requires;
1091 this.exports = exports;
1092 this.opens = opens;
1093 this.uses = uses;
1094 this.provides = provides;
1095 this.packages = packages;
1096 this.version = version;
1097 this.mainClass = mainClass;
1098 this.osName = osName;
1099 this.osArch = osArch;
1100 this.osVersion = osVersion;
1101 this.hashes = hashes;
1102 this.hash = hashCode;
1103 }
1104
1105 /**
1106 * <p> The module name. </p>
1107 *
1108 * @return The module name
1109 */
1110 public String name() {
1111 return name;
1112 }
1113
1114 /**
1115 * <p> Returns {@code true} if this is an open module. </p>
1116 *
1117 * <p> An open module does not declare any open packages (the {@link #opens()
1118 * opens} method returns an empty set) but the resulting module is treated
1119 * as if all packages are open. </p>
1120 *
1121 * @return {@code true} if this is an open module
1122 */
1274 public Optional<String> osVersion() {
1275 return Optional.ofNullable(osVersion);
1276 }
1277
1278 /**
1279 * Returns the names of all packages in this module.
1280 *
1281 * @return A possibly-empty unmodifiable set of all packages in the module
1282 */
1283 public Set<String> packages() {
1284 return packages;
1285 }
1286
1287 /**
1288 * Returns the object with the hashes of other modules
1289 */
1290 Optional<ModuleHashes> hashes() {
1291 return Optional.ofNullable(hashes);
1292 }
1293
1294
1295 /**
1296 * A builder used for building {@link ModuleDescriptor} objects.
1297 *
1298 * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1299 * #openModule openModule}, and {@link #automaticModule automaticModule}
1300 * methods to create builders for building different kinds of modules. </p>
1301 *
1302 * <p> Example usage: </p>
1303 * <pre>{@code ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1304 * .exports("p")
1305 * .requires("m2")
1306 * .build();
1307 * }</pre>
1308 *
1309 * @apiNote A {@code Builder} checks the components and invariants as
1310 * components are added to the builder. The rational for this is to detect
1311 * errors as early as possible and not defer all validation to the
1312 * {@link #build build} method. A {@code Builder} cannot be used to create
1313 * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
1317 public static final class Builder {
1318 final String name;
1319 final boolean strict; // true if module names are checked
1320 boolean open;
1321 boolean automatic;
1322 boolean synthetic;
1323 final Map<String, Requires> requires = new HashMap<>();
1324
1325 final Map<String, Exports> exports = new HashMap<>();
1326 final Map<String, Opens> opens = new HashMap<>();
1327 final Set<String> concealedPackages = new HashSet<>();
1328
1329 final Set<String> uses = new HashSet<>();
1330 final Map<String, Provides> provides = new HashMap<>();
1331 Version version;
1332 String osName;
1333 String osArch;
1334 String osVersion;
1335 String mainClass;
1336 ModuleHashes hashes;
1337
1338 /**
1339 * Initializes a new builder with the given module name.
1340 *
1341 * @param strict
1342 * Indicates whether module names are checked or not
1343 */
1344 Builder(String name, boolean strict) {
1345 this.strict = strict;
1346 this.name = (strict) ? requireModuleName(name) : name;
1347 }
1348
1349 /* package */ Builder open(boolean open) {
1350 this.open = open;
1351 return this;
1352 }
1353
1354 /* package */ Builder automatic(boolean automatic) {
1355 this.automatic = automatic;
1356 return this;
1688 /**
1689 * Adds an <em>opens</em> directive to open a package.
1690 *
1691 * @param pn
1692 * The package name
1693 *
1694 * @return This builder
1695 *
1696 * @throws IllegalArgumentException
1697 * If the package name is {@code null} or is not a legal Java
1698 * identifier
1699 * @throws IllegalStateException
1700 * If the package is already declared as a package with the
1701 * {@link #contains contains} method, the package is already
1702 * declared as open, or this is a builder for an open module
1703 */
1704 public Builder opens(String pn) {
1705 return opens(Collections.emptySet(), pn);
1706 }
1707
1708
1709 // Used by ModuleInfo, after a packageFinder is invoked
1710 /* package */ Set<String> exportedAndOpenPackages() {
1711 if (opens.isEmpty())
1712 return exports.keySet();
1713 Set<String> result = new HashSet<>();
1714 result.addAll(exports.keySet());
1715 result.addAll(opens.keySet());
1716 return result;
1717 }
1718
1719 /**
1720 * Adds a service dependence.
1721 *
1722 * @param service
1723 * The service type
1724 *
1725 * @return This builder
1726 *
1727 * @throws IllegalArgumentException
1996 Set<Exports> exports = new HashSet<>(this.exports.values());
1997 Set<Opens> opens = new HashSet<>(this.opens.values());
1998
1999 Set<Provides> provides = new HashSet<>(this.provides.values());
2000
2001 return new ModuleDescriptor(name,
2002 open,
2003 automatic,
2004 synthetic,
2005 requires,
2006 exports,
2007 opens,
2008 uses,
2009 provides,
2010 version,
2011 mainClass,
2012 osName,
2013 osArch,
2014 osVersion,
2015 packages,
2016 hashes);
2017 }
2018
2019 }
2020
2021 /**
2022 * Compares this module descriptor to another.
2023 *
2024 * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2025 * module name lexicographically. Where the module names are equal then
2026 * the versions, if present, are compared. </p>
2027 *
2028 * @apiNote For now, the natural ordering is not consistent with equals.
2029 * If two module descriptors have equal module names, equal versions if
2030 * present, but their corresponding components are not equal, then they
2031 * will be considered equal by this method.
2032 *
2033 * @param that
2034 * The object to which this module descriptor is to be compared
2035 *
2036 * @return A negative integer, zero, or a positive integer if this module
2072 if (ob == this)
2073 return true;
2074 if (!(ob instanceof ModuleDescriptor))
2075 return false;
2076 ModuleDescriptor that = (ModuleDescriptor)ob;
2077 return (name.equals(that.name)
2078 && open == that.open
2079 && automatic == that.automatic
2080 && synthetic == that.synthetic
2081 && requires.equals(that.requires)
2082 && exports.equals(that.exports)
2083 && opens.equals(that.opens)
2084 && uses.equals(that.uses)
2085 && provides.equals(that.provides)
2086 && Objects.equals(version, that.version)
2087 && Objects.equals(mainClass, that.mainClass)
2088 && Objects.equals(osName, that.osName)
2089 && Objects.equals(osArch, that.osArch)
2090 && Objects.equals(osVersion, that.osVersion)
2091 && Objects.equals(packages, that.packages)
2092 && Objects.equals(hashes, that.hashes));
2093 }
2094
2095 private transient int hash; // cached hash code
2096
2097 /**
2098 * Computes a hash code for this module descriptor.
2099 *
2100 * <p> The hash code is based upon the components of the module descriptor,
2101 * and satisfies the general contract of the {@link Object#hashCode
2102 * Object.hashCode} method. </p>
2103 *
2104 * @return The hash-code value for this module descriptor
2105 */
2106 @Override
2107 public int hashCode() {
2108 int hc = hash;
2109 if (hc == 0) {
2110 hc = name.hashCode();
2111 hc = hc * 43 + Boolean.hashCode(open);
2112 hc = hc * 43 + Boolean.hashCode(automatic);
2113 hc = hc * 43 + Boolean.hashCode(synthetic);
2114 hc = hc * 43 + requires.hashCode();
2115 hc = hc * 43 + exports.hashCode();
2116 hc = hc * 43 + opens.hashCode();
2117 hc = hc * 43 + uses.hashCode();
2118 hc = hc * 43 + provides.hashCode();
2119 hc = hc * 43 + Objects.hashCode(version);
2120 hc = hc * 43 + Objects.hashCode(mainClass);
2121 hc = hc * 43 + Objects.hashCode(osName);
2122 hc = hc * 43 + Objects.hashCode(osArch);
2123 hc = hc * 43 + Objects.hashCode(osVersion);
2124 hc = hc * 43 + Objects.hashCode(packages);
2125 hc = hc * 43 + Objects.hashCode(hashes);
2126 if (hc == 0)
2127 hc = -1;
2128 hash = hc;
2129 }
2130 return hc;
2131 }
2132
2133 /**
2134 * Returns a string describing this descriptor.
2135 *
2136 * @return A string describing this descriptor
2137 */
2138 @Override
2139 public String toString() {
2140 StringBuilder sb = new StringBuilder();
2141
2142 if (isOpen())
2143 sb.append("open ");
2144 sb.append("module { name: ").append(toNameAndVersion());
2145 if (!requires.isEmpty())
2431 return new ModuleDescriptor(md, pkgs);
2432 }
2433
2434 @Override
2435 public ModuleDescriptor newModuleDescriptor(String name,
2436 boolean open,
2437 boolean automatic,
2438 boolean synthetic,
2439 Set<Requires> requires,
2440 Set<Exports> exports,
2441 Set<Opens> opens,
2442 Set<String> uses,
2443 Set<Provides> provides,
2444 Version version,
2445 String mainClass,
2446 String osName,
2447 String osArch,
2448 String osVersion,
2449 Set<String> packages,
2450 ModuleHashes hashes,
2451 int hashCode) {
2452 return new ModuleDescriptor(name,
2453 open,
2454 automatic,
2455 synthetic,
2456 requires,
2457 exports,
2458 opens,
2459 uses,
2460 provides,
2461 version,
2462 mainClass,
2463 osName,
2464 osArch,
2465 osVersion,
2466 packages,
2467 hashes,
2468 hashCode,
2469 false);
2470 }
2471
2472 @Override
2473 public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
2474 return descriptor.hashes();
2475 }
2476
2477 @Override
2478 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2479 Collection<String> roots,
2480 boolean check,
2481 PrintStream traceOutput)
2482 {
2483 return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2484 }
2485
2486 @Override
2487 public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
2488 URI location,
2489 Supplier<ModuleReader> s) {
2490 return new ModuleReference(descriptor, location, s, true, null);
2491 }
2492
2493 @Override
2494 public ModuleFinder newModulePath(Runtime.Version version,
2495 boolean isLinkPhase,
2496 Path... entries) {
2497 return new ModulePath(version, isLinkPhase, entries);
2498 }
2499 });
2500 }
2501
2502 }
|
36 import java.util.Collection;
37 import java.util.Collections;
38 import java.util.EnumSet;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.LinkedHashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Objects;
45 import java.util.Optional;
46 import java.util.Set;
47 import java.util.function.Supplier;
48 import java.util.stream.Collectors;
49 import java.util.stream.Stream;
50
51 import static jdk.internal.module.Checks.*;
52 import static java.util.Objects.*;
53
54 import jdk.internal.module.Checks;
55 import jdk.internal.module.ModuleHashes;
56 import jdk.internal.module.WarnIfResolvedReason;
57
58
59 /**
60 * A module descriptor.
61 *
62 * <p> A {@code ModuleDescriptor} is typically created from the binary form
63 * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
64 * class can be used to create a {@code ModuleDescriptor} from its components.
65 * The {@link #module module}, {@link #openModule openModule}, and {@link
66 * #automaticModule automaticModule} methods create builders for building
67 * different kinds of modules. </p>
68 *
69 * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
70 * multiple concurrent threads.</p>
71 *
72 * @since 9
73 * @see java.lang.reflect.Module
74 */
75
76 public class ModuleDescriptor
976 // Indicates if synthesised for a JAR file found on the module path
977 private final boolean automatic;
978
979 // Not generated from a module-info.java
980 private final boolean synthetic;
981
982 private final Set<Requires> requires;
983 private final Set<Exports> exports;
984 private final Set<Opens> opens;
985 private final Set<String> uses;
986 private final Set<Provides> provides;
987
988 // "Extended" information, added post-compilation by tools
989 private final Version version;
990 private final String mainClass;
991 private final String osName;
992 private final String osArch;
993 private final String osVersion;
994 private final Set<String> packages;
995 private final ModuleHashes hashes;
996 private final boolean doNotResolveByDefault;
997 private final WarnIfResolvedReason warnIfResolvedReason;
998
999
1000 private ModuleDescriptor(String name,
1001 boolean open,
1002 boolean automatic,
1003 boolean synthetic,
1004 Set<Requires> requires,
1005 Set<Exports> exports,
1006 Set<Opens> opens,
1007 Set<String> uses,
1008 Set<Provides> provides,
1009 Version version,
1010 String mainClass,
1011 String osName,
1012 String osArch,
1013 String osVersion,
1014 Set<String> packages,
1015 ModuleHashes hashes,
1016 boolean doNotResolveByDefault,
1017 WarnIfResolvedReason warnIfResolvedReason)
1018 {
1019
1020 this.name = name;
1021 this.open = open;
1022 this.automatic = automatic;
1023 this.synthetic = synthetic;
1024
1025 assert (requires.stream().map(Requires::name).distinct().count()
1026 == requires.size());
1027 this.requires = emptyOrUnmodifiableSet(requires);
1028
1029 this.exports = emptyOrUnmodifiableSet(exports);
1030 this.opens = emptyOrUnmodifiableSet(opens);
1031 this.uses = emptyOrUnmodifiableSet(uses);
1032 this.provides = emptyOrUnmodifiableSet(provides);
1033 this.version = version;
1034 this.mainClass = mainClass;
1035 this.osName = osName;
1036 this.osArch = osArch;
1037 this.osVersion = osVersion;
1038 this.hashes = hashes;
1039 this.packages = emptyOrUnmodifiableSet(packages);
1040 this.doNotResolveByDefault = doNotResolveByDefault;
1041 this.warnIfResolvedReason = warnIfResolvedReason;
1042 }
1043
1044 /**
1045 * Clones the given module descriptor with an augmented set of packages
1046 */
1047 ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1048 this.name = md.name;
1049 this.open = md.open;
1050 this.automatic = md.automatic;
1051 this.synthetic = md.synthetic;
1052
1053 this.requires = md.requires;
1054 this.exports = md.exports;
1055 this.opens = md.opens;
1056 this.uses = md.uses;
1057 this.provides = md.provides;
1058
1059 this.version = md.version;
1060 this.mainClass = md.mainClass;
1061 this.osName = md.osName;
1062 this.osArch = md.osArch;
1063 this.osVersion = md.osVersion;
1064 this.hashes = null; // need to ignore
1065 this.doNotResolveByDefault = md.doNotResolveByDefault;
1066 this.warnIfResolvedReason = md.warnIfResolvedReason;
1067
1068 Set<String> packages = new HashSet<>(md.packages);
1069 packages.addAll(pkgs);
1070 this.packages = emptyOrUnmodifiableSet(packages);
1071 }
1072
1073 /**
1074 * Creates a module descriptor from its components.
1075 * The arguments are pre-validated and sets are unmodifiable sets.
1076 */
1077 ModuleDescriptor(String name,
1078 boolean open,
1079 boolean automatic,
1080 boolean synthetic,
1081 Set<Requires> requires,
1082 Set<Exports> exports,
1083 Set<Opens> opens,
1084 Set<String> uses,
1085 Set<Provides> provides,
1086 Version version,
1087 String mainClass,
1088 String osName,
1089 String osArch,
1090 String osVersion,
1091 Set<String> packages,
1092 ModuleHashes hashes,
1093 int hashCode,
1094 boolean doNotResolveByDefault,
1095 WarnIfResolvedReason warnIfResolvedReason,
1096 boolean unused) {
1097 this.name = name;
1098 this.open = open;
1099 this.automatic = automatic;
1100 this.synthetic = synthetic;
1101 this.requires = requires;
1102 this.exports = exports;
1103 this.opens = opens;
1104 this.uses = uses;
1105 this.provides = provides;
1106 this.packages = packages;
1107 this.version = version;
1108 this.mainClass = mainClass;
1109 this.osName = osName;
1110 this.osArch = osArch;
1111 this.osVersion = osVersion;
1112 this.hashes = hashes;
1113 this.hash = hashCode;
1114 this.doNotResolveByDefault = doNotResolveByDefault;
1115 this.warnIfResolvedReason = warnIfResolvedReason;
1116 }
1117
1118 /**
1119 * <p> The module name. </p>
1120 *
1121 * @return The module name
1122 */
1123 public String name() {
1124 return name;
1125 }
1126
1127 /**
1128 * <p> Returns {@code true} if this is an open module. </p>
1129 *
1130 * <p> An open module does not declare any open packages (the {@link #opens()
1131 * opens} method returns an empty set) but the resulting module is treated
1132 * as if all packages are open. </p>
1133 *
1134 * @return {@code true} if this is an open module
1135 */
1287 public Optional<String> osVersion() {
1288 return Optional.ofNullable(osVersion);
1289 }
1290
1291 /**
1292 * Returns the names of all packages in this module.
1293 *
1294 * @return A possibly-empty unmodifiable set of all packages in the module
1295 */
1296 public Set<String> packages() {
1297 return packages;
1298 }
1299
1300 /**
1301 * Returns the object with the hashes of other modules
1302 */
1303 Optional<ModuleHashes> hashes() {
1304 return Optional.ofNullable(hashes);
1305 }
1306
1307 /* package */ boolean doNotResolveByDefault() {
1308 return doNotResolveByDefault;
1309 }
1310
1311
1312 /**
1313 * A builder used for building {@link ModuleDescriptor} objects.
1314 *
1315 * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1316 * #openModule openModule}, and {@link #automaticModule automaticModule}
1317 * methods to create builders for building different kinds of modules. </p>
1318 *
1319 * <p> Example usage: </p>
1320 * <pre>{@code ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1321 * .exports("p")
1322 * .requires("m2")
1323 * .build();
1324 * }</pre>
1325 *
1326 * @apiNote A {@code Builder} checks the components and invariants as
1327 * components are added to the builder. The rational for this is to detect
1328 * errors as early as possible and not defer all validation to the
1329 * {@link #build build} method. A {@code Builder} cannot be used to create
1330 * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
1334 public static final class Builder {
1335 final String name;
1336 final boolean strict; // true if module names are checked
1337 boolean open;
1338 boolean automatic;
1339 boolean synthetic;
1340 final Map<String, Requires> requires = new HashMap<>();
1341
1342 final Map<String, Exports> exports = new HashMap<>();
1343 final Map<String, Opens> opens = new HashMap<>();
1344 final Set<String> concealedPackages = new HashSet<>();
1345
1346 final Set<String> uses = new HashSet<>();
1347 final Map<String, Provides> provides = new HashMap<>();
1348 Version version;
1349 String osName;
1350 String osArch;
1351 String osVersion;
1352 String mainClass;
1353 ModuleHashes hashes;
1354 boolean doNotResolveByDefault;
1355 WarnIfResolvedReason warnIfResolvedReason = WarnIfResolvedReason.NONE;
1356
1357 /**
1358 * Initializes a new builder with the given module name.
1359 *
1360 * @param strict
1361 * Indicates whether module names are checked or not
1362 */
1363 Builder(String name, boolean strict) {
1364 this.strict = strict;
1365 this.name = (strict) ? requireModuleName(name) : name;
1366 }
1367
1368 /* package */ Builder open(boolean open) {
1369 this.open = open;
1370 return this;
1371 }
1372
1373 /* package */ Builder automatic(boolean automatic) {
1374 this.automatic = automatic;
1375 return this;
1707 /**
1708 * Adds an <em>opens</em> directive to open a package.
1709 *
1710 * @param pn
1711 * The package name
1712 *
1713 * @return This builder
1714 *
1715 * @throws IllegalArgumentException
1716 * If the package name is {@code null} or is not a legal Java
1717 * identifier
1718 * @throws IllegalStateException
1719 * If the package is already declared as a package with the
1720 * {@link #contains contains} method, the package is already
1721 * declared as open, or this is a builder for an open module
1722 */
1723 public Builder opens(String pn) {
1724 return opens(Collections.emptySet(), pn);
1725 }
1726
1727 /* package */ Builder doNotResolveByDefault(boolean value) {
1728 this.doNotResolveByDefault = value;
1729 return this;
1730 }
1731
1732 /* package */ Builder warnIfResolved(WarnIfResolvedReason reason) {
1733 this.warnIfResolvedReason = reason;
1734 return this;
1735 }
1736
1737 // Used by ModuleInfo, after a packageFinder is invoked
1738 /* package */ Set<String> exportedAndOpenPackages() {
1739 if (opens.isEmpty())
1740 return exports.keySet();
1741 Set<String> result = new HashSet<>();
1742 result.addAll(exports.keySet());
1743 result.addAll(opens.keySet());
1744 return result;
1745 }
1746
1747 /**
1748 * Adds a service dependence.
1749 *
1750 * @param service
1751 * The service type
1752 *
1753 * @return This builder
1754 *
1755 * @throws IllegalArgumentException
2024 Set<Exports> exports = new HashSet<>(this.exports.values());
2025 Set<Opens> opens = new HashSet<>(this.opens.values());
2026
2027 Set<Provides> provides = new HashSet<>(this.provides.values());
2028
2029 return new ModuleDescriptor(name,
2030 open,
2031 automatic,
2032 synthetic,
2033 requires,
2034 exports,
2035 opens,
2036 uses,
2037 provides,
2038 version,
2039 mainClass,
2040 osName,
2041 osArch,
2042 osVersion,
2043 packages,
2044 hashes,
2045 doNotResolveByDefault,
2046 warnIfResolvedReason);
2047 }
2048
2049 }
2050
2051 /**
2052 * Compares this module descriptor to another.
2053 *
2054 * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2055 * module name lexicographically. Where the module names are equal then
2056 * the versions, if present, are compared. </p>
2057 *
2058 * @apiNote For now, the natural ordering is not consistent with equals.
2059 * If two module descriptors have equal module names, equal versions if
2060 * present, but their corresponding components are not equal, then they
2061 * will be considered equal by this method.
2062 *
2063 * @param that
2064 * The object to which this module descriptor is to be compared
2065 *
2066 * @return A negative integer, zero, or a positive integer if this module
2102 if (ob == this)
2103 return true;
2104 if (!(ob instanceof ModuleDescriptor))
2105 return false;
2106 ModuleDescriptor that = (ModuleDescriptor)ob;
2107 return (name.equals(that.name)
2108 && open == that.open
2109 && automatic == that.automatic
2110 && synthetic == that.synthetic
2111 && requires.equals(that.requires)
2112 && exports.equals(that.exports)
2113 && opens.equals(that.opens)
2114 && uses.equals(that.uses)
2115 && provides.equals(that.provides)
2116 && Objects.equals(version, that.version)
2117 && Objects.equals(mainClass, that.mainClass)
2118 && Objects.equals(osName, that.osName)
2119 && Objects.equals(osArch, that.osArch)
2120 && Objects.equals(osVersion, that.osVersion)
2121 && Objects.equals(packages, that.packages)
2122 && Objects.equals(hashes, that.hashes)
2123 && doNotResolveByDefault == that.doNotResolveByDefault
2124 && warnIfResolvedReason == that.warnIfResolvedReason);
2125 }
2126
2127 private transient int hash; // cached hash code
2128
2129 /**
2130 * Computes a hash code for this module descriptor.
2131 *
2132 * <p> The hash code is based upon the components of the module descriptor,
2133 * and satisfies the general contract of the {@link Object#hashCode
2134 * Object.hashCode} method. </p>
2135 *
2136 * @return The hash-code value for this module descriptor
2137 */
2138 @Override
2139 public int hashCode() {
2140 int hc = hash;
2141 if (hc == 0) {
2142 hc = name.hashCode();
2143 hc = hc * 43 + Boolean.hashCode(open);
2144 hc = hc * 43 + Boolean.hashCode(automatic);
2145 hc = hc * 43 + Boolean.hashCode(synthetic);
2146 hc = hc * 43 + requires.hashCode();
2147 hc = hc * 43 + exports.hashCode();
2148 hc = hc * 43 + opens.hashCode();
2149 hc = hc * 43 + uses.hashCode();
2150 hc = hc * 43 + provides.hashCode();
2151 hc = hc * 43 + Objects.hashCode(version);
2152 hc = hc * 43 + Objects.hashCode(mainClass);
2153 hc = hc * 43 + Objects.hashCode(osName);
2154 hc = hc * 43 + Objects.hashCode(osArch);
2155 hc = hc * 43 + Objects.hashCode(osVersion);
2156 hc = hc * 43 + Objects.hashCode(packages);
2157 hc = hc * 43 + Objects.hashCode(hashes);
2158 hc = hc * 43 + Objects.hashCode(doNotResolveByDefault);
2159 hc = hc * 43 + Objects.hashCode(warnIfResolvedReason);
2160 if (hc == 0)
2161 hc = -1;
2162 hash = hc;
2163 }
2164 return hc;
2165 }
2166
2167 /**
2168 * Returns a string describing this descriptor.
2169 *
2170 * @return A string describing this descriptor
2171 */
2172 @Override
2173 public String toString() {
2174 StringBuilder sb = new StringBuilder();
2175
2176 if (isOpen())
2177 sb.append("open ");
2178 sb.append("module { name: ").append(toNameAndVersion());
2179 if (!requires.isEmpty())
2465 return new ModuleDescriptor(md, pkgs);
2466 }
2467
2468 @Override
2469 public ModuleDescriptor newModuleDescriptor(String name,
2470 boolean open,
2471 boolean automatic,
2472 boolean synthetic,
2473 Set<Requires> requires,
2474 Set<Exports> exports,
2475 Set<Opens> opens,
2476 Set<String> uses,
2477 Set<Provides> provides,
2478 Version version,
2479 String mainClass,
2480 String osName,
2481 String osArch,
2482 String osVersion,
2483 Set<String> packages,
2484 ModuleHashes hashes,
2485 int hashCode,
2486 boolean doNotResolveByDefault,
2487 WarnIfResolvedReason reason) {
2488 return new ModuleDescriptor(name,
2489 open,
2490 automatic,
2491 synthetic,
2492 requires,
2493 exports,
2494 opens,
2495 uses,
2496 provides,
2497 version,
2498 mainClass,
2499 osName,
2500 osArch,
2501 osVersion,
2502 packages,
2503 hashes,
2504 hashCode,
2505 doNotResolveByDefault,
2506 reason,
2507 false);
2508 }
2509
2510 @Override
2511 public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
2512 return descriptor.hashes();
2513 }
2514
2515 @Override
2516 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2517 Collection<String> roots,
2518 boolean check,
2519 PrintStream traceOutput)
2520 {
2521 return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2522 }
2523
2524 @Override
2525 public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
2526 URI location,
2527 Supplier<ModuleReader> s) {
2528 return new ModuleReference(descriptor, location, s, true, null);
2529 }
2530
2531 @Override
2532 public boolean doNotResolveByDefault(ModuleDescriptor descriptor) {
2533 return descriptor.doNotResolveByDefault;
2534 }
2535
2536 @Override
2537 public WarnIfResolvedReason warnIfResolvedReason(ModuleDescriptor descriptor) {
2538 return descriptor.warnIfResolvedReason;
2539 }
2540
2541 @Override
2542 public ModuleFinder newModulePath(Runtime.Version version,
2543 boolean isLinkPhase,
2544 Path... entries) {
2545 return new ModulePath(version, isLinkPhase, entries);
2546 }
2547 });
2548 }
2549
2550 }
|