< prev index next >

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

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.module;
  27 
  28 import java.io.InputStream;
  29 import java.io.IOException;
  30 import java.io.PrintStream;
  31 import java.io.UncheckedIOException;
  32 import java.net.URI;
  33 import java.nio.ByteBuffer;
  34 import java.nio.file.Path;
  35 import java.util.ArrayList;
  36 import java.util.Collection;
  37 import java.util.Collections;
  38 import java.util.EnumSet;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.LinkedHashSet;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.Objects;
  45 import java.util.Optional;
  46 import java.util.Set;
  47 import java.util.function.Supplier;
  48 import java.util.stream.Collectors;
  49 import java.util.stream.Stream;
  50 
  51 import static jdk.internal.module.Checks.*;
  52 import static java.util.Objects.*;
  53 
  54 import jdk.internal.module.Checks;
  55 import jdk.internal.module.ModuleHashes;
  56 
  57 
  58 /**
  59  * A module descriptor.
  60  *
  61  * <p> A {@code ModuleDescriptor} is typically created from the binary form
  62  * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
  63  * class can be used to create a {@code ModuleDescriptor} from its components.
  64  * The {@link #module module}, {@link #openModule openModule}, and {@link
  65  * #automaticModule automaticModule} methods create builders for building
  66  * different kinds of modules. </p>
  67  *
  68  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  69  * multiple concurrent threads.</p>
  70  *
  71  * @since 9
  72  * @see java.lang.reflect.Module
  73  */
  74 
  75 public class ModuleDescriptor


 106              * but is optional in the dynamic phase, during execution.
 107              */
 108             STATIC,
 109 
 110             /**
 111              * The dependence was not explicitly or implicitly declared in the
 112              * source of the module declaration.
 113              */
 114             SYNTHETIC,
 115 
 116             /**
 117              * The dependence was implicitly declared in the source of the module
 118              * declaration.
 119              */
 120             MANDATED;
 121 
 122         }
 123 
 124         private final Set<Modifier> mods;
 125         private final String name;

 126 
 127         private Requires(Set<Modifier> ms, String mn) {
 128             if (ms.isEmpty()) {
 129                 ms = Collections.emptySet();
 130             } else {
 131                 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
 132             }
 133             this.mods = ms;
 134             this.name = mn;

 135         }
 136 
 137         private Requires(Set<Modifier> ms, String mn, boolean unused) {
 138             this.mods = ms;
 139             this.name = mn;

 140         }
 141 
 142         /**
 143          * Returns the set of modifiers.
 144          *
 145          * @return A possibly-empty unmodifiable set of modifiers
 146          */
 147         public Set<Modifier> modifiers() {
 148             return mods;
 149         }
 150 
 151         /**
 152          * Return the module name.
 153          *
 154          * @return The module name
 155          */
 156         public String name() {
 157             return name;
 158         }
 159 
 160         /**









 161          * Compares this module dependence to another.
 162          *
 163          * <p> Two {@code Requires} objects are compared by comparing their
 164          * module name lexicographically.  Where the module names are equal then
 165          * the sets of modifiers are compared based on a value computed from the
 166          * ordinal of each modifier. </p>





 167          *
 168          * @return A negative integer, zero, or a positive integer if this module
 169          *         dependence is less than, equal to, or greater than the given
 170          *         module dependence
 171          */
 172         @Override
 173         public int compareTo(Requires that) {
 174             int c = this.name().compareTo(that.name());
 175             if (c != 0)
 176                 return c;
 177             // same name, compare by modifiers
 178             return Long.compare(this.modsValue(), that.modsValue());
















 179         }
 180 
 181         /**
 182          * Return a value for the modifiers to allow sets of modifiers to be
 183          * compared.
 184          */
 185         private long modsValue() {
 186             long value = 0;
 187             for (Modifier m : mods) {
 188                 value += 1 << m.ordinal();
 189             }
 190             return value;
 191         }
 192 
 193         /**
 194          * Tests this module dependence for equality with the given object.
 195          *
 196          * <p> If the given object is not a {@code Requires} then this method
 197          * returns {@code false}. Two module dependence objects are equal if
 198          * the module names are equal and set of modifiers are equal. </p>


 199          *
 200          * <p> This method satisfies the general contract of the {@link
 201          * java.lang.Object#equals(Object) Object.equals} method. </p>
 202          *
 203          * @param   ob
 204          *          the object to which this object is to be compared
 205          *
 206          * @return  {@code true} if, and only if, the given object is a module
 207          *          dependence that is equal to this module dependence
 208          */
 209         @Override
 210         public boolean equals(Object ob) {
 211             if (!(ob instanceof Requires))
 212                 return false;
 213             Requires that = (Requires)ob;
 214             return (name.equals(that.name) && mods.equals(that.mods));

 215         }
 216 
 217         /**
 218          * Computes a hash code for this module dependence.
 219          *
 220          * <p> The hash code is based upon the module name and modifiers. It
 221          * satisfies the general contract of the {@link Object#hashCode
 222          * Object.hashCode} method. </p>
 223          *
 224          * @return The hash-code value for this module dependence
 225          */
 226         @Override
 227         public int hashCode() {
 228             return name.hashCode() * 43 + mods.hashCode();



 229         }
 230 
 231         /**
 232          * Returns a string describing module dependence.
 233          *
 234          * @return A string describing module dependence
 235          */
 236         @Override
 237         public String toString() {
 238             return ModuleDescriptor.toString(mods, name);






 239         }
 240     }
 241 
 242 
 243 
 244     /**
 245      * <p> A module export, may be qualified or unqualified. </p>
 246      *
 247      * @see ModuleDescriptor#exports()
 248      * @since 9
 249      */
 250 
 251     public final static class Exports {
 252 
 253         /**
 254          * A modifier on a module export.
 255          *
 256          * @since 9
 257          */
 258         public static enum Modifier {


 950          * @return The hash-code value for this module version
 951          */
 952         @Override
 953         public int hashCode() {
 954             return version.hashCode();
 955         }
 956 
 957         /**
 958          * Returns the string from which this version was parsed.
 959          *
 960          * @return The string from which this version was parsed.
 961          */
 962         @Override
 963         public String toString() {
 964             return version;
 965         }
 966 
 967     }
 968 
 969 
 970 
 971     // From module declarations
 972     private final String name;

 973     private final boolean open;
 974 
 975     // Indicates if synthesised for a JAR file found on the module path
 976     private final boolean automatic;
 977 
 978     // Not generated from a module-info.java
 979     private final boolean synthetic;
 980 
 981     private final Set<Requires> requires;
 982     private final Set<Exports> exports;
 983     private final Set<Opens> opens;
 984     private final Set<String> uses;
 985     private final Set<Provides> provides;
 986 
 987     // "Extended" information, added post-compilation by tools
 988     private final Version version;
 989     private final String mainClass;
 990     private final String osName;
 991     private final String osArch;
 992     private final String osVersion;
 993     private final Set<String> packages;
 994     private final ModuleHashes hashes;
 995 
 996 
 997     private ModuleDescriptor(String name,

 998                              boolean open,
 999                              boolean automatic,
1000                              boolean synthetic,
1001                              Set<Requires> requires,
1002                              Set<Exports> exports,
1003                              Set<Opens> opens,
1004                              Set<String> uses,
1005                              Set<Provides> provides,
1006                              Version version,
1007                              String mainClass,
1008                              String osName,
1009                              String osArch,
1010                              String osVersion,
1011                              Set<String> packages,
1012                              ModuleHashes hashes)
1013     {
1014 
1015         this.name = name;

1016         this.open = open;
1017         this.automatic = automatic;
1018         this.synthetic = synthetic;
1019 
1020         assert (requires.stream().map(Requires::name).distinct().count()
1021                 == requires.size());
1022         this.requires = emptyOrUnmodifiableSet(requires);
1023 
1024         this.exports = emptyOrUnmodifiableSet(exports);
1025         this.opens = emptyOrUnmodifiableSet(opens);
1026         this.uses = emptyOrUnmodifiableSet(uses);
1027         this.provides = emptyOrUnmodifiableSet(provides);
1028         this.version = version;

1029         this.mainClass = mainClass;
1030         this.osName = osName;
1031         this.osArch = osArch;
1032         this.osVersion = osVersion;
1033         this.hashes = hashes;
1034         this.packages = emptyOrUnmodifiableSet(packages);
1035     }
1036 
1037     /**
1038      * Clones the given module descriptor with an augmented set of packages
1039      */
1040     ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1041         this.name = md.name;

1042         this.open = md.open;
1043         this.automatic = md.automatic;
1044         this.synthetic = md.synthetic;
1045 
1046         this.requires = md.requires;
1047         this.exports = md.exports;
1048         this.opens = md.opens;
1049         this.uses = md.uses;
1050         this.provides = md.provides;
1051 
1052         this.version = md.version;



1053         this.mainClass = md.mainClass;
1054         this.osName = md.osName;
1055         this.osArch = md.osArch;
1056         this.osVersion = md.osVersion;
1057         this.hashes = null; // need to ignore
1058 
1059         Set<String> packages = new HashSet<>(md.packages);
1060         packages.addAll(pkgs);
1061         this.packages = emptyOrUnmodifiableSet(packages);
1062     }
1063 
1064     /**
1065      * Creates a module descriptor from its components.
1066      * The arguments are pre-validated and sets are unmodifiable sets.
1067      */
1068     ModuleDescriptor(String name,

1069                      boolean open,
1070                      boolean automatic,
1071                      boolean synthetic,
1072                      Set<Requires> requires,
1073                      Set<Exports> exports,
1074                      Set<Opens> opens,
1075                      Set<String> uses,
1076                      Set<Provides> provides,
1077                      Version version,
1078                      String mainClass,
1079                      String osName,
1080                      String osArch,
1081                      String osVersion,
1082                      Set<String> packages,
1083                      ModuleHashes hashes,
1084                      int hashCode,
1085                      boolean unused) {
1086         this.name = name;

1087         this.open = open;
1088         this.automatic = automatic;
1089         this.synthetic = synthetic;
1090         this.requires = requires;
1091         this.exports = exports;
1092         this.opens = opens;
1093         this.uses = uses;
1094         this.provides = provides;
1095         this.packages = packages;
1096         this.version = version;
1097         this.mainClass = mainClass;
1098         this.osName = osName;
1099         this.osArch = osArch;
1100         this.osVersion = osVersion;
1101         this.hashes = hashes;
1102         this.hash = hashCode;
1103     }
1104 
1105     /**
1106      * <p> The module name. </p>
1107      *
1108      * @return The module name
1109      */
1110     public String name() {
1111         return name;
1112     }
1113 
1114     /**
1115      * <p> Returns {@code true} if this is an open module. </p>
1116      *
1117      * <p> An open module does not declare any open packages (the {@link #opens()
1118      * opens} method returns an empty set) but the resulting module is treated
1119      * as if all packages are open. </p>
1120      *
1121      * @return  {@code true} if this is an open module


1267     /**
1268      * Returns the operating system version if this module is operating
1269      * system version specific.
1270      *
1271      * @return The operating system version or an empty {@code Optional}
1272      *         if this module is not operating system version specific
1273      */
1274     public Optional<String> osVersion() {
1275         return Optional.ofNullable(osVersion);
1276     }
1277 
1278     /**
1279      * Returns the names of all packages in this module.
1280      *
1281      * @return A possibly-empty unmodifiable set of all packages in the module
1282      */
1283     public Set<String> packages() {
1284         return packages;
1285     }
1286 
1287     /**
1288      * Returns the object with the hashes of other modules
1289      */
1290     Optional<ModuleHashes> hashes() {
1291         return Optional.ofNullable(hashes);
1292     }
1293 
1294 
1295     /**
1296      * A builder used for building {@link ModuleDescriptor} objects.
1297      *
1298      * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1299      * #openModule openModule}, and {@link #automaticModule automaticModule}
1300      * methods to create builders for building different kinds of modules. </p>
1301      *
1302      * <p> Example usage: </p>
1303      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1304      *         .exports("p")
1305      *         .requires("m2")
1306      *         .build();
1307      * }</pre>
1308      *
1309      * @apiNote A {@code Builder} checks the components and invariants as
1310      * components are added to the builder. The rational for this is to detect
1311      * errors as early as possible and not defer all validation to the
1312      * {@link #build build} method. A {@code Builder} cannot be used to create
1313      * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
1314      *
1315      * @since 9
1316      */
1317     public static final class Builder {
1318         final String name;
1319         final boolean strict; // true if module names are checked
1320         boolean open;

1321         boolean automatic;
1322         boolean synthetic;
1323         final Map<String, Requires> requires = new HashMap<>();
1324 
1325         final Map<String, Exports> exports = new HashMap<>();
1326         final Map<String, Opens> opens = new HashMap<>();
1327         final Set<String> concealedPackages = new HashSet<>();
1328 
1329         final Set<String> uses = new HashSet<>();
1330         final Map<String, Provides> provides = new HashMap<>();
1331         Version version;
1332         String osName;
1333         String osArch;
1334         String osVersion;
1335         String mainClass;
1336         ModuleHashes hashes;
1337 
1338         /**
1339          * Initializes a new builder with the given module name.
1340          *
1341          * @param strict
1342          *        Indicates whether module names are checked or not
1343          */
1344         Builder(String name, boolean strict) {
1345             this.strict = strict;
1346             this.name = (strict) ? requireModuleName(name) : name;
1347         }
1348 
1349         /* package */ Builder open(boolean open) {
1350             this.open = open;
1351             return this;
1352         }
1353 
1354         /* package */ Builder automatic(boolean automatic) {
1355             this.automatic = automatic;
1356             return this;
1357         }
1358 
1359         /* package */ boolean isOpen() { return open; }






1360 
1361         /* package */ boolean isAutomatic() {
1362             return automatic;




1363         }
1364 
1365         /**
1366          * Adds a dependence on a module.
1367          *
1368          * @param  req
1369          *         The dependence
1370          *
1371          * @return This builder
1372          *
1373          * @throws IllegalArgumentException
1374          *         If the dependence is on the module that this builder was
1375          *         initialized to build
1376          * @throws IllegalStateException
1377          *         If the dependence on the module has already been declared
1378          */
1379         public Builder requires(Requires req) {
1380             String mn = req.name();
1381             if (name.equals(mn))
1382                 throw new IllegalArgumentException("Dependence on self");
1383             if (requires.containsKey(mn))
1384                 throw new IllegalStateException("Dependence upon " + mn
1385                                                 + " already declared");
1386             requires.put(mn, req);
1387             return this;
1388         }
1389 
1390         /**
1391          * Adds a dependence on a module with the given (and possibly empty)






























1392          * set of modifiers.
1393          *
1394          * @param  ms
1395          *         The set of modifiers
1396          * @param  mn
1397          *         The module name
1398          *
1399          * @return This builder
1400          *
1401          * @throws IllegalArgumentException
1402          *         If the module name is {@code null}, is not a legal Java
1403          *         identifier, or is equal to the module name that this builder
1404          *         was initialized to build
1405          * @throws IllegalStateException
1406          *         If the dependence on the module has already been declared
1407          */
1408         public Builder requires(Set<Requires.Modifier> ms, String mn) {
1409             if (strict)
1410                 mn = requireModuleName(mn);
1411             return requires(new Requires(ms, mn));
1412         }
1413 
1414         /**
1415          * Adds a dependence on a module with an empty set of modifiers.
1416          *
1417          * @param  mn
1418          *         The module name
1419          *
1420          * @return This builder
1421          *
1422          * @throws IllegalArgumentException
1423          *         If the module name is {@code null}, is not a legal Java
1424          *         identifier, or is equal to the module name that this builder
1425          *         was initialized to build
1426          * @throws IllegalStateException
1427          *         If the dependence on the module has already been declared
1428          */
1429         public Builder requires(String mn) {
1430             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1431         }


1688         /**
1689          * Adds an <em>opens</em> directive to open a package.
1690          *
1691          * @param  pn
1692          *         The package name
1693          *
1694          * @return This builder
1695          *
1696          * @throws IllegalArgumentException
1697          *         If the package name is {@code null} or is not a legal Java
1698          *         identifier
1699          * @throws IllegalStateException
1700          *         If the package is already declared as a package with the
1701          *         {@link #contains contains} method, the package is already
1702          *         declared as open, or this is a builder for an open module
1703          */
1704         public Builder opens(String pn) {
1705             return opens(Collections.emptySet(), pn);
1706         }
1707 
1708 
1709         // Used by ModuleInfo, after a packageFinder is invoked
1710         /* package */ Set<String> exportedAndOpenPackages() {
1711             if (opens.isEmpty())
1712                 return exports.keySet();
1713             Set<String> result = new HashSet<>();
1714             result.addAll(exports.keySet());
1715             result.addAll(opens.keySet());
1716             return result;
1717         }
1718 
1719         /**
1720          * Adds a service dependence.
1721          *
1722          * @param  service
1723          *         The service type
1724          *
1725          * @return This builder
1726          *
1727          * @throws IllegalArgumentException
1728          *         If the service type is {@code null} or is not a legal Java
1729          *         identifier
1730          * @throws IllegalStateException
1731          *         If a dependency on the service type has already been declared
1732          */
1733         public Builder uses(String service) {
1734             if (uses.contains(requireServiceTypeName(service)))
1735                 throw new IllegalStateException("Dependence upon service "
1736                                                 + service + " already declared");
1737             uses.add(service);
1738             return this;


1772          * @throws IllegalArgumentException
1773          *         If the service type or any of the provider class names is
1774          *         {@code null} or is not a legal Java identifier, or the list
1775          *         of provider class names is empty
1776          * @throws IllegalStateException
1777          *         If the providers for the service type have already been
1778          *         declared
1779          */
1780         public Builder provides(String service, List<String> providers) {
1781             if (provides.containsKey(service))
1782                 throw new IllegalStateException("Providers of service "
1783                                                 + service + " already declared by " + name);
1784 
1785             Provides p = new Provides(requireServiceTypeName(service), providers);
1786 
1787             // check providers after the set has been copied.
1788             List<String> providerNames = p.providers();
1789             if (providerNames.isEmpty())
1790                 throw new IllegalArgumentException("Empty providers set");
1791             providerNames.forEach(Checks::requireServiceProviderName);
1792 
1793             provides.put(service, p);
1794             return this;
1795         }
1796 
1797         /**
1798          * Provides an implementation of a service.
1799          *
1800          * @param  service
1801          *         The service type
1802          * @param  provider
1803          *         The provider or provider factory class name
1804          *
1805          * @return This builder
1806          *
1807          * @throws IllegalArgumentException
1808          *         If the service type or the provider class name is {@code
1809          *         null} or is not a legal Java identifier
1810          * @throws IllegalStateException
1811          *         If the providers for the service type have already been
1812          *         declared


1897          *         If {@code v} is null or cannot be parsed as a version string
1898          *
1899          * @see Version#parse(String)
1900          */
1901         public Builder version(String v) {
1902             return version(Version.parse(v));
1903         }
1904 
1905         /**
1906          * Sets the module main class.
1907          *
1908          * @param  mc
1909          *         The module main class
1910          *
1911          * @return This builder
1912          *
1913          * @throws IllegalArgumentException
1914          *         If {@code mainClass} is null or is not a legal Java identifier
1915          */
1916         public Builder mainClass(String mc) {
1917             mainClass = requireJavaIdentifier("main class name", mc);
1918             return this;
1919         }
1920 
1921         /**
1922          * Sets the operating system name.
1923          *
1924          * @param  name
1925          *         The operating system name
1926          *
1927          * @return This builder
1928          *
1929          * @throws IllegalArgumentException
1930          *         If {@code name} is null or the empty String
1931          */
1932         public Builder osName(String name) {
1933             if (name == null || name.isEmpty())
1934                 throw new IllegalArgumentException("OS name is null or empty");
1935             osName = name;
1936             return this;
1937         }


1955         }
1956 
1957         /**
1958          * Sets the operating system version.
1959          *
1960          * @param  version
1961          *         The operating system version
1962          *
1963          * @return This builder
1964          *
1965          * @throws IllegalArgumentException
1966          *         If {@code name} is null or the empty String
1967          */
1968         public Builder osVersion(String version) {
1969             if (version == null || version.isEmpty())
1970                 throw new IllegalArgumentException("OS version is null or empty");
1971             osVersion = version;
1972             return this;
1973         }
1974 
1975         /* package */ Builder hashes(ModuleHashes hashes) {
1976             this.hashes = hashes;
1977             return this;
1978         }
1979 
1980         /* package */ Builder synthetic(boolean v) {
1981             this.synthetic = v;
1982             return this;
1983         }
1984 
1985         /**
1986          * Builds and returns a {@code ModuleDescriptor} from its components.
1987          *
1988          * @return The module descriptor
1989          */
1990         public ModuleDescriptor build() {
1991             Set<Requires> requires = new HashSet<>(this.requires.values());
1992 
1993             Set<String> packages = new HashSet<>(exportedAndOpenPackages());


1994             packages.addAll(concealedPackages);
1995 
1996             Set<Exports> exports = new HashSet<>(this.exports.values());
1997             Set<Opens> opens = new HashSet<>(this.opens.values());
1998 
1999             Set<Provides> provides = new HashSet<>(this.provides.values());
2000 
2001             return new ModuleDescriptor(name,

2002                                         open,
2003                                         automatic,
2004                                         synthetic,
2005                                         requires,
2006                                         exports,
2007                                         opens,
2008                                         uses,
2009                                         provides,
2010                                         version,
2011                                         mainClass,
2012                                         osName,
2013                                         osArch,
2014                                         osVersion,
2015                                         packages,
2016                                         hashes);
2017         }
2018 
2019     }
2020 
2021     /**
2022      * Compares this module descriptor to another.
2023      *
2024      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2025      * module name lexicographically.  Where the module names are equal then
2026      * the versions, if present, are compared. </p>
2027      *
2028      * @apiNote For now, the natural ordering is not consistent with equals.
2029      * If two module descriptors have equal module names, equal versions if
2030      * present, but their corresponding components are not equal, then they
2031      * will be considered equal by this method.
2032      *
2033      * @param  that
2034      *         The object to which this module descriptor is to be compared
2035      *
2036      * @return A negative integer, zero, or a positive integer if this module


2071     public boolean equals(Object ob) {
2072         if (ob == this)
2073             return true;
2074         if (!(ob instanceof ModuleDescriptor))
2075             return false;
2076         ModuleDescriptor that = (ModuleDescriptor)ob;
2077         return (name.equals(that.name)
2078                 && open == that.open
2079                 && automatic == that.automatic
2080                 && synthetic == that.synthetic
2081                 && requires.equals(that.requires)
2082                 && exports.equals(that.exports)
2083                 && opens.equals(that.opens)
2084                 && uses.equals(that.uses)
2085                 && provides.equals(that.provides)
2086                 && Objects.equals(version, that.version)
2087                 && Objects.equals(mainClass, that.mainClass)
2088                 && Objects.equals(osName, that.osName)
2089                 && Objects.equals(osArch, that.osArch)
2090                 && Objects.equals(osVersion, that.osVersion)
2091                 && Objects.equals(packages, that.packages)
2092                 && Objects.equals(hashes, that.hashes));
2093     }
2094 
2095     private transient int hash;  // cached hash code
2096 
2097     /**
2098      * Computes a hash code for this module descriptor.
2099      *
2100      * <p> The hash code is based upon the components of the module descriptor,
2101      * and satisfies the general contract of the {@link Object#hashCode
2102      * Object.hashCode} method. </p>
2103      *
2104      * @return The hash-code value for this module descriptor
2105      */
2106     @Override
2107     public int hashCode() {
2108         int hc = hash;
2109         if (hc == 0) {
2110             hc = name.hashCode();
2111             hc = hc * 43 + Boolean.hashCode(open);
2112             hc = hc * 43 + Boolean.hashCode(automatic);
2113             hc = hc * 43 + Boolean.hashCode(synthetic);
2114             hc = hc * 43 + requires.hashCode();
2115             hc = hc * 43 + exports.hashCode();
2116             hc = hc * 43 + opens.hashCode();
2117             hc = hc * 43 + uses.hashCode();
2118             hc = hc * 43 + provides.hashCode();
2119             hc = hc * 43 + Objects.hashCode(version);
2120             hc = hc * 43 + Objects.hashCode(mainClass);
2121             hc = hc * 43 + Objects.hashCode(osName);
2122             hc = hc * 43 + Objects.hashCode(osArch);
2123             hc = hc * 43 + Objects.hashCode(osVersion);
2124             hc = hc * 43 + Objects.hashCode(packages);
2125             hc = hc * 43 + Objects.hashCode(hashes);
2126             if (hc == 0)
2127                 hc = -1;
2128             hash = hc;
2129         }
2130         return hc;
2131     }
2132 
2133     /**
2134      * Returns a string describing this descriptor.
2135      *
2136      * @return A string describing this descriptor
2137      */
2138     @Override
2139     public String toString() {
2140         StringBuilder sb = new StringBuilder();
2141 
2142         if (isOpen())
2143             sb.append("open ");
2144         sb.append("module { name: ").append(toNameAndVersion());
2145         if (!requires.isEmpty())
2146             sb.append(", ").append(requires);
2147         if (!uses.isEmpty())
2148             sb.append(", ").append(uses);
2149         if (!exports.isEmpty())
2150             sb.append(", exports: ").append(exports);
2151         if (!opens.isEmpty())
2152             sb.append(", opens: ").append(opens);
2153         if (!provides.isEmpty()) {
2154             sb.append(", provides: ").append(provides);
2155         }
2156         sb.append(" }");
2157         return sb.toString();
2158     }
2159 
2160 
2161     /**
2162      * Instantiates a builder to build a module descriptor.
2163      *
2164      * @param  name
2165      *         The module name
2166      *
2167      * @return A new builder
2168      *
2169      * @throws IllegalArgumentException
2170      *         If the module name is {@code null} or is not a legal Java
2171      *         identifier
2172      */
2173     public static Builder module(String name) {
2174         return new Builder(name, true);
2175     }
2176 
2177     /**
2178      * Instantiates a builder to build a module descriptor for an open module.
2179      * An open module does not declare any open packages but the resulting
2180      * module is treated as if all packages are open.
2181      *
2182      * <p> As an example, the following creates a module descriptor for an open
2183      * name "{@code m}" containing two packages, one of which is exported. </p>
2184      * <pre>{@code
2185      *     ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
2186      *         .requires("java.base")
2187      *         .exports("p")
2188      *         .contains("q")
2189      *         .build();
2190      * }</pre>
2191      *
2192      * @param  name
2193      *         The module name
2194      *
2195      * @return A new builder that builds an open module
2196      *
2197      * @throws IllegalArgumentException
2198      *         If the module name is {@code null} or is not a legal Java
2199      *         identifier
2200      */
2201     public static Builder openModule(String name) {
2202         return new Builder(name, true).open(true);
2203     }
2204 
2205     /**
2206      * Instantiates a builder to build a module descriptor for an automatic
2207      * module. Automatic modules receive special treatment during resolution
2208      * (see {@link Configuration}) so that they read all other modules. When
2209      * Instantiated in the Java virtual machine as a {@link java.lang.reflect.Module}
2210      * then the Module reads every unnamed module in the Java virtual machine.
2211      *
2212      * @param  name
2213      *         The module name
2214      *
2215      * @return A new builder that builds an automatic module
2216      *
2217      * @throws IllegalArgumentException
2218      *         If the module name is {@code null} or is not a legal Java
2219      *         identifier
2220      *
2221      * @see ModuleFinder#of(Path[])
2222      */
2223     public static Builder automaticModule(String name) {
2224         return new Builder(name, true).automatic(true);
2225     }
2226 
2227 
2228     /**
2229      * Reads the binary form of a module declaration from an input stream
2230      * as a module descriptor.
2231      *
2232      * <p> If the descriptor encoded in the input stream does not indicate a
2233      * set of packages in the module then the {@code packageFinder} will be
2234      * invoked. If the {@code packageFinder} throws an {@link UncheckedIOException}
2235      * then {@link IOException} cause will be re-thrown. </p>
2236      *
2237      * <p> If there are bytes following the module descriptor then it is
2238      * implementation specific as to whether those bytes are read, ignored,
2239      * or reported as an {@code InvalidModuleDescriptorException}. If this
2240      * method fails with an {@code InvalidModuleDescriptorException} or {@code
2241      * IOException} then it may do so after some, but not all, bytes have
2242      * been read from the input stream. It is strongly recommended that the
2243      * stream be promptly closed and discarded if an exception occurs. </p>
2244      *


2246      * module descriptors from legacy module-artifact formats that do not
2247      * record the set of packages in the descriptor itself.
2248      *
2249      * @param  in
2250      *         The input stream
2251      * @param  packageFinder
2252      *         A supplier that can produce the set of packages
2253      *
2254      * @return The module descriptor
2255      *
2256      * @throws InvalidModuleDescriptorException
2257      *         If an invalid module descriptor is detected
2258      * @throws IOException
2259      *         If an I/O error occurs reading from the input stream or {@code
2260      *         UncheckedIOException} is thrown by the package finder
2261      */
2262     public static ModuleDescriptor read(InputStream in,
2263                                         Supplier<Set<String>> packageFinder)
2264         throws IOException
2265     {
2266         return ModuleInfo.read(in, requireNonNull(packageFinder));
2267     }
2268 
2269     /**
2270      * Reads the binary form of a module declaration from an input stream
2271      * as a module descriptor.
2272      *
2273      * @param  in
2274      *         The input stream
2275      *
2276      * @return The module descriptor
2277      *
2278      * @throws InvalidModuleDescriptorException
2279      *         If an invalid module descriptor is detected
2280      * @throws IOException
2281      *         If an I/O error occurs reading from the input stream
2282      */
2283     public static ModuleDescriptor read(InputStream in) throws IOException {
2284         return ModuleInfo.read(in, null);
2285     }
2286 
2287     /**
2288      * Reads the binary form of a module declaration from a byte buffer
2289      * as a module descriptor.
2290      *
2291      * <p> If the descriptor encoded in the byte buffer does not indicate a
2292      * set of packages then the {@code packageFinder} will be invoked. </p>
2293      *
2294      * <p> The module descriptor is read from the buffer stating at index
2295      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
2296      * position} when this method is invoked. Upon return the buffer's position
2297      * will be equal to {@code p + n} where {@code n} is the number of bytes
2298      * read from the buffer. </p>
2299      *
2300      * <p> If there are bytes following the module descriptor then it is
2301      * implementation specific as to whether those bytes are read, ignored,
2302      * or reported as an {@code InvalidModuleDescriptorException}. If this
2303      * method fails with an {@code InvalidModuleDescriptorException} then it
2304      * may do so after some, but not all, bytes have been read. </p>
2305      *
2306      * @apiNote The {@code packageFinder} parameter is for use when reading
2307      * module descriptors from legacy module-artifact formats that do not
2308      * record the set of packages in the descriptor itself.
2309      *
2310      * @param  bb
2311      *         The byte buffer
2312      * @param  packageFinder
2313      *         A supplier that can produce the set of packages
2314      *
2315      * @return The module descriptor
2316      *
2317      * @throws InvalidModuleDescriptorException
2318      *         If an invalid module descriptor is detected
2319      */
2320     public static ModuleDescriptor read(ByteBuffer bb,
2321                                         Supplier<Set<String>> packageFinder)
2322     {
2323         return ModuleInfo.read(bb, requireNonNull(packageFinder));
2324     }
2325 
2326     /**
2327      * Reads the binary form of a module declaration from a byte buffer
2328      * as a module descriptor.
2329      *
2330      * @param  bb
2331      *         The byte buffer
2332      *
2333      * @return The module descriptor
2334      *
2335      * @throws InvalidModuleDescriptorException
2336      *         If an invalid module descriptor is detected
2337      */
2338     public static ModuleDescriptor read(ByteBuffer bb) {
2339         return ModuleInfo.read(bb, null);
2340     }
2341 
2342     private static <K,V> Map<K,V> emptyOrUnmodifiableMap(Map<K,V> map) {
2343         if (map.isEmpty()) {
2344             return Collections.emptyMap();
2345         } else if (map.size() == 1) {
2346             Map.Entry<K, V> entry = map.entrySet().iterator().next();
2347             return Collections.singletonMap(entry.getKey(), entry.getValue());
2348         } else {
2349             return Collections.unmodifiableMap(map);
2350         }
2351     }
2352 
2353     private static <T> Set<T> emptyOrUnmodifiableSet(Set<T> set) {
2354         if (set.isEmpty()) {
2355             return Collections.emptySet();
2356         } else if (set.size() == 1) {
2357             return Collections.singleton(set.iterator().next());
2358         } else {
2359             return Collections.unmodifiableSet(set);
2360         }
2361     }
2362 
2363     /**
2364      * Returns a string containing the given set of modifiers and label.
2365      */
2366     private static <M> String toString(Set<M> mods, String what) {
2367         return (Stream.concat(mods.stream().map(e -> e.toString().toLowerCase()),
2368                               Stream.of(what)))
2369                 .collect(Collectors.joining(" "));
2370     }
2371 
2372     static {
2373         /**
2374          * Setup the shared secret to allow code in other packages access
2375          * private package methods in java.lang.module.
2376          */
2377         jdk.internal.misc.SharedSecrets
2378             .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
2379                 @Override
2380                 public Builder newModuleBuilder(String mn, boolean strict) {
2381                     return new Builder(mn, strict);








2382                 }
2383 
2384                 @Override
2385                 public Builder newOpenModuleBuilder(String mn, boolean strict) {
2386                     return new Builder(mn, strict).open(true);
2387                 }
2388 
2389                 @Override
2390                 public Requires newRequires(Set<Requires.Modifier> ms, String mn) {
2391                     return new Requires(ms, mn, true);
2392                 }
2393 
2394                 @Override
2395                 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2396                     return new Exports(ms, source, Collections.emptySet(), true);
2397                 }
2398 
2399                 @Override
2400                 public Exports newExports(Set<Exports.Modifier> ms,
2401                                           String source,
2402                                           Set<String> targets) {
2403                     return new Exports(ms, source, targets, true);
2404                 }
2405 
2406                 @Override
2407                 public Opens newOpens(Set<Opens.Modifier> ms,
2408                                       String source,
2409                                       Set<String> targets) {
2410                     return new Opens(ms, source, targets, true);
2411                 }


