< prev index next >

src/java.base/share/classes/java/lang/module/ModuleDescriptor.java

Print this page




 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 }
< prev index next >