< prev index next >

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

Print this page




  36 import java.util.Collection;
  37 import java.util.Collections;
  38 import java.util.EnumSet;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.LinkedHashSet;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.Objects;
  45 import java.util.Optional;
  46 import java.util.Set;
  47 import java.util.function.Supplier;
  48 import java.util.stream.Collectors;
  49 import java.util.stream.Stream;
  50 
  51 import static jdk.internal.module.Checks.*;
  52 import static java.util.Objects.*;
  53 
  54 import jdk.internal.module.Checks;
  55 import jdk.internal.module.ModuleHashes;

  56 
  57 
  58 /**
  59  * A module descriptor.
  60  *
  61  * <p> A {@code ModuleDescriptor} is typically created from the binary form
  62  * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
  63  * class can be used to create a {@code ModuleDescriptor} from its components.
  64  * The {@link #module module}, {@link #openModule openModule}, and {@link
  65  * #automaticModule automaticModule} methods create builders for building
  66  * different kinds of modules. </p>
  67  *
  68  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  69  * multiple concurrent threads.</p>
  70  *
  71  * @since 9
  72  * @see java.lang.reflect.Module
  73  */
  74 
  75 public class ModuleDescriptor


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


 995 
 996 
 997     private ModuleDescriptor(String name,
 998                              boolean open,
 999                              boolean automatic,
1000                              boolean synthetic,
1001                              Set<Requires> requires,
1002                              Set<Exports> exports,
1003                              Set<Opens> opens,
1004                              Set<String> uses,
1005                              Set<Provides> provides,
1006                              Version version,
1007                              String mainClass,
1008                              String osName,
1009                              String osArch,
1010                              String osVersion,
1011                              Set<String> packages,
1012                              ModuleHashes hashes)


1013     {
1014 
1015         this.name = name;
1016         this.open = open;
1017         this.automatic = automatic;
1018         this.synthetic = synthetic;
1019 
1020         assert (requires.stream().map(Requires::name).distinct().count()
1021                 == requires.size());
1022         this.requires = emptyOrUnmodifiableSet(requires);
1023 
1024         this.exports = emptyOrUnmodifiableSet(exports);
1025         this.opens = emptyOrUnmodifiableSet(opens);
1026         this.uses = emptyOrUnmodifiableSet(uses);
1027         this.provides = emptyOrUnmodifiableSet(provides);
1028         this.version = version;
1029         this.mainClass = mainClass;
1030         this.osName = osName;
1031         this.osArch = osArch;
1032         this.osVersion = osVersion;
1033         this.hashes = hashes;
1034         this.packages = emptyOrUnmodifiableSet(packages);


1035     }
1036 
1037     /**
1038      * Clones the given module descriptor with an augmented set of packages
1039      */
1040     ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1041         this.name = md.name;
1042         this.open = md.open;
1043         this.automatic = md.automatic;
1044         this.synthetic = md.synthetic;
1045 
1046         this.requires = md.requires;
1047         this.exports = md.exports;
1048         this.opens = md.opens;
1049         this.uses = md.uses;
1050         this.provides = md.provides;
1051 
1052         this.version = md.version;
1053         this.mainClass = md.mainClass;
1054         this.osName = md.osName;
1055         this.osArch = md.osArch;
1056         this.osVersion = md.osVersion;
1057         this.hashes = null; // need to ignore


