jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
changeset 44359 c6761862ca0b
parent 43712 5dfd0950317c
child 44545 83b611b88ac8
equal deleted inserted replaced
44210:5a8499c4b32c 44359:c6761862ca0b
   177         }
   177         }
   178 
   178 
   179         private final Set<Modifier> mods;
   179         private final Set<Modifier> mods;
   180         private final String name;
   180         private final String name;
   181         private final Version compiledVersion;
   181         private final Version compiledVersion;
   182 
   182         private final String rawCompiledVersion;
   183         private Requires(Set<Modifier> ms, String mn, Version v) {
   183 
       
   184         private Requires(Set<Modifier> ms, String mn, Version v, String vs) {
       
   185             assert v == null || vs == null;
   184             if (ms.isEmpty()) {
   186             if (ms.isEmpty()) {
   185                 ms = Collections.emptySet();
   187                 ms = Collections.emptySet();
   186             } else {
   188             } else {
   187                 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
   189                 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
   188             }
   190             }
   189             this.mods = ms;
   191             this.mods = ms;
   190             this.name = mn;
   192             this.name = mn;
   191             this.compiledVersion = v;
   193             this.compiledVersion = v;
       
   194             this.rawCompiledVersion = vs;
   192         }
   195         }
   193 
   196 
   194         private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
   197         private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
   195             this.mods = ms;
   198             this.mods = ms;
   196             this.name = mn;
   199             this.name = mn;
   197             this.compiledVersion = v;
   200             this.compiledVersion = v;
       
   201             this.rawCompiledVersion = null;
   198         }
   202         }
   199 
   203 
   200         /**
   204         /**
   201          * Returns the set of modifiers.
   205          * Returns the set of modifiers.
   202          *
   206          *
   216         }
   220         }
   217 
   221 
   218         /**
   222         /**
   219          * Returns the version of the module if recorded at compile-time.
   223          * Returns the version of the module if recorded at compile-time.
   220          *
   224          *
   221          * @return The version of the module if recorded at compile-time
   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}
   222          */
   229          */
   223         public Optional<Version> compiledVersion() {
   230         public Optional<Version> compiledVersion() {
   224             return Optional.ofNullable(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, or an empty {@code Optional} if no version
       
   240          *         was recorded
       
   241          *
       
   242          * @see #compiledVersion()
       
   243          */
       
   244         public Optional<String> rawCompiledVersion() {
       
   245             if (compiledVersion != null) {
       
   246                 return Optional.of(compiledVersion.toString());
       
   247             } else {
       
   248                 return Optional.ofNullable(rawCompiledVersion);
       
   249             }
   225         }
   250         }
   226 
   251 
   227         /**
   252         /**
   228          * Compares this module dependence to another.
   253          * Compares this module dependence to another.
   229          *
   254          *
   234          * ModuleDescriptor.compareTo}). Where the module names are equal and
   259          * ModuleDescriptor.compareTo}). Where the module names are equal and
   235          * the set of modifiers are equal then the version of the modules
   260          * the set of modifiers are equal then the version of the modules
   236          * recorded at compile-time are compared. When comparing the versions
   261          * recorded at compile-time are compared. When comparing the versions
   237          * recorded at compile-time then a dependence that has a recorded
   262          * recorded at compile-time then a dependence that has a recorded
   238          * version is considered to succeed a dependence that does not have a
   263          * version is considered to succeed a dependence that does not have a
   239          * recorded version. </p>
   264          * recorded version. If both recorded versions are {@linkplain
       
   265          * Version#parse(String) unparseable} then the {@linkplain
       
   266          * #rawCompiledVersion() raw version strings} are compared
       
   267          * lexicographically. </p>
   240          *
   268          *
   241          * @param  that
   269          * @param  that
   242          *         The module dependence to compare
   270          *         The module dependence to compare
   243          *
   271          *
   244          * @return A negative integer, zero, or a positive integer if this module
   272          * @return A negative integer, zero, or a positive integer if this module
   258             c = Long.compare(v1, v2);
   286             c = Long.compare(v1, v2);
   259             if (c != 0) return c;
   287             if (c != 0) return c;
   260 
   288 
   261             // compiledVersion
   289             // compiledVersion
   262             c = compare(this.compiledVersion, that.compiledVersion);
   290             c = compare(this.compiledVersion, that.compiledVersion);
       
   291             if (c != 0) return c;
       
   292 
       
   293             // rawCompiledVersion
       
   294             c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
   263             if (c != 0) return c;
   295             if (c != 0) return c;
   264 
   296 
   265             return 0;
   297             return 0;
   266         }
   298         }
   267 
   299 
   287         public boolean equals(Object ob) {
   319         public boolean equals(Object ob) {
   288             if (!(ob instanceof Requires))
   320             if (!(ob instanceof Requires))
   289                 return false;
   321                 return false;
   290             Requires that = (Requires)ob;
   322             Requires that = (Requires)ob;
   291             return name.equals(that.name) && mods.equals(that.mods)
   323             return name.equals(that.name) && mods.equals(that.mods)
   292                     && Objects.equals(compiledVersion, that.compiledVersion);
   324                     && Objects.equals(compiledVersion, that.compiledVersion)
       
   325                     && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
   293         }
   326         }
   294 
   327 
   295         /**
   328         /**
   296          * Computes a hash code for this module dependence.
   329          * Computes a hash code for this module dependence.
   297          *
   330          *
   304         @Override
   337         @Override
   305         public int hashCode() {
   338         public int hashCode() {
   306             int hash = name.hashCode() * 43 + mods.hashCode();
   339             int hash = name.hashCode() * 43 + mods.hashCode();
   307             if (compiledVersion != null)
   340             if (compiledVersion != null)
   308                 hash = hash * 43 + compiledVersion.hashCode();
   341                 hash = hash * 43 + compiledVersion.hashCode();
       
   342             if (rawCompiledVersion != null)
       
   343                 hash = hash * 43 + rawCompiledVersion.hashCode();
   309             return hash;
   344             return hash;
   310         }
   345         }
   311 
   346 
   312         /**
   347         /**
   313          * Returns a string describing this module dependence.
   348          * Returns a string describing this module dependence.
   772         }
   807         }
   773 
   808 
   774         /**
   809         /**
   775          * Returns the fully qualified class name of the service type.
   810          * Returns the fully qualified class name of the service type.
   776          *
   811          *
   777          * @return The fully qualified class name of the service type.
   812          * @return The fully qualified class name of the service type
   778          */
   813          */
   779         public String service() { return service; }
   814         public String service() { return service; }
   780 
   815 
   781         /**
   816         /**
   782          * Returns the list of the fully qualified class names of the providers
   817          * Returns the list of the fully qualified class names of the providers
  1197     }
  1232     }
  1198 
  1233 
  1199 
  1234 
  1200     private final String name;
  1235     private final String name;
  1201     private final Version version;
  1236     private final Version version;
       
  1237     private final String rawVersionString;
  1202     private final Set<Modifier> modifiers;
  1238     private final Set<Modifier> modifiers;
  1203     private final boolean open;  // true if modifiers contains OPEN
  1239     private final boolean open;  // true if modifiers contains OPEN
  1204     private final boolean automatic;  // true if modifiers contains AUTOMATIC
  1240     private final boolean automatic;  // true if modifiers contains AUTOMATIC
  1205     private final Set<Requires> requires;
  1241     private final Set<Requires> requires;
  1206     private final Set<Exports> exports;
  1242     private final Set<Exports> exports;
  1207     private final Set<Opens> opens;
  1243     private final Set<Opens> opens;
  1208     private final Set<String> uses;
  1244     private final Set<String> uses;
  1209     private final Set<Provides> provides;
  1245     private final Set<Provides> provides;
  1210     private final Set<String> packages;
  1246     private final Set<String> packages;
  1211     private final String mainClass;
  1247     private final String mainClass;
  1212     private final String osName;
       
  1213     private final String osArch;
       
  1214     private final String osVersion;
       
  1215 
  1248 
  1216     private ModuleDescriptor(String name,
  1249     private ModuleDescriptor(String name,
  1217                              Version version,
  1250                              Version version,
       
  1251                              String rawVersionString,
  1218                              Set<Modifier> modifiers,
  1252                              Set<Modifier> modifiers,
  1219                              Set<Requires> requires,
  1253                              Set<Requires> requires,
  1220                              Set<Exports> exports,
  1254                              Set<Exports> exports,
  1221                              Set<Opens> opens,
  1255                              Set<Opens> opens,
  1222                              Set<String> uses,
  1256                              Set<String> uses,
  1223                              Set<Provides> provides,
  1257                              Set<Provides> provides,
  1224                              Set<String> packages,
  1258                              Set<String> packages,
  1225                              String mainClass,
  1259                              String mainClass)
  1226                              String osName,
       
  1227                              String osArch,
       
  1228                              String osVersion)
       
  1229     {
  1260     {
       
  1261         assert version == null || rawVersionString == null;
  1230         this.name = name;
  1262         this.name = name;
  1231         this.version = version;
  1263         this.version = version;
       
  1264         this.rawVersionString = rawVersionString;
  1232         this.modifiers = emptyOrUnmodifiableSet(modifiers);
  1265         this.modifiers = emptyOrUnmodifiableSet(modifiers);
  1233         this.open = modifiers.contains(Modifier.OPEN);
  1266         this.open = modifiers.contains(Modifier.OPEN);
  1234         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
  1267         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
  1235         assert (requires.stream().map(Requires::name).distinct().count()
  1268         assert (requires.stream().map(Requires::name).distinct().count()
  1236                 == requires.size());
  1269                 == requires.size());
  1240         this.uses = emptyOrUnmodifiableSet(uses);
  1273         this.uses = emptyOrUnmodifiableSet(uses);
  1241         this.provides = emptyOrUnmodifiableSet(provides);
  1274         this.provides = emptyOrUnmodifiableSet(provides);
  1242 
  1275 
  1243         this.packages = emptyOrUnmodifiableSet(packages);
  1276         this.packages = emptyOrUnmodifiableSet(packages);
  1244         this.mainClass = mainClass;
  1277         this.mainClass = mainClass;
  1245         this.osName = osName;
       
  1246         this.osArch = osArch;
       
  1247         this.osVersion = osVersion;
       
  1248     }
  1278     }
  1249 
  1279 
  1250     /**
  1280     /**
  1251      * Creates a module descriptor from its components.
  1281      * Creates a module descriptor from its components.
  1252      * The arguments are pre-validated and sets are unmodifiable sets.
  1282      * The arguments are pre-validated and sets are unmodifiable sets.
  1259                      Set<Opens> opens,
  1289                      Set<Opens> opens,
  1260                      Set<String> uses,
  1290                      Set<String> uses,
  1261                      Set<Provides> provides,
  1291                      Set<Provides> provides,
  1262                      Set<String> packages,
  1292                      Set<String> packages,
  1263                      String mainClass,
  1293                      String mainClass,
  1264                      String osName,
       
  1265                      String osArch,
       
  1266                      String osVersion,
       
  1267                      int hashCode,
  1294                      int hashCode,
  1268                      boolean unused) {
  1295                      boolean unused) {
  1269         this.name = name;
  1296         this.name = name;
  1270         this.version = version;
  1297         this.version = version;
       
  1298         this.rawVersionString = null;
  1271         this.modifiers = modifiers;
  1299         this.modifiers = modifiers;
  1272         this.open = modifiers.contains(Modifier.OPEN);
  1300         this.open = modifiers.contains(Modifier.OPEN);
  1273         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
  1301         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
  1274         this.requires = requires;
  1302         this.requires = requires;
  1275         this.exports = exports;
  1303         this.exports = exports;
  1276         this.opens = opens;
  1304         this.opens = opens;
  1277         this.uses = uses;
  1305         this.uses = uses;
  1278         this.provides = provides;
  1306         this.provides = provides;
  1279         this.packages = packages;
  1307         this.packages = packages;
  1280         this.mainClass = mainClass;
  1308         this.mainClass = mainClass;
  1281         this.osName = osName;
       
  1282         this.osArch = osArch;
       
  1283         this.osVersion = osVersion;
       
  1284         this.hash = hashCode;
  1309         this.hash = hashCode;
  1285     }
  1310     }
  1286 
  1311 
  1287     /**
  1312     /**
  1288      * <p> Returns the module name. </p>
  1313      * <p> Returns the module name. </p>
  1392     }
  1417     }
  1393 
  1418 
  1394     /**
  1419     /**
  1395      * <p> Returns the module version. </p>
  1420      * <p> Returns the module version. </p>
  1396      *
  1421      *
  1397      * @return This module's version
  1422      * @return This module's version, or an empty {@code Optional} if the
       
  1423      *         module does not have a version or the version is
       
  1424      *         {@linkplain Version#parse(String) unparseable}
  1398      */
  1425      */
  1399     public Optional<Version> version() {
  1426     public Optional<Version> version() {
  1400         return Optional.ofNullable(version);
  1427         return Optional.ofNullable(version);
  1401     }
  1428     }
  1402 
  1429 
  1403     /**
  1430     /**
       
  1431      * <p> Returns the string with the possibly-unparseable version of the
       
  1432      * module </p>
       
  1433      *
       
  1434      * @return The string containing the version of the module or an empty
       
  1435      *         {@code Optional} if the module does not have a version
       
  1436      *
       
  1437      * @see #version()
       
  1438      */
       
  1439     public Optional<String> rawVersion() {
       
  1440         if (version != null) {
       
  1441             return Optional.of(version.toString());
       
  1442         } else {
       
  1443             return Optional.ofNullable(rawVersionString);
       
  1444         }
       
  1445     }
       
  1446 
       
  1447     /**
  1404      * <p> Returns a string containing the module name and, if present, its
  1448      * <p> Returns a string containing the module name and, if present, its
  1405      * version. </p>
  1449      * version. </p>
  1406      *
  1450      *
  1407      * @return A string containing the module name and, if present, its
  1451      * @return A string containing the module name and, if present, its
  1408      *         version.
  1452      *         version
  1409      */
  1453      */
  1410     public String toNameAndVersion() {
  1454     public String toNameAndVersion() {
  1411         if (version != null) {
  1455         if (version != null) {
  1412             return name() + "@" + version;
  1456             return name() + "@" + version;
  1413         } else {
  1457         } else {
  1423     public Optional<String> mainClass() {
  1467     public Optional<String> mainClass() {
  1424         return Optional.ofNullable(mainClass);
  1468         return Optional.ofNullable(mainClass);
  1425     }
  1469     }
  1426 
  1470 
  1427     /**
  1471     /**
  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.
  1472      * Returns the set of packages in the module.
       
  1473      *
       
  1474      * <p> The set of packages includes all exported and open packages, as well
       
  1475      * as the packages of any service providers, and the package for the main
       
  1476      * class. </p>
  1462      *
  1477      *
  1463      * @return A possibly-empty unmodifiable set of the packages in the module
  1478      * @return A possibly-empty unmodifiable set of the packages in the module
  1464      */
  1479      */
  1465     public Set<String> packages() {
  1480     public Set<String> packages() {
  1466         return packages;
  1481         return packages;
  1516         final Map<String, Exports> exports = new HashMap<>();
  1531         final Map<String, Exports> exports = new HashMap<>();
  1517         final Map<String, Opens> opens = new HashMap<>();
  1532         final Map<String, Opens> opens = new HashMap<>();
  1518         final Set<String> uses = new HashSet<>();
  1533         final Set<String> uses = new HashSet<>();
  1519         final Map<String, Provides> provides = new HashMap<>();
  1534         final Map<String, Provides> provides = new HashMap<>();
  1520         Version version;
  1535         Version version;
  1521         String osName;
  1536         String rawVersionString;
  1522         String osArch;
       
  1523         String osVersion;
       
  1524         String mainClass;
  1537         String mainClass;
  1525 
  1538 
  1526         /**
  1539         /**
  1527          * Initializes a new builder with the given module name.
  1540          * Initializes a new builder with the given module name.
  1528          *
  1541          *
  1602                                 String mn,
  1615                                 String mn,
  1603                                 Version compiledVersion) {
  1616                                 Version compiledVersion) {
  1604             Objects.requireNonNull(compiledVersion);
  1617             Objects.requireNonNull(compiledVersion);
  1605             if (strict)
  1618             if (strict)
  1606                 mn = requireModuleName(mn);
  1619                 mn = requireModuleName(mn);
  1607             return requires(new Requires(ms, mn, compiledVersion));
  1620             return requires(new Requires(ms, mn, compiledVersion, null));
  1608         }
  1621         }
  1609 
  1622 
  1610         /* package */Builder requires(Set<Requires.Modifier> ms,
  1623         /* package */Builder requires(Set<Requires.Modifier> ms,
  1611                                       String mn,
  1624                                       String mn,
  1612                                       String compiledVersion) {
  1625                                       String rawCompiledVersion) {
  1613             Version v = null;
  1626             Requires r;
  1614             try {
  1627             try {
  1615                 v = Version.parse(compiledVersion);
  1628                 Version v = Version.parse(rawCompiledVersion);
       
  1629                 r = new Requires(ms, mn, v, null);
  1616             } catch (IllegalArgumentException e) {
  1630             } catch (IllegalArgumentException e) {
  1617                 // for now, drop un-parsable version when non-strict
       
  1618                 if (strict) throw e;
  1631                 if (strict) throw e;
  1619             }
  1632                 r = new Requires(ms, mn, null, rawCompiledVersion);
  1620             if (v == null) {
  1633             }
  1621                 return requires(ms, mn);
  1634             return requires(r);
  1622             } else {
       
  1623                 return requires(ms, mn, v);
       
  1624             }
       
  1625         }
  1635         }
  1626 
  1636 
  1627         /**
  1637         /**
  1628          * Adds a dependence on a module with the given (and possibly empty)
  1638          * Adds a dependence on a module with the given (and possibly empty)
  1629          * set of modifiers.
  1639          * set of modifiers.
  1644          *         or this builder is for an automatic module
  1654          *         or this builder is for an automatic module
  1645          */
  1655          */
  1646         public Builder requires(Set<Requires.Modifier> ms, String mn) {
  1656         public Builder requires(Set<Requires.Modifier> ms, String mn) {
  1647             if (strict)
  1657             if (strict)
  1648                 mn = requireModuleName(mn);
  1658                 mn = requireModuleName(mn);
  1649             return requires(new Requires(ms, mn, null));
  1659             return requires(new Requires(ms, mn, null, null));
  1650         }
  1660         }
  1651 
  1661 
  1652         /**
  1662         /**
  1653          * Adds a dependence on a module with an empty set of modifiers.
  1663          * Adds a dependence on a module with an empty set of modifiers.
  1654          *
  1664          *
  1950          * @throws IllegalArgumentException
  1960          * @throws IllegalArgumentException
  1951          *         If the service type is {@code null} or not a qualified name of
  1961          *         If the service type is {@code null} or not a qualified name of
  1952          *         a class in a named package
  1962          *         a class in a named package
  1953          * @throws IllegalStateException
  1963          * @throws IllegalStateException
  1954          *         If a dependency on the service type has already been declared
  1964          *         If a dependency on the service type has already been declared
  1955          *         or this is a builder for an an automatic module
  1965          *         or this is a builder for an automatic module
  1956          */
  1966          */
  1957         public Builder uses(String service) {
  1967         public Builder uses(String service) {
  1958             if (automatic)
  1968             if (automatic)
  1959                 throw new IllegalStateException("Automatic modules can not declare"
  1969                 throw new IllegalStateException("Automatic modules can not declare"
  1960                                                 + " service dependences");
  1970                                                 + " service dependences");
  2066          *
  2076          *
  2067          * @return This builder
  2077          * @return This builder
  2068          */
  2078          */
  2069         public Builder version(Version v) {
  2079         public Builder version(Version v) {
  2070             version = requireNonNull(v);
  2080             version = requireNonNull(v);
       
  2081             rawVersionString = null;
  2071             return this;
  2082             return this;
  2072         }
  2083         }
  2073 
  2084 
  2074         /**
  2085         /**
  2075          * Sets the module version.
  2086          * Sets the module version.
  2084          *         version string
  2095          *         version string
  2085          *
  2096          *
  2086          * @see Version#parse(String)
  2097          * @see Version#parse(String)
  2087          */
  2098          */
  2088         public Builder version(String vs) {
  2099         public Builder version(String vs) {
  2089             Version v;
  2100             try {
  2090             if (strict) {
  2101                 version = Version.parse(vs);
  2091                 v = Version.parse(vs);
  2102                 rawVersionString = null;
  2092             } else {
  2103             } catch (IllegalArgumentException e) {
  2093                 try {
  2104                 if (strict) throw e;
  2094                     v = Version.parse(vs);
  2105                 version = null;
  2095                 } catch (IllegalArgumentException ignore) {
  2106                 rawVersionString = vs;
  2096                     // for now, ignore when non-strict
  2107             }
  2097                     return this;
  2108             return this;
  2098                 }
       
  2099             }
       
  2100             return version(v);
       
  2101         }
  2109         }
  2102 
  2110 
  2103         /**
  2111         /**
  2104          * Sets the module main class. The package for the main class is added
  2112          * Sets the module main class. The package for the main class is added
  2105          * to the module if not already added.
  2113          * to the module if not already added.
  2130             packages.add(pn);
  2138             packages.add(pn);
  2131             return this;
  2139             return this;
  2132         }
  2140         }
  2133 
  2141 
  2134         /**
  2142         /**
  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.
  2143          * Builds and returns a {@code ModuleDescriptor} from its components.
  2190          *
  2144          *
  2191          * <p> The module will require "{@code java.base}" even if the dependence
  2145          * <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
  2146          * has not been declared (the exception is when building a module named
  2193          * "{@code java.base}" as it cannot require itself). The dependence on
  2147          * "{@code java.base}" as it cannot require itself). The dependence on
  2206             if (strict
  2160             if (strict
  2207                     && !name.equals("java.base")
  2161                     && !name.equals("java.base")
  2208                     && !this.requires.containsKey("java.base")) {
  2162                     && !this.requires.containsKey("java.base")) {
  2209                 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
  2163                 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
  2210                                           "java.base",
  2164                                           "java.base",
       
  2165                                           null,
  2211                                           null));
  2166                                           null));
  2212             }
  2167             }
  2213 
  2168 
  2214             Set<Provides> provides = new HashSet<>(this.provides.values());
  2169             Set<Provides> provides = new HashSet<>(this.provides.values());
  2215 
  2170 
  2216             return new ModuleDescriptor(name,
  2171             return new ModuleDescriptor(name,
  2217                                         version,
  2172                                         version,
       
  2173                                         rawVersionString,
  2218                                         modifiers,
  2174                                         modifiers,
  2219                                         requires,
  2175                                         requires,
  2220                                         exports,
  2176                                         exports,
  2221                                         opens,
  2177                                         opens,
  2222                                         uses,
  2178                                         uses,
  2223                                         provides,
  2179                                         provides,
  2224                                         packages,
  2180                                         packages,
  2225                                         mainClass,
  2181                                         mainClass);
  2226                                         osName,
       
  2227                                         osArch,
       
  2228                                         osVersion);
       
  2229         }
  2182         }
  2230 
  2183 
  2231     }
  2184     }
  2232 
  2185 
  2233     /**
  2186     /**
  2235      *
  2188      *
  2236      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
  2189      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
  2237      * module names lexicographically. Where the module names are equal then the
  2190      * module names lexicographically. Where the module names are equal then the
  2238      * module versions are compared. When comparing the module versions then a
  2191      * module versions are compared. When comparing the module versions then a
  2239      * module descriptor with a version is considered to succeed a module
  2192      * 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
  2193      * descriptor that does not have a version. If both versions are {@linkplain
  2241      * and the versions are equal (or not present in both), then the set of
  2194      * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
  2242      * modifiers are compared. Sets of modifiers are compared by comparing
  2195      * raw version strings} are compared lexicographically. Where the module names
       
  2196      * are equal and the versions are equal (or not present in both), then the
       
  2197      * set of 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
  2198      * 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}
  2199      * 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
  2200      * 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
  2201      * are also equal then the other components of the module descriptors are
  2247      * compared in a manner that is consistent with {@code equals}. </p>
  2202      * compared in a manner that is consistent with {@code equals}. </p>
  2261         if (c != 0) return c;
  2216         if (c != 0) return c;
  2262 
  2217 
  2263         c = compare(this.version, that.version);
  2218         c = compare(this.version, that.version);
  2264         if (c != 0) return c;
  2219         if (c != 0) return c;
  2265 
  2220 
       
  2221         c = compare(this.rawVersionString, that.rawVersionString);
       
  2222         if (c != 0) return c;
       
  2223 
  2266         long v1 = modsValue(this.modifiers());
  2224         long v1 = modsValue(this.modifiers());
  2267         long v2 = modsValue(that.modifiers());
  2225         long v2 = modsValue(that.modifiers());
  2268         c = Long.compare(v1, v2);
  2226         c = Long.compare(v1, v2);
  2269         if (c != 0) return c;
  2227         if (c != 0) return c;
  2270 
  2228 
  2285 
  2243 
  2286         c = compare(this.provides, that.provides);
  2244         c = compare(this.provides, that.provides);
  2287         if (c != 0) return c;
  2245         if (c != 0) return c;
  2288 
  2246 
  2289         c = compare(this.mainClass, that.mainClass);
  2247         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;
  2248         if (c != 0) return c;
  2300 
  2249 
  2301         return 0;
  2250         return 0;
  2302     }
  2251     }
  2303 
  2252 
  2331                 && exports.equals(that.exports)
  2280                 && exports.equals(that.exports)
  2332                 && opens.equals(that.opens)
  2281                 && opens.equals(that.opens)
  2333                 && uses.equals(that.uses)
  2282                 && uses.equals(that.uses)
  2334                 && provides.equals(that.provides)
  2283                 && provides.equals(that.provides)
  2335                 && Objects.equals(version, that.version)
  2284                 && Objects.equals(version, that.version)
  2336                 && Objects.equals(mainClass, that.mainClass)
  2285                 && Objects.equals(rawVersionString, that.rawVersionString)
  2337                 && Objects.equals(osName, that.osName)
  2286                 && Objects.equals(mainClass, that.mainClass));
  2338                 && Objects.equals(osArch, that.osArch)
       
  2339                 && Objects.equals(osVersion, that.osVersion));
       
  2340     }
  2287     }
  2341 
  2288 
  2342     /**
  2289     /**
  2343      * Computes a hash code for this module descriptor.
  2290      * Computes a hash code for this module descriptor.
  2344      *
  2291      *
  2359             hc = hc * 43 + exports.hashCode();
  2306             hc = hc * 43 + exports.hashCode();
  2360             hc = hc * 43 + opens.hashCode();
  2307             hc = hc * 43 + opens.hashCode();
  2361             hc = hc * 43 + uses.hashCode();
  2308             hc = hc * 43 + uses.hashCode();
  2362             hc = hc * 43 + provides.hashCode();
  2309             hc = hc * 43 + provides.hashCode();
  2363             hc = hc * 43 + Objects.hashCode(version);
  2310             hc = hc * 43 + Objects.hashCode(version);
       
  2311             hc = hc * 43 + Objects.hashCode(rawVersionString);
  2364             hc = hc * 43 + Objects.hashCode(mainClass);
  2312             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)
  2313             if (hc == 0)
  2369                 hc = -1;
  2314                 hc = -1;
  2370             hash = hc;
  2315             hash = hc;
  2371         }
  2316         }
  2372         return hc;
  2317         return hc;
  2711 
  2656 
  2712                 @Override
  2657                 @Override
  2713                 public void requires(ModuleDescriptor.Builder builder,
  2658                 public void requires(ModuleDescriptor.Builder builder,
  2714                                      Set<Requires.Modifier> ms,
  2659                                      Set<Requires.Modifier> ms,
  2715                                      String mn,
  2660                                      String mn,
  2716                                      String compiledVersion) {
  2661                                      String rawCompiledVersion) {
  2717                     builder.requires(ms, mn, compiledVersion);
  2662                     builder.requires(ms, mn, rawCompiledVersion);
  2718                 }
  2663                 }
  2719 
  2664 
  2720                 @Override
  2665                 @Override
  2721                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
  2666                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
  2722                     return new Requires(ms, mn, v, true);
  2667                     return new Requires(ms, mn, v, true);
  2760                                                             Set<Opens> opens,
  2705                                                             Set<Opens> opens,
  2761                                                             Set<String> uses,
  2706                                                             Set<String> uses,
  2762                                                             Set<Provides> provides,
  2707                                                             Set<Provides> provides,
  2763                                                             Set<String> packages,
  2708                                                             Set<String> packages,
  2764                                                             String mainClass,
  2709                                                             String mainClass,
  2765                                                             String osName,
       
  2766                                                             String osArch,
       
  2767                                                             String osVersion,
       
  2768                                                             int hashCode) {
  2710                                                             int hashCode) {
  2769                     return new ModuleDescriptor(name,
  2711                     return new ModuleDescriptor(name,
  2770                                                 version,
  2712                                                 version,
  2771                                                 modifiers,
  2713                                                 modifiers,
  2772                                                 requires,
  2714                                                 requires,
  2774                                                 opens,
  2716                                                 opens,
  2775                                                 uses,
  2717                                                 uses,
  2776                                                 provides,
  2718                                                 provides,
  2777                                                 packages,
  2719                                                 packages,
  2778                                                 mainClass,
  2720                                                 mainClass,
  2779                                                 osName,
       
  2780                                                 osArch,
       
  2781                                                 osVersion,
       
  2782                                                 hashCode,
  2721                                                 hashCode,
  2783                                                 false);
  2722                                                 false);
  2784                 }
  2723                 }
  2785 
  2724 
  2786                 @Override
  2725                 @Override