2416                 }
2417 
2418                 @Override
2419                 public Provides newProvides(String service, List<String> providers) {
2420                     return new Provides(service, providers, true);
2421                 }
2422 
2423                 @Override
2424                 public Version newVersion(String v) {
2425                     return new Version(v);
2426                 }
2427 
2428                 @Override
2429                 public ModuleDescriptor newModuleDescriptor(ModuleDescriptor md,
2430                                                             Set<String> pkgs) {
2431                     return new ModuleDescriptor(md, pkgs);
2432                 }
2433 
2434                 @Override
2435                 public ModuleDescriptor newModuleDescriptor(String name,

2436                                                             boolean open,
2437                                                             boolean automatic,
2438                                                             boolean synthetic,
2439                                                             Set<Requires> requires,
2440                                                             Set<Exports> exports,
2441                                                             Set<Opens> opens,
2442                                                             Set<String> uses,
2443                                                             Set<Provides> provides,
2444                                                             Version version,
2445                                                             String mainClass,
2446                                                             String osName,
2447                                                             String osArch,
2448                                                             String osVersion,
2449                                                             Set<String> packages,
2450                                                             ModuleHashes hashes,
2451                                                             int hashCode) {
2452                     return new ModuleDescriptor(name,

2453                                                 open,
2454                                                 automatic,
2455                                                 synthetic,
2456                                                 requires,
2457                                                 exports,
2458                                                 opens,
2459                                                 uses,
2460                                                 provides,
2461                                                 version,
2462                                                 mainClass,
2463                                                 osName,
2464                                                 osArch,
2465                                                 osVersion,
2466                                                 packages,
2467                                                 hashes,
2468                                                 hashCode,
2469                                                 false);
2470                 }
2471 
2472                 @Override
2473                 public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
2474                     return descriptor.hashes();
2475                 }
2476 
2477                 @Override
2478                 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2479                                                             Collection<String> roots,
2480                                                             boolean check,
2481                                                             PrintStream traceOutput)
2482                 {
2483                     return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2484                 }
2485 
2486                 @Override
2487                 public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
2488                                                         URI location,
2489                                                         Supplier<ModuleReader> s) {
2490                     return new ModuleReference(descriptor, location, s, true, null);
2491                 }
2492 
2493                 @Override
2494                 public ModuleFinder newModulePath(Runtime.Version version,
2495                                                   boolean isLinkPhase,
2496                                                   Path... entries) {
2497                     return new ModulePath(version, isLinkPhase, entries);
2498                 }
2499             });
2500     }
2501 
2502 }


  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.module;
  27 
  28 import java.io.InputStream;
  29 import java.io.IOException;
  30 import java.io.PrintStream;
  31 import java.io.UncheckedIOException;

  32 import java.nio.ByteBuffer;
  33 import java.nio.file.Path;
  34 import java.util.ArrayList;
  35 import java.util.Collection;
  36 import java.util.Collections;
  37 import java.util.EnumSet;
  38 import java.util.HashMap;
  39 import java.util.HashSet;

  40 import java.util.List;
  41 import java.util.Map;
  42 import java.util.Objects;
  43 import java.util.Optional;
  44 import java.util.Set;
  45 import java.util.function.Supplier;
  46 import java.util.stream.Collectors;
  47 import java.util.stream.Stream;
  48 
  49 import static jdk.internal.module.Checks.*;
  50 import static java.util.Objects.*;
  51 
  52 import jdk.internal.module.Checks;
  53 import jdk.internal.module.ModuleInfo;
  54 
  55 
  56 /**
  57  * A module descriptor.
  58  *
  59  * <p> A {@code ModuleDescriptor} is typically created from the binary form
  60  * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
  61  * class can be used to create a {@code ModuleDescriptor} from its components.
  62  * The {@link #module module}, {@link #openModule openModule}, and {@link
  63  * #automaticModule automaticModule} methods create builders for building
  64  * different kinds of modules. </p>
  65  *
  66  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  67  * multiple concurrent threads.</p>
  68  *
  69  * @since 9
  70  * @see java.lang.reflect.Module
  71  */
  72 
  73 public class ModuleDescriptor


 104              * but is optional in the dynamic phase, during execution.
 105              */
 106             STATIC,
 107 
 108             /**
 109              * The dependence was not explicitly or implicitly declared in the
 110              * source of the module declaration.
 111              */
 112             SYNTHETIC,
 113 
 114             /**
 115              * The dependence was implicitly declared in the source of the module
 116              * declaration.
 117              */
 118             MANDATED;
 119 
 120         }
 121 
 122         private final Set<Modifier> mods;
 123         private final String name;
 124         private final Version compiledVersion;
 125 
 126         private Requires(Set<Modifier> ms, String mn, Version v) {
 127             if (ms.isEmpty()) {
 128                 ms = Collections.emptySet();
 129             } else {
 130                 ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
 131             }
 132             this.mods = ms;
 133             this.name = mn;
 134             this.compiledVersion = v;
 135         }
 136 
 137         private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
 138             this.mods = ms;
 139             this.name = mn;
 140             this.compiledVersion = v;
 141         }
 142 
 143         /**
 144          * Returns the set of modifiers.
 145          *
 146          * @return A possibly-empty unmodifiable set of modifiers
 147          */
 148         public Set<Modifier> modifiers() {
 149             return mods;
 150         }
 151 
 152         /**
 153          * Return the module name.
 154          *
 155          * @return The module name
 156          */
 157         public String name() {
 158             return name;
 159         }
 160 
 161         /**
 162          * Returns the version of the module if recorded at compile-time.
 163          *
 164          * @return The version of the module if recorded at compile-time
 165          */
 166         public Optional<Version> compiledVersion() {
 167             return Optional.ofNullable(compiledVersion);
 168         }
 169 
 170         /**
 171          * Compares this module dependence to another.
 172          *
 173          * <p> Two {@code Requires} objects are compared by comparing their
 174          * module name lexicographically.  Where the module names are equal then
 175          * the sets of modifiers are compared based on a value computed from the
 176          * ordinal of each modifier. Where the module names are equal and the
 177          * set of modifiers are equal then the version of the modules recorded
 178          * at compile-time are compared. When comparing the versions recorded
 179          * at compile-time then a dependence that has a recorded version is
 180          * considered to succeed a dependence that does not have a recorded
 181          * version. </p>
 182          *
 183          * @return A negative integer, zero, or a positive integer if this module
 184          *         dependence is less than, equal to, or greater than the given
 185          *         module dependence
 186          */
 187         @Override
 188         public int compareTo(Requires that) {
 189             int c = this.name().compareTo(that.name());
 190             if (c != 0)
 191                 return c;
 192 
 193             // modifiers
 194             c = Long.compare(this.modsValue(), that.modsValue());
 195             if (c != 0)
 196                 return c;
 197 
 198             // compiledVersion
 199             if (this.compiledVersion != null) {
 200                 if (that.compiledVersion != null)
 201                     c = this.compiledVersion.compareTo(that.compiledVersion);
 202                 else
 203                     c = 1;
 204             } else {
 205                 if (that.compiledVersion != null)
 206                     c = -1;
 207             }
 208 
 209             return c;
 210         }
 211 
 212         /**
 213          * Return a value for the modifiers to allow sets of modifiers to be
 214          * compared.
 215          */
 216         private long modsValue() {
 217             long value = 0;
 218             for (Modifier m : mods) {
 219                 value += 1 << m.ordinal();
 220             }
 221             return value;
 222         }
 223 
 224         /**
 225          * Tests this module dependence for equality with the given object.
 226          *
 227          * <p> If the given object is not a {@code Requires} then this method
 228          * returns {@code false}. Two module dependence objects are equal if
 229          * the module names are equal, set of modifiers are equal, and the
 230          * compiled version of both modules is equal or not recorded for
 231          * both modules. </p>
 232          *
 233          * <p> This method satisfies the general contract of the {@link
 234          * java.lang.Object#equals(Object) Object.equals} method. </p>
 235          *
 236          * @param   ob
 237          *          the object to which this object is to be compared
 238          *
 239          * @return  {@code true} if, and only if, the given object is a module
 240          *          dependence that is equal to this module dependence
 241          */
 242         @Override
 243         public boolean equals(Object ob) {
 244             if (!(ob instanceof Requires))
 245                 return false;
 246             Requires that = (Requires)ob;
 247             return name.equals(that.name) && mods.equals(that.mods)
 248                     && Objects.equals(compiledVersion, that.compiledVersion);
 249         }
 250 
 251         /**
 252          * Computes a hash code for this module dependence.
 253          *
 254          * <p> The hash code is based upon the module name, modifiers, and the
 255          * module version if recorded at compile time. It satisfies the general
 256          * contract of the {@link Object#hashCode Object.hashCode} method. </p>
 257          *
 258          * @return The hash-code value for this module dependence
 259          */
 260         @Override
 261         public int hashCode() {
 262             int hash = name.hashCode() * 43 + mods.hashCode();
 263             if (compiledVersion != null)
 264                 hash = hash * 43 + compiledVersion.hashCode();
 265             return hash;
 266         }
 267 
 268         /**
 269          * Returns a string describing module dependence.
 270          *
 271          * @return A string describing module dependence
 272          */
 273         @Override
 274         public String toString() {
 275             String what;
 276             if (compiledVersion != null) {
 277                 what = name() + " (@" + compiledVersion + ")";
 278             } else {
 279                 what = name();
 280             }
 281             return ModuleDescriptor.toString(mods, what);
 282         }
 283     }
 284 
 285 
 286 
 287     /**
 288      * <p> A module export, may be qualified or unqualified. </p>
 289      *
 290      * @see ModuleDescriptor#exports()
 291      * @since 9
 292      */
 293 
 294     public final static class Exports {
 295 
 296         /**
 297          * A modifier on a module export.
 298          *
 299          * @since 9
 300          */
 301         public static enum Modifier {


 993          * @return The hash-code value for this module version
 994          */
 995         @Override
 996         public int hashCode() {
 997             return version.hashCode();
 998         }
 999 
1000         /**
1001          * Returns the string from which this version was parsed.
1002          *
1003          * @return The string from which this version was parsed.
1004          */
1005         @Override
1006         public String toString() {
1007             return version;
1008         }
1009 
1010     }
1011 
1012 


1013     private final String name;
1014     private final Version version;
1015     private final boolean open;
1016 
1017     // Indicates if synthesised for a JAR file found on the module path
1018     private final boolean automatic;
1019 
1020     // Not generated from a module-info.java
1021     private final boolean synthetic;
1022 
1023     private final Set<Requires> requires;
1024     private final Set<Exports> exports;
1025     private final Set<Opens> opens;
1026     private final Set<String> uses;
1027     private final Set<Provides> provides;
1028 
1029     // Added post-compilation by tools
1030     private final Set<String> packages;
1031     private final String mainClass;
1032     private final String osName;
1033     private final String osArch;
1034     private final String osVersion;


1035 
1036 
1037     private ModuleDescriptor(String name,
1038                              Version version,
1039                              boolean open,
1040                              boolean automatic,
1041                              boolean synthetic,
1042                              Set<Requires> requires,
1043                              Set<Exports> exports,
1044                              Set<Opens> opens,
1045                              Set<String> uses,
1046                              Set<Provides> provides,
1047                              Set<String> packages,
1048                              String mainClass,
1049                              String osName,
1050                              String osArch,
1051                              String osVersion)


1052     {

1053         this.name = name;
1054         this.version = version;
1055         this.open = open;
1056         this.automatic = automatic;
1057         this.synthetic = synthetic;
1058 
1059         assert (requires.stream().map(Requires::name).distinct().count()
1060                 == requires.size());
1061         this.requires = emptyOrUnmodifiableSet(requires);

1062         this.exports = emptyOrUnmodifiableSet(exports);
1063         this.opens = emptyOrUnmodifiableSet(opens);
1064         this.uses = emptyOrUnmodifiableSet(uses);
1065         this.provides = emptyOrUnmodifiableSet(provides);
1066 
1067         this.packages = emptyOrUnmodifiableSet(packages);
1068         this.mainClass = mainClass;
1069         this.osName = osName;
1070         this.osArch = osArch;
1071         this.osVersion = osVersion;


1072     }
1073 
1074     /**
1075      * Clones the given module descriptor with an augmented set of packages
1076      */
1077     ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1078         this.name = md.name;
1079         this.version = md.version;
1080         this.open = md.open;
1081         this.automatic = md.automatic;
1082         this.synthetic = md.synthetic;
1083 
1084         this.requires = md.requires;
1085         this.exports = md.exports;
1086         this.opens = md.opens;
1087         this.uses = md.uses;
1088         this.provides = md.provides;
1089 
1090         Set<String> packages = new HashSet<>(md.packages);
1091         packages.addAll(pkgs);
1092         this.packages = emptyOrUnmodifiableSet(packages);
1093 
1094         this.mainClass = md.mainClass;
1095         this.osName = md.osName;
1096         this.osArch = md.osArch;
1097         this.osVersion = md.osVersion;





1098     }
1099 
1100     /**
1101      * Creates a module descriptor from its components.
1102      * The arguments are pre-validated and sets are unmodifiable sets.
1103      */
1104     ModuleDescriptor(String name,
1105                      Version version,
1106                      boolean open,
1107                      boolean automatic,
1108                      boolean synthetic,
1109                      Set<Requires> requires,
1110                      Set<Exports> exports,
1111                      Set<Opens> opens,
1112                      Set<String> uses,
1113                      Set<Provides> provides,
1114                      Set<String> packages,
1115                      String mainClass,
1116                      String osName,
1117                      String osArch,
1118                      String osVersion,


1119                      int hashCode,
1120                      boolean unused) {
1121         this.name = name;
1122         this.version = version;
1123         this.open = open;
1124         this.automatic = automatic;
1125         this.synthetic = synthetic;
1126         this.requires = requires;
1127         this.exports = exports;
1128         this.opens = opens;
1129         this.uses = uses;
1130         this.provides = provides;
1131         this.packages = packages;

1132         this.mainClass = mainClass;
1133         this.osName = osName;
1134         this.osArch = osArch;
1135         this.osVersion = osVersion;

1136         this.hash = hashCode;
1137     }
1138 
1139     /**
1140      * <p> The module name. </p>
1141      *
1142      * @return The module name
1143      */
1144     public String name() {
1145         return name;
1146     }
1147 
1148     /**
1149      * <p> Returns {@code true} if this is an open module. </p>
1150      *
1151      * <p> An open module does not declare any open packages (the {@link #opens()
1152      * opens} method returns an empty set) but the resulting module is treated
1153      * as if all packages are open. </p>
1154      *
1155      * @return  {@code true} if this is an open module


1301     /**
1302      * Returns the operating system version if this module is operating
1303      * system version specific.
1304      *
1305      * @return The operating system version or an empty {@code Optional}
1306      *         if this module is not operating system version specific
1307      */
1308     public Optional<String> osVersion() {
1309         return Optional.ofNullable(osVersion);
1310     }
1311 
1312     /**
1313      * Returns the names of all packages in this module.
1314      *
1315      * @return A possibly-empty unmodifiable set of all packages in the module
1316      */
1317     public Set<String> packages() {
1318         return packages;
1319     }
1320 