1058 
1059         Set<String> packages = new HashSet<>(md.packages);
1060         packages.addAll(pkgs);
1061         this.packages = emptyOrUnmodifiableSet(packages);
1062     }
1063 
1064     /**
1065      * Creates a module descriptor from its components.
1066      * The arguments are pre-validated and sets are unmodifiable sets.
1067      */
1068     ModuleDescriptor(String name,
1069                      boolean open,
1070                      boolean automatic,
1071                      boolean synthetic,
1072                      Set<Requires> requires,
1073                      Set<Exports> exports,
1074                      Set<Opens> opens,
1075                      Set<String> uses,
1076                      Set<Provides> provides,
1077                      Version version,
1078                      String mainClass,
1079                      String osName,
1080                      String osArch,
1081                      String osVersion,
1082                      Set<String> packages,
1083                      ModuleHashes hashes,
1084                      int hashCode,


1085                      boolean unused) {
1086         this.name = name;
1087         this.open = open;
1088         this.automatic = automatic;
1089         this.synthetic = synthetic;
1090         this.requires = requires;
1091         this.exports = exports;
1092         this.opens = opens;
1093         this.uses = uses;
1094         this.provides = provides;
1095         this.packages = packages;
1096         this.version = version;
1097         this.mainClass = mainClass;
1098         this.osName = osName;
1099         this.osArch = osArch;
1100         this.osVersion = osVersion;
1101         this.hashes = hashes;
1102         this.hash = hashCode;


1103     }
1104 
1105     /**
1106      * <p> The module name. </p>
1107      *
1108      * @return The module name
1109      */
1110     public String name() {
1111         return name;
1112     }
1113 
1114     /**
1115      * <p> Returns {@code true} if this is an open module. </p>
1116      *
1117      * <p> An open module does not declare any open packages (the {@link #opens()
1118      * opens} method returns an empty set) but the resulting module is treated
1119      * as if all packages are open. </p>
1120      *
1121      * @return  {@code true} if this is an open module
1122      */


1274     public Optional<String> osVersion() {
1275         return Optional.ofNullable(osVersion);
1276     }
1277 
1278     /**
1279      * Returns the names of all packages in this module.
1280      *
1281      * @return A possibly-empty unmodifiable set of all packages in the module
1282      */
1283     public Set<String> packages() {
1284         return packages;
1285     }
1286 
1287     /**
1288      * Returns the object with the hashes of other modules
1289      */
1290     Optional<ModuleHashes> hashes() {
1291         return Optional.ofNullable(hashes);
1292     }
1293 




