162 */
163 STATIC,
164
165 /**
166 * The dependence was not explicitly or implicitly declared in the
167 * source of the module declaration.
168 */
169 SYNTHETIC,
170
171 /**
172 * The dependence was implicitly declared in the source of the module
173 * declaration.
174 */
175 MANDATED;
176
177 }
178
179 private final Set<Modifier> mods;
180 private final String name;
181 private final Version compiledVersion;
182
183 private Requires(Set<Modifier> ms, String mn, Version v) {
184 if (ms.isEmpty()) {
185 ms = Collections.emptySet();
186 } else {
187 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
188 }
189 this.mods = ms;
190 this.name = mn;
191 this.compiledVersion = v;
192 }
193
194 private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
195 this.mods = ms;
196 this.name = mn;
197 this.compiledVersion = v;
198 }
199
200 /**
201 * Returns the set of modifiers.
202 *
203 * @return A possibly-empty unmodifiable set of modifiers
204 */
205 public Set<Modifier> modifiers() {
206 return mods;
207 }
208
209 /**
210 * Return the module name.
211 *
212 * @return The module name
213 */
214 public String name() {
215 return name;
216 }
217
218 /**
219 * Returns the version of the module if recorded at compile-time.
220 *
221 * @return The version of the module if recorded at compile-time
222 */
223 public Optional<Version> compiledVersion() {
224 return Optional.ofNullable(compiledVersion);
225 }
226
227 /**
228 * Compares this module dependence to another.
229 *
230 * <p> Two {@code Requires} objects are compared by comparing their
231 * module names lexicographically. Where the module names are equal
232 * then the sets of modifiers are compared in the same way that
233 * module modifiers are compared (see {@link ModuleDescriptor#compareTo
234 * ModuleDescriptor.compareTo}). Where the module names are equal and
235 * the set of modifiers are equal then the version of the modules
236 * recorded at compile-time are compared. When comparing the versions
237 * recorded at compile-time then a dependence that has a recorded
238 * version is considered to succeed a dependence that does not have a
239 * recorded version. </p>
240 *
241 * @param that
242 * The module dependence to compare
243 *
244 * @return A negative integer, zero, or a positive integer if this module
245 * dependence is less than, equal to, or greater than the given
246 * module dependence
247 */
248 @Override
249 public int compareTo(Requires that) {
250 if (this == that) return 0;
251
252 int c = this.name().compareTo(that.name());
253 if (c != 0) return c;
254
255 // modifiers
256 long v1 = modsValue(this.modifiers());
257 long v2 = modsValue(that.modifiers());
258 c = Long.compare(v1, v2);
259 if (c != 0) return c;
260
261 // compiledVersion
262 c = compare(this.compiledVersion, that.compiledVersion);
263 if (c != 0) return c;
264
265 return 0;
266 }
267
268 /**
269 * Tests this module dependence for equality with the given object.
270 *
271 * <p> If the given object is not a {@code Requires} then this method
272 * returns {@code false}. Two module dependence objects are equal if
273 * the module names are equal, set of modifiers are equal, and the
274 * compiled version of both modules is equal or not recorded for
275 * both modules. </p>
276 *
277 * <p> This method satisfies the general contract of the {@link
278 * java.lang.Object#equals(Object) Object.equals} method. </p>
279 *
280 * @param ob
281 * the object to which this object is to be compared
282 *
283 * @return {@code true} if, and only if, the given object is a module
284 * dependence that is equal to this module dependence
285 */
286 @Override
287 public boolean equals(Object ob) {
288 if (!(ob instanceof Requires))
289 return false;
290 Requires that = (Requires)ob;
291 return name.equals(that.name) && mods.equals(that.mods)
292 && Objects.equals(compiledVersion, that.compiledVersion);
293 }
294
295 /**
296 * Computes a hash code for this module dependence.
297 *
298 * <p> The hash code is based upon the module name, modifiers, and the
299 * module version if recorded at compile time. It satisfies the general
300 * contract of the {@link Object#hashCode Object.hashCode} method. </p>
301 *
302 * @return The hash-code value for this module dependence
303 */
304 @Override
305 public int hashCode() {
306 int hash = name.hashCode() * 43 + mods.hashCode();
307 if (compiledVersion != null)
308 hash = hash * 43 + compiledVersion.hashCode();
309 return hash;
310 }
311
312 /**
313 * Returns a string describing this module dependence.
314 *
315 * @return A string describing this module dependence
316 */
317 @Override
318 public String toString() {
319 String what;
320 if (compiledVersion != null) {
321 what = name() + " (@" + compiledVersion + ")";
322 } else {
323 what = name();
324 }
325 return ModuleDescriptor.toString(mods, what);
326 }
327 }
328
757
758 public final static class Provides
759 implements Comparable<Provides>
760 {
761 private final String service;
762 private final List<String> providers;
763
764 private Provides(String service, List<String> providers) {
765 this.service = service;
766 this.providers = Collections.unmodifiableList(providers);
767 }
768
769 private Provides(String service, List<String> providers, boolean unused) {
770 this.service = service;
771 this.providers = providers;
772 }
773
774 /**
775 * Returns the fully qualified class name of the service type.
776 *
777 * @return The fully qualified class name of the service type.
778 */
779 public String service() { return service; }
780
781 /**
782 * Returns the list of the fully qualified class names of the providers
783 * or provider factories.
784 *
785 * @return A non-empty and unmodifiable list of the fully qualified class
786 * names of the providers or provider factories
787 */
788 public List<String> providers() { return providers; }
789
790 /**
791 * Compares this provides to another.
792 *
793 * <p> Two {@code Provides} objects are compared by comparing the fully
794 * qualified class name of the service type lexicographically. Where the
795 * class names are equal then the list of the provider class names are
796 * compared by comparing the corresponding elements of both lists
797 * lexicographically and in sequence. Where the lists differ in size,
1182 @Override
1183 public int hashCode() {
1184 return version.hashCode();
1185 }
1186
1187 /**
1188 * Returns the string from which this version was parsed.
1189 *
1190 * @return The string from which this version was parsed.
1191 */
1192 @Override
1193 public String toString() {
1194 return version;
1195 }
1196
1197 }
1198
1199
1200 private final String name;
1201 private final Version version;
1202 private final Set<Modifier> modifiers;
1203 private final boolean open; // true if modifiers contains OPEN
1204 private final boolean automatic; // true if modifiers contains AUTOMATIC
1205 private final Set<Requires> requires;
1206 private final Set<Exports> exports;
1207 private final Set<Opens> opens;
1208 private final Set<String> uses;
1209 private final Set<Provides> provides;
1210 private final Set<String> packages;
1211 private final String mainClass;
1212 private final String osName;
1213 private final String osArch;
1214 private final String osVersion;
1215
1216 private ModuleDescriptor(String name,
1217 Version version,
1218 Set<Modifier> modifiers,
1219 Set<Requires> requires,
1220 Set<Exports> exports,
1221 Set<Opens> opens,
1222 Set<String> uses,
1223 Set<Provides> provides,
1224 Set<String> packages,
1225 String mainClass,
1226 String osName,
1227 String osArch,
1228 String osVersion)
1229 {
1230 this.name = name;
1231 this.version = version;
1232 this.modifiers = emptyOrUnmodifiableSet(modifiers);
1233 this.open = modifiers.contains(Modifier.OPEN);
1234 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1235 assert (requires.stream().map(Requires::name).distinct().count()
1236 == requires.size());
1237 this.requires = emptyOrUnmodifiableSet(requires);
1238 this.exports = emptyOrUnmodifiableSet(exports);
1239 this.opens = emptyOrUnmodifiableSet(opens);
1240 this.uses = emptyOrUnmodifiableSet(uses);
1241 this.provides = emptyOrUnmodifiableSet(provides);
1242
1243 this.packages = emptyOrUnmodifiableSet(packages);
1244 this.mainClass = mainClass;
1245 this.osName = osName;
1246 this.osArch = osArch;
1247 this.osVersion = osVersion;
1248 }
1249
1250 /**
1251 * Creates a module descriptor from its components.
1252 * The arguments are pre-validated and sets are unmodifiable sets.
1253 */
1254 ModuleDescriptor(String name,
1255 Version version,
1256 Set<Modifier> modifiers,
1257 Set<Requires> requires,
1258 Set<Exports> exports,
1259 Set<Opens> opens,
1260 Set<String> uses,
1261 Set<Provides> provides,
1262 Set<String> packages,
1263 String mainClass,
1264 String osName,
1265 String osArch,
1266 String osVersion,
1267 int hashCode,
1268 boolean unused) {
1269 this.name = name;
1270 this.version = version;
1271 this.modifiers = modifiers;
1272 this.open = modifiers.contains(Modifier.OPEN);
1273 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1274 this.requires = requires;
1275 this.exports = exports;
1276 this.opens = opens;
1277 this.uses = uses;
1278 this.provides = provides;
1279 this.packages = packages;
1280 this.mainClass = mainClass;
1281 this.osName = osName;
1282 this.osArch = osArch;
1283 this.osVersion = osVersion;
1284 this.hash = hashCode;
1285 }
1286
1287 /**
1288 * <p> Returns the module name. </p>
1289 *
1290 * @return The module name
1291 */
1292 public String name() {
1293 return name;
1294 }
1295
1296 /**
1297 * <p> Returns the set of module modifiers. </p>
1298 *
1299 * @return A possibly-empty unmodifiable set of modifiers
1300 */
1301 public Set<Modifier> modifiers() {
1302 return modifiers;
1303 }
1377 * names of the service types used
1378 */
1379 public Set<String> uses() {
1380 return uses;
1381 }
1382
1383 /**
1384 * <p> Returns the set of {@code Provides} objects representing the
1385 * services that the module provides. </p>
1386 *
1387 * @return The possibly-empty unmodifiable set of the services that this
1388 * module provides
1389 */
1390 public Set<Provides> provides() {
1391 return provides;
1392 }
1393
1394 /**
1395 * <p> Returns the module version. </p>
1396 *
1397 * @return This module's version
1398 */
1399 public Optional<Version> version() {
1400 return Optional.ofNullable(version);
1401 }
1402
1403 /**
1404 * <p> Returns a string containing the module name and, if present, its
1405 * version. </p>
1406 *
1407 * @return A string containing the module name and, if present, its
1408 * version.
1409 */
1410 public String toNameAndVersion() {
1411 if (version != null) {
1412 return name() + "@" + version;
1413 } else {
1414 return name();
1415 }
1416 }
1417
1418 /**
1419 * <p> Returns the module main class. </p>
1420 *
1421 * @return The fully qualified class name of the module's main class
1422 */
1423 public Optional<String> mainClass() {
1424 return Optional.ofNullable(mainClass);
1425 }
1426
1427 /**
1428 * Returns the operating system name if the module is operating system
1429 * specific.
1430 *
1431 * @return The operating system name or an empty {@code Optional}
1432 * if the module is not operating system specific
1433 */
1434 public Optional<String> osName() {
1435 return Optional.ofNullable(osName);
1436 }
1437
1438 /**
1439 * Returns the operating system architecture if the module is operating
1440 * system architecture specific.
1441 *
1442 * @return The operating system architecture or an empty {@code Optional}
1443 * if the module is not operating system architecture specific
1444 */
1445 public Optional<String> osArch() {
1446 return Optional.ofNullable(osArch);
1447 }
1448
1449 /**
1450 * Returns the operating system version if the module is operating
1451 * system version specific.
1452 *
1453 * @return The operating system version or an empty {@code Optional}
1454 * if the module is not operating system version specific
1455 */
1456 public Optional<String> osVersion() {
1457 return Optional.ofNullable(osVersion);
1458 }
1459
1460 /**
1461 * Returns the set of packages in the module.
1462 *
1463 * @return A possibly-empty unmodifiable set of the packages in the module
1464 */
1465 public Set<String> packages() {
1466 return packages;
1467 }
1468
1469
1470 /**
1471 * A builder for building {@link ModuleDescriptor} objects.
1472 *
1473 * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
1474 * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
1475 * newAutomaticModule} methods to create builders for building
1476 * <em>normal</em>, open, and automatic modules. </p>
1477 *
1478 * <p> The set of packages in the module are accumulated by the {@code
1479 * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
1480 * {@link ModuleDescriptor.Builder#opens(String) opens},
1481 * {@link ModuleDescriptor.Builder#packages(Set) packages},
1482 * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
1501 * components are added to the builder. The rationale for this is to detect
1502 * errors as early as possible and not defer all validation to the
1503 * {@link #build build} method.
1504 *
1505 * @since 9
1506 * @spec JPMS
1507 */
1508 public static final class Builder {
1509 final String name;
1510 final boolean strict;
1511 final Set<Modifier> modifiers;
1512 final boolean open;
1513 final boolean automatic;
1514 final Set<String> packages = new HashSet<>();
1515 final Map<String, Requires> requires = new HashMap<>();
1516 final Map<String, Exports> exports = new HashMap<>();
1517 final Map<String, Opens> opens = new HashMap<>();
1518 final Set<String> uses = new HashSet<>();
1519 final Map<String, Provides> provides = new HashMap<>();
1520 Version version;
1521 String osName;
1522 String osArch;
1523 String osVersion;
1524 String mainClass;
1525
1526 /**
1527 * Initializes a new builder with the given module name.
1528 *
1529 * If {@code strict} is {@code true} then module, package, and class
1530 * names are checked to ensure they are legal names. In addition, the
1531 * {@link #build buid} method will add "{@code requires java.base}" if
1532 * the dependency is not declared.
1533 */
1534 Builder(String name, boolean strict, Set<Modifier> modifiers) {
1535 this.name = (strict) ? requireModuleName(name) : name;
1536 this.strict = strict;
1537 this.modifiers = modifiers;
1538 this.open = modifiers.contains(Modifier.OPEN);
1539 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1540 assert !open || !automatic;
1541 }
1542
1543 /**
1587 * The module name
1588 * @param compiledVersion
1589 * The version of the module recorded at compile-time
1590 *
1591 * @return This builder
1592 *
1593 * @throws IllegalArgumentException
1594 * If the module name is {@code null}, is not a legal module
1595 * name, or is equal to the module name that this builder
1596 * was initialized to build
1597 * @throws IllegalStateException
1598 * If the dependence on the module has already been declared
1599 * or this builder is for an automatic module
1600 */
1601 public Builder requires(Set<Requires.Modifier> ms,
1602 String mn,
1603 Version compiledVersion) {
1604 Objects.requireNonNull(compiledVersion);
1605 if (strict)
1606 mn = requireModuleName(mn);
1607 return requires(new Requires(ms, mn, compiledVersion));
1608 }
1609
1610 /* package */Builder requires(Set<Requires.Modifier> ms,
1611 String mn,
1612 String compiledVersion) {
1613 Version v = null;
1614 try {
1615 v = Version.parse(compiledVersion);
1616 } catch (IllegalArgumentException e) {
1617 // for now, drop un-parsable version when non-strict
1618 if (strict) throw e;
1619 }
1620 if (v == null) {
1621 return requires(ms, mn);
1622 } else {
1623 return requires(ms, mn, v);
1624 }
1625 }
1626
1627 /**
1628 * Adds a dependence on a module with the given (and possibly empty)
1629 * set of modifiers.
1630 *
1631 * @param ms
1632 * The set of modifiers
1633 * @param mn
1634 * The module name
1635 *
1636 * @return This builder
1637 *
1638 * @throws IllegalArgumentException
1639 * If the module name is {@code null}, is not a legal module
1640 * name, or is equal to the module name that this builder
1641 * was initialized to build
1642 * @throws IllegalStateException
1643 * If the dependence on the module has already been declared
1644 * or this builder is for an automatic module
1645 */
1646 public Builder requires(Set<Requires.Modifier> ms, String mn) {
1647 if (strict)
1648 mn = requireModuleName(mn);
1649 return requires(new Requires(ms, mn, null));
1650 }
1651
1652 /**
1653 * Adds a dependence on a module with an empty set of modifiers.
1654 *
1655 * @param mn
1656 * The module name
1657 *
1658 * @return This builder
1659 *
1660 * @throws IllegalArgumentException
1661 * If the module name is {@code null}, is not a legal module
1662 * name, or is equal to the module name that this builder
1663 * was initialized to build
1664 * @throws IllegalStateException
1665 * If the dependence on the module has already been declared
1666 * or this builder is for an automatic module
1667 */
1668 public Builder requires(String mn) {
1669 return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1935 * If the package is already declared as open, or this is a
1936 * builder for an open module or automatic module
1937 */
1938 public Builder opens(String pn) {
1939 return opens(Collections.emptySet(), pn);
1940 }
1941
1942 /**
1943 * Adds a service dependence.
1944 *
1945 * @param service
1946 * The service type
1947 *
1948 * @return This builder
1949 *
1950 * @throws IllegalArgumentException
1951 * If the service type is {@code null} or not a qualified name of
1952 * a class in a named package
1953 * @throws IllegalStateException
1954 * If a dependency on the service type has already been declared
1955 * or this is a builder for an an automatic module
1956 */
1957 public Builder uses(String service) {
1958 if (automatic)
1959 throw new IllegalStateException("Automatic modules can not declare"
1960 + " service dependences");
1961 if (uses.contains(requireServiceTypeName(service)))
1962 throw new IllegalStateException("Dependence upon service "
1963 + service + " already declared");
1964 uses.add(service);
1965 return this;
1966 }
1967
1968 /**
1969 * Provides a service with one or more implementations. The package for
1970 * each {@link Provides#providers provider} (or provider factory) is
1971 * added to the module if not already added.
1972 *
1973 * @param p
1974 * The provides
1975 *
2051 */
2052 public Builder packages(Set<String> pns) {
2053 if (strict) {
2054 pns = new HashSet<>(pns);
2055 pns.forEach(Checks::requirePackageName);
2056 }
2057 this.packages.addAll(pns);
2058 return this;
2059 }
2060
2061 /**
2062 * Sets the module version.
2063 *
2064 * @param v
2065 * The version
2066 *
2067 * @return This builder
2068 */
2069 public Builder version(Version v) {
2070 version = requireNonNull(v);
2071 return this;
2072 }
2073
2074 /**
2075 * Sets the module version.
2076 *
2077 * @param vs
2078 * The version string to parse
2079 *
2080 * @return This builder
2081 *
2082 * @throws IllegalArgumentException
2083 * If {@code vs} is {@code null} or cannot be parsed as a
2084 * version string
2085 *
2086 * @see Version#parse(String)
2087 */
2088 public Builder version(String vs) {
2089 Version v;
2090 if (strict) {
2091 v = Version.parse(vs);
2092 } else {
2093 try {
2094 v = Version.parse(vs);
2095 } catch (IllegalArgumentException ignore) {
2096 // for now, ignore when non-strict
2097 return this;
2098 }
2099 }
2100 return version(v);
2101 }
2102
2103 /**
2104 * Sets the module main class. The package for the main class is added
2105 * to the module if not already added.
2106 *
2107 * @param mc
2108 * The module main class
2109 *
2110 * @return This builder
2111 *
2112 * @throws IllegalArgumentException
2113 * If {@code mainClass} is {@code null} or not a qualified
2114 * name of a class in a named package
2115 */
2116 public Builder mainClass(String mc) {
2117 String pn;
2118 if (strict) {
2119 mc = requireQualifiedClassName("main class name", mc);
2120 pn = packageName(mc);
2121 assert !pn.isEmpty();
2122 } else {
2123 // Disallow main class in unnamed package
2124 pn = packageName(mc);
2125 if (pn.isEmpty()) {
2126 throw new IllegalArgumentException(mc + ": unnamed package");
2127 }
2128 }
2129 mainClass = mc;
2130 packages.add(pn);
2131 return this;
2132 }
2133
2134 /**
2135 * Sets the operating system name.
2136 *
2137 * @param name
2138 * The operating system name
2139 *
2140 * @return This builder
2141 *
2142 * @throws IllegalArgumentException
2143 * If {@code name} is {@code null} or the empty String
2144 */
2145 public Builder osName(String name) {
2146 if (name == null || name.isEmpty())
2147 throw new IllegalArgumentException("OS name is null or empty");
2148 osName = name;
2149 return this;
2150 }
2151
2152 /**
2153 * Sets the operating system architecture.
2154 *
2155 * @param arch
2156 * The operating system architecture
2157 *
2158 * @return This builder
2159 *
2160 * @throws IllegalArgumentException
2161 * If {@code name} is {@code null} or the empty String
2162 */
2163 public Builder osArch(String arch) {
2164 if (arch == null || arch.isEmpty())
2165 throw new IllegalArgumentException("OS arch is null or empty");
2166 osArch = arch;
2167 return this;
2168 }
2169
2170 /**
2171 * Sets the operating system version.
2172 *
2173 * @param version
2174 * The operating system version
2175 *
2176 * @return This builder
2177 *
2178 * @throws IllegalArgumentException
2179 * If {@code name} is {@code null} or the empty String
2180 */
2181 public Builder osVersion(String version) {
2182 if (version == null || version.isEmpty())
2183 throw new IllegalArgumentException("OS version is null or empty");
2184 osVersion = version;
2185 return this;
2186 }
2187
2188 /**
2189 * Builds and returns a {@code ModuleDescriptor} from its components.
2190 *
2191 * <p> The module will require "{@code java.base}" even if the dependence
2192 * has not been declared (the exception is when building a module named
2193 * "{@code java.base}" as it cannot require itself). The dependence on
2194 * "{@code java.base}" will have the {@link
2195 * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
2196 * modifier if the dependence was not declared. </p>
2197 *
2198 * @return The module descriptor
2199 */
2200 public ModuleDescriptor build() {
2201 Set<Requires> requires = new HashSet<>(this.requires.values());
2202 Set<Exports> exports = new HashSet<>(this.exports.values());
2203 Set<Opens> opens = new HashSet<>(this.opens.values());
2204
2205 // add dependency on java.base
2206 if (strict
2207 && !name.equals("java.base")
2208 && !this.requires.containsKey("java.base")) {
2209 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
2210 "java.base",
2211 null));
2212 }
2213
2214 Set<Provides> provides = new HashSet<>(this.provides.values());
2215
2216 return new ModuleDescriptor(name,
2217 version,
2218 modifiers,
2219 requires,
2220 exports,
2221 opens,
2222 uses,
2223 provides,
2224 packages,
2225 mainClass,
2226 osName,
2227 osArch,
2228 osVersion);
2229 }
2230
2231 }
2232
2233 /**
2234 * Compares this module descriptor to another.
2235 *
2236 * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2237 * module names lexicographically. Where the module names are equal then the
2238 * module versions are compared. When comparing the module versions then a
2239 * module descriptor with a version is considered to succeed a module
2240 * descriptor that does not have a version. Where the module names are equal
2241 * and the versions are equal (or not present in both), then the set of
2242 * modifiers are compared. Sets of modifiers are compared by comparing
2243 * a <em>binary value</em> computed for each set. If a modifier is present
2244 * in the set then the bit at the position of its ordinal is {@code 1}
2245 * in the binary value, otherwise {@code 0}. If the two set of modifiers
2246 * are also equal then the other components of the module descriptors are
2247 * compared in a manner that is consistent with {@code equals}. </p>
2248 *
2249 * @param that
2250 * The module descriptor to compare
2251 *
2252 * @return A negative integer, zero, or a positive integer if this module
2253 * descriptor is less than, equal to, or greater than the given
2254 * module descriptor
2255 */
2256 @Override
2257 public int compareTo(ModuleDescriptor that) {
2258 if (this == that) return 0;
2259
2260 int c = this.name().compareTo(that.name());
2261 if (c != 0) return c;
2262
2263 c = compare(this.version, that.version);
2264 if (c != 0) return c;
2265
2266 long v1 = modsValue(this.modifiers());
2267 long v2 = modsValue(that.modifiers());
2268 c = Long.compare(v1, v2);
2269 if (c != 0) return c;
2270
2271 c = compare(this.requires, that.requires);
2272 if (c != 0) return c;
2273
2274 c = compare(this.packages, that.packages);
2275 if (c != 0) return c;
2276
2277 c = compare(this.exports, that.exports);
2278 if (c != 0) return c;
2279
2280 c = compare(this.opens, that.opens);
2281 if (c != 0) return c;
2282
2283 c = compare(this.uses, that.uses);
2284 if (c != 0) return c;
2285
2286 c = compare(this.provides, that.provides);
2287 if (c != 0) return c;
2288
2289 c = compare(this.mainClass, that.mainClass);
2290 if (c != 0) return c;
2291
2292 c = compare(this.osName, that.osName);
2293 if (c != 0) return c;
2294
2295 c = compare(this.osArch, that.osArch);
2296 if (c != 0) return c;
2297
2298 c = compare(this.osVersion, that.osVersion);
2299 if (c != 0) return c;
2300
2301 return 0;
2302 }
2303
2304 /**
2305 * Tests this module descriptor for equality with the given object.
2306 *
2307 * <p> If the given object is not a {@code ModuleDescriptor} then this
2308 * method returns {@code false}. Two module descriptors are equal if each
2309 * of their corresponding components is equal. </p>
2310 *
2311 * <p> This method satisfies the general contract of the {@link
2312 * java.lang.Object#equals(Object) Object.equals} method. </p>
2313 *
2314 * @param ob
2315 * the object to which this object is to be compared
2316 *
2317 * @return {@code true} if, and only if, the given object is a module
2318 * descriptor that is equal to this module descriptor
2319 */
2320 @Override
2321 public boolean equals(Object ob) {
2322 if (ob == this)
2323 return true;
2324 if (!(ob instanceof ModuleDescriptor))
2325 return false;
2326 ModuleDescriptor that = (ModuleDescriptor)ob;
2327 return (name.equals(that.name)
2328 && modifiers.equals(that.modifiers)
2329 && requires.equals(that.requires)
2330 && Objects.equals(packages, that.packages)
2331 && exports.equals(that.exports)
2332 && opens.equals(that.opens)
2333 && uses.equals(that.uses)
2334 && provides.equals(that.provides)
2335 && Objects.equals(version, that.version)
2336 && Objects.equals(mainClass, that.mainClass)
2337 && Objects.equals(osName, that.osName)
2338 && Objects.equals(osArch, that.osArch)
2339 && Objects.equals(osVersion, that.osVersion));
2340 }
2341
2342 /**
2343 * Computes a hash code for this module descriptor.
2344 *
2345 * <p> The hash code is based upon the components of the module descriptor,
2346 * and satisfies the general contract of the {@link Object#hashCode
2347 * Object.hashCode} method. </p>
2348 *
2349 * @return The hash-code value for this module descriptor
2350 */
2351 @Override
2352 public int hashCode() {
2353 int hc = hash;
2354 if (hc == 0) {
2355 hc = name.hashCode();
2356 hc = hc * 43 + Objects.hashCode(modifiers);
2357 hc = hc * 43 + requires.hashCode();
2358 hc = hc * 43 + Objects.hashCode(packages);
2359 hc = hc * 43 + exports.hashCode();
2360 hc = hc * 43 + opens.hashCode();
2361 hc = hc * 43 + uses.hashCode();
2362 hc = hc * 43 + provides.hashCode();
2363 hc = hc * 43 + Objects.hashCode(version);
2364 hc = hc * 43 + Objects.hashCode(mainClass);
2365 hc = hc * 43 + Objects.hashCode(osName);
2366 hc = hc * 43 + Objects.hashCode(osArch);
2367 hc = hc * 43 + Objects.hashCode(osVersion);
2368 if (hc == 0)
2369 hc = -1;
2370 hash = hc;
2371 }
2372 return hc;
2373 }
2374 private transient int hash; // cached hash code
2375
2376 /**
2377 * <p> Returns a string describing the module. </p>
2378 *
2379 * @return A string describing the module
2380 */
2381 @Override
2382 public String toString() {
2383 StringBuilder sb = new StringBuilder();
2384
2385 if (isOpen())
2386 sb.append("open ");
2387 sb.append("module { name: ").append(toNameAndVersion());
2696 * private package methods in java.lang.module.
2697 */
2698 jdk.internal.misc.SharedSecrets
2699 .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
2700 @Override
2701 public Builder newModuleBuilder(String mn,
2702 boolean strict,
2703 Set<ModuleDescriptor.Modifier> modifiers) {
2704 return new Builder(mn, strict, modifiers);
2705 }
2706
2707 @Override
2708 public Set<String> packages(ModuleDescriptor.Builder builder) {
2709 return builder.packages();
2710 }
2711
2712 @Override
2713 public void requires(ModuleDescriptor.Builder builder,
2714 Set<Requires.Modifier> ms,
2715 String mn,
2716 String compiledVersion) {
2717 builder.requires(ms, mn, compiledVersion);
2718 }
2719
2720 @Override
2721 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2722 return new Requires(ms, mn, v, true);
2723 }
2724
2725 @Override
2726 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2727 return new Exports(ms, source, Collections.emptySet(), true);
2728 }
2729
2730 @Override
2731 public Exports newExports(Set<Exports.Modifier> ms,
2732 String source,
2733 Set<String> targets) {
2734 return new Exports(ms, source, targets, true);
2735 }
2736
2737 @Override
2745 public Opens newOpens(Set<Opens.Modifier> ms, String source) {
2746 return new Opens(ms, source, Collections.emptySet(), true);
2747 }
2748
2749 @Override
2750 public Provides newProvides(String service, List<String> providers) {
2751 return new Provides(service, providers, true);
2752 }
2753
2754 @Override
2755 public ModuleDescriptor newModuleDescriptor(String name,
2756 Version version,
2757 Set<ModuleDescriptor.Modifier> modifiers,
2758 Set<Requires> requires,
2759 Set<Exports> exports,
2760 Set<Opens> opens,
2761 Set<String> uses,
2762 Set<Provides> provides,
2763 Set<String> packages,
2764 String mainClass,
2765 String osName,
2766 String osArch,
2767 String osVersion,
2768 int hashCode) {
2769 return new ModuleDescriptor(name,
2770 version,
2771 modifiers,
2772 requires,
2773 exports,
2774 opens,
2775 uses,
2776 provides,
2777 packages,
2778 mainClass,
2779 osName,
2780 osArch,
2781 osVersion,
2782 hashCode,
2783 false);
2784 }
2785
2786 @Override
2787 public Configuration resolveAndBind(ModuleFinder finder,
2788 Collection<String> roots,
2789 boolean check,
2790 PrintStream traceOutput)
2791 {
2792 return Configuration.resolveAndBind(finder, roots, check, traceOutput);
2793 }
2794 });
2795 }
2796
2797 }
|
162 */
163 STATIC,
164
165 /**
166 * The dependence was not explicitly or implicitly declared in the
167 * source of the module declaration.
168 */
169 SYNTHETIC,
170
171 /**
172 * The dependence was implicitly declared in the source of the module
173 * declaration.
174 */
175 MANDATED;
176
177 }
178
179 private final Set<Modifier> mods;
180 private final String name;
181 private final Version compiledVersion;
182 private final String rawCompiledVersion;
183
184 private Requires(Set<Modifier> ms, String mn, Version v, String vs) {
185 assert v == null || vs == null;
186 if (ms.isEmpty()) {
187 ms = Collections.emptySet();
188 } else {
189 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
190 }
191 this.mods = ms;
192 this.name = mn;
193 this.compiledVersion = v;
194 this.rawCompiledVersion = vs;
195 }
196
197 private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
198 this.mods = ms;
199 this.name = mn;
200 this.compiledVersion = v;
201 this.rawCompiledVersion = null;
202 }
203
204 /**
205 * Returns the set of modifiers.
206 *
207 * @return A possibly-empty unmodifiable set of modifiers
208 */
209 public Set<Modifier> modifiers() {
210 return mods;
211 }
212
213 /**
214 * Return the module name.
215 *
216 * @return The module name
217 */
218 public String name() {
219 return name;
220 }
221
222 /**
223 * Returns the version of the module if recorded at compile-time.
224 *
225 * @return The version of the module if recorded at compile-time,
226 * or an empty {@code Optional} if no version was recorded or
227 * the version string recorded is {@linkplain Version#parse(String)
228 * unparseable}
229 */
230 public Optional<Version> compiledVersion() {
231 return Optional.ofNullable(compiledVersion);
232 }
233
234 /**
235 * Returns the string with the possibly-unparseable version of the module
236 * if recorded at compile-time.
237 *
238 * @return The string containing the version of the module if recorded
239 * at compile-time
240 *
241 * @see #compiledVersion()
242 */
243 public Optional<String> rawCompiledVersion() {
244 if (compiledVersion != null) {
245 return Optional.of(compiledVersion.toString());
246 } else {
247 return Optional.ofNullable(rawCompiledVersion);
248 }
249 }
250
251 /**
252 * Compares this module dependence to another.
253 *
254 * <p> Two {@code Requires} objects are compared by comparing their
255 * module names lexicographically. Where the module names are equal
256 * then the sets of modifiers are compared in the same way that
257 * module modifiers are compared (see {@link ModuleDescriptor#compareTo
258 * ModuleDescriptor.compareTo}). Where the module names are equal and
259 * the set of modifiers are equal then the version of the modules
260 * recorded at compile-time are compared. When comparing the versions
261 * recorded at compile-time then a dependence that has a recorded
262 * version is considered to succeed a dependence that does not have a
263 * recorded version. If both recorded versions are {@linkplain
264 * Version#parse(String) unparseable} then the {@linkplain
265 * #rawCompiledVersion() raw version strings} are compared
266 * lexicographically. </p>
267 *
268 * @param that
269 * The module dependence to compare
270 *
271 * @return A negative integer, zero, or a positive integer if this module
272 * dependence is less than, equal to, or greater than the given
273 * module dependence
274 */
275 @Override
276 public int compareTo(Requires that) {
277 if (this == that) return 0;
278
279 int c = this.name().compareTo(that.name());
280 if (c != 0) return c;
281
282 // modifiers
283 long v1 = modsValue(this.modifiers());
284 long v2 = modsValue(that.modifiers());
285 c = Long.compare(v1, v2);
286 if (c != 0) return c;
287
288 // compiledVersion
289 c = compare(this.compiledVersion, that.compiledVersion);
290 if (c != 0) return c;
291
292 // rawCompiledVersion
293 c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
294 if (c != 0) return c;
295
296 return 0;
297 }
298
299 /**
300 * Tests this module dependence for equality with the given object.
301 *
302 * <p> If the given object is not a {@code Requires} then this method
303 * returns {@code false}. Two module dependence objects are equal if
304 * the module names are equal, set of modifiers are equal, and the
305 * compiled version of both modules is equal or not recorded for
306 * both modules. </p>
307 *
308 * <p> This method satisfies the general contract of the {@link
309 * java.lang.Object#equals(Object) Object.equals} method. </p>
310 *
311 * @param ob
312 * the object to which this object is to be compared
313 *
314 * @return {@code true} if, and only if, the given object is a module
315 * dependence that is equal to this module dependence
316 */
317 @Override
318 public boolean equals(Object ob) {
319 if (!(ob instanceof Requires))
320 return false;
321 Requires that = (Requires)ob;
322 return name.equals(that.name) && mods.equals(that.mods)
323 && Objects.equals(compiledVersion, that.compiledVersion)
324 && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
325 }
326
327 /**
328 * Computes a hash code for this module dependence.
329 *
330 * <p> The hash code is based upon the module name, modifiers, and the
331 * module version if recorded at compile time. It satisfies the general
332 * contract of the {@link Object#hashCode Object.hashCode} method. </p>
333 *
334 * @return The hash-code value for this module dependence
335 */
336 @Override
337 public int hashCode() {
338 int hash = name.hashCode() * 43 + mods.hashCode();
339 if (compiledVersion != null)
340 hash = hash * 43 + compiledVersion.hashCode();
341 if (rawCompiledVersion != null)
342 hash = hash * 43 + rawCompiledVersion.hashCode();
343 return hash;
344 }
345
346 /**
347 * Returns a string describing this module dependence.
348 *
349 * @return A string describing this module dependence
350 */
351 @Override
352 public String toString() {
353 String what;
354 if (compiledVersion != null) {
355 what = name() + " (@" + compiledVersion + ")";
356 } else {
357 what = name();
358 }
359 return ModuleDescriptor.toString(mods, what);
360 }
361 }
362
791
792 public final static class Provides
793 implements Comparable<Provides>
794 {
795 private final String service;
796 private final List<String> providers;
797
798 private Provides(String service, List<String> providers) {
799 this.service = service;
800 this.providers = Collections.unmodifiableList(providers);
801 }
802
803 private Provides(String service, List<String> providers, boolean unused) {
804 this.service = service;
805 this.providers = providers;
806 }
807
808 /**
809 * Returns the fully qualified class name of the service type.
810 *
811 * @return The fully qualified class name of the service type
812 */
813 public String service() { return service; }
814
815 /**
816 * Returns the list of the fully qualified class names of the providers
817 * or provider factories.
818 *
819 * @return A non-empty and unmodifiable list of the fully qualified class
820 * names of the providers or provider factories
821 */
822 public List<String> providers() { return providers; }
823
824 /**
825 * Compares this provides to another.
826 *
827 * <p> Two {@code Provides} objects are compared by comparing the fully
828 * qualified class name of the service type lexicographically. Where the
829 * class names are equal then the list of the provider class names are
830 * compared by comparing the corresponding elements of both lists
831 * lexicographically and in sequence. Where the lists differ in size,
1216 @Override
1217 public int hashCode() {
1218 return version.hashCode();
1219 }
1220
1221 /**
1222 * Returns the string from which this version was parsed.
1223 *
1224 * @return The string from which this version was parsed.
1225 */
1226 @Override
1227 public String toString() {
1228 return version;
1229 }
1230
1231 }
1232
1233
1234 private final String name;
1235 private final Version version;
1236 private final String rawVersionString;
1237 private final Set<Modifier> modifiers;
1238 private final boolean open; // true if modifiers contains OPEN
1239 private final boolean automatic; // true if modifiers contains AUTOMATIC
1240 private final Set<Requires> requires;
1241 private final Set<Exports> exports;
1242 private final Set<Opens> opens;
1243 private final Set<String> uses;
1244 private final Set<Provides> provides;
1245 private final Set<String> packages;
1246 private final String mainClass;
1247
1248 private ModuleDescriptor(String name,
1249 Version version,
1250 String rawVersionString,
1251 Set<Modifier> modifiers,
1252 Set<Requires> requires,
1253 Set<Exports> exports,
1254 Set<Opens> opens,
1255 Set<String> uses,
1256 Set<Provides> provides,
1257 Set<String> packages,
1258 String mainClass)
1259 {
1260 assert version == null || rawVersionString == null;
1261 this.name = name;
1262 this.version = version;
1263 this.rawVersionString = rawVersionString;
1264 this.modifiers = emptyOrUnmodifiableSet(modifiers);
1265 this.open = modifiers.contains(Modifier.OPEN);
1266 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1267 assert (requires.stream().map(Requires::name).distinct().count()
1268 == requires.size());
1269 this.requires = emptyOrUnmodifiableSet(requires);
1270 this.exports = emptyOrUnmodifiableSet(exports);
1271 this.opens = emptyOrUnmodifiableSet(opens);
1272 this.uses = emptyOrUnmodifiableSet(uses);
1273 this.provides = emptyOrUnmodifiableSet(provides);
1274
1275 this.packages = emptyOrUnmodifiableSet(packages);
1276 this.mainClass = mainClass;
1277 }
1278
1279 /**
1280 * Creates a module descriptor from its components.
1281 * The arguments are pre-validated and sets are unmodifiable sets.
1282 */
1283 ModuleDescriptor(String name,
1284 Version version,
1285 Set<Modifier> modifiers,
1286 Set<Requires> requires,
1287 Set<Exports> exports,
1288 Set<Opens> opens,
1289 Set<String> uses,
1290 Set<Provides> provides,
1291 Set<String> packages,
1292 String mainClass,
1293 int hashCode,
1294 boolean unused) {
1295 this.name = name;
1296 this.version = version;
1297 this.rawVersionString = null;
1298 this.modifiers = modifiers;
1299 this.open = modifiers.contains(Modifier.OPEN);
1300 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1301 this.requires = requires;
1302 this.exports = exports;
1303 this.opens = opens;
1304 this.uses = uses;
1305 this.provides = provides;
1306 this.packages = packages;
1307 this.mainClass = mainClass;
1308 this.hash = hashCode;
1309 }
1310
1311 /**
1312 * <p> Returns the module name. </p>
1313 *
1314 * @return The module name
1315 */
1316 public String name() {
1317 return name;
1318 }
1319
1320 /**
1321 * <p> Returns the set of module modifiers. </p>
1322 *
1323 * @return A possibly-empty unmodifiable set of modifiers
1324 */
1325 public Set<Modifier> modifiers() {
1326 return modifiers;
1327 }
1401 * names of the service types used
1402 */
1403 public Set<String> uses() {
1404 return uses;
1405 }
1406
1407 /**
1408 * <p> Returns the set of {@code Provides} objects representing the
1409 * services that the module provides. </p>
1410 *
1411 * @return The possibly-empty unmodifiable set of the services that this
1412 * module provides
1413 */
1414 public Set<Provides> provides() {
1415 return provides;
1416 }
1417
1418 /**
1419 * <p> Returns the module version. </p>
1420 *
1421 * @return This module's version, or an empty {@code Optional} if the
1422 * module does not have a version or the version is
1423 * {@linkplain Version#parse(String) unparseable}
1424 */
1425 public Optional<Version> version() {
1426 return Optional.ofNullable(version);
1427 }
1428
1429 /**
1430 * <p> Returns the string with the possibly-unparseable version of the
1431 * module </p>
1432 *
1433 * @return The string containing the version of the module
1434 *
1435 * @see #version()
1436 */
1437 public Optional<String> rawVersion() {
1438 if (version != null) {
1439 return Optional.of(version.toString());
1440 } else {
1441 return Optional.ofNullable(rawVersionString);
1442 }
1443 }
1444
1445 /**
1446 * <p> Returns a string containing the module name and, if present, its
1447 * version. </p>
1448 *
1449 * @return A string containing the module name and, if present, its
1450 * version
1451 */
1452 public String toNameAndVersion() {
1453 if (version != null) {
1454 return name() + "@" + version;
1455 } else {
1456 return name();
1457 }
1458 }
1459
1460 /**
1461 * <p> Returns the module main class. </p>
1462 *
1463 * @return The fully qualified class name of the module's main class
1464 */
1465 public Optional<String> mainClass() {
1466 return Optional.ofNullable(mainClass);
1467 }
1468
1469 /**
1470 * Returns the set of packages in the module.
1471 *
1472 * <p> The set of packages includes all exported and open packages, as well
1473 * as the packages of any service providers, and the package for the main
1474 * class. </p>
1475 *
1476 * @return A possibly-empty unmodifiable set of the packages in the module
1477 */
1478 public Set<String> packages() {
1479 return packages;
1480 }
1481
1482
1483 /**
1484 * A builder for building {@link ModuleDescriptor} objects.
1485 *
1486 * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
1487 * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
1488 * newAutomaticModule} methods to create builders for building
1489 * <em>normal</em>, open, and automatic modules. </p>
1490 *
1491 * <p> The set of packages in the module are accumulated by the {@code
1492 * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
1493 * {@link ModuleDescriptor.Builder#opens(String) opens},
1494 * {@link ModuleDescriptor.Builder#packages(Set) packages},
1495 * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
1514 * components are added to the builder. The rationale for this is to detect
1515 * errors as early as possible and not defer all validation to the
1516 * {@link #build build} method.
1517 *
1518 * @since 9
1519 * @spec JPMS
1520 */
1521 public static final class Builder {
1522 final String name;
1523 final boolean strict;
1524 final Set<Modifier> modifiers;
1525 final boolean open;
1526 final boolean automatic;
1527 final Set<String> packages = new HashSet<>();
1528 final Map<String, Requires> requires = new HashMap<>();
1529 final Map<String, Exports> exports = new HashMap<>();
1530 final Map<String, Opens> opens = new HashMap<>();
1531 final Set<String> uses = new HashSet<>();
1532 final Map<String, Provides> provides = new HashMap<>();
1533 Version version;
1534 String rawVersionString;
1535 String mainClass;
1536
1537 /**
1538 * Initializes a new builder with the given module name.
1539 *
1540 * If {@code strict} is {@code true} then module, package, and class
1541 * names are checked to ensure they are legal names. In addition, the
1542 * {@link #build buid} method will add "{@code requires java.base}" if
1543 * the dependency is not declared.
1544 */
1545 Builder(String name, boolean strict, Set<Modifier> modifiers) {
1546 this.name = (strict) ? requireModuleName(name) : name;
1547 this.strict = strict;
1548 this.modifiers = modifiers;
1549 this.open = modifiers.contains(Modifier.OPEN);
1550 this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1551 assert !open || !automatic;
1552 }
1553
1554 /**
1598 * The module name
1599 * @param compiledVersion
1600 * The version of the module recorded at compile-time
1601 *
1602 * @return This builder
1603 *
1604 * @throws IllegalArgumentException
1605 * If the module name is {@code null}, is not a legal module
1606 * name, or is equal to the module name that this builder
1607 * was initialized to build
1608 * @throws IllegalStateException
1609 * If the dependence on the module has already been declared
1610 * or this builder is for an automatic module
1611 */
1612 public Builder requires(Set<Requires.Modifier> ms,
1613 String mn,
1614 Version compiledVersion) {
1615 Objects.requireNonNull(compiledVersion);
1616 if (strict)
1617 mn = requireModuleName(mn);
1618 return requires(new Requires(ms, mn, compiledVersion, null));
1619 }
1620
1621 /* package */Builder requires(Set<Requires.Modifier> ms,
1622 String mn,
1623 String rawCompiledVersion) {
1624 Requires r;
1625 try {
1626 Version v = Version.parse(rawCompiledVersion);
1627 r = new Requires(ms, mn, v, null);
1628 } catch (IllegalArgumentException e) {
1629 if (strict) throw e;
1630 r = new Requires(ms, mn, null, rawCompiledVersion);
1631 }
1632 return requires(r);
1633 }
1634
1635 /**
1636 * Adds a dependence on a module with the given (and possibly empty)
1637 * set of modifiers.
1638 *
1639 * @param ms
1640 * The set of modifiers
1641 * @param mn
1642 * The module name
1643 *
1644 * @return This builder
1645 *
1646 * @throws IllegalArgumentException
1647 * If the module name is {@code null}, is not a legal module
1648 * name, or is equal to the module name that this builder
1649 * was initialized to build
1650 * @throws IllegalStateException
1651 * If the dependence on the module has already been declared
1652 * or this builder is for an automatic module
1653 */
1654 public Builder requires(Set<Requires.Modifier> ms, String mn) {
1655 if (strict)
1656 mn = requireModuleName(mn);
1657 return requires(new Requires(ms, mn, null, null));
1658 }
1659
1660 /**
1661 * Adds a dependence on a module with an empty set of modifiers.
1662 *
1663 * @param mn
1664 * The module name
1665 *
1666 * @return This builder
1667 *
1668 * @throws IllegalArgumentException
1669 * If the module name is {@code null}, is not a legal module
1670 * name, or is equal to the module name that this builder
1671 * was initialized to build
1672 * @throws IllegalStateException
1673 * If the dependence on the module has already been declared
1674 * or this builder is for an automatic module
1675 */
1676 public Builder requires(String mn) {
1677 return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1943 * If the package is already declared as open, or this is a
1944 * builder for an open module or automatic module
1945 */
1946 public Builder opens(String pn) {
1947 return opens(Collections.emptySet(), pn);
1948 }
1949
1950 /**
1951 * Adds a service dependence.
1952 *
1953 * @param service
1954 * The service type
1955 *
1956 * @return This builder
1957 *
1958 * @throws IllegalArgumentException
1959 * If the service type is {@code null} or not a qualified name of
1960 * a class in a named package
1961 * @throws IllegalStateException
1962 * If a dependency on the service type has already been declared
1963 * or this is a builder for an automatic module
1964 */
1965 public Builder uses(String service) {
1966 if (automatic)
1967 throw new IllegalStateException("Automatic modules can not declare"
1968 + " service dependences");
1969 if (uses.contains(requireServiceTypeName(service)))
1970 throw new IllegalStateException("Dependence upon service "
1971 + service + " already declared");
1972 uses.add(service);
1973 return this;
1974 }
1975
1976 /**
1977 * Provides a service with one or more implementations. The package for
1978 * each {@link Provides#providers provider} (or provider factory) is
1979 * added to the module if not already added.
1980 *
1981 * @param p
1982 * The provides
1983 *
2059 */
2060 public Builder packages(Set<String> pns) {
2061 if (strict) {
2062 pns = new HashSet<>(pns);
2063 pns.forEach(Checks::requirePackageName);
2064 }
2065 this.packages.addAll(pns);
2066 return this;
2067 }
2068
2069 /**
2070 * Sets the module version.
2071 *
2072 * @param v
2073 * The version
2074 *
2075 * @return This builder
2076 */
2077 public Builder version(Version v) {
2078 version = requireNonNull(v);
2079 rawVersionString = null;
2080 return this;
2081 }
2082
2083 /**
2084 * Sets the module version.
2085 *
2086 * @param vs
2087 * The version string to parse
2088 *
2089 * @return This builder
2090 *
2091 * @throws IllegalArgumentException
2092 * If {@code vs} is {@code null} or cannot be parsed as a
2093 * version string
2094 *
2095 * @see Version#parse(String)
2096 */
2097 public Builder version(String vs) {
2098 try {
2099 version = Version.parse(vs);
2100 rawVersionString = null;
2101 } catch (IllegalArgumentException e) {
2102 if (strict) throw e;
2103 version = null;
2104 rawVersionString = vs;
2105 }
2106 return this;
2107 }
2108
2109 /**
2110 * Sets the module main class. The package for the main class is added
2111 * to the module if not already added.
2112 *
2113 * @param mc
2114 * The module main class
2115 *
2116 * @return This builder
2117 *
2118 * @throws IllegalArgumentException
2119 * If {@code mainClass} is {@code null} or not a qualified
2120 * name of a class in a named package
2121 */
2122 public Builder mainClass(String mc) {
2123 String pn;
2124 if (strict) {
2125 mc = requireQualifiedClassName("main class name", mc);
2126 pn = packageName(mc);
2127 assert !pn.isEmpty();
2128 } else {
2129 // Disallow main class in unnamed package
2130 pn = packageName(mc);
2131 if (pn.isEmpty()) {
2132 throw new IllegalArgumentException(mc + ": unnamed package");
2133 }
2134 }
2135 mainClass = mc;
2136 packages.add(pn);
2137 return this;
2138 }
2139
2140 /**
2141 * Builds and returns a {@code ModuleDescriptor} from its components.
2142 *
2143 * <p> The module will require "{@code java.base}" even if the dependence
2144 * has not been declared (the exception is when building a module named
2145 * "{@code java.base}" as it cannot require itself). The dependence on
2146 * "{@code java.base}" will have the {@link
2147 * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
2148 * modifier if the dependence was not declared. </p>
2149 *
2150 * @return The module descriptor
2151 */
2152 public ModuleDescriptor build() {
2153 Set<Requires> requires = new HashSet<>(this.requires.values());
2154 Set<Exports> exports = new HashSet<>(this.exports.values());
2155 Set<Opens> opens = new HashSet<>(this.opens.values());
2156
2157 // add dependency on java.base
2158 if (strict
2159 && !name.equals("java.base")
2160 && !this.requires.containsKey("java.base")) {
2161 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
2162 "java.base",
2163 null,
2164 null));
2165 }
2166
2167 Set<Provides> provides = new HashSet<>(this.provides.values());
2168
2169 return new ModuleDescriptor(name,
2170 version,
2171 rawVersionString,
2172 modifiers,
2173 requires,
2174 exports,
2175 opens,
2176 uses,
2177 provides,
2178 packages,
2179 mainClass);
2180 }
2181
2182 }
2183
2184 /**
2185 * Compares this module descriptor to another.
2186 *
2187 * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2188 * module names lexicographically. Where the module names are equal then the
2189 * module versions are compared. When comparing the module versions then a
2190 * module descriptor with a version is considered to succeed a module
2191 * descriptor that does not have a version. If both versions are {@linkplain
2192 * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
2193 * raw version strings} are compared lexicographically. Where the module names
2194 * are equal and the versions are equal (or not present in both), then the
2195 * set of modifiers are compared. Sets of modifiers are compared by comparing
2196 * a <em>binary value</em> computed for each set. If a modifier is present
2197 * in the set then the bit at the position of its ordinal is {@code 1}
2198 * in the binary value, otherwise {@code 0}. If the two set of modifiers
2199 * are also equal then the other components of the module descriptors are
2200 * compared in a manner that is consistent with {@code equals}. </p>
2201 *
2202 * @param that
2203 * The module descriptor to compare
2204 *
2205 * @return A negative integer, zero, or a positive integer if this module
2206 * descriptor is less than, equal to, or greater than the given
2207 * module descriptor
2208 */
2209 @Override
2210 public int compareTo(ModuleDescriptor that) {
2211 if (this == that) return 0;
2212
2213 int c = this.name().compareTo(that.name());
2214 if (c != 0) return c;
2215
2216 c = compare(this.version, that.version);
2217 if (c != 0) return c;
2218
2219 c = compare(this.rawVersionString, that.rawVersionString);
2220 if (c != 0) return c;
2221
2222 long v1 = modsValue(this.modifiers());
2223 long v2 = modsValue(that.modifiers());
2224 c = Long.compare(v1, v2);
2225 if (c != 0) return c;
2226
2227 c = compare(this.requires, that.requires);
2228 if (c != 0) return c;
2229
2230 c = compare(this.packages, that.packages);
2231 if (c != 0) return c;
2232
2233 c = compare(this.exports, that.exports);
2234 if (c != 0) return c;
2235
2236 c = compare(this.opens, that.opens);
2237 if (c != 0) return c;
2238
2239 c = compare(this.uses, that.uses);
2240 if (c != 0) return c;
2241
2242 c = compare(this.provides, that.provides);
2243 if (c != 0) return c;
2244
2245 c = compare(this.mainClass, that.mainClass);
2246 if (c != 0) return c;
2247
2248 return 0;
2249 }
2250
2251 /**
2252 * Tests this module descriptor for equality with the given object.
2253 *
2254 * <p> If the given object is not a {@code ModuleDescriptor} then this
2255 * method returns {@code false}. Two module descriptors are equal if each
2256 * of their corresponding components is equal. </p>
2257 *
2258 * <p> This method satisfies the general contract of the {@link
2259 * java.lang.Object#equals(Object) Object.equals} method. </p>
2260 *
2261 * @param ob
2262 * the object to which this object is to be compared
2263 *
2264 * @return {@code true} if, and only if, the given object is a module
2265 * descriptor that is equal to this module descriptor
2266 */
2267 @Override
2268 public boolean equals(Object ob) {
2269 if (ob == this)
2270 return true;
2271 if (!(ob instanceof ModuleDescriptor))
2272 return false;
2273 ModuleDescriptor that = (ModuleDescriptor)ob;
2274 return (name.equals(that.name)
2275 && modifiers.equals(that.modifiers)
2276 && requires.equals(that.requires)
2277 && Objects.equals(packages, that.packages)
2278 && exports.equals(that.exports)
2279 && opens.equals(that.opens)
2280 && uses.equals(that.uses)
2281 && provides.equals(that.provides)
2282 && Objects.equals(version, that.version)
2283 && Objects.equals(rawVersionString, that.rawVersionString)
2284 && Objects.equals(mainClass, that.mainClass));
2285 }
2286
2287 /**
2288 * Computes a hash code for this module descriptor.
2289 *
2290 * <p> The hash code is based upon the components of the module descriptor,
2291 * and satisfies the general contract of the {@link Object#hashCode
2292 * Object.hashCode} method. </p>
2293 *
2294 * @return The hash-code value for this module descriptor
2295 */
2296 @Override
2297 public int hashCode() {
2298 int hc = hash;
2299 if (hc == 0) {
2300 hc = name.hashCode();
2301 hc = hc * 43 + Objects.hashCode(modifiers);
2302 hc = hc * 43 + requires.hashCode();
2303 hc = hc * 43 + Objects.hashCode(packages);
2304 hc = hc * 43 + exports.hashCode();
2305 hc = hc * 43 + opens.hashCode();
2306 hc = hc * 43 + uses.hashCode();
2307 hc = hc * 43 + provides.hashCode();
2308 hc = hc * 43 + Objects.hashCode(version);
2309 hc = hc * 43 + Objects.hashCode(rawVersionString);
2310 hc = hc * 43 + Objects.hashCode(mainClass);
2311 if (hc == 0)
2312 hc = -1;
2313 hash = hc;
2314 }
2315 return hc;
2316 }
2317 private transient int hash; // cached hash code
2318
2319 /**
2320 * <p> Returns a string describing the module. </p>
2321 *
2322 * @return A string describing the module
2323 */
2324 @Override
2325 public String toString() {
2326 StringBuilder sb = new StringBuilder();
2327
2328 if (isOpen())
2329 sb.append("open ");
2330 sb.append("module { name: ").append(toNameAndVersion());
2639 * private package methods in java.lang.module.
2640 */
2641 jdk.internal.misc.SharedSecrets
2642 .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
2643 @Override
2644 public Builder newModuleBuilder(String mn,
2645 boolean strict,
2646 Set<ModuleDescriptor.Modifier> modifiers) {
2647 return new Builder(mn, strict, modifiers);
2648 }
2649
2650 @Override
2651 public Set<String> packages(ModuleDescriptor.Builder builder) {
2652 return builder.packages();
2653 }
2654
2655 @Override
2656 public void requires(ModuleDescriptor.Builder builder,
2657 Set<Requires.Modifier> ms,
2658 String mn,
2659 String rawCompiledVersion) {
2660 builder.requires(ms, mn, rawCompiledVersion);
2661 }
2662
2663 @Override
2664 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2665 return new Requires(ms, mn, v, true);
2666 }
2667
2668 @Override
2669 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2670 return new Exports(ms, source, Collections.emptySet(), true);
2671 }
2672
2673 @Override
2674 public Exports newExports(Set<Exports.Modifier> ms,
2675 String source,
2676 Set<String> targets) {
2677 return new Exports(ms, source, targets, true);
2678 }
2679
2680 @Override
2688 public Opens newOpens(Set<Opens.Modifier> ms, String source) {
2689 return new Opens(ms, source, Collections.emptySet(), true);
2690 }
2691
2692 @Override
2693 public Provides newProvides(String service, List<String> providers) {
2694 return new Provides(service, providers, true);
2695 }
2696
2697 @Override
2698 public ModuleDescriptor newModuleDescriptor(String name,
2699 Version version,
2700 Set<ModuleDescriptor.Modifier> modifiers,
2701 Set<Requires> requires,
2702 Set<Exports> exports,
2703 Set<Opens> opens,
2704 Set<String> uses,
2705 Set<Provides> provides,
2706 Set<String> packages,
2707 String mainClass,
2708 int hashCode) {
2709 return new ModuleDescriptor(name,
2710 version,
2711 modifiers,
2712 requires,
2713 exports,
2714 opens,
2715 uses,
2716 provides,
2717 packages,
2718 mainClass,
2719 hashCode,
2720 false);
2721 }
2722
2723 @Override
2724 public Configuration resolveAndBind(ModuleFinder finder,
2725 Collection<String> roots,
2726 boolean check,
2727 PrintStream traceOutput)
2728 {
2729 return Configuration.resolveAndBind(finder, roots, check, traceOutput);
2730 }
2731 });
2732 }
2733
2734 }
|