1321 
1322     /**
1323      * A builder used for building {@link ModuleDescriptor} objects.
1324      *
1325      * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1326      * #openModule openModule}, and {@link #automaticModule automaticModule}
1327      * methods to create builders for building different kinds of modules. </p>
1328      *
1329      * <p> Example usage: </p>
1330      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1331      *         .exports("p")
1332      *         .requires("m2")
1333      *         .build();
1334      * }</pre>
1335      *
1336      * @apiNote A {@code Builder} checks the components and invariants as
1337      * components are added to the builder. The rational for this is to detect
1338      * errors as early as possible and not defer all validation to the
1339      * {@link #build build} method. A {@code Builder} cannot be used to create
1340      * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
1341      *
1342      * @since 9
1343      */
1344     public static final class Builder {
1345         final String name;
1346         final boolean strict; // true if module names are checked
1347         final boolean open;
1348         final boolean synthetic;
1349         boolean automatic;

1350         final Map<String, Requires> requires = new HashMap<>();

1351         final Map<String, Exports> exports = new HashMap<>();
1352         final Map<String, Opens> opens = new HashMap<>();
1353         final Set<String> concealedPackages = new HashSet<>();

1354         final Set<String> uses = new HashSet<>();
1355         final Map<String, Provides> provides = new HashMap<>();
1356         Version version;
1357         String osName;
1358         String osArch;
1359         String osVersion;
1360         String mainClass;

1361 
1362         /**
1363          * Initializes a new builder with the given module name.
1364          *
1365          * @param strict
1366          *        Indicates whether module names are checked or not
1367          */
1368         Builder(String name, boolean strict, boolean open, boolean synthetic) {

1369             this.name = (strict) ? requireModuleName(name) : name;
1370             this.strict = strict;


1371             this.open = open;
1372             this.synthetic = synthetic;
1373         }
1374 
1375         /* package */ Builder automatic(boolean automatic) {
1376             this.automatic = automatic;
1377             return this;
1378         }
1379 
1380         /**
1381          * Returns the set of packages that are exported (unconditionally or
1382          * unconditionally).
1383          */
1384         /* package */ Set<String> exportedPackages() {
1385             return exports.keySet();
1386         }
1387 
1388         /**
1389          * Returns the set of packages that are opened (unconditionally or
1390          * unconditionally).
1391          */
1392         /* package */Set<String> openPackages() {
1393             return opens.keySet();
1394         }
1395 
1396         /**
1397          * Adds a dependence on a module.
1398          *
1399          * @param  req
1400          *         The dependence
1401          *
1402          * @return This builder
1403          *
1404          * @throws IllegalArgumentException
1405          *         If the dependence is on the module that this builder was
1406          *         initialized to build
1407          * @throws IllegalStateException
1408          *         If the dependence on the module has already been declared
1409          */
1410         public Builder requires(Requires req) {
1411             String mn = req.name();
1412             if (name.equals(mn))
1413                 throw new IllegalArgumentException("Dependence on self");
1414             if (requires.containsKey(mn))
1415                 throw new IllegalStateException("Dependence upon " + mn
1416                                                 + " already declared");
1417             requires.put(mn, req);
1418             return this;
1419         }
1420 
1421         /**
1422          * Adds a dependence on a module with the given (and possibly empty)
1423          * set of modifiers. The dependence includes the version of the
1424          * module that that was recorded at compile-time.
1425          *
1426          * @param  ms
1427          *         The set of modifiers
1428          * @param  mn
1429          *         The module name
1430          * @param  compiledVersion
1431          *         The version of the module recorded at compile-time
1432          *
1433          * @return This builder
1434          *
1435          * @throws IllegalArgumentException
1436          *         If the module name is {@code null}, is not a legal Java
1437          *         identifier, or is equal to the module name that this builder
1438          *         was initialized to build
1439          * @throws IllegalStateException
1440          *         If the dependence on the module has already been declared
1441          */
1442         public Builder requires(Set<Requires.Modifier> ms,
1443                                 String mn,
1444                                 Version compiledVersion) {
1445             Objects.requireNonNull(compiledVersion);
1446             if (strict)
1447                 mn = requireModuleName(mn);
1448             return requires(new Requires(ms, mn, compiledVersion));
1449         }
1450 
1451         /**
1452          * Adds a dependence on a module with the given (and possibly empty)
1453          * set of modifiers.
1454          *
1455          * @param  ms
1456          *         The set of modifiers
1457          * @param  mn
1458          *         The module name
1459          *
1460          * @return This builder
1461          *
1462          * @throws IllegalArgumentException
1463          *         If the module name is {@code null}, is not a legal Java
1464          *         identifier, or is equal to the module name that this builder
1465          *         was initialized to build
1466          * @throws IllegalStateException
1467          *         If the dependence on the module has already been declared
1468          */
1469         public Builder requires(Set<Requires.Modifier> ms, String mn) {
1470             if (strict)
1471                 mn = requireModuleName(mn);
1472             return requires(new Requires(ms, mn, null));
1473         }
1474 
1475         /**
1476          * Adds a dependence on a module with an empty set of modifiers.
1477          *
1478          * @param  mn
1479          *         The module name
1480          *
1481          * @return This builder
1482          *
1483          * @throws IllegalArgumentException
1484          *         If the module name is {@code null}, is not a legal Java
1485          *         identifier, or is equal to the module name that this builder
1486          *         was initialized to build
1487          * @throws IllegalStateException
1488          *         If the dependence on the module has already been declared
1489          */
1490         public Builder requires(String mn) {
1491             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1492         }


1749         /**
1750          * Adds an <em>opens</em> directive to open a package.
1751          *
1752          * @param  pn
1753          *         The package name
1754          *
1755          * @return This builder
1756          *
1757          * @throws IllegalArgumentException
1758          *         If the package name is {@code null} or is not a legal Java
1759          *         identifier
1760          * @throws IllegalStateException
1761          *         If the package is already declared as a package with the
1762          *         {@link #contains contains} method, the package is already
1763          *         declared as open, or this is a builder for an open module
1764          */
1765         public Builder opens(String pn) {
1766             return opens(Collections.emptySet(), pn);
1767         }
1768 











1769         /**
1770          * Adds a service dependence.
1771          *
1772          * @param  service
1773          *         The service type
1774          *
1775          * @return This builder
1776          *
1777          * @throws IllegalArgumentException
1778          *         If the service type is {@code null} or is not a legal Java
1779          *         identifier
1780          * @throws IllegalStateException
1781          *         If a dependency on the service type has already been declared
1782          */
1783         public Builder uses(String service) {
1784             if (uses.contains(requireServiceTypeName(service)))
1785                 throw new IllegalStateException("Dependence upon service "
1786                                                 + service + " already declared");
1787             uses.add(service);
1788             return this;


1822          * @throws IllegalArgumentException
1823          *         If the service type or any of the provider class names is
1824          *         {@code null} or is not a legal Java identifier, or the list
1825          *         of provider class names is empty
1826          * @throws IllegalStateException
1827          *         If the providers for the service type have already been
1828          *         declared
1829          */
1830         public Builder provides(String service, List<String> providers) {
1831             if (provides.containsKey(service))
1832                 throw new IllegalStateException("Providers of service "
1833                                                 + service + " already declared by " + name);
1834 
1835             Provides p = new Provides(requireServiceTypeName(service), providers);
1836 
1837             // check providers after the set has been copied.
1838             List<String> providerNames = p.providers();
1839             if (providerNames.isEmpty())
1840                 throw new IllegalArgumentException("Empty providers set");
1841             providerNames.forEach(Checks::requireServiceProviderName);

1842             provides.put(service, p);
1843             return this;
1844         }
1845 
1846         /**
1847          * Provides an implementation of a service.
1848          *
1849          * @param  service
1850          *         The service type
1851          * @param  provider
1852          *         The provider or provider factory class name
1853          *
1854          * @return This builder
1855          *
1856          * @throws IllegalArgumentException
1857          *         If the service type or the provider class name is {@code
1858          *         null} or is not a legal Java identifier
1859          * @throws IllegalStateException
1860          *         If the providers for the service type have already been
1861          *         declared


1946          *         If {@code v} is null or cannot be parsed as a version string
1947          *
1948          * @see Version#parse(String)
1949          */
1950         public Builder version(String v) {
1951             return version(Version.parse(v));
1952         }
1953 
1954         /**
1955          * Sets the module main class.
1956          *
1957          * @param  mc
1958          *         The module main class
1959          *
1960          * @return This builder
1961          *
1962          * @throws IllegalArgumentException
1963          *         If {@code mainClass} is null or is not a legal Java identifier
1964          */
1965         public Builder mainClass(String mc) {
1966             mainClass = requireBinaryName("main class name", mc);
1967             return this;
1968         }
1969 
1970         /**
1971          * Sets the operating system name.
1972          *
1973          * @param  name
1974          *         The operating system name
1975          *
1976          * @return This builder
1977          *
1978          * @throws IllegalArgumentException
1979          *         If {@code name} is null or the empty String
1980          */
1981         public Builder osName(String name) {
1982             if (name == null || name.isEmpty())
1983                 throw new IllegalArgumentException("OS name is null or empty");
1984             osName = name;
1985             return this;
1986         }


2004         }
2005 
2006         /**
2007          * Sets the operating system version.
2008          *
2009          * @param  version
2010          *         The operating system version
2011          *
2012          * @return This builder
2013          *
2014          * @throws IllegalArgumentException
2015          *         If {@code name} is null or the empty String
2016          */
2017         public Builder osVersion(String version) {
2018             if (version == null || version.isEmpty())
2019                 throw new IllegalArgumentException("OS version is null or empty");
2020             osVersion = version;
2021             return this;
2022         }
2023 










2024         /**
2025          * Builds and returns a {@code ModuleDescriptor} from its components.
2026          *
2027          * @return The module descriptor
2028          */
2029         public ModuleDescriptor build() {
2030             Set<Requires> requires = new HashSet<>(this.requires.values());
2031 
2032             Set<String> packages = new HashSet<>();
2033             packages.addAll(exports.keySet());
2034             packages.addAll(opens.keySet());
2035             packages.addAll(concealedPackages);
2036 
2037             Set<Exports> exports = new HashSet<>(this.exports.values());
2038             Set<Opens> opens = new HashSet<>(this.opens.values());
2039 
2040             Set<Provides> provides = new HashSet<>(this.provides.values());
2041 
2042             return new ModuleDescriptor(name,
2043                                         version,
2044                                         open,
2045                                         automatic,
2046                                         synthetic,
2047                                         requires,
2048                                         exports,
2049                                         opens,
2050                                         uses,
2051                                         provides,
2052                                         packages,
2053                                         mainClass,
2054                                         osName,
2055                                         osArch,
2056                                         osVersion);


2057         }
2058 
2059     }
2060 
2061     /**
2062      * Compares this module descriptor to another.
2063      *
2064      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2065      * module name lexicographically.  Where the module names are equal then
2066      * the versions, if present, are compared. </p>
2067      *
2068      * @apiNote For now, the natural ordering is not consistent with equals.
2069      * If two module descriptors have equal module names, equal versions if
2070      * present, but their corresponding components are not equal, then they
2071      * will be considered equal by this method.
2072      *
2073      * @param  that
2074      *         The object to which this module descriptor is to be compared
2075      *
2076      * @return A negative integer, zero, or a positive integer if this module


2111     public boolean equals(Object ob) {
2112         if (ob == this)
2113             return true;
2114         if (!(ob instanceof ModuleDescriptor))
2115             return false;
2116         ModuleDescriptor that = (ModuleDescriptor)ob;
2117         return (name.equals(that.name)
2118                 && open == that.open
2119                 && automatic == that.automatic
2120                 && synthetic == that.synthetic
2121                 && requires.equals(that.requires)
2122                 && exports.equals(that.exports)
2123                 && opens.equals(that.opens)
2124                 && uses.equals(that.uses)
2125                 && provides.equals(that.provides)
2126                 && Objects.equals(version, that.version)
2127                 && Objects.equals(mainClass, that.mainClass)
2128                 && Objects.equals(osName, that.osName)
2129                 && Objects.equals(osArch, that.osArch)
2130                 && Objects.equals(osVersion, that.osVersion)
2131                 && Objects.equals(packages, that.packages));

2132     }
2133 
2134     private transient int hash;  // cached hash code
2135 
2136     /**
2137      * Computes a hash code for this module descriptor.
2138      *
2139      * <p> The hash code is based upon the components of the module descriptor,
2140      * and satisfies the general contract of the {@link Object#hashCode
2141      * Object.hashCode} method. </p>
2142      *
2143      * @return The hash-code value for this module descriptor
2144      */
2145     @Override
2146     public int hashCode() {
2147         int hc = hash;
2148         if (hc == 0) {
2149             hc = name.hashCode();
2150             hc = hc * 43 + Boolean.hashCode(open);
2151             hc = hc * 43 + Boolean.hashCode(automatic);
2152             hc = hc * 43 + Boolean.hashCode(synthetic);
2153             hc = hc * 43 + requires.hashCode();
2154             hc = hc * 43 + exports.hashCode();
2155             hc = hc * 43 + opens.hashCode();
2156             hc = hc * 43 + uses.hashCode();
2157             hc = hc * 43 + provides.hashCode();
2158             hc = hc * 43 + Objects.hashCode(version);
2159             hc = hc * 43 + Objects.hashCode(mainClass);
2160             hc = hc * 43 + Objects.hashCode(osName);
2161             hc = hc * 43 + Objects.hashCode(osArch);
2162             hc = hc * 43 + Objects.hashCode(osVersion);
2163             hc = hc * 43 + Objects.hashCode(packages);

2164             if (hc == 0)
2165                 hc = -1;
2166             hash = hc;
2167         }
2168         return hc;
2169     }
2170 
2171     /**
2172      * Returns a string describing this descriptor.
2173      *
2174      * @return A string describing this descriptor
2175      */
2176     @Override
2177     public String toString() {
2178         StringBuilder sb = new StringBuilder();
2179 
2180         if (isOpen())
2181             sb.append("open ");
2182         sb.append("module { name: ").append(toNameAndVersion());
2183         if (!requires.isEmpty())
2184             sb.append(", ").append(requires);
2185         if (!uses.isEmpty())
2186             sb.append(", uses: ").append(uses);
2187         if (!exports.isEmpty())
2188             sb.append(", exports: ").append(exports);
2189         if (!opens.isEmpty())
2190             sb.append(", opens: ").append(opens);
2191         if (!provides.isEmpty()) {
2192             sb.append(", provides: ").append(provides);
2193         }
2194         sb.append(" }");
2195         return sb.toString();
2196     }
2197 
2198 
2199     /**
2200      * Instantiates a builder to build a module descriptor.
2201      *
2202      * @param  name
2203      *         The module name
2204      *
2205      * @return A new builder
2206      *
2207      * @throws IllegalArgumentException
2208      *         If the module name is {@code null} or is not a legal Java
2209      *         identifier
2210      */
2211     public static Builder module(String name) {
2212         return new Builder(name, true, false, false);
2213     }
2214 
2215     /**
2216      * Instantiates a builder to build a module descriptor for an open module.
2217      * An open module does not declare any open packages but the resulting
2218      * module is treated as if all packages are open.
2219      *
2220      * <p> As an example, the following creates a module descriptor for an open
2221      * name "{@code m}" containing two packages, one of which is exported. </p>
2222      * <pre>{@code
2223      *     ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
2224      *         .requires("java.base")
2225      *         .exports("p")
2226      *         .contains("q")
2227      *         .build();
2228      * }</pre>
2229      *
2230      * @param  name
2231      *         The module name
2232      *
2233      * @return A new builder that builds an open module
2234      *
2235      * @throws IllegalArgumentException
2236      *         If the module name is {@code null} or is not a legal Java
2237      *         identifier
2238      */
2239     public static Builder openModule(String name) {
2240         return new Builder(name, true, true, false);
2241     }
2242 
2243     /**
2244      * Instantiates a builder to build a module descriptor for an automatic
2245      * module. Automatic modules receive special treatment during resolution
2246      * (see {@link Configuration}) so that they read all other modules. When
2247      * Instantiated in the Java virtual machine as a {@link java.lang.reflect.Module}
2248      * then the Module reads every unnamed module in the Java virtual machine.
2249      *
2250      * @param  name
2251      *         The module name
2252      *
2253      * @return A new builder that builds an automatic module
2254      *
2255      * @throws IllegalArgumentException
2256      *         If the module name is {@code null} or is not a legal Java
2257      *         identifier
2258      *
2259      * @see ModuleFinder#of(Path[])
2260      */
2261     public static Builder automaticModule(String name) {
2262         return new Builder(name, true, false, false).automatic(true);
2263     }
2264 
2265 
2266     /**
2267      * Reads the binary form of a module declaration from an input stream
2268      * as a module descriptor.
2269      *
2270      * <p> If the descriptor encoded in the input stream does not indicate a
2271      * set of packages in the module then the {@code packageFinder} will be
2272      * invoked. If the {@code packageFinder} throws an {@link UncheckedIOException}
2273      * then {@link IOException} cause will be re-thrown. </p>
2274      *
2275      * <p> If there are bytes following the module descriptor then it is
2276      * implementation specific as to whether those bytes are read, ignored,
2277      * or reported as an {@code InvalidModuleDescriptorException}. If this
2278      * method fails with an {@code InvalidModuleDescriptorException} or {@code
2279      * IOException} then it may do so after some, but not all, bytes have
2280      * been read from the input stream. It is strongly recommended that the
2281      * stream be promptly closed and discarded if an exception occurs. </p>
2282      *


2284      * module descriptors from legacy module-artifact formats that do not
2285      * record the set of packages in the descriptor itself.
2286      *
2287      * @param  in
2288      *         The input stream
2289      * @param  packageFinder
2290      *         A supplier that can produce the set of packages
2291      *
2292      * @return The module descriptor
2293      *
2294      * @throws InvalidModuleDescriptorException
2295      *         If an invalid module descriptor is detected
2296      * @throws IOException
2297      *         If an I/O error occurs reading from the input stream or {@code
2298      *         UncheckedIOException} is thrown by the package finder
2299      */
2300     public static ModuleDescriptor read(InputStream in,
2301                                         Supplier<Set<String>> packageFinder)
2302         throws IOException
2303     {
2304         return ModuleInfo.read(in, requireNonNull(packageFinder)).descriptor();
2305     }
2306 
2307     /**
2308      * Reads the binary form of a module declaration from an input stream
2309      * as a module descriptor.
2310      *
2311      * @param  in
2312      *         The input stream
2313      *
2314      * @return The module descriptor
2315      *
2316      * @throws InvalidModuleDescriptorException
2317      *         If an invalid module descriptor is detected
2318      * @throws IOException
2319      *         If an I/O error occurs reading from the input stream
2320      */
2321     public static ModuleDescriptor read(InputStream in) throws IOException {
2322         return ModuleInfo.read(in, null).descriptor();
2323     }
2324 
2325     /**
2326      * Reads the binary form of a module declaration from a byte buffer
2327      * as a module descriptor.
2328      *
2329      * <p> If the descriptor encoded in the byte buffer does not indicate a
2330      * set of packages then the {@code packageFinder} will be invoked. </p>
2331      *
2332      * <p> The module descriptor is read from the buffer stating at index
2333      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
2334      * position} when this method is invoked. Upon return the buffer's position
2335      * will be equal to {@code p + n} where {@code n} is the number of bytes
2336      * read from the buffer. </p>
2337      *
2338      * <p> If there are bytes following the module descriptor then it is
2339      * implementation specific as to whether those bytes are read, ignored,
2340      * or reported as an {@code InvalidModuleDescriptorException}. If this
2341      * method fails with an {@code InvalidModuleDescriptorException} then it
2342      * may do so after some, but not all, bytes have been read. </p>
2343      *
2344      * @apiNote The {@code packageFinder} parameter is for use when reading
2345      * module descriptors from legacy module-artifact formats that do not
2346      * record the set of packages in the descriptor itself.
2347      *
2348      * @param  bb
2349      *         The byte buffer
2350      * @param  packageFinder
2351      *         A supplier that can produce the set of packages
2352      *
2353      * @return The module descriptor
2354      *
2355      * @throws InvalidModuleDescriptorException
2356      *         If an invalid module descriptor is detected
2357      */
2358     public static ModuleDescriptor read(ByteBuffer bb,
2359                                         Supplier<Set<String>> packageFinder)
2360     {
2361         return ModuleInfo.read(bb, requireNonNull(packageFinder)).descriptor();
2362     }
2363 
2364     /**
2365      * Reads the binary form of a module declaration from a byte buffer
2366      * as a module descriptor.
2367      *
2368      * @param  bb
2369      *         The byte buffer
2370      *
2371      * @return The module descriptor
2372      *
2373      * @throws InvalidModuleDescriptorException
2374      *         If an invalid module descriptor is detected
2375      */
2376     public static ModuleDescriptor read(ByteBuffer bb) {
2377         return ModuleInfo.read(bb, null).descriptor();
2378     }
2379 
2380     private static <K,V> Map<K,V> emptyOrUnmodifiableMap(Map<K,V> map) {
2381         if (map.isEmpty()) {
2382             return Collections.emptyMap();
2383         } else if (map.size() == 1) {
2384             Map.Entry<K, V> entry = map.entrySet().iterator().next();
2385             return Collections.singletonMap(entry.getKey(), entry.getValue());
2386         } else {
2387             return Collections.unmodifiableMap(map);
2388         }
2389     }
2390 
2391     private static <T> Set<T> emptyOrUnmodifiableSet(Set<T> set) {
2392         if (set.isEmpty()) {
2393             return Collections.emptySet();
2394         } else if (set.size() == 1) {
2395             return Collections.singleton(set.iterator().next());
2396         } else {
2397             return Collections.unmodifiableSet(set);
2398         }
2399     }
2400 
2401     /**
2402      * Returns a string containing the given set of modifiers and label.
2403      */
2404     private static <M> String toString(Set<M> mods, String what) {
2405         return (Stream.concat(mods.stream().map(e -> e.toString().toLowerCase()),
2406                               Stream.of(what)))
2407                 .collect(Collectors.joining(" "));
2408     }
2409 
2410     static {
2411         /**
2412          * Setup the shared secret to allow code in other packages access
2413          * private package methods in java.lang.module.
2414          */
2415         jdk.internal.misc.SharedSecrets
2416             .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
2417                 @Override
2418                 public Builder newModuleBuilder(String mn,
2419                                                 boolean strict,
2420                                                 boolean open,
2421                                                 boolean synthetic) {
2422                     return new Builder(mn, strict, open, synthetic);
2423                 }
2424 
2425                 @Override
2426                 public Set<String> exportedPackages(ModuleDescriptor.Builder builder) {
2427                     return builder.exportedPackages();
2428                 }
2429 
2430                 @Override
2431                 public Set<String> openPackages(ModuleDescriptor.Builder builder) {
2432                     return builder.openPackages();
2433                 }
2434 
2435                 @Override
2436                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2437                     return new Requires(ms, mn, v, true);
2438                 }
2439 
2440                 @Override
2441                 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2442                     return new Exports(ms, source, Collections.emptySet(), true);
2443                 }
2444 
2445                 @Override
2446                 public Exports newExports(Set<Exports.Modifier> ms,
2447                                           String source,
2448                                           Set<String> targets) {
2449                     return new Exports(ms, source, targets, true);
2450                 }
2451 
2452                 @Override
2453                 public Opens newOpens(Set<Opens.Modifier> ms,
2454                                       String source,
2455                                       Set<String> targets) {
2456                     return new Opens(ms, source, targets, true);
2457                 }