1294 
1295     /**
1296      * A builder used for building {@link ModuleDescriptor} objects.
1297      *
1298      * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1299      * #openModule openModule}, and {@link #automaticModule automaticModule}
1300      * methods to create builders for building different kinds of modules. </p>
1301      *
1302      * <p> Example usage: </p>
1303      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1304      *         .exports("p")
1305      *         .requires("m2")
1306      *         .build();
1307      * }</pre>
1308      *
1309      * @apiNote A {@code Builder} checks the components and invariants as
1310      * components are added to the builder. The rational for this is to detect
1311      * errors as early as possible and not defer all validation to the
1312      * {@link #build build} method. A {@code Builder} cannot be used to create
1313      * a {@link ModuleDescriptor#isSynthetic() synthetic} module.


1317     public static final class Builder {
1318         final String name;
1319         final boolean strict; // true if module names are checked
1320         boolean open;
1321         boolean automatic;
1322         boolean synthetic;
1323         final Map<String, Requires> requires = new HashMap<>();
1324 
1325         final Map<String, Exports> exports = new HashMap<>();
1326         final Map<String, Opens> opens = new HashMap<>();
1327         final Set<String> concealedPackages = new HashSet<>();
1328 
1329         final Set<String> uses = new HashSet<>();
1330         final Map<String, Provides> provides = new HashMap<>();
1331         Version version;
1332         String osName;
1333         String osArch;
1334         String osVersion;
1335         String mainClass;
1336         ModuleHashes hashes;


1337 
1338         /**
1339          * Initializes a new builder with the given module name.
1340          *
1341          * @param strict
1342          *        Indicates whether module names are checked or not
1343          */
1344         Builder(String name, boolean strict) {
1345             this.strict = strict;
1346             this.name = (strict) ? requireModuleName(name) : name;
1347         }
1348 
1349         /* package */ Builder open(boolean open) {
1350             this.open = open;
1351             return this;
1352         }
1353 
1354         /* package */ Builder automatic(boolean automatic) {
1355             this.automatic = automatic;
1356             return this;


1688         /**
1689          * Adds an <em>opens</em> directive to open a package.
1690          *
1691          * @param  pn
1692          *         The package name
1693          *
1694          * @return This builder
1695          *
1696          * @throws IllegalArgumentException
1697          *         If the package name is {@code null} or is not a legal Java
1698          *         identifier
1699          * @throws IllegalStateException
1700          *         If the package is already declared as a package with the
1701          *         {@link #contains contains} method, the package is already
1702          *         declared as open, or this is a builder for an open module
1703          */
1704         public Builder opens(String pn) {
1705             return opens(Collections.emptySet(), pn);
1706         }
1707 









1708 
1709         // Used by ModuleInfo, after a packageFinder is invoked
1710         /* package */ Set<String> exportedAndOpenPackages() {
1711             if (opens.isEmpty())
1712                 return exports.keySet();
1713             Set<String> result = new HashSet<>();
1714             result.addAll(exports.keySet());
1715             result.addAll(opens.keySet());
1716             return result;
1717         }
1718 
1719         /**
1720          * Adds a service dependence.
1721          *
1722          * @param  service
1723          *         The service type
1724          *
1725          * @return This builder
1726          *
1727          * @throws IllegalArgumentException


1996             Set<Exports> exports = new HashSet<>(this.exports.values());
1997             Set<Opens> opens = new HashSet<>(this.opens.values());
1998 
1999             Set<Provides> provides = new HashSet<>(this.provides.values());
2000 
2001             return new ModuleDescriptor(name,
2002                                         open,
2003                                         automatic,
2004                                         synthetic,
2005                                         requires,
2006                                         exports,
2007                                         opens,
2008                                         uses,
2009                                         provides,
2010                                         version,
2011                                         mainClass,
2012                                         osName,
2013                                         osArch,
2014                                         osVersion,
2015                                         packages,
2016                                         hashes);


2017         }
2018 
2019     }
2020 
2021     /**
2022      * Compares this module descriptor to another.
2023      *
2024      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2025      * module name lexicographically.  Where the module names are equal then
2026      * the versions, if present, are compared. </p>
2027      *
2028      * @apiNote For now, the natural ordering is not consistent with equals.
2029      * If two module descriptors have equal module names, equal versions if
2030      * present, but their corresponding components are not equal, then they
2031      * will be considered equal by this method.
2032      *
2033      * @param  that
2034      *         The object to which this module descriptor is to be compared
2035      *
2036      * @return A negative integer, zero, or a positive integer if this module


2072         if (ob == this)
2073             return true;
2074         if (!(ob instanceof ModuleDescriptor))
2075             return false;
2076         ModuleDescriptor that = (ModuleDescriptor)ob;
2077         return (name.equals(that.name)
2078                 && open == that.open
2079                 && automatic == that.automatic
2080                 && synthetic == that.synthetic
2081                 && requires.equals(that.requires)
2082                 && exports.equals(that.exports)
2083                 && opens.equals(that.opens)
2084                 && uses.equals(that.uses)
2085                 && provides.equals(that.provides)
2086                 && Objects.equals(version, that.version)
2087                 && Objects.equals(mainClass, that.mainClass)
2088                 && Objects.equals(osName, that.osName)
2089                 && Objects.equals(osArch, that.osArch)
2090                 && Objects.equals(osVersion, that.osVersion)
2091                 && Objects.equals(packages, that.packages)
2092                 && Objects.equals(hashes, that.hashes));


2093     }
2094 
2095     private transient int hash;  // cached hash code
2096 
2097     /**
2098      * Computes a hash code for this module descriptor.
2099      *
2100      * <p> The hash code is based upon the components of the module descriptor,
2101      * and satisfies the general contract of the {@link Object#hashCode
2102      * Object.hashCode} method. </p>
2103      *
2104      * @return The hash-code value for this module descriptor
2105      */
2106     @Override
2107     public int hashCode() {
2108         int hc = hash;
2109         if (hc == 0) {
2110             hc = name.hashCode();
2111             hc = hc * 43 + Boolean.hashCode(open);
2112             hc = hc * 43 + Boolean.hashCode(automatic);
2113             hc = hc * 43 + Boolean.hashCode(synthetic);
2114             hc = hc * 43 + requires.hashCode();
2115             hc = hc * 43 + exports.hashCode();
2116             hc = hc * 43 + opens.hashCode();
2117             hc = hc * 43 + uses.hashCode();
2118             hc = hc * 43 + provides.hashCode();
2119             hc = hc * 43 + Objects.hashCode(version);
2120             hc = hc * 43 + Objects.hashCode(mainClass);
2121             hc = hc * 43 + Objects.hashCode(osName);
2122             hc = hc * 43 + Objects.hashCode(osArch);
2123             hc = hc * 43 + Objects.hashCode(osVersion);
2124             hc = hc * 43 + Objects.hashCode(packages);
2125             hc = hc * 43 + Objects.hashCode(hashes);


2126             if (hc == 0)
2127                 hc = -1;
2128             hash = hc;
2129         }
2130         return hc;
2131     }
2132 
2133     /**
2134      * Returns a string describing this descriptor.
2135      *
2136      * @return A string describing this descriptor
2137      */
2138     @Override
2139     public String toString() {
2140         StringBuilder sb = new StringBuilder();
2141 
2142         if (isOpen())
2143             sb.append("open ");
2144         sb.append("module { name: ").append(toNameAndVersion());
2145         if (!requires.isEmpty())


2431                     return new ModuleDescriptor(md, pkgs);
2432                 }
2433 
2434                 @Override
2435                 public ModuleDescriptor newModuleDescriptor(String name,
2436                                                             boolean open,
2437                                                             boolean automatic,
2438                                                             boolean synthetic,
2439                                                             Set<Requires> requires,
2440                                                             Set<Exports> exports,
2441                                                             Set<Opens> opens,
2442                                                             Set<String> uses,
2443                                                             Set<Provides> provides,
2444                                                             Version version,
2445                                                             String mainClass,
2446                                                             String osName,
2447                                                             String osArch,
2448                                                             String osVersion,
2449                                                             Set<String> packages,
2450                                                             ModuleHashes hashes,
2451                                                             int hashCode) {


2452                     return new ModuleDescriptor(name,
2453                                                 open,
2454                                                 automatic,
2455                                                 synthetic,
2456                                                 requires,
2457                                                 exports,
2458                                                 opens,
2459                                                 uses,
2460                                                 provides,
2461                                                 version,
2462                                                 mainClass,
2463                                                 osName,
2464                                                 osArch,
2465                                                 osVersion,
2466                                                 packages,
2467                                                 hashes,
2468                                                 hashCode,


2469                                                 false);
2470                 }
2471 
2472                 @Override
2473                 public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
2474                     return descriptor.hashes();
2475                 }
2476 
2477                 @Override
2478                 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2479                                                             Collection<String> roots,
2480                                                             boolean check,
2481                                                             PrintStream traceOutput)
2482                 {
2483                     return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2484                 }
2485 
2486                 @Override
2487                 public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
2488                                                         URI location,
2489                                                         Supplier<ModuleReader> s) {
2490                     return new ModuleReference(descriptor, location, s, true, null);










2491                 }
2492 
2493                 @Override
2494                 public ModuleFinder newModulePath(Runtime.Version version,
2495                                                   boolean isLinkPhase,
2496                                                   Path... entries) {
2497                     return new ModulePath(version, isLinkPhase, entries);
2498                 }
2499             });
2500     }
2501 
2502 }


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


 976     // Indicates if synthesised for a JAR file found on the module path
 977     private final boolean automatic;
 978 
 979     // Not generated from a module-info.java
 980     private final boolean synthetic;
 981 
 982     private final Set<Requires> requires;
 983     private final Set<Exports> exports;
 984     private final Set<Opens> opens;
 985     private final Set<String> uses;
 986     private final Set<Provides> provides;
 987 
 988     // "Extended" information, added post-compilation by tools
 989     private final Version version;
 990     private final String mainClass;
 991     private final String osName;
 992     private final String osArch;
 993     private final String osVersion;
 994     private final Set<String> packages;
 995     private final ModuleHashes hashes;
 996     private final boolean doNotResolveByDefault;
 997     private final WarnIfResolvedReason warnIfResolvedReason;
 998 
 999 
