1 /*
   2  * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  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.Arrays;
  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.List;
  42 import java.util.Locale;
  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.ModuleInfo;
  56 
  57 
  58 /**
  59  * A module descriptor.
  60  *
  61  * <p> A module descriptor describes a named module and defines methods to
  62  * obtain each of its components. The module descriptor for a named module
  63  * in the Java virtual machine is obtained by invoking the {@link
  64  * java.lang.Module Module}'s {@link java.lang.Module#getDescriptor
  65  * getDescriptor} method. Module descriptors can also be created using the
  66  * {@link ModuleDescriptor.Builder} class or by reading the binary form of a
  67  * module declaration ({@code module-info.class}) using the {@link
  68  * #read(InputStream,Supplier) read} methods defined here. </p>
  69  *
  70  * <p> A module descriptor describes a <em>normal</em>, open, or automatic
  71  * module. <em>Normal</em> modules and open modules describe their {@link
  72  * #requires() dependences}, {@link #exports() exported-packages}, the services
  73  * that they {@link #uses() use} or {@link #provides() provide}, and other
  74  * components. <em>Normal</em> modules may {@link #opens() open} specific
  75  * packages. The module descriptor for an open modules does not declare any
  76  * open packages (its {@code opens} method returns an empty set) but when
  77  * instantiated in the Java virtual machine then it is treated as if all
  78  * packages are open. The module descriptor for an automatic module does not
  79  * declare any dependences (except for the mandatory dependency on {@code
  80  * java.base}), and does not declare any exported or open packages. Automatic
  81  * module receive special treatment during resolution so that they read all
  82  * other modules in the configuration. When an automatic module is instantiated
  83  * in the Java virtual machine then it reads every unnamed module and is
  84  * treated as if all packages are exported and open. </p>
  85  *
  86  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  87  * multiple concurrent threads.</p>
  88  *
  89  * @see java.lang.Module
  90  * @since 9
  91  * @spec JPMS
  92  */
  93 
  94 public class ModuleDescriptor
  95     implements Comparable<ModuleDescriptor>
  96 {
  97 
  98     /**
  99      * A modifier on a module.
 100      *
 101      * @see ModuleDescriptor#modifiers()
 102      * @since 9
 103      * @spec JPMS
 104      */
 105     public enum Modifier {
 106         /**
 107          * An open module. An open module does not declare any open packages
 108          * but the resulting module is treated as if all packages are open.
 109          */
 110         OPEN,
 111 
 112         /**
 113          * An automatic module. An automatic module is treated as if it exports
 114          * and opens all packages.
 115          *
 116          * @apiNote This modifier does not correspond to a module flag in the
 117          * binary form of a module declaration ({@code module-info.class}).
 118          */
 119         AUTOMATIC,
 120 
 121         /**
 122          * The module was not explicitly or implicitly declared.
 123          */
 124         SYNTHETIC,
 125 
 126         /**
 127          * The module was implicitly declared.
 128          */
 129         MANDATED;
 130     }
 131 
 132 
 133     /**
 134      * <p> A dependence upon a module </p>
 135      *
 136      * @see ModuleDescriptor#requires()
 137      * @since 9
 138      * @spec JPMS
 139      */
 140 
 141     public final static class Requires
 142         implements Comparable<Requires>
 143     {
 144 
 145         /**
 146          * A modifier on a module dependence.
 147          *
 148          * @see Requires#modifiers()
 149          * @since 9
 150          * @spec JPMS
 151          */
 152         public enum Modifier {
 153 
 154             /**
 155              * The dependence causes any module which depends on the <i>current
 156              * module</i> to have an implicitly declared dependence on the module
 157              * named by the {@code Requires}.
 158              */
 159             TRANSITIVE,
 160 
 161             /**
 162              * The dependence is mandatory in the static phase, during compilation,
 163              * but is optional in the dynamic phase, during execution.
 164              */
 165             STATIC,
 166 
 167             /**
 168              * The dependence was not explicitly or implicitly declared in the
 169              * source of the module declaration.
 170              */
 171             SYNTHETIC,
 172 
 173             /**
 174              * The dependence was implicitly declared in the source of the module
 175              * declaration.
 176              */
 177             MANDATED;
 178 
 179         }
 180 
 181         private final Set<Modifier> mods;
 182         private final String name;
 183         private final Version compiledVersion;
 184         private final String rawCompiledVersion;
 185 
 186         private Requires(Set<Modifier> ms, String mn, Version v, String vs) {
 187             assert v == null || vs == null;
 188             this.mods = Set.copyOf(ms);
 189             this.name = mn;
 190             this.compiledVersion = v;
 191             this.rawCompiledVersion = vs;
 192         }
 193 
 194         private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
 195             this.mods = ms;
 196             this.name = mn;
 197             this.compiledVersion = v;
 198             this.rawCompiledVersion = null;
 199         }
 200 
 201         /**
 202          * Returns the set of modifiers.
 203          *
 204          * @return A possibly-empty unmodifiable set of modifiers
 205          */
 206         public Set<Modifier> modifiers() {
 207             return mods;
 208         }
 209 
 210         /**
 211          * Return the module name.
 212          *
 213          * @return The module name
 214          */
 215         public String name() {
 216             return name;
 217         }
 218 
 219         /**
 220          * Returns the version of the module if recorded at compile-time.
 221          *
 222          * @return The version of the module if recorded at compile-time,
 223          *         or an empty {@code Optional} if no version was recorded or
 224          *         the version string recorded is {@linkplain Version#parse(String)
 225          *         unparseable}
 226          */
 227         public Optional<Version> compiledVersion() {
 228             return Optional.ofNullable(compiledVersion);
 229         }
 230 
 231         /**
 232          * Returns the string with the possibly-unparseable version of the module
 233          * if recorded at compile-time.
 234          *
 235          * @return The string containing the version of the module if recorded
 236          *         at compile-time, or an empty {@code Optional} if no version
 237          *         was recorded
 238          *
 239          * @see #compiledVersion()
 240          */
 241         public Optional<String> rawCompiledVersion() {
 242             if (compiledVersion != null) {
 243                 return Optional.of(compiledVersion.toString());
 244             } else {
 245                 return Optional.ofNullable(rawCompiledVersion);
 246             }
 247         }
 248 
 249         /**
 250          * Compares this module dependence to another.
 251          *
 252          * <p> Two {@code Requires} objects are compared by comparing their
 253          * module names lexicographically. Where the module names are equal
 254          * then the sets of modifiers are compared in the same way that
 255          * module modifiers are compared (see {@link ModuleDescriptor#compareTo
 256          * ModuleDescriptor.compareTo}). Where the module names are equal and
 257          * the set of modifiers are equal then the version of the modules
 258          * recorded at compile-time are compared. When comparing the versions
 259          * recorded at compile-time then a dependence that has a recorded
 260          * version is considered to succeed a dependence that does not have a
 261          * recorded version. If both recorded versions are {@linkplain
 262          * Version#parse(String) unparseable} then the {@linkplain
 263          * #rawCompiledVersion() raw version strings} are compared
 264          * lexicographically. </p>
 265          *
 266          * @param  that
 267          *         The module dependence to compare
 268          *
 269          * @return A negative integer, zero, or a positive integer if this module
 270          *         dependence is less than, equal to, or greater than the given
 271          *         module dependence
 272          */
 273         @Override
 274         public int compareTo(Requires that) {
 275             if (this == that) return 0;
 276 
 277             int c = this.name().compareTo(that.name());
 278             if (c != 0) return c;
 279 
 280             // modifiers
 281             long v1 = modsValue(this.modifiers());
 282             long v2 = modsValue(that.modifiers());
 283             c = Long.compare(v1, v2);
 284             if (c != 0) return c;
 285 
 286             // compiledVersion
 287             c = compare(this.compiledVersion, that.compiledVersion);
 288             if (c != 0) return c;
 289 
 290             // rawCompiledVersion
 291             c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
 292             if (c != 0) return c;
 293 
 294             return 0;
 295         }
 296 
 297         /**
 298          * Tests this module dependence for equality with the given object.
 299          *
 300          * <p> If the given object is not a {@code Requires} then this method
 301          * returns {@code false}. Two module dependence objects are equal if
 302          * the module names are equal, set of modifiers are equal, and the
 303          * compiled version of both modules is equal or not recorded for
 304          * both modules. </p>
 305          *
 306          * <p> This method satisfies the general contract of the {@link
 307          * java.lang.Object#equals(Object) Object.equals} method. </p>
 308          *
 309          * @param   ob
 310          *          the object to which this object is to be compared
 311          *
 312          * @return  {@code true} if, and only if, the given object is a module
 313          *          dependence that is equal to this module dependence
 314          */
 315         @Override
 316         public boolean equals(Object ob) {
 317             if (!(ob instanceof Requires))
 318                 return false;
 319             Requires that = (Requires)ob;
 320             return name.equals(that.name) && mods.equals(that.mods)
 321                     && Objects.equals(compiledVersion, that.compiledVersion)
 322                     && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
 323         }
 324 
 325         /**
 326          * Computes a hash code for this module dependence.
 327          *
 328          * <p> The hash code is based upon the module name, modifiers, and the
 329          * module version if recorded at compile time. It satisfies the general
 330          * contract of the {@link Object#hashCode Object.hashCode} method. </p>
 331          *
 332          * @return The hash-code value for this module dependence
 333          */
 334         @Override
 335         public int hashCode() {
 336             int hash = name.hashCode() * 43 + mods.hashCode();
 337             if (compiledVersion != null)
 338                 hash = hash * 43 + compiledVersion.hashCode();
 339             if (rawCompiledVersion != null)
 340                 hash = hash * 43 + rawCompiledVersion.hashCode();
 341             return hash;
 342         }
 343 
 344         /**
 345          * Returns a string describing this module dependence.
 346          *
 347          * @return A string describing this module dependence
 348          */
 349         @Override
 350         public String toString() {
 351             String what;
 352             if (compiledVersion != null) {
 353                 what = name() + " (@" + compiledVersion + ")";
 354             } else {
 355                 what = name();
 356             }
 357             return ModuleDescriptor.toString(mods, what);
 358         }
 359     }
 360 
 361 
 362 
 363     /**
 364      * <p> A package exported by a module, may be qualified or unqualified. </p>
 365      *
 366      * @see ModuleDescriptor#exports()
 367      * @since 9
 368      * @spec JPMS
 369      */
 370 
 371     public final static class Exports
 372         implements Comparable<Exports>
 373     {
 374 
 375         /**
 376          * A modifier on an exported package.
 377          *
 378          * @see Exports#modifiers()
 379          * @since 9
 380          * @spec JPMS
 381          */
 382         public enum Modifier {
 383 
 384             /**
 385              * The export was not explicitly or implicitly declared in the
 386              * source of the module declaration.
 387              */
 388             SYNTHETIC,
 389 
 390             /**
 391              * The export was implicitly declared in the source of the module
 392              * declaration.
 393              */
 394             MANDATED;
 395 
 396         }
 397 
 398         private final Set<Modifier> mods;
 399         private final String source;
 400         private final Set<String> targets;  // empty if unqualified export
 401 
 402         /**
 403          * Constructs an export
 404          */
 405         private Exports(Set<Modifier> ms, String source, Set<String> targets) {
 406             this.mods = Set.copyOf(ms);
 407             this.source = source;
 408             this.targets = Set.copyOf(targets);
 409         }
 410 
 411         private Exports(Set<Modifier> ms,
 412                         String source,
 413                         Set<String> targets,
 414                         boolean unused) {
 415             this.mods = ms;
 416             this.source = source;
 417             this.targets = targets;
 418         }
 419 
 420         /**
 421          * Returns the set of modifiers.
 422          *
 423          * @return A possibly-empty unmodifiable set of modifiers
 424          */
 425         public Set<Modifier> modifiers() {
 426             return mods;
 427         }
 428 
 429         /**
 430          * Returns {@code true} if this is a qualified export.
 431          *
 432          * @return {@code true} if this is a qualified export
 433          */
 434         public boolean isQualified() {
 435             return !targets.isEmpty();
 436         }
 437 
 438         /**
 439          * Returns the package name.
 440          *
 441          * @return The package name
 442          */
 443         public String source() {
 444             return source;
 445         }
 446 
 447         /**
 448          * For a qualified export, returns the non-empty and immutable set
 449          * of the module names to which the package is exported. For an
 450          * unqualified export, returns an empty set.
 451          *
 452          * @return The set of target module names or for an unqualified
 453          *         export, an empty set
 454          */
 455         public Set<String> targets() {
 456             return targets;
 457         }
 458 
 459         /**
 460          * Compares this module export to another.
 461          *
 462          * <p> Two {@code Exports} objects are compared by comparing the package
 463          * names lexicographically. Where the packages names are equal then the
 464          * sets of modifiers are compared in the same way that module modifiers
 465          * are compared (see {@link ModuleDescriptor#compareTo
 466          * ModuleDescriptor.compareTo}). Where the package names are equal and
 467          * the set of modifiers are equal then the set of target modules are
 468          * compared. This is done by sorting the names of the target modules
 469          * in ascending order, and according to their natural ordering, and then
 470          * comparing the corresponding elements lexicographically. Where the
 471          * sets differ in size, and the larger set contains all elements of the
 472          * smaller set, then the larger set is considered to succeed the smaller
 473          * set. </p>
 474          *
 475          * @param  that
 476          *         The module export to compare
 477          *
 478          * @return A negative integer, zero, or a positive integer if this module
 479          *         export is less than, equal to, or greater than the given
 480          *         export dependence
 481          */
 482         @Override
 483         public int compareTo(Exports that) {
 484             if (this == that) return 0;
 485 
 486             int c = source.compareTo(that.source);
 487             if (c != 0)
 488                 return c;
 489 
 490             // modifiers
 491             long v1 = modsValue(this.modifiers());
 492             long v2 = modsValue(that.modifiers());
 493             c = Long.compare(v1, v2);
 494             if (c != 0)
 495                 return c;
 496 
 497             // targets
 498             c = compare(targets, that.targets);
 499             if (c != 0)
 500                 return c;
 501 
 502             return 0;
 503         }
 504 
 505         /**
 506          * Computes a hash code for this module export.
 507          *
 508          * <p> The hash code is based upon the modifiers, the package name,
 509          * and for a qualified export, the set of modules names to which the
 510          * package is exported. It satisfies the general contract of the
 511          * {@link Object#hashCode Object.hashCode} method.
 512          *
 513          * @return The hash-code value for this module export
 514          */
 515         @Override
 516         public int hashCode() {
 517             int hash = mods.hashCode();
 518             hash = hash * 43 + source.hashCode();
 519             return hash * 43 + targets.hashCode();
 520         }
 521 
 522         /**
 523          * Tests this module export for equality with the given object.
 524          *
 525          * <p> If the given object is not an {@code Exports} then this method
 526          * returns {@code false}. Two module exports objects are equal if their
 527          * set of modifiers is equal, the package names are equal and the set
 528          * of target module names is equal. </p>
 529          *
 530          * <p> This method satisfies the general contract of the {@link
 531          * java.lang.Object#equals(Object) Object.equals} method. </p>
 532          *
 533          * @param   ob
 534          *          the object to which this object is to be compared
 535          *
 536          * @return  {@code true} if, and only if, the given object is a module
 537          *          dependence that is equal to this module dependence
 538          */
 539         @Override
 540         public boolean equals(Object ob) {
 541             if (!(ob instanceof Exports))
 542                 return false;
 543             Exports other = (Exports)ob;
 544             return Objects.equals(this.mods, other.mods)
 545                     && Objects.equals(this.source, other.source)
 546                     && Objects.equals(this.targets, other.targets);
 547         }
 548 
 549         /**
 550          * Returns a string describing the exported package.
 551          *
 552          * @return A string describing the exported package
 553          */
 554         @Override
 555         public String toString() {
 556             String s = ModuleDescriptor.toString(mods, source);
 557             if (targets.isEmpty())
 558                 return s;
 559             else
 560                 return s + " to " + targets;
 561         }
 562     }
 563 
 564 
 565     /**
 566      * <p> A package opened by a module, may be qualified or unqualified. </p>
 567      *
 568      * <p> The <em>opens</em> directive in a module declaration declares a
 569      * package to be open to allow all types in the package, and all their
 570      * members, not just public types and their public members to be reflected
 571      * on by APIs that support private access or a way to bypass or suppress
 572      * default Java language access control checks. </p>
 573      *
 574      * @see ModuleDescriptor#opens()
 575      * @since 9
 576      * @spec JPMS
 577      */
 578 
 579     public final static class Opens
 580         implements Comparable<Opens>
 581     {
 582         /**
 583          * A modifier on an open package.
 584          *
 585          * @see Opens#modifiers()
 586          * @since 9
 587          * @spec JPMS
 588          */
 589         public enum Modifier {
 590 
 591             /**
 592              * The open package was not explicitly or implicitly declared in
 593              * the source of the module declaration.
 594              */
 595             SYNTHETIC,
 596 
 597             /**
 598              * The open package was implicitly declared in the source of the
 599              * module declaration.
 600              */
 601             MANDATED;
 602 
 603         }
 604 
 605         private final Set<Modifier> mods;
 606         private final String source;
 607         private final Set<String> targets;  // empty if unqualified export
 608 
 609         /**
 610          * Constructs an Opens
 611          */
 612         private Opens(Set<Modifier> ms, String source, Set<String> targets) {
 613             this.mods = Set.copyOf(ms);
 614             this.source = source;
 615             this.targets = Set.copyOf(targets);
 616         }
 617 
 618         private Opens(Set<Modifier> ms,
 619                       String source,
 620                       Set<String> targets,
 621                       boolean unused) {
 622             this.mods = ms;
 623             this.source = source;
 624             this.targets = targets;
 625         }
 626 
 627         /**
 628          * Returns the set of modifiers.
 629          *
 630          * @return A possibly-empty unmodifiable set of modifiers
 631          */
 632         public Set<Modifier> modifiers() {
 633             return mods;
 634         }
 635 
 636         /**
 637          * Returns {@code true} if this is a qualified opens.
 638          *
 639          * @return {@code true} if this is a qualified opens
 640          */
 641         public boolean isQualified() {
 642             return !targets.isEmpty();
 643         }
 644 
 645         /**
 646          * Returns the package name.
 647          *
 648          * @return The package name
 649          */
 650         public String source() {
 651             return source;
 652         }
 653 
 654         /**
 655          * For a qualified opens, returns the non-empty and immutable set
 656          * of the module names to which the package is open. For an
 657          * unqualified opens, returns an empty set.
 658          *
 659          * @return The set of target module names or for an unqualified
 660          *         opens, an empty set
 661          */
 662         public Set<String> targets() {
 663             return targets;
 664         }
 665 
 666         /**
 667          * Compares this module opens to another.
 668          *
 669          * <p> Two {@code Opens} objects are compared by comparing the package
 670          * names lexicographically. Where the packages names are equal then the
 671          * sets of modifiers are compared in the same way that module modifiers
 672          * are compared (see {@link ModuleDescriptor#compareTo
 673          * ModuleDescriptor.compareTo}). Where the package names are equal and
 674          * the set of modifiers are equal then the set of target modules are
 675          * compared. This is done by sorting the names of the target modules
 676          * in ascending order, and according to their natural ordering, and then
 677          * comparing the corresponding elements lexicographically. Where the
 678          * sets differ in size, and the larger set contains all elements of the
 679          * smaller set, then the larger set is considered to succeed the smaller
 680          * set. </p>
 681          *
 682          * @param  that
 683          *         The module opens to compare
 684          *
 685          * @return A negative integer, zero, or a positive integer if this module
 686          *         opens is less than, equal to, or greater than the given
 687          *         module opens
 688          */
 689         @Override
 690         public int compareTo(Opens that) {
 691             if (this == that) return 0;
 692 
 693             int c = source.compareTo(that.source);
 694             if (c != 0)
 695                 return c;
 696 
 697             // modifiers
 698             long v1 = modsValue(this.modifiers());
 699             long v2 = modsValue(that.modifiers());
 700             c = Long.compare(v1, v2);
 701             if (c != 0)
 702                 return c;
 703 
 704             // targets
 705             c = compare(targets, that.targets);
 706             if (c != 0)
 707                 return c;
 708 
 709             return 0;
 710         }
 711 
 712         /**
 713          * Computes a hash code for this module opens.
 714          *
 715          * <p> The hash code is based upon the modifiers, the package name,
 716          * and for a qualified opens, the set of modules names to which the
 717          * package is opened. It satisfies the general contract of the
 718          * {@link Object#hashCode Object.hashCode} method.
 719          *
 720          * @return The hash-code value for this module opens
 721          */
 722         @Override
 723         public int hashCode() {
 724             int hash = mods.hashCode();
 725             hash = hash * 43 + source.hashCode();
 726             return hash * 43 + targets.hashCode();
 727         }
 728 
 729         /**
 730          * Tests this module opens for equality with the given object.
 731          *
 732          * <p> If the given object is not an {@code Opens} then this method
 733          * returns {@code false}. Two {@code Opens} objects are equal if their
 734          * set of modifiers is equal, the package names are equal and the set
 735          * of target module names is equal. </p>
 736          *
 737          * <p> This method satisfies the general contract of the {@link
 738          * java.lang.Object#equals(Object) Object.equals} method. </p>
 739          *
 740          * @param   ob
 741          *          the object to which this object is to be compared
 742          *
 743          * @return  {@code true} if, and only if, the given object is a module
 744          *          dependence that is equal to this module dependence
 745          */
 746         @Override
 747         public boolean equals(Object ob) {
 748             if (!(ob instanceof Opens))
 749                 return false;
 750             Opens other = (Opens)ob;
 751             return Objects.equals(this.mods, other.mods)
 752                     && Objects.equals(this.source, other.source)
 753                     && Objects.equals(this.targets, other.targets);
 754         }
 755 
 756         /**
 757          * Returns a string describing the open package.
 758          *
 759          * @return A string describing the open package
 760          */
 761         @Override
 762         public String toString() {
 763             String s = ModuleDescriptor.toString(mods, source);
 764             if (targets.isEmpty())
 765                 return s;
 766             else
 767                 return s + " to " + targets;
 768         }
 769     }
 770 
 771 
 772     /**
 773      * <p> A service that a module provides one or more implementations of. </p>
 774      *
 775      * @see ModuleDescriptor#provides()
 776      * @since 9
 777      * @spec JPMS
 778      */
 779 
 780     public final static class Provides
 781         implements Comparable<Provides>
 782     {
 783         private final String service;
 784         private final List<String> providers;
 785 
 786         private Provides(String service, List<String> providers) {
 787             this.service = service;
 788             this.providers = List.copyOf(providers);
 789         }
 790 
 791         private Provides(String service, List<String> providers, boolean unused) {
 792             this.service = service;
 793             this.providers = providers;
 794         }
 795 
 796         /**
 797          * Returns the fully qualified class name of the service type.
 798          *
 799          * @return The fully qualified class name of the service type
 800          */
 801         public String service() { return service; }
 802 
 803         /**
 804          * Returns the list of the fully qualified class names of the providers
 805          * or provider factories.
 806          *
 807          * @return A non-empty and unmodifiable list of the fully qualified class
 808          *         names of the providers or provider factories
 809          */
 810         public List<String> providers() { return providers; }
 811 
 812         /**
 813          * Compares this provides to another.
 814          *
 815          * <p> Two {@code Provides} objects are compared by comparing the fully
 816          * qualified class name of the service type lexicographically. Where the
 817          * class names are equal then the list of the provider class names are
 818          * compared by comparing the corresponding elements of both lists
 819          * lexicographically and in sequence. Where the lists differ in size,
 820          * {@code N} is the size of the shorter list, and the first {@code N}
 821          * corresponding elements are equal, then the longer list is considered
 822          * to succeed the shorter list. </p>
 823          *
 824          * @param  that
 825          *         The {@code Provides} to compare
 826          *
 827          * @return A negative integer, zero, or a positive integer if this provides
 828          *         is less than, equal to, or greater than the given provides
 829          */
 830         public int compareTo(Provides that) {
 831             if (this == that) return 0;
 832 
 833             int c = service.compareTo(that.service);
 834             if (c != 0) return c;
 835 
 836             // compare provider class names in sequence
 837             int size1 = this.providers.size();
 838             int size2 = that.providers.size();
 839             for (int index=0; index<Math.min(size1, size2); index++) {
 840                 String e1 = this.providers.get(index);
 841                 String e2 = that.providers.get(index);
 842                 c = e1.compareTo(e2);
 843                 if (c != 0) return c;
 844             }
 845             if (size1 == size2) {
 846                 return 0;
 847             } else {
 848                 return (size1 > size2) ? 1 : -1;
 849             }
 850         }
 851 
 852         /**
 853          * Computes a hash code for this provides.
 854          *
 855          * <p> The hash code is based upon the service type and the set of
 856          * providers. It satisfies the general contract of the {@link
 857          * Object#hashCode Object.hashCode} method. </p>
 858          *
 859          * @return The hash-code value for this module provides
 860          */
 861         @Override
 862         public int hashCode() {
 863             return service.hashCode() * 43 + providers.hashCode();
 864         }
 865 
 866         /**
 867          * Tests this provides for equality with the given object.
 868          *
 869          * <p> If the given object is not a {@code Provides} then this method
 870          * returns {@code false}. Two {@code Provides} objects are equal if the
 871          * service type is equal and the list of providers is equal. </p>
 872          *
 873          * <p> This method satisfies the general contract of the {@link
 874          * java.lang.Object#equals(Object) Object.equals} method. </p>
 875          *
 876          * @param   ob
 877          *          the object to which this object is to be compared
 878          *
 879          * @return  {@code true} if, and only if, the given object is a
 880          *          {@code Provides} that is equal to this {@code Provides}
 881          */
 882         @Override
 883         public boolean equals(Object ob) {
 884             if (!(ob instanceof Provides))
 885                 return false;
 886             Provides other = (Provides)ob;
 887             return Objects.equals(this.service, other.service) &&
 888                     Objects.equals(this.providers, other.providers);
 889         }
 890 
 891         /**
 892          * Returns a string describing this provides.
 893          *
 894          * @return A string describing this provides
 895          */
 896         @Override
 897         public String toString() {
 898             return service + " with " + providers;
 899         }
 900 
 901     }
 902 
 903 
 904 
 905     /**
 906      * A module's version string.
 907      *
 908      * <p> A version string has three components: The version number itself, an
 909      * optional pre-release version, and an optional build version.  Each
 910      * component is a sequence of tokens; each token is either a non-negative
 911      * integer or a string.  Tokens are separated by the punctuation characters
 912      * {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a
 913      * sequence of digits to a sequence of characters that are neither digits
 914      * nor punctuation characters, or vice versa.
 915      *
 916      * <ul>
 917      *
 918      *   <li> The <i>version number</i> is a sequence of tokens separated by
 919      *   {@code '.'} characters, terminated by the first {@code '-'} or {@code
 920      *   '+'} character. </li>
 921      *
 922      *   <li> The <i>pre-release version</i> is a sequence of tokens separated
 923      *   by {@code '.'} or {@code '-'} characters, terminated by the first
 924      *   {@code '+'} character. </li>
 925      *
 926      *   <li> The <i>build version</i> is a sequence of tokens separated by
 927      *   {@code '.'}, {@code '-'}, or {@code '+'} characters.
 928      *
 929      * </ul>
 930      *
 931      * <p> When comparing two version strings, the elements of their
 932      * corresponding components are compared in pointwise fashion.  If one
 933      * component is longer than the other, but otherwise equal to it, then the
 934      * first component is considered the greater of the two; otherwise, if two
 935      * corresponding elements are integers then they are compared as such;
 936      * otherwise, at least one of the elements is a string, so the other is
 937      * converted into a string if it is an integer and the two are compared
 938      * lexicographically.  Trailing integer elements with the value zero are
 939      * ignored.
 940      *
 941      * <p> Given two version strings, if their version numbers differ then the
 942      * result of comparing them is the result of comparing their version
 943      * numbers; otherwise, if one of them has a pre-release version but the
 944      * other does not then the first is considered to precede the second,
 945      * otherwise the result of comparing them is the result of comparing their
 946      * pre-release versions; otherwise, the result of comparing them is the
 947      * result of comparing their build versions.
 948      *
 949      * @see ModuleDescriptor#version()
 950      * @since 9
 951      * @spec JPMS
 952      */
 953 
 954     public final static class Version
 955         implements Comparable<Version>
 956     {
 957 
 958         private final String version;
 959 
 960         // If Java had disjunctive types then we'd write List<Integer|String> here
 961         //
 962         private final List<Object> sequence;
 963         private final List<Object> pre;
 964         private final List<Object> build;
 965 
 966         // Take a numeric token starting at position i
 967         // Append it to the given list
 968         // Return the index of the first character not taken
 969         // Requires: s.charAt(i) is (decimal) numeric
 970         //
 971         private static int takeNumber(String s, int i, List<Object> acc) {
 972             char c = s.charAt(i);
 973             int d = (c - '0');
 974             int n = s.length();
 975             while (++i < n) {
 976                 c = s.charAt(i);
 977                 if (c >= '0' && c <= '9') {
 978                     d = d * 10 + (c - '0');
 979                     continue;
 980                 }
 981                 break;
 982             }
 983             acc.add(d);
 984             return i;
 985         }
 986 
 987         // Take a string token starting at position i
 988         // Append it to the given list
 989         // Return the index of the first character not taken
 990         // Requires: s.charAt(i) is not '.'
 991         //
 992         private static int takeString(String s, int i, List<Object> acc) {
 993             int b = i;
 994             int n = s.length();
 995             while (++i < n) {
 996                 char c = s.charAt(i);
 997                 if (c != '.' && c != '-' && c != '+' && !(c >= '0' && c <= '9'))
 998                     continue;
 999                 break;
1000             }
1001             acc.add(s.substring(b, i));
1002             return i;
1003         }
1004 
1005         // Syntax: tok+ ( '-' tok+)? ( '+' tok+)?
1006         // First token string is sequence, second is pre, third is build
1007         // Tokens are separated by '.' or '-', or by changes between alpha & numeric
1008         // Numeric tokens are compared as decimal integers
1009         // Non-numeric tokens are compared lexicographically
1010         // A version with a non-empty pre is less than a version with same seq but no pre
1011         // Tokens in build may contain '-' and '+'
1012         //
1013         private Version(String v) {
1014 
1015             if (v == null)
1016                 throw new IllegalArgumentException("Null version string");
1017             int n = v.length();
1018             if (n == 0)
1019                 throw new IllegalArgumentException("Empty version string");
1020 
1021             int i = 0;
1022             char c = v.charAt(i);
1023             if (!(c >= '0' && c <= '9'))
1024                 throw new IllegalArgumentException(v
1025                                                    + ": Version string does not start"
1026                                                    + " with a number");
1027 
1028             List<Object> sequence = new ArrayList<>(4);
1029             List<Object> pre = new ArrayList<>(2);
1030             List<Object> build = new ArrayList<>(2);
1031 
1032             i = takeNumber(v, i, sequence);
1033 
1034             while (i < n) {
1035                 c = v.charAt(i);
1036                 if (c == '.') {
1037                     i++;
1038                     continue;
1039                 }
1040                 if (c == '-' || c == '+') {
1041                     i++;
1042                     break;
1043                 }
1044                 if (c >= '0' && c <= '9')
1045                     i = takeNumber(v, i, sequence);
1046                 else
1047                     i = takeString(v, i, sequence);
1048             }
1049 
1050             if (c == '-' && i >= n)
1051                 throw new IllegalArgumentException(v + ": Empty pre-release");
1052 
1053             while (i < n) {
1054                 c = v.charAt(i);
1055                 if (c >= '0' && c <= '9')
1056                     i = takeNumber(v, i, pre);
1057                 else
1058                     i = takeString(v, i, pre);
1059                 if (i >= n)
1060                     break;
1061                 c = v.charAt(i);
1062                 if (c == '.' || c == '-') {
1063                     i++;
1064                     continue;
1065                 }
1066                 if (c == '+') {
1067                     i++;
1068                     break;
1069                 }
1070             }
1071 
1072             if (c == '+' && i >= n)
1073                 throw new IllegalArgumentException(v + ": Empty pre-release");
1074 
1075             while (i < n) {
1076                 c = v.charAt(i);
1077                 if (c >= '0' && c <= '9')
1078                     i = takeNumber(v, i, build);
1079                 else
1080                     i = takeString(v, i, build);
1081                 if (i >= n)
1082                     break;
1083                 c = v.charAt(i);
1084                 if (c == '.' || c == '-' || c == '+') {
1085                     i++;
1086                     continue;
1087                 }
1088             }
1089 
1090             this.version = v;
1091             this.sequence = sequence;
1092             this.pre = pre;
1093             this.build = build;
1094         }
1095 
1096         /**
1097          * Parses the given string as a version string.
1098          *
1099          * @param  v
1100          *         The string to parse
1101          *
1102          * @return The resulting {@code Version}
1103          *
1104          * @throws IllegalArgumentException
1105          *         If {@code v} is {@code null}, an empty string, or cannot be
1106          *         parsed as a version string
1107          */
1108         public static Version parse(String v) {
1109             return new Version(v);
1110         }
1111 
1112         @SuppressWarnings("unchecked")
1113         private int cmp(Object o1, Object o2) {
1114             return ((Comparable)o1).compareTo(o2);
1115         }
1116 
1117         private int compareTokens(List<Object> ts1, List<Object> ts2) {
1118             int n = Math.min(ts1.size(), ts2.size());
1119             for (int i = 0; i < n; i++) {
1120                 Object o1 = ts1.get(i);
1121                 Object o2 = ts2.get(i);
1122                 if ((o1 instanceof Integer && o2 instanceof Integer)
1123                     || (o1 instanceof String && o2 instanceof String))
1124                 {
1125                     int c = cmp(o1, o2);
1126                     if (c == 0)
1127                         continue;
1128                     return c;
1129                 }
1130                 // Types differ, so convert number to string form
1131                 int c = o1.toString().compareTo(o2.toString());
1132                 if (c == 0)
1133                     continue;
1134                 return c;
1135             }
1136             List<Object> rest = ts1.size() > ts2.size() ? ts1 : ts2;
1137             int e = rest.size();
1138             for (int i = n; i < e; i++) {
1139                 Object o = rest.get(i);
1140                 if (o instanceof Integer && ((Integer)o) == 0)
1141                     continue;
1142                 return ts1.size() - ts2.size();
1143             }
1144             return 0;
1145         }
1146 
1147         /**
1148          * Compares this module version to another module version. Module
1149          * versions are compared as described in the class description.
1150          *
1151          * @param that
1152          *        The module version to compare
1153          *
1154          * @return A negative integer, zero, or a positive integer as this
1155          *         module version is less than, equal to, or greater than the
1156          *         given module version
1157          */
1158         @Override
1159         public int compareTo(Version that) {
1160             int c = compareTokens(this.sequence, that.sequence);
1161             if (c != 0) return c;
1162             if (this.pre.isEmpty()) {
1163                 if (!that.pre.isEmpty()) return +1;
1164             } else {
1165                 if (that.pre.isEmpty()) return -1;
1166             }
1167             c = compareTokens(this.pre, that.pre);
1168             if (c != 0) return c;
1169             return compareTokens(this.build, that.build);
1170         }
1171 
1172         /**
1173          * Tests this module version for equality with the given object.
1174          *
1175          * <p> If the given object is not a {@code Version} then this method
1176          * returns {@code false}. Two module version are equal if their
1177          * corresponding components are equal. </p>
1178          *
1179          * <p> This method satisfies the general contract of the {@link
1180          * java.lang.Object#equals(Object) Object.equals} method. </p>
1181          *
1182          * @param   ob
1183          *          the object to which this object is to be compared
1184          *
1185          * @return  {@code true} if, and only if, the given object is a module
1186          *          reference that is equal to this module reference
1187          */
1188         @Override
1189         public boolean equals(Object ob) {
1190             if (!(ob instanceof Version))
1191                 return false;
1192             return compareTo((Version)ob) == 0;
1193         }
1194 
1195         /**
1196          * Computes a hash code for this module version.
1197          *
1198          * <p> The hash code is based upon the components of the version and
1199          * satisfies the general contract of the {@link Object#hashCode
1200          * Object.hashCode} method. </p>
1201          *
1202          * @return The hash-code value for this module version
1203          */
1204         @Override
1205         public int hashCode() {
1206             return version.hashCode();
1207         }
1208 
1209         /**
1210          * Returns the string from which this version was parsed.
1211          *
1212          * @return The string from which this version was parsed.
1213          */
1214         @Override
1215         public String toString() {
1216             return version;
1217         }
1218 
1219     }
1220 
1221 
1222     private final String name;
1223     private final Version version;
1224     private final String rawVersionString;
1225     private final Set<Modifier> modifiers;
1226     private final boolean open;  // true if modifiers contains OPEN
1227     private final boolean automatic;  // true if modifiers contains AUTOMATIC
1228     private final Set<Requires> requires;
1229     private final Set<Exports> exports;
1230     private final Set<Opens> opens;
1231     private final Set<String> uses;
1232     private final Set<Provides> provides;
1233     private final Set<String> packages;
1234     private final String mainClass;
1235 
1236     private ModuleDescriptor(String name,
1237                              Version version,
1238                              String rawVersionString,
1239                              Set<Modifier> modifiers,
1240                              Set<Requires> requires,
1241                              Set<Exports> exports,
1242                              Set<Opens> opens,
1243                              Set<String> uses,
1244                              Set<Provides> provides,
1245                              Set<String> packages,
1246                              String mainClass)
1247     {
1248         // Either one, and only one should be set.
1249         assert ((version != null) ^ (rawVersionString != null));
1250         this.name = name;
1251         this.version = version;
1252         this.rawVersionString = rawVersionString;
1253         this.modifiers = Set.copyOf(modifiers);
1254         this.open = modifiers.contains(Modifier.OPEN);
1255         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1256         assert (requires.stream().map(Requires::name).distinct().count()
1257                 == requires.size());
1258         this.requires = Set.copyOf(requires);
1259         this.exports = Set.copyOf(exports);
1260         this.opens = Set.copyOf(opens);
1261         this.uses = Set.copyOf(uses);
1262         this.provides = Set.copyOf(provides);
1263 
1264         this.packages = Set.copyOf(packages);
1265         this.mainClass = mainClass;
1266     }
1267 
1268     /**
1269      * Creates a module descriptor from its components.
1270      * The arguments are pre-validated and sets are unmodifiable sets.
1271      */
1272     ModuleDescriptor(String name,
1273                      Version version,
1274                      Set<Modifier> modifiers,
1275                      Set<Requires> requires,
1276                      Set<Exports> exports,
1277                      Set<Opens> opens,
1278                      Set<String> uses,
1279                      Set<Provides> provides,
1280                      Set<String> packages,
1281                      String mainClass,
1282                      int hashCode,
1283                      boolean unused) {
1284         this.name = name;
1285         this.version = version;
1286         this.rawVersionString = null;
1287         this.modifiers = modifiers;
1288         this.open = modifiers.contains(Modifier.OPEN);
1289         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1290         this.requires = requires;
1291         this.exports = exports;
1292         this.opens = opens;
1293         this.uses = uses;
1294         this.provides = provides;
1295         this.packages = packages;
1296         this.mainClass = mainClass;
1297         this.hash = hashCode;
1298     }
1299 
1300     /**
1301      * <p> Returns the module name. </p>
1302      *
1303      * @return The module name
1304      */
1305     public String name() {
1306         return name;
1307     }
1308 
1309     /**
1310      * <p> Returns the set of module modifiers. </p>
1311      *
1312      * @return A possibly-empty unmodifiable set of modifiers
1313      */
1314     public Set<Modifier> modifiers() {
1315         return modifiers;
1316     }
1317 
1318     /**
1319      * <p> Returns {@code true} if this is an open module. </p>
1320      *
1321      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1322      * modifiers} contains the {@link Modifier#OPEN OPEN} modifier. </p>
1323      *
1324      * @return  {@code true} if this is an open module
1325      */
1326     public boolean isOpen() {
1327         return open;
1328     }
1329 
1330     /**
1331      * <p> Returns {@code true} if this is an automatic module. </p>
1332      *
1333      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1334      * modifiers} contains the {@link Modifier#OPEN AUTOMATIC} modifier. </p>
1335      *
1336      * @return  {@code true} if this is an automatic module
1337      */
1338     public boolean isAutomatic() {
1339         return automatic;
1340     }
1341 
1342     /**
1343      * <p> Returns the set of {@code Requires} objects representing the module
1344      * dependences. </p>
1345      *
1346      * <p> The set includes a dependency on "{@code java.base}" when this
1347      * module is not named "{@code java.base}". If this module is an automatic
1348      * module then it does not have a dependency on any module other than
1349      * "{@code java.base}". </p>
1350      *
1351      * @return  A possibly-empty unmodifiable set of {@link Requires} objects
1352      */
1353     public Set<Requires> requires() {
1354         return requires;
1355     }
1356 
1357     /**
1358      * <p> Returns the set of {@code Exports} objects representing the exported
1359      * packages. </p>
1360      *
1361      * <p> If this module is an automatic module then the set of exports
1362      * is empty. </p>
1363      *
1364      * @return  A possibly-empty unmodifiable set of exported packages
1365      */
1366     public Set<Exports> exports() {
1367         return exports;
1368     }
1369 
1370     /**
1371      * <p> Returns the set of {@code Opens} objects representing the open
1372      * packages. </p>
1373      *
1374      * <p> If this module is an open module or an automatic module then the
1375      * set of open packages is empty. </p>
1376      *
1377      * @return  A possibly-empty unmodifiable set of open packages
1378      */
1379     public Set<Opens> opens() {
1380         return opens;
1381     }
1382 
1383     /**
1384      * <p> Returns the set of service dependences. </p>
1385      *
1386      * <p> If this module is an automatic module then the set of service
1387      * dependences is empty. </p>
1388      *
1389      * @return  A possibly-empty unmodifiable set of the fully qualified class
1390      *          names of the service types used
1391      */
1392     public Set<String> uses() {
1393         return uses;
1394     }
1395 
1396     /**
1397      * <p> Returns the set of {@code Provides} objects representing the
1398      * services that the module provides. </p>
1399      *
1400      * @return The possibly-empty unmodifiable set of the services that this
1401      *         module provides
1402      */
1403     public Set<Provides> provides() {
1404         return provides;
1405     }
1406 
1407     /**
1408      * <p> Returns the module version. </p>
1409      *
1410      * @return This module's version, or an empty {@code Optional} if the
1411      *         module does not have a version or the version is
1412      *         {@linkplain Version#parse(String) unparseable}
1413      */
1414     public Optional<Version> version() {
1415         return Optional.ofNullable(version);
1416     }
1417 
1418     /**
1419      * <p> Returns the string with the possibly-unparseable version of the
1420      * module </p>
1421      *
1422      * @return The string containing the version of the module or an empty
1423      *         {@code Optional} if the module does not have a version
1424      *
1425      * @see #version()
1426      */
1427     public Optional<String> rawVersion() {
1428         if (version != null) {
1429             return Optional.of(version.toString());
1430         } else {
1431             return Optional.ofNullable(rawVersionString);
1432         }
1433     }
1434 
1435     /**
1436      * <p> Returns a string containing the module name and, if present, its
1437      * version. </p>
1438      *
1439      * @return A string containing the module name and, if present, its
1440      *         version
1441      */
1442     public String toNameAndVersion() {
1443         if (version != null) {
1444             return name() + "@" + version;
1445         } else {
1446             return name();
1447         }
1448     }
1449 
1450     /**
1451      * <p> Returns the module main class. </p>
1452      *
1453      * @return The fully qualified class name of the module's main class
1454      */
1455     public Optional<String> mainClass() {
1456         return Optional.ofNullable(mainClass);
1457     }
1458 
1459     /**
1460      * Returns the set of packages in the module.
1461      *
1462      * <p> The set of packages includes all exported and open packages, as well
1463      * as the packages of any service providers, and the package for the main
1464      * class. </p>
1465      *
1466      * @return A possibly-empty unmodifiable set of the packages in the module
1467      */
1468     public Set<String> packages() {
1469         return packages;
1470     }
1471 
1472 
1473     /**
1474      * A builder for building {@link ModuleDescriptor} objects.
1475      *
1476      * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
1477      * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
1478      * newAutomaticModule} methods to create builders for building
1479      * <em>normal</em>, open, and automatic modules. </p>
1480      *
1481      * <p> The set of packages in the module are accumulated by the {@code
1482      * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
1483      * {@link ModuleDescriptor.Builder#opens(String) opens},
1484      * {@link ModuleDescriptor.Builder#packages(Set) packages},
1485      * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
1486      * {@link ModuleDescriptor.Builder#mainClass(String) mainClass} methods are
1487      * invoked. </p>
1488      *
1489      * <p> The module names, package names, and class names that are parameters
1490      * specified to the builder methods are the module names, package names,
1491      * and qualified names of classes (in named packages) as defined in the
1492      * <cite>The Java&trade; Language Specification</cite>. </p>
1493      *
1494      * <p> Example usage: </p>
1495      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.newModule("stats.core")
1496      *         .requires("java.base")
1497      *         .exports("org.acme.stats.core.clustering")
1498      *         .exports("org.acme.stats.core.regression")
1499      *         .packages(Set.of("org.acme.stats.core.internal"))
1500      *         .build();
1501      * }</pre>
1502      *
1503      * @apiNote A {@code Builder} checks the components and invariants as
1504      * components are added to the builder. The rationale for this is to detect
1505      * errors as early as possible and not defer all validation to the
1506      * {@link #build build} method.
1507      *
1508      * @since 9
1509      * @spec JPMS
1510      */
1511     public static final class Builder {
1512         final String name;
1513         final boolean strict;
1514         final Set<Modifier> modifiers;
1515         final boolean open;
1516         final boolean automatic;
1517         final Set<String> packages = new HashSet<>();
1518         final Map<String, Requires> requires = new HashMap<>();
1519         final Map<String, Exports> exports = new HashMap<>();
1520         final Map<String, Opens> opens = new HashMap<>();
1521         final Set<String> uses = new HashSet<>();
1522         final Map<String, Provides> provides = new HashMap<>();
1523         Version version;
1524         String rawVersionString;
1525         String mainClass;
1526 
1527         /**
1528          * Initializes a new builder with the given module name.
1529          *
1530          * If {@code strict} is {@code true} then module, package, and class
1531          * names are checked to ensure they are legal names. In addition, the
1532          * {@link #build buid} method will add "{@code requires java.base}" if
1533          * the dependency is not declared.
1534          */
1535         Builder(String name, boolean strict, Set<Modifier> modifiers) {
1536             this.name = (strict) ? requireModuleName(name) : name;
1537             this.strict = strict;
1538             this.modifiers = modifiers;
1539             this.open = modifiers.contains(Modifier.OPEN);
1540             this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1541             assert !open || !automatic;
1542         }
1543 
1544         /**
1545          * Returns a snapshot of the packages in the module.
1546          */
1547         /* package */ Set<String> packages() {
1548             return Collections.unmodifiableSet(packages);
1549         }
1550 
1551         /**
1552          * Adds a dependence on a module.
1553          *
1554          * @param  req
1555          *         The dependence
1556          *
1557          * @return This builder
1558          *
1559          * @throws IllegalArgumentException
1560          *         If the dependence is on the module that this builder was
1561          *         initialized to build
1562          * @throws IllegalStateException
1563          *         If the dependence on the module has already been declared
1564          *         or this builder is for an automatic module
1565          */
1566         public Builder requires(Requires req) {
1567             if (automatic)
1568                 throw new IllegalStateException("Automatic modules cannot declare"
1569                                                 + " dependences");
1570             String mn = req.name();
1571             if (name.equals(mn))
1572                 throw new IllegalArgumentException("Dependence on self");
1573             if (requires.containsKey(mn))
1574                 throw new IllegalStateException("Dependence upon " + mn
1575                                                 + " already declared");
1576             requires.put(mn, req);
1577             return this;
1578         }
1579 
1580         /**
1581          * Adds a dependence on a module with the given (and possibly empty)
1582          * set of modifiers. The dependence includes the version of the
1583          * module that was recorded at compile-time.
1584          *
1585          * @param  ms
1586          *         The set of modifiers
1587          * @param  mn
1588          *         The module name
1589          * @param  compiledVersion
1590          *         The version of the module recorded at compile-time
1591          *
1592          * @return This builder
1593          *
1594          * @throws IllegalArgumentException
1595          *         If the module name is {@code null}, is not a legal module
1596          *         name, or is equal to the module name that this builder
1597          *         was initialized to build
1598          * @throws IllegalStateException
1599          *         If the dependence on the module has already been declared
1600          *         or this builder is for an automatic module
1601          */
1602         public Builder requires(Set<Requires.Modifier> ms,
1603                                 String mn,
1604                                 Version compiledVersion) {
1605             Objects.requireNonNull(compiledVersion);
1606             if (strict)
1607                 mn = requireModuleName(mn);
1608             return requires(new Requires(ms, mn, compiledVersion, null));
1609         }
1610 
1611         /* package */Builder requires(Set<Requires.Modifier> ms,
1612                                       String mn,
1613                                       String rawCompiledVersion) {
1614             Requires r;
1615             try {
1616                 Version v = Version.parse(rawCompiledVersion);
1617                 r = new Requires(ms, mn, v, null);
1618             } catch (IllegalArgumentException e) {
1619                 if (strict) throw e;
1620                 r = new Requires(ms, mn, null, rawCompiledVersion);
1621             }
1622             return requires(r);
1623         }
1624 
1625         /**
1626          * Adds a dependence on a module with the given (and possibly empty)
1627          * set of modifiers.
1628          *
1629          * @param  ms
1630          *         The set of modifiers
1631          * @param  mn
1632          *         The module name
1633          *
1634          * @return This builder
1635          *
1636          * @throws IllegalArgumentException
1637          *         If the module name is {@code null}, is not a legal module
1638          *         name, or is equal to the module name that this builder
1639          *         was initialized to build
1640          * @throws IllegalStateException
1641          *         If the dependence on the module has already been declared
1642          *         or this builder is for an automatic module
1643          */
1644         public Builder requires(Set<Requires.Modifier> ms, String mn) {
1645             if (strict)
1646                 mn = requireModuleName(mn);
1647             return requires(new Requires(ms, mn, null, null));
1648         }
1649 
1650         /**
1651          * Adds a dependence on a module with an empty set of modifiers.
1652          *
1653          * @param  mn
1654          *         The module name
1655          *
1656          * @return This builder
1657          *
1658          * @throws IllegalArgumentException
1659          *         If the module name is {@code null}, is not a legal module
1660          *         name, or is equal to the module name that this builder
1661          *         was initialized to build
1662          * @throws IllegalStateException
1663          *         If the dependence on the module has already been declared
1664          *         or this builder is for an automatic module
1665          */
1666         public Builder requires(String mn) {
1667             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1668         }
1669 
1670         /**
1671          * Adds an exported package.
1672          *
1673          * @param  e
1674          *         The export
1675          *
1676          * @return This builder
1677          *
1678          * @throws IllegalStateException
1679          *         If the {@link Exports#source() package} is already declared as
1680          *         exported or this builder is for an automatic module
1681          */
1682         public Builder exports(Exports e) {
1683             if (automatic) {
1684                 throw new IllegalStateException("Automatic modules cannot declare"
1685                                                  + " exported packages");
1686             }
1687             String source = e.source();
1688             if (exports.containsKey(source)) {
1689                 throw new IllegalStateException("Exported package " + source
1690                                                  + " already declared");
1691             }
1692             exports.put(source, e);
1693             packages.add(source);
1694             return this;
1695         }
1696 
1697         /**
1698          * Adds an exported package with the given (and possibly empty) set of
1699          * modifiers. The package is exported to a set of target modules.
1700          *
1701          * @param  ms
1702          *         The set of modifiers
1703          * @param  pn
1704          *         The package name
1705          * @param  targets
1706          *         The set of target modules names
1707          *
1708          * @return This builder
1709          *
1710          * @throws IllegalArgumentException
1711          *         If the package name is {@code null} or is not a legal
1712          *         package name, the set of target modules is empty, or the set
1713          *         of target modules contains a name that is not a legal module
1714          *         name
1715          * @throws IllegalStateException
1716          *         If the package is already declared as exported
1717          *         or this builder is for an automatic module
1718          */
1719         public Builder exports(Set<Exports.Modifier> ms,
1720                                String pn,
1721                                Set<String> targets)
1722         {
1723             targets = new HashSet<>(targets);
1724             if (targets.isEmpty())
1725                 throw new IllegalArgumentException("Empty target set");
1726             if (strict) {
1727                 requirePackageName(pn);
1728                 targets.forEach(Checks::requireModuleName);
1729             }
1730             Exports e = new Exports(ms, pn, targets);
1731             return exports(e);
1732         }
1733 
1734         /**
1735          * Adds an exported package with the given (and possibly empty) set of
1736          * modifiers. The package is exported to all modules.
1737          *
1738          * @param  ms
1739          *         The set of modifiers
1740          * @param  pn
1741          *         The package name
1742          *
1743          * @return This builder
1744          *
1745          * @throws IllegalArgumentException
1746          *         If the package name is {@code null} or is not a legal
1747          *         package name
1748          * @throws IllegalStateException
1749          *         If the package is already declared as exported
1750          *         or this builder is for an automatic module
1751          */
1752         public Builder exports(Set<Exports.Modifier> ms, String pn) {
1753             if (strict) {
1754                 requirePackageName(pn);
1755             }
1756             Exports e = new Exports(ms, pn, Set.of());
1757             return exports(e);
1758         }
1759 
1760         /**
1761          * Adds an exported package. The package is exported to a set of target
1762          * modules.
1763          *
1764          * @param  pn
1765          *         The package name
1766          * @param  targets
1767          *         The set of target modules names
1768          *
1769          * @return This builder
1770          *
1771          * @throws IllegalArgumentException
1772          *         If the package name is {@code null} or is not a legal
1773          *         package name, the set of target modules is empty, or the set
1774          *         of target modules contains a name that is not a legal module
1775          *         name
1776          * @throws IllegalStateException
1777          *         If the package is already declared as exported
1778          *         or this builder is for an automatic module
1779          */
1780         public Builder exports(String pn, Set<String> targets) {
1781             return exports(Set.of(), pn, targets);
1782         }
1783 
1784         /**
1785          * Adds an exported package. The package is exported to all modules.
1786          *
1787          * @param  pn
1788          *         The package name
1789          *
1790          * @return This builder
1791          *
1792          * @throws IllegalArgumentException
1793          *         If the package name is {@code null} or is not a legal
1794          *         package name
1795          * @throws IllegalStateException
1796          *         If the package is already declared as exported
1797          *         or this builder is for an automatic module
1798          */
1799         public Builder exports(String pn) {
1800             return exports(Set.of(), pn);
1801         }
1802 
1803         /**
1804          * Adds an open package.
1805          *
1806          * @param  obj
1807          *         The {@code Opens} object
1808          *
1809          * @return This builder
1810          *
1811          * @throws IllegalStateException
1812          *         If the package is already declared as open, or this is a
1813          *         builder for an open module or automatic module
1814          */
1815         public Builder opens(Opens obj) {
1816             if (open || automatic) {
1817                 throw new IllegalStateException("Open or automatic modules cannot"
1818                                                 + " declare open packages");
1819             }
1820             String source = obj.source();
1821             if (opens.containsKey(source)) {
1822                 throw new IllegalStateException("Open package " + source
1823                                                 + " already declared");
1824             }
1825             opens.put(source, obj);
1826             packages.add(source);
1827             return this;
1828         }
1829 
1830 
1831         /**
1832          * Adds an open package with the given (and possibly empty) set of
1833          * modifiers. The package is open to a set of target modules.
1834          *
1835          * @param  ms
1836          *         The set of modifiers
1837          * @param  pn
1838          *         The package name
1839          * @param  targets
1840          *         The set of target modules names
1841          *
1842          * @return This builder
1843          *
1844          * @throws IllegalArgumentException
1845          *         If the package name is {@code null} or is not a legal
1846          *         package name, the set of target modules is empty, or the set
1847          *         of target modules contains a name that is not a legal module
1848          *         name
1849          * @throws IllegalStateException
1850          *         If the package is already declared as open, or this is a
1851          *         builder for an open module or automatic module
1852          */
1853         public Builder opens(Set<Opens.Modifier> ms,
1854                              String pn,
1855                              Set<String> targets)
1856         {
1857             targets = new HashSet<>(targets);
1858             if (targets.isEmpty())
1859                 throw new IllegalArgumentException("Empty target set");
1860             if (strict) {
1861                 requirePackageName(pn);
1862                 targets.forEach(Checks::requireModuleName);
1863             }
1864             Opens opens = new Opens(ms, pn, targets);
1865             return opens(opens);
1866         }
1867 
1868         /**
1869          * Adds an open package with the given (and possibly empty) set of
1870          * modifiers. The package is open to all modules.
1871          *
1872          * @param  ms
1873          *         The set of modifiers
1874          * @param  pn
1875          *         The package name
1876          *
1877          * @return This builder
1878          *
1879          * @throws IllegalArgumentException
1880          *         If the package name is {@code null} or is not a legal
1881          *         package name
1882          * @throws IllegalStateException
1883          *         If the package is already declared as open, or this is a
1884          *         builder for an open module or automatic module
1885          */
1886         public Builder opens(Set<Opens.Modifier> ms, String pn) {
1887             if (strict) {
1888                 requirePackageName(pn);
1889             }
1890             Opens e = new Opens(ms, pn, Set.of());
1891             return opens(e);
1892         }
1893 
1894         /**
1895          * Adds an open package. The package is open to a set of target modules.
1896          *
1897          * @param  pn
1898          *         The package name
1899          * @param  targets
1900          *         The set of target modules names
1901          *
1902          * @return This builder
1903          *
1904          * @throws IllegalArgumentException
1905          *         If the package name is {@code null} or is not a legal
1906          *         package name, the set of target modules is empty, or the set
1907          *         of target modules contains a name that is not a legal module
1908          *         name
1909          * @throws IllegalStateException
1910          *         If the package is already declared as open, or this is a
1911          *         builder for an open module or automatic module
1912          */
1913         public Builder opens(String pn, Set<String> targets) {
1914             return opens(Set.of(), pn, targets);
1915         }
1916 
1917         /**
1918          * Adds an open package. The package is open to all modules.
1919          *
1920          * @param  pn
1921          *         The package name
1922          *
1923          * @return This builder
1924          *
1925          * @throws IllegalArgumentException
1926          *         If the package name is {@code null} or is not a legal
1927          *         package name
1928          * @throws IllegalStateException
1929          *         If the package is already declared as open, or this is a
1930          *         builder for an open module or automatic module
1931          */
1932         public Builder opens(String pn) {
1933             return opens(Set.of(), pn);
1934         }
1935 
1936         /**
1937          * Adds a service dependence.
1938          *
1939          * @param  service
1940          *         The service type
1941          *
1942          * @return This builder
1943          *
1944          * @throws IllegalArgumentException
1945          *         If the service type is {@code null} or not a qualified name of
1946          *         a class in a named package
1947          * @throws IllegalStateException
1948          *         If a dependency on the service type has already been declared
1949          *         or this is a builder for an automatic module
1950          */
1951         public Builder uses(String service) {
1952             if (automatic)
1953                 throw new IllegalStateException("Automatic modules can not declare"
1954                                                 + " service dependences");
1955             if (uses.contains(requireServiceTypeName(service)))
1956                 throw new IllegalStateException("Dependence upon service "
1957                                                 + service + " already declared");
1958             uses.add(service);
1959             return this;
1960         }
1961 
1962         /**
1963          * Provides a service with one or more implementations. The package for
1964          * each {@link Provides#providers provider} (or provider factory) is
1965          * added to the module if not already added.
1966          *
1967          * @param  p
1968          *         The provides
1969          *
1970          * @return This builder
1971          *
1972          * @throws IllegalStateException
1973          *         If the providers for the service type have already been
1974          *         declared
1975          */
1976         public Builder provides(Provides p) {
1977             String service = p.service();
1978             if (provides.containsKey(service))
1979                 throw new IllegalStateException("Providers of service "
1980                                                 + service + " already declared");
1981             provides.put(service, p);
1982             p.providers().forEach(name -> packages.add(packageName(name)));
1983             return this;
1984         }
1985 
1986         /**
1987          * Provides implementations of a service. The package for each provider
1988          * (or provider factory) is added to the module if not already added.
1989          *
1990          * @param  service
1991          *         The service type
1992          * @param  providers
1993          *         The list of provider or provider factory class names
1994          *
1995          * @return This builder
1996          *
1997          * @throws IllegalArgumentException
1998          *         If the service type or any of the provider class names is
1999          *         {@code null} or not a qualified name of a class in a named
2000          *         package, or the list of provider class names is empty
2001          * @throws IllegalStateException
2002          *         If the providers for the service type have already been
2003          *         declared
2004          */
2005         public Builder provides(String service, List<String> providers) {
2006             providers = new ArrayList<>(providers);
2007             if (providers.isEmpty())
2008                 throw new IllegalArgumentException("Empty providers set");
2009             if (strict) {
2010                 requireServiceTypeName(service);
2011                 providers.forEach(Checks::requireServiceProviderName);
2012             } else {
2013                 // Disallow service/providers in unnamed package
2014                 String pn = packageName(service);
2015                 if (pn.isEmpty()) {
2016                     throw new IllegalArgumentException(service
2017                                                        + ": unnamed package");
2018                 }
2019                 for (String name : providers) {
2020                     pn = packageName(name);
2021                     if (pn.isEmpty()) {
2022                         throw new IllegalArgumentException(name
2023                                                            + ": unnamed package");
2024                     }
2025                 }
2026             }
2027             Provides p = new Provides(service, providers);
2028             return provides(p);
2029         }
2030 
2031         /**
2032          * Adds packages to the module. All packages in the set of package names
2033          * that are not in the module are added to module.
2034          *
2035          * @param  pns
2036          *         The (possibly empty) set of package names
2037          *
2038          * @return This builder
2039          *
2040          * @throws IllegalArgumentException
2041          *         If any of the package names is {@code null} or is not a
2042          *         legal package name
2043          */
2044         public Builder packages(Set<String> pns) {
2045             if (strict) {
2046                 pns = new HashSet<>(pns);
2047                 pns.forEach(Checks::requirePackageName);
2048             }
2049             this.packages.addAll(pns);
2050             return this;
2051         }
2052 
2053         /**
2054          * Sets the module version.
2055          *
2056          * @param  v
2057          *         The version
2058          *
2059          * @return This builder
2060          */
2061         public Builder version(Version v) {
2062             version = requireNonNull(v);
2063             rawVersionString = null;
2064             return this;
2065         }
2066 
2067         /**
2068          * Sets the module version.
2069          *
2070          * @param  vs
2071          *         The version string to parse
2072          *
2073          * @return This builder
2074          *
2075          * @throws IllegalArgumentException
2076          *         If {@code vs} is {@code null} or cannot be parsed as a
2077          *         version string
2078          *
2079          * @see Version#parse(String)
2080          */
2081         public Builder version(String vs) {
2082             try {
2083                 version = Version.parse(vs);
2084                 rawVersionString = null;
2085             } catch (IllegalArgumentException e) {
2086                 if (strict) throw e;
2087                 version = null;
2088                 rawVersionString = vs;
2089             }
2090             return this;
2091         }
2092 
2093         /**
2094          * Sets the module main class. The package for the main class is added
2095          * to the module if not already added. In other words, this method is
2096          * equivalent to first invoking this builder's {@link #packages(Set)
2097          * packages} method to add the package name of the main class.
2098          *
2099          * @param  mc
2100          *         The module main class
2101          *
2102          * @return This builder
2103          *
2104          * @throws IllegalArgumentException
2105          *         If {@code mainClass} is {@code null} or not a qualified
2106          *         name of a class in a named package
2107          */
2108         public Builder mainClass(String mc) {
2109             String pn;
2110             if (strict) {
2111                 mc = requireQualifiedClassName("main class name", mc);
2112                 pn = packageName(mc);
2113                 assert !pn.isEmpty();
2114             } else {
2115                 // Disallow main class in unnamed package
2116                 pn = packageName(mc);
2117                 if (pn.isEmpty()) {
2118                     throw new IllegalArgumentException(mc + ": unnamed package");
2119                 }
2120             }
2121             packages.add(pn);
2122             mainClass = mc;
2123             return this;
2124         }
2125 
2126         /**
2127          * Builds and returns a {@code ModuleDescriptor} from its components.
2128          *
2129          * <p> The module will require "{@code java.base}" even if the dependence
2130          * has not been declared (the exception is when building a module named
2131          * "{@code java.base}" as it cannot require itself). The dependence on
2132          * "{@code java.base}" will have the {@link
2133          * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
2134          * modifier if the dependence was not declared. </p>
2135          *
2136          * @return The module descriptor
2137          */
2138         public ModuleDescriptor build() {
2139             Set<Requires> requires = new HashSet<>(this.requires.values());
2140             Set<Exports> exports = new HashSet<>(this.exports.values());
2141             Set<Opens> opens = new HashSet<>(this.opens.values());
2142 
2143             // add dependency on java.base
2144             if (strict
2145                     && !name.equals("java.base")
2146                     && !this.requires.containsKey("java.base")) {
2147                 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
2148                                           "java.base",
2149                                           null,
2150                                           null));
2151             }
2152 
2153             Set<Provides> provides = new HashSet<>(this.provides.values());
2154 
2155             return new ModuleDescriptor(name,
2156                                         version,
2157                                         rawVersionString,
2158                                         modifiers,
2159                                         requires,
2160                                         exports,
2161                                         opens,
2162                                         uses,
2163                                         provides,
2164                                         packages,
2165                                         mainClass);
2166         }
2167 
2168     }
2169 
2170     /**
2171      * Compares this module descriptor to another.
2172      *
2173      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2174      * module names lexicographically. Where the module names are equal then the
2175      * module versions are compared. When comparing the module versions then a
2176      * module descriptor with a version is considered to succeed a module
2177      * descriptor that does not have a version. If both versions are {@linkplain
2178      * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
2179      * raw version strings} are compared lexicographically. Where the module names
2180      * are equal and the versions are equal (or not present in both), then the
2181      * set of modifiers are compared. Sets of modifiers are compared by comparing
2182      * a <em>binary value</em> computed for each set. If a modifier is present
2183      * in the set then the bit at the position of its ordinal is {@code 1}
2184      * in the binary value, otherwise {@code 0}. If the two set of modifiers
2185      * are also equal then the other components of the module descriptors are
2186      * compared in a manner that is consistent with {@code equals}. </p>
2187      *
2188      * @param  that
2189      *         The module descriptor to compare
2190      *
2191      * @return A negative integer, zero, or a positive integer if this module
2192      *         descriptor is less than, equal to, or greater than the given
2193      *         module descriptor
2194      */
2195     @Override
2196     public int compareTo(ModuleDescriptor that) {
2197         if (this == that) return 0;
2198 
2199         int c = this.name().compareTo(that.name());
2200         if (c != 0) return c;
2201 
2202         c = compare(this.version, that.version);
2203         if (c != 0) return c;
2204 
2205         c = compare(this.rawVersionString, that.rawVersionString);
2206         if (c != 0) return c;
2207 
2208         long v1 = modsValue(this.modifiers());
2209         long v2 = modsValue(that.modifiers());
2210         c = Long.compare(v1, v2);
2211         if (c != 0) return c;
2212 
2213         c = compare(this.requires, that.requires);
2214         if (c != 0) return c;
2215 
2216         c = compare(this.packages, that.packages);
2217         if (c != 0) return c;
2218 
2219         c = compare(this.exports, that.exports);
2220         if (c != 0) return c;
2221 
2222         c = compare(this.opens, that.opens);
2223         if (c != 0) return c;
2224 
2225         c = compare(this.uses, that.uses);
2226         if (c != 0) return c;
2227 
2228         c = compare(this.provides, that.provides);
2229         if (c != 0) return c;
2230 
2231         c = compare(this.mainClass, that.mainClass);
2232         if (c != 0) return c;
2233 
2234         return 0;
2235     }
2236 
2237     /**
2238      * Tests this module descriptor for equality with the given object.
2239      *
2240      * <p> If the given object is not a {@code ModuleDescriptor} then this
2241      * method returns {@code false}. Two module descriptors are equal if each
2242      * of their corresponding components is equal. </p>
2243      *
2244      * <p> This method satisfies the general contract of the {@link
2245      * java.lang.Object#equals(Object) Object.equals} method. </p>
2246      *
2247      * @param   ob
2248      *          the object to which this object is to be compared
2249      *
2250      * @return  {@code true} if, and only if, the given object is a module
2251      *          descriptor that is equal to this module descriptor
2252      */
2253     @Override
2254     public boolean equals(Object ob) {
2255         if (ob == this)
2256             return true;
2257         if (!(ob instanceof ModuleDescriptor))
2258             return false;
2259         ModuleDescriptor that = (ModuleDescriptor)ob;
2260         return (name.equals(that.name)
2261                 && modifiers.equals(that.modifiers)
2262                 && requires.equals(that.requires)
2263                 && Objects.equals(packages, that.packages)
2264                 && exports.equals(that.exports)
2265                 && opens.equals(that.opens)
2266                 && uses.equals(that.uses)
2267                 && provides.equals(that.provides)
2268                 && Objects.equals(version, that.version)
2269                 && Objects.equals(rawVersionString, that.rawVersionString)
2270                 && Objects.equals(mainClass, that.mainClass));
2271     }
2272 
2273     /**
2274      * Computes a hash code for this module descriptor.
2275      *
2276      * <p> The hash code is based upon the components of the module descriptor,
2277      * and satisfies the general contract of the {@link Object#hashCode
2278      * Object.hashCode} method. </p>
2279      *
2280      * @return The hash-code value for this module descriptor
2281      */
2282     @Override
2283     public int hashCode() {
2284         int hc = hash;
2285         if (hc == 0) {
2286             hc = name.hashCode();
2287             hc = hc * 43 + Objects.hashCode(modifiers);
2288             hc = hc * 43 + requires.hashCode();
2289             hc = hc * 43 + Objects.hashCode(packages);
2290             hc = hc * 43 + exports.hashCode();
2291             hc = hc * 43 + opens.hashCode();
2292             hc = hc * 43 + uses.hashCode();
2293             hc = hc * 43 + provides.hashCode();
2294             hc = hc * 43 + Objects.hashCode(version);
2295             hc = hc * 43 + Objects.hashCode(rawVersionString);
2296             hc = hc * 43 + Objects.hashCode(mainClass);
2297             if (hc == 0)
2298                 hc = -1;
2299             hash = hc;
2300         }
2301         return hc;
2302     }
2303     private transient int hash;  // cached hash code
2304 
2305     /**
2306      * <p> Returns a string describing the module. </p>
2307      *
2308      * @return A string describing the module
2309      */
2310     @Override
2311     public String toString() {
2312         StringBuilder sb = new StringBuilder();
2313 
2314         if (isOpen())
2315             sb.append("open ");
2316         sb.append("module { name: ").append(toNameAndVersion());
2317         if (!requires.isEmpty())
2318             sb.append(", ").append(requires);
2319         if (!uses.isEmpty())
2320             sb.append(", uses: ").append(uses);
2321         if (!exports.isEmpty())
2322             sb.append(", exports: ").append(exports);
2323         if (!opens.isEmpty())
2324             sb.append(", opens: ").append(opens);
2325         if (!provides.isEmpty()) {
2326             sb.append(", provides: ").append(provides);
2327         }
2328         sb.append(" }");
2329         return sb.toString();
2330     }
2331 
2332 
2333     /**
2334      * Instantiates a builder to build a module descriptor.
2335      *
2336      * @param  name
2337      *         The module name
2338      * @param  ms
2339      *         The set of module modifiers
2340      *
2341      * @return A new builder
2342      *
2343      * @throws IllegalArgumentException
2344      *         If the module name is {@code null} or is not a legal module
2345      *         name, or the set of modifiers contains {@link
2346      *         Modifier#AUTOMATIC AUTOMATIC} with other modifiers
2347      */
2348     public static Builder newModule(String name, Set<Modifier> ms) {
2349         Set<Modifier> mods = new HashSet<>(ms);
2350         if (mods.contains(Modifier.AUTOMATIC) && mods.size() > 1)
2351             throw new IllegalArgumentException("AUTOMATIC cannot be used with"
2352                                                + " other modifiers");
2353 
2354         return new Builder(name, true, mods);
2355     }
2356 
2357     /**
2358      * Instantiates a builder to build a module descriptor for a <em>normal</em>
2359      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2360      * newModule} with an empty set of {@link ModuleDescriptor.Modifier modifiers}.
2361      *
2362      * @param  name
2363      *         The module name
2364      *
2365      * @return A new builder
2366      *
2367      * @throws IllegalArgumentException
2368      *         If the module name is {@code null} or is not a legal module
2369      *         name
2370      */
2371     public static Builder newModule(String name) {
2372         return new Builder(name, true, Set.of());
2373     }
2374 
2375     /**
2376      * Instantiates a builder to build a module descriptor for an open module.
2377      * This method is equivalent to invoking {@link #newModule(String,Set)
2378      * newModule} with the {@link ModuleDescriptor.Modifier#OPEN OPEN} modifier.
2379      *
2380      * <p> The builder for an open module cannot be used to declare any open
2381      * packages. </p>
2382      *
2383      * @param  name
2384      *         The module name
2385      *
2386      * @return A new builder that builds an open module
2387      *
2388      * @throws IllegalArgumentException
2389      *         If the module name is {@code null} or is not a legal module
2390      *         name
2391      */
2392     public static Builder newOpenModule(String name) {
2393         return new Builder(name, true, Set.of(Modifier.OPEN));
2394     }
2395 
2396     /**
2397      * Instantiates a builder to build a module descriptor for an automatic
2398      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2399      * newModule} with the {@link ModuleDescriptor.Modifier#AUTOMATIC AUTOMATIC}
2400      * modifier.
2401      *
2402      * <p> The builder for an automatic module cannot be used to declare module
2403      * or service dependences. It also cannot be used to declare any exported
2404      * or open packages. </p>
2405      *
2406      * @param  name
2407      *         The module name
2408      *
2409      * @return A new builder that builds an automatic module
2410      *
2411      * @throws IllegalArgumentException
2412      *         If the module name is {@code null} or is not a legal module
2413      *         name
2414      *
2415      * @see ModuleFinder#of(Path[])
2416      */
2417     public static Builder newAutomaticModule(String name) {
2418         return new Builder(name, true, Set.of(Modifier.AUTOMATIC));
2419     }
2420 
2421 
2422     /**
2423      * Reads the binary form of a module declaration from an input stream
2424      * as a module descriptor.
2425      *
2426      * <p> If the descriptor encoded in the input stream does not indicate a
2427      * set of packages in the module then the {@code packageFinder} will be
2428      * invoked. The set of packages that the {@code packageFinder} returns
2429      * must include all the packages that the module exports, opens, as well
2430      * as the packages of the service implementations that the module provides,
2431      * and the package of the main class (if the module has a main class). If
2432      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2433      * {@link IOException} cause will be re-thrown. </p>
2434      *
2435      * <p> If there are bytes following the module descriptor then it is
2436      * implementation specific as to whether those bytes are read, ignored,
2437      * or reported as an {@code InvalidModuleDescriptorException}. If this
2438      * method fails with an {@code InvalidModuleDescriptorException} or {@code
2439      * IOException} then it may do so after some, but not all, bytes have
2440      * been read from the input stream. It is strongly recommended that the
2441      * stream be promptly closed and discarded if an exception occurs. </p>
2442      *
2443      * @apiNote The {@code packageFinder} parameter is for use when reading
2444      * module descriptors from legacy module-artifact formats that do not
2445      * record the set of packages in the descriptor itself.
2446      *
2447      * @param  in
2448      *         The input stream
2449      * @param  packageFinder
2450      *         A supplier that can produce the set of packages
2451      *
2452      * @return The module descriptor
2453      *
2454      * @throws InvalidModuleDescriptorException
2455      *         If an invalid module descriptor is detected or the set of
2456      *         packages returned by the {@code packageFinder} does not include
2457      *         all of the packages obtained from the module descriptor
2458      * @throws IOException
2459      *         If an I/O error occurs reading from the input stream or {@code
2460      *         UncheckedIOException} is thrown by the package finder
2461      */
2462     public static ModuleDescriptor read(InputStream in,
2463                                         Supplier<Set<String>> packageFinder)
2464         throws IOException
2465     {
2466         return ModuleInfo.read(in, requireNonNull(packageFinder)).descriptor();
2467     }
2468 
2469     /**
2470      * Reads the binary form of a module declaration from an input stream as a
2471      * module descriptor. This method works exactly as specified by the 2-arg
2472      * {@link #read(InputStream,Supplier) read} method with the exception that
2473      * a packager finder is not used to find additional packages when the
2474      * module descriptor read from the stream does not indicate the set of
2475      * packages.
2476      *
2477      * @param  in
2478      *         The input stream
2479      *
2480      * @return The module descriptor
2481      *
2482      * @throws InvalidModuleDescriptorException
2483      *         If an invalid module descriptor is detected
2484      * @throws IOException
2485      *         If an I/O error occurs reading from the input stream
2486      */
2487     public static ModuleDescriptor read(InputStream in) throws IOException {
2488         return ModuleInfo.read(in, null).descriptor();
2489     }
2490 
2491     /**
2492      * Reads the binary form of a module declaration from a byte buffer
2493      * as a module descriptor.
2494      *
2495      * <p> If the descriptor encoded in the byte buffer does not indicate a
2496      * set of packages in the module then the {@code packageFinder} will be
2497      * invoked. The set of packages that the {@code packageFinder} returns
2498      * must include all the packages that the module exports, opens, as well
2499      * as the packages of the service implementations that the module provides,
2500      * and the package of the main class (if the module has a main class). If
2501      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2502      * {@link IOException} cause will be re-thrown. </p>
2503      *
2504      * <p> The module descriptor is read from the buffer starting at index
2505      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
2506      * position} when this method is invoked. Upon return the buffer's position
2507      * will be equal to {@code p + n} where {@code n} is the number of bytes
2508      * read from the buffer. </p>
2509      *
2510      * <p> If there are bytes following the module descriptor then it is
2511      * implementation specific as to whether those bytes are read, ignored,
2512      * or reported as an {@code InvalidModuleDescriptorException}. If this
2513      * method fails with an {@code InvalidModuleDescriptorException} then it
2514      * may do so after some, but not all, bytes have been read. </p>
2515      *
2516      * @apiNote The {@code packageFinder} parameter is for use when reading
2517      * module descriptors from legacy module-artifact formats that do not
2518      * record the set of packages in the descriptor itself.
2519      *
2520      * @param  bb
2521      *         The byte buffer
2522      * @param  packageFinder
2523      *         A supplier that can produce the set of packages
2524      *
2525      * @return The module descriptor
2526      *
2527      * @throws InvalidModuleDescriptorException
2528      *         If an invalid module descriptor is detected or the set of
2529      *         packages returned by the {@code packageFinder} does not include
2530      *         all of the packages obtained from the module descriptor
2531      */
2532     public static ModuleDescriptor read(ByteBuffer bb,
2533                                         Supplier<Set<String>> packageFinder)
2534     {
2535         return ModuleInfo.read(bb, requireNonNull(packageFinder)).descriptor();
2536     }
2537 
2538     /**
2539      * Reads the binary form of a module declaration from a byte buffer as a
2540      * module descriptor. This method works exactly as specified by the 2-arg
2541      * {@link #read(ByteBuffer,Supplier) read} method with the exception that a
2542      * packager finder is not used to find additional packages when the module
2543      * descriptor encoded in the buffer does not indicate the set of packages.
2544      *
2545      * @param  bb
2546      *         The byte buffer
2547      *
2548      * @return The module descriptor
2549      *
2550      * @throws InvalidModuleDescriptorException
2551      *         If an invalid module descriptor is detected
2552      */
2553     public static ModuleDescriptor read(ByteBuffer bb) {
2554         return ModuleInfo.read(bb, null).descriptor();
2555     }
2556 
2557     private static String packageName(String cn) {
2558         int index = cn.lastIndexOf('.');
2559         return (index == -1) ? "" : cn.substring(0, index);
2560     }
2561 
2562     /**
2563      * Returns a string containing the given set of modifiers and label.
2564      */
2565     private static <M> String toString(Set<M> mods, String what) {
2566         return (Stream.concat(mods.stream().map(e -> e.toString()
2567                                                       .toLowerCase(Locale.ROOT)),
2568                               Stream.of(what)))
2569                 .collect(Collectors.joining(" "));
2570     }
2571 
2572     private static <T extends Object & Comparable<? super T>>
2573     int compare(T obj1, T obj2) {
2574         if (obj1 != null) {
2575             return (obj2 != null) ? obj1.compareTo(obj2) : 1;
2576         } else {
2577             return (obj2 == null) ? 0 : -1;
2578         }
2579     }
2580 
2581     /**
2582      * Compares two sets of {@code Comparable} objects.
2583      */
2584     @SuppressWarnings("unchecked")
2585     private static <T extends Object & Comparable<? super T>>
2586     int compare(Set<T> s1, Set<T> s2) {
2587         T[] a1 = (T[]) s1.toArray();
2588         T[] a2 = (T[]) s2.toArray();
2589         Arrays.sort(a1);
2590         Arrays.sort(a2);
2591         return Arrays.compare(a1, a2);
2592     }
2593 
2594     private static <E extends Enum<E>> long modsValue(Set<E> set) {
2595         long value = 0;
2596         for (Enum<E> e : set) {
2597             value += 1 << e.ordinal();
2598         }
2599         return value;
2600     }
2601 
2602     static {
2603         /**
2604          * Setup the shared secret to allow code in other packages access
2605          * private package methods in java.lang.module.
2606          */
2607         jdk.internal.access.SharedSecrets
2608             .setJavaLangModuleAccess(new jdk.internal.access.JavaLangModuleAccess() {
2609                 @Override
2610                 public Builder newModuleBuilder(String mn,
2611                                                 boolean strict,
2612                                                 Set<ModuleDescriptor.Modifier> modifiers) {
2613                     return new Builder(mn, strict, modifiers);
2614                 }
2615 
2616                 @Override
2617                 public Set<String> packages(ModuleDescriptor.Builder builder) {
2618                     return builder.packages();
2619                 }
2620 
2621                 @Override
2622                 public void requires(ModuleDescriptor.Builder builder,
2623                                      Set<Requires.Modifier> ms,
2624                                      String mn,
2625                                      String rawCompiledVersion) {
2626                     builder.requires(ms, mn, rawCompiledVersion);
2627                 }
2628 
2629                 @Override
2630                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2631                     return new Requires(ms, mn, v, true);
2632                 }
2633 
2634                 @Override
2635                 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2636                     return new Exports(ms, source, Set.of(), true);
2637                 }
2638 
2639                 @Override
2640                 public Exports newExports(Set<Exports.Modifier> ms,
2641                                           String source,
2642                                           Set<String> targets) {
2643                     return new Exports(ms, source, targets, true);
2644                 }
2645 
2646                 @Override
2647                 public Opens newOpens(Set<Opens.Modifier> ms,
2648                                       String source,
2649                                       Set<String> targets) {
2650                     return new Opens(ms, source, targets, true);
2651                 }
2652 
2653                 @Override
2654                 public Opens newOpens(Set<Opens.Modifier> ms, String source) {
2655                     return new Opens(ms, source, Set.of(), true);
2656                 }
2657 
2658                 @Override
2659                 public Provides newProvides(String service, List<String> providers) {
2660                     return new Provides(service, providers, true);
2661                 }
2662 
2663                 @Override
2664                 public ModuleDescriptor newModuleDescriptor(String name,
2665                                                             Version version,
2666                                                             Set<ModuleDescriptor.Modifier> modifiers,
2667                                                             Set<Requires> requires,
2668                                                             Set<Exports> exports,
2669                                                             Set<Opens> opens,
2670                                                             Set<String> uses,
2671                                                             Set<Provides> provides,
2672                                                             Set<String> packages,
2673                                                             String mainClass,
2674                                                             int hashCode) {
2675                     return new ModuleDescriptor(name,
2676                                                 version,
2677                                                 modifiers,
2678                                                 requires,
2679                                                 exports,
2680                                                 opens,
2681                                                 uses,
2682                                                 provides,
2683                                                 packages,
2684                                                 mainClass,
2685                                                 hashCode,
2686                                                 false);
2687                 }
2688 
2689                 @Override
2690                 public Configuration resolveAndBind(ModuleFinder finder,
2691                                                     Collection<String> roots,
2692                                                     PrintStream traceOutput)
2693                 {
2694                     return Configuration.resolveAndBind(finder, roots, traceOutput);
2695                 }
2696 
2697                 @Override
2698                 public Configuration newConfiguration(ModuleFinder finder,
2699                                                       Map<String, Set<String>> graph) {
2700                     return new Configuration(finder, graph);
2701                 }
2702             });
2703     }
2704 
2705 }