2462                 }
2463 
2464                 @Override
2465                 public Provides newProvides(String service, List<String> providers) {
2466                     return new Provides(service, providers, true);
2467                 }
2468 
2469                 @Override
2470                 public Version newVersion(String v) {
2471                     return new Version(v);
2472                 }
2473 
2474                 @Override
2475                 public ModuleDescriptor newModuleDescriptor(ModuleDescriptor md,
2476                                                             Set<String> pkgs) {
2477                     return new ModuleDescriptor(md, pkgs);
2478                 }
2479 
2480                 @Override
2481                 public ModuleDescriptor newModuleDescriptor(String name,
2482                                                             Version version,
2483                                                             boolean open,
2484                                                             boolean automatic,
2485                                                             boolean synthetic,
2486                                                             Set<Requires> requires,
2487                                                             Set<Exports> exports,
2488                                                             Set<Opens> opens,
2489                                                             Set<String> uses,
2490                                                             Set<Provides> provides,
2491                                                             Set<String> packages,
2492                                                             String mainClass,
2493                                                             String osName,
2494                                                             String osArch,
2495                                                             String osVersion,


2496                                                             int hashCode) {
2497                     return new ModuleDescriptor(name,
2498                                                 version,
2499                                                 open,
2500                                                 automatic,
2501                                                 synthetic,
2502                                                 requires,
2503                                                 exports,
2504                                                 opens,
2505                                                 uses,
2506                                                 provides,
2507                                                 packages,
2508                                                 mainClass,
2509                                                 osName,
2510                                                 osArch,
2511                                                 osVersion,


2512                                                 hashCode,
2513                                                 false);
2514                 }
2515 
2516                 @Override





2517                 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2518                                                             Collection<String> roots,
2519                                                             boolean check,
2520                                                             PrintStream traceOutput)
2521                 {
2522                     return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2523                 }














2524             });
2525     }
2526 
2527 }
< prev index next >