1000     private ModuleDescriptor(String name,
1001                              boolean open,
1002                              boolean automatic,
1003                              boolean synthetic,
1004                              Set<Requires> requires,
1005                              Set<Exports> exports,
1006                              Set<Opens> opens,
1007                              Set<String> uses,
1008                              Set<Provides> provides,
1009                              Version version,
1010                              String mainClass,
1011                              String osName,
1012                              String osArch,
1013                              String osVersion,
1014                              Set<String> packages,
1015                              ModuleHashes hashes,
1016                              boolean doNotResolveByDefault,
1017                              WarnIfResolvedReason warnIfResolvedReason)
1018     {
1019 
1020         this.name = name;
1021         this.open = open;
1022         this.automatic = automatic;
1023         this.synthetic = synthetic;
1024 
1025         assert (requires.stream().map(Requires::name).distinct().count()
1026                 == requires.size());
1027         this.requires = emptyOrUnmodifiableSet(requires);
1028 
1029         this.exports = emptyOrUnmodifiableSet(exports);
1030         this.opens = emptyOrUnmodifiableSet(opens);
1031         this.uses = emptyOrUnmodifiableSet(uses);
1032         this.provides = emptyOrUnmodifiableSet(provides);
1033         this.version = version;
1034         this.mainClass = mainClass;
1035         this.osName = osName;
1036         this.osArch = osArch;
1037         this.osVersion = osVersion;
1038         this.hashes = hashes;
1039         this.packages = emptyOrUnmodifiableSet(packages);
1040         this.doNotResolveByDefault = doNotResolveByDefault;
1041         this.warnIfResolvedReason = warnIfResolvedReason;
1042     }
1043 
1044     /**
1045      * Clones the given module descriptor with an augmented set of packages
1046      */
1047     ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
1048         this.name = md.name;
1049         this.open = md.open;
1050         this.automatic = md.automatic;
1051         this.synthetic = md.synthetic;
1052 
1053         this.requires = md.requires;
1054         this.exports = md.exports;
1055         this.opens = md.opens;
1056         this.uses = md.uses;
1057         this.provides = md.provides;
1058 
1059         this.version = md.version;
1060         this.mainClass = md.mainClass;
1061         this.osName = md.osName;
1062         this.osArch = md.osArch;
1063         this.osVersion = md.osVersion;
1064         this.hashes = null; // need to ignore
1065         this.doNotResolveByDefault = md.doNotResolveByDefault;
1066         this.warnIfResolvedReason = md.warnIfResolvedReason;
1067 
1068         Set<String> packages = new HashSet<>(md.packages);
1069         packages.addAll(pkgs);
1070         this.packages = emptyOrUnmodifiableSet(packages);
1071     }
1072 
1073     /**
1074      * Creates a module descriptor from its components.
1075      * The arguments are pre-validated and sets are unmodifiable sets.
1076      */
1077     ModuleDescriptor(String name,
1078                      boolean open,
1079                      boolean automatic,
1080                      boolean synthetic,
1081                      Set<Requires> requires,
1082                      Set<Exports> exports,
1083                      Set<Opens> opens,
1084                      Set<String> uses,
1085                      Set<Provides> provides,
1086                      Version version,
1087                      String mainClass,
1088                      String osName,
1089                      String osArch,
1090                      String osVersion,
1091                      Set<String> packages,
1092                      ModuleHashes hashes,
1093                      int hashCode,
1094                      boolean doNotResolveByDefault,
1095                      WarnIfResolvedReason warnIfResolvedReason,
1096                      boolean unused) {
1097         this.name = name;
1098         this.open = open;
1099         this.automatic = automatic;
1100         this.synthetic = synthetic;
1101         this.requires = requires;
1102         this.exports = exports;
1103         this.opens = opens;
1104         this.uses = uses;
1105         this.provides = provides;
1106         this.packages = packages;
1107         this.version = version;
1108         this.mainClass = mainClass;
1109         this.osName = osName;
1110         this.osArch = osArch;
1111         this.osVersion = osVersion;
1112         this.hashes = hashes;
1113         this.hash = hashCode;
1114         this.doNotResolveByDefault = doNotResolveByDefault;
1115         this.warnIfResolvedReason = warnIfResolvedReason;
1116     }
1117 
1118     /**
1119      * <p> The module name. </p>
1120      *
1121      * @return The module name
1122      */
1123     public String name() {
1124         return name;
1125     }
1126 
1127     /**
1128      * <p> Returns {@code true} if this is an open module. </p>
1129      *
1130      * <p> An open module does not declare any open packages (the {@link #opens()
1131      * opens} method returns an empty set) but the resulting module is treated
1132      * as if all packages are open. </p>
1133      *
1134      * @return  {@code true} if this is an open module
1135      */


1287     public Optional<String> osVersion() {
1288         return Optional.ofNullable(osVersion);
1289     }
1290 
1291     /**
1292      * Returns the names of all packages in this module.
1293      *
1294      * @return A possibly-empty unmodifiable set of all packages in the module
1295      */
1296     public Set<String> packages() {
1297         return packages;
1298     }
1299 
1300     /**
1301      * Returns the object with the hashes of other modules
1302      */
1303     Optional<ModuleHashes> hashes() {
1304         return Optional.ofNullable(hashes);
1305     }
1306 
1307     /* package */ boolean doNotResolveByDefault() {
1308         return doNotResolveByDefault;
1309     }
1310 
1311 
1312     /**
1313      * A builder used for building {@link ModuleDescriptor} objects.
1314      *
1315      * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
1316      * #openModule openModule}, and {@link #automaticModule automaticModule}
1317      * methods to create builders for building different kinds of modules. </p>
1318      *
1319      * <p> Example usage: </p>
1320      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
1321      *         .exports("p")
1322      *         .requires("m2")
1323      *         .build();
1324      * }</pre>
1325      *
1326      * @apiNote A {@code Builder} checks the components and invariants as
1327      * components are added to the builder. The rational for this is to detect
1328      * errors as early as possible and not defer all validation to the
1329      * {@link #build build} method. A {@code Builder} cannot be used to create
1330      * a {@link ModuleDescriptor#isSynthetic() synthetic} module.


1334     public static final class Builder {
1335         final String name;
1336         final boolean strict; // true if module names are checked
1337         boolean open;
1338         boolean automatic;
1339         boolean synthetic;
1340         final Map<String, Requires> requires = new HashMap<>();
1341 
1342         final Map<String, Exports> exports = new HashMap<>();
1343         final Map<String, Opens> opens = new HashMap<>();
1344         final Set<String> concealedPackages = new HashSet<>();
1345 
1346         final Set<String> uses = new HashSet<>();
1347         final Map<String, Provides> provides = new HashMap<>();
1348         Version version;
1349         String osName;
1350         String osArch;
1351         String osVersion;
1352         String mainClass;
1353         ModuleHashes hashes;
1354         boolean doNotResolveByDefault;
1355         WarnIfResolvedReason warnIfResolvedReason = WarnIfResolvedReason.NONE;
1356 
1357         /**
1358          * Initializes a new builder with the given module name.
1359          *
1360          * @param strict
1361          *        Indicates whether module names are checked or not
1362          */
1363         Builder(String name, boolean strict) {
1364             this.strict = strict;
1365             this.name = (strict) ? requireModuleName(name) : name;
1366         }
1367 
1368         /* package */ Builder open(boolean open) {
1369             this.open = open;
1370             return this;
1371         }
1372 
1373         /* package */ Builder automatic(boolean automatic) {
1374             this.automatic = automatic;
1375             return this;


1707         /**
1708          * Adds an <em>opens</em> directive to open a package.
1709          *
1710          * @param  pn
1711          *         The package name
1712          *
1713          * @return This builder
1714          *
1715          * @throws IllegalArgumentException
1716          *         If the package name is {@code null} or is not a legal Java
1717          *         identifier
1718          * @throws IllegalStateException
1719          *         If the package is already declared as a package with the
1720          *         {@link #contains contains} method, the package is already
1721          *         declared as open, or this is a builder for an open module
1722          */
1723         public Builder opens(String pn) {
1724             return opens(Collections.emptySet(), pn);
1725         }
1726 
1727         /* package */ Builder doNotResolveByDefault(boolean value) {
1728             this.doNotResolveByDefault = value;
1729             return this;
1730         }
1731 
1732         /* package */ Builder warnIfResolved(WarnIfResolvedReason reason) {
1733             this.warnIfResolvedReason = reason;
1734             return this;
1735         }
1736 
1737         // Used by ModuleInfo, after a packageFinder is invoked
1738         /* package */ Set<String> exportedAndOpenPackages() {
1739             if (opens.isEmpty())
1740                 return exports.keySet();
1741             Set<String> result = new HashSet<>();
1742             result.addAll(exports.keySet());
1743             result.addAll(opens.keySet());
1744             return result;
1745         }
1746 
1747         /**
1748          * Adds a service dependence.
1749          *
1750          * @param  service
1751          *         The service type
1752          *
1753          * @return This builder
1754          *
1755          * @throws IllegalArgumentException


2024             Set<Exports> exports = new HashSet<>(this.exports.values());
2025             Set<Opens> opens = new HashSet<>(this.opens.values());
2026 
2027             Set<Provides> provides = new HashSet<>(this.provides.values());
2028 
2029             return new ModuleDescriptor(name,
2030                                         open,
2031                                         automatic,
2032                                         synthetic,
2033                                         requires,
2034                                         exports,
2035                                         opens,
2036                                         uses,
2037                                         provides,
2038                                         version,
2039                                         mainClass,
2040                                         osName,
2041                                         osArch,
2042                                         osVersion,
2043                                         packages,
2044                                         hashes,
2045                                         doNotResolveByDefault,
2046                                         warnIfResolvedReason);
2047         }
2048 
2049     }
2050 
2051     /**
2052      * Compares this module descriptor to another.
2053      *
2054      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2055      * module name lexicographically.  Where the module names are equal then
2056      * the versions, if present, are compared. </p>
2057      *
2058      * @apiNote For now, the natural ordering is not consistent with equals.
2059      * If two module descriptors have equal module names, equal versions if
2060      * present, but their corresponding components are not equal, then they
2061      * will be considered equal by this method.
2062      *
2063      * @param  that
2064      *         The object to which this module descriptor is to be compared
2065      *
2066      * @return A negative integer, zero, or a positive integer if this module


2102         if (ob == this)
2103             return true;
2104         if (!(ob instanceof ModuleDescriptor))
2105             return false;
2106         ModuleDescriptor that = (ModuleDescriptor)ob;
2107         return (name.equals(that.name)
2108                 && open == that.open
2109                 && automatic == that.automatic
2110                 && synthetic == that.synthetic
2111                 && requires.equals(that.requires)
2112                 && exports.equals(that.exports)
2113                 && opens.equals(that.opens)
2114                 && uses.equals(that.uses)
2115                 && provides.equals(that.provides)
2116                 && Objects.equals(version, that.version)
2117                 && Objects.equals(mainClass, that.mainClass)
2118                 && Objects.equals(osName, that.osName)
2119                 && Objects.equals(osArch, that.osArch)
2120                 && Objects.equals(osVersion, that.osVersion)
2121                 && Objects.equals(packages, that.packages)
2122                 && Objects.equals(hashes, that.hashes)
2123                 && doNotResolveByDefault == that.doNotResolveByDefault
2124                 && warnIfResolvedReason == that.warnIfResolvedReason);
2125     }
2126 
2127     private transient int hash;  // cached hash code
2128 
2129     /**
2130      * Computes a hash code for this module descriptor.
2131      *
2132      * <p> The hash code is based upon the components of the module descriptor,
2133      * and satisfies the general contract of the {@link Object#hashCode
2134      * Object.hashCode} method. </p>
2135      *
2136      * @return The hash-code value for this module descriptor
2137      */
2138     @Override
2139     public int hashCode() {
2140         int hc = hash;
2141         if (hc == 0) {
2142             hc = name.hashCode();
2143             hc = hc * 43 + Boolean.hashCode(open);
2144             hc = hc * 43 + Boolean.hashCode(automatic);
2145             hc = hc * 43 + Boolean.hashCode(synthetic);
2146             hc = hc * 43 + requires.hashCode();
2147             hc = hc * 43 + exports.hashCode();
2148             hc = hc * 43 + opens.hashCode();
2149             hc = hc * 43 + uses.hashCode();
2150             hc = hc * 43 + provides.hashCode();
2151             hc = hc * 43 + Objects.hashCode(version);
2152             hc = hc * 43 + Objects.hashCode(mainClass);
2153             hc = hc * 43 + Objects.hashCode(osName);
2154             hc = hc * 43 + Objects.hashCode(osArch);
2155             hc = hc * 43 + Objects.hashCode(osVersion);
2156             hc = hc * 43 + Objects.hashCode(packages);
2157             hc = hc * 43 + Objects.hashCode(hashes);
2158             hc = hc * 43 + Objects.hashCode(doNotResolveByDefault);
2159             hc = hc * 43 + Objects.hashCode(warnIfResolvedReason);
2160             if (hc == 0)
2161                 hc = -1;
2162             hash = hc;
2163         }
2164         return hc;
2165     }
2166 
2167     /**
2168      * Returns a string describing this descriptor.
2169      *
2170      * @return A string describing this descriptor
2171      */
2172     @Override
2173     public String toString() {
2174         StringBuilder sb = new StringBuilder();
2175 
2176         if (isOpen())
2177             sb.append("open ");
2178         sb.append("module { name: ").append(toNameAndVersion());
2179         if (!requires.isEmpty())


2465                     return new ModuleDescriptor(md, pkgs);
2466                 }
2467 
2468                 @Override
2469                 public ModuleDescriptor newModuleDescriptor(String name,
2470                                                             boolean open,
2471                                                             boolean automatic,
2472                                                             boolean synthetic,
2473                                                             Set<Requires> requires,
2474                                                             Set<Exports> exports,
2475                                                             Set<Opens> opens,
2476                                                             Set<String> uses,
2477                                                             Set<Provides> provides,
2478                                                             Version version,
2479                                                             String mainClass,
2480                                                             String osName,
2481                                                             String osArch,
2482                                                             String osVersion,
2483                                                             Set<String> packages,
2484                                                             ModuleHashes hashes,
2485                                                             int hashCode,
2486                                                             boolean doNotResolveByDefault,
2487                                                             WarnIfResolvedReason reason) {
2488                     return new ModuleDescriptor(name,
2489                                                 open,
2490                                                 automatic,
2491                                                 synthetic,
2492                                                 requires,
2493                                                 exports,
2494                                                 opens,
2495                                                 uses,
2496                                                 provides,
2497                                                 version,
2498                                                 mainClass,
2499                                                 osName,
2500                                                 osArch,
2501                                                 osVersion,
2502                                                 packages,
2503                                                 hashes,
2504                                                 hashCode,
2505                                                 doNotResolveByDefault,
2506                                                 reason,
2507                                                 false);
2508                 }
2509 
2510                 @Override
2511                 public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
2512                     return descriptor.hashes();
2513                 }
2514 
2515                 @Override
2516                 public Configuration resolveRequiresAndUses(ModuleFinder finder,
2517                                                             Collection<String> roots,
2518                                                             boolean check,
2519                                                             PrintStream traceOutput)
2520                 {
2521                     return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
2522                 }
2523 
2524                 @Override
2525                 public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
2526                                                         URI location,
2527                                                         Supplier<ModuleReader> s) {
2528                     return new ModuleReference(descriptor, location, s, true, null);
2529                 }
2530 
2531                 @Override
2532                 public boolean doNotResolveByDefault(ModuleDescriptor descriptor) {
2533                     return descriptor.doNotResolveByDefault;
2534                 }
2535 
2536                 @Override
2537                 public WarnIfResolvedReason warnIfResolvedReason(ModuleDescriptor descriptor) {
2538                     return descriptor.warnIfResolvedReason;
2539                 }
2540 
2541                 @Override
2542                 public ModuleFinder newModulePath(Runtime.Version version,
2543                                                   boolean isLinkPhase,
2544                                                   Path... entries) {
2545                     return new ModulePath(version, isLinkPhase, entries);
2546                 }
2547             });
2548     }
2549 
2550 }
< prev index next >