1 /*
2  * Copyright (c) 2009, 2017, 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 trueif, 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 trueif this is a qualified export.
431          *
432          * @return {@code trueif 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 trueif, 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 trueif this is a qualified opens.
638          *
639          * @return {@code trueif 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 trueif, 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 trueif, 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 trueif, 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         assert version == null || rawVersionString == null;
1249         this.name = name;
1250         this.version = version;
1251         this.rawVersionString = rawVersionString;
1252         this.modifiers = Set.copyOf(modifiers);
1253         this.open = modifiers.contains(Modifier.OPEN);
1254         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1255         assert (requires.stream().map(Requires::name).distinct().count()
1256                 == requires.size());
1257         this.requires = Set.copyOf(requires);
1258         this.exports = Set.copyOf(exports);
1259         this.opens = Set.copyOf(opens);
1260         this.uses = Set.copyOf(uses);
1261         this.provides = Set.copyOf(provides);
1262
1263         this.packages = Set.copyOf(packages);
1264         this.mainClass = mainClass;
1265     }
1266
1267     /**
1268      * Creates a module descriptor from its components.
1269      * The arguments are pre-validated and sets are unmodifiable sets.
1270      */

1271     ModuleDescriptor(String name,
1272                      Version version,
1273                      Set<Modifier> modifiers,
1274                      Set<Requires> requires,
1275                      Set<Exports> exports,
1276                      Set<Opens> opens,
1277                      Set<String> uses,
1278                      Set<Provides> provides,
1279                      Set<String> packages,
1280                      String mainClass,
1281                      int hashCode,
1282                      boolean unused) {
1283         this.name = name;
1284         this.version = version;
1285         this.rawVersionString = null;
1286         this.modifiers = modifiers;
1287         this.open = modifiers.contains(Modifier.OPEN);
1288         this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1289         this.requires = requires;
1290         this.exports = exports;
1291         this.opens = opens;
1292         this.uses = uses;
1293         this.provides = provides;
1294         this.packages = packages;
1295         this.mainClass = mainClass;
1296         this.hash = hashCode;
1297     }
1298
1299     /**
1300      * <p> Returns the module name. </p>
1301      *
1302      * @return The module name
1303      */

1304     public String name() {
1305         return name;
1306     }
1307
1308     /**
1309      * <p> Returns the set of module modifiers. </p>
1310      *
1311      * @return A possibly-empty unmodifiable set of modifiers
1312      */

1313     public Set<Modifier> modifiers() {
1314         return modifiers;
1315     }
1316
1317     /**
1318      * <p> Returns {@code trueif this is an open module. </p>
1319      *
1320      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1321      * modifiers} contains the {@link Modifier#OPEN OPEN} modifier. </p>
1322      *
1323      * @return  {@code trueif this is an open module
1324      */

1325     public boolean isOpen() {
1326         return open;
1327     }
1328
1329     /**
1330      * <p> Returns {@code trueif this is an automatic module. </p>
1331      *
1332      * <p> This method is equivalent to testing if the set of {@link #modifiers()
1333      * modifiers} contains the {@link Modifier#OPEN AUTOMATIC} modifier. </p>
1334      *
1335      * @return  {@code trueif this is an automatic module
1336      */

1337     public boolean isAutomatic() {
1338         return automatic;
1339     }
1340
1341     /**
1342      * <p> Returns the set of {@code Requires} objects representing the module
1343      * dependences. </p>
1344      *
1345      * <p> The set includes a dependency on "{@code java.base}" when this
1346      * module is not named "{@code java.base}". If this module is an automatic
1347      * module then it does not have a dependency on any module other than
1348      * "{@code java.base}". </p>
1349      *
1350      * @return  A possibly-empty unmodifiable set of {@link Requires} objects
1351      */

1352     public Set<Requires> requires() {
1353         return requires;
1354     }
1355
1356     /**
1357      * <p> Returns the set of {@code Exports} objects representing the exported
1358      * packages. </p>
1359      *
1360      * <p> If this module is an automatic module then the set of exports
1361      * is empty. </p>
1362      *
1363      * @return  A possibly-empty unmodifiable set of exported packages
1364      */

1365     public Set<Exports> exports() {
1366         return exports;
1367     }
1368
1369     /**
1370      * <p> Returns the set of {@code Opens} objects representing the open
1371      * packages. </p>
1372      *
1373      * <p> If this module is an open module or an automatic module then the
1374      * set of open packages is empty. </p>
1375      *
1376      * @return  A possibly-empty unmodifiable set of open packages
1377      */

1378     public Set<Opens> opens() {
1379         return opens;
1380     }
1381
1382     /**
1383      * <p> Returns the set of service dependences. </p>
1384      *
1385      * <p> If this module is an automatic module then the set of service
1386      * dependences is empty. </p>
1387      *
1388      * @return  A possibly-empty unmodifiable set of the fully qualified class
1389      *          names of the service types used
1390      */

1391     public Set<String> uses() {
1392         return uses;
1393     }
1394
1395     /**
1396      * <p> Returns the set of {@code Provides} objects representing the
1397      * services that the module provides. </p>
1398      *
1399      * @return The possibly-empty unmodifiable set of the services that this
1400      *         module provides
1401      */

1402     public Set<Provides> provides() {
1403         return provides;
1404     }
1405
1406     /**
1407      * <p> Returns the module version. </p>
1408      *
1409      * @return This module's version, or an empty {@code Optional} if the
1410      *         module does not have a version or the version is
1411      *         {@linkplain Version#parse(String) unparseable}
1412      */

1413     public Optional<Version> version() {
1414         return Optional.ofNullable(version);
1415     }
1416
1417     /**
1418      * <p> Returns the string with the possibly-unparseable version of the
1419      * module </p>
1420      *
1421      * @return The string containing the version of the module or an empty
1422      *         {@code Optional} if the module does not have a version
1423      *
1424      * @see #version()
1425      */

1426     public Optional<String> rawVersion() {
1427         if (version != null) {
1428             return Optional.of(version.toString());
1429         } else {
1430             return Optional.ofNullable(rawVersionString);
1431         }
1432     }
1433
1434     /**
1435      * <p> Returns a string containing the module name and, if present, its
1436      * version. </p>
1437      *
1438      * @return A string containing the module name and, if present, its
1439      *         version
1440      */

1441     public String toNameAndVersion() {
1442         if (version != null) {
1443             return name() + "@" + version;
1444         } else {
1445             return name();
1446         }
1447     }
1448
1449     /**
1450      * <p> Returns the module main class. </p>
1451      *
1452      * @return The fully qualified class name of the module's main class
1453      */

1454     public Optional<String> mainClass() {
1455         return Optional.ofNullable(mainClass);
1456     }
1457
1458     /**
1459      * Returns the set of packages in the module.
1460      *
1461      * <p> The set of packages includes all exported and open packages, as well
1462      * as the packages of any service providers, and the package for the main
1463      * class. </p>
1464      *
1465      * @return A possibly-empty unmodifiable set of the packages in the module
1466      */

1467     public Set<String> packages() {
1468         return packages;
1469     }
1470
1471
1472     /**
1473      * A builder for building {@link ModuleDescriptor} objects.
1474      *
1475      * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
1476      * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
1477      * newAutomaticModule} methods to create builders for building
1478      * <em>normal</em>, open, and automatic modules. </p>
1479      *
1480      * <p> The set of packages in the module are accumulated by the {@code
1481      * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
1482      * {@link ModuleDescriptor.Builder#opens(String) opens},
1483      * {@link ModuleDescriptor.Builder#packages(Set) packages},
1484      * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
1485      * {@link ModuleDescriptor.Builder#mainClass(String) mainClass} methods are
1486      * invoked. </p>
1487      *
1488      * <p> The module names, package names, and class names that are parameters
1489      * specified to the builder methods are the module names, package names,
1490      * and qualified names of classes (in named packages) as defined in the
1491      * <cite>The Java&trade; Language Specification</cite>. </p>
1492      *
1493      * <p> Example usage: </p>
1494      * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.newModule("stats.core")
1495      *         .requires("java.base")
1496      *         .exports("org.acme.stats.core.clustering")
1497      *         .exports("org.acme.stats.core.regression")
1498      *         .packages(Set.of("org.acme.stats.core.internal"))
1499      *         .build();
1500      * }</pre>
1501      *
1502      * @apiNote A {@code Builder} checks the components and invariants as
1503      * components are added to the builder. The rationale for this is to detect
1504      * errors as early as possible and not defer all validation to the
1505      * {@link #build build} method.
1506      *
1507      * @since 9
1508      * @spec JPMS
1509      */

1510     public static final class Builder {
1511         final String name;
1512         final boolean strict;
1513         final Set<Modifier> modifiers;
1514         final boolean open;
1515         final boolean automatic;
1516         final Set<String> packages = new HashSet<>();
1517         final Map<String, Requires> requires = new HashMap<>();
1518         final Map<String, Exports> exports = new HashMap<>();
1519         final Map<String, Opens> opens = new HashMap<>();
1520         final Set<String> uses = new HashSet<>();
1521         final Map<String, Provides> provides = new HashMap<>();
1522         Version version;
1523         String rawVersionString;
1524         String mainClass;
1525
1526         /**
1527          * Initializes a new builder with the given module name.
1528          *
1529          * If {@code strict} is {@code true} then module, package, and class
1530          * names are checked to ensure they are legal names. In addition, the
1531          * {@link #build buid} method will add "{@code requires java.base}" if
1532          * the dependency is not declared.
1533          */

1534         Builder(String name, boolean strict, Set<Modifier> modifiers) {
1535             this.name = (strict) ? requireModuleName(name) : name;
1536             this.strict = strict;
1537             this.modifiers = modifiers;
1538             this.open = modifiers.contains(Modifier.OPEN);
1539             this.automatic = modifiers.contains(Modifier.AUTOMATIC);
1540             assert !open || !automatic;
1541         }
1542
1543         /**
1544          * Returns a snapshot of the packages in the module.
1545          */

1546         /* package */ Set<String> packages() {
1547             return Collections.unmodifiableSet(packages);
1548         }
1549
1550         /**
1551          * Adds a dependence on a module.
1552          *
1553          * @param  req
1554          *         The dependence
1555          *
1556          * @return This builder
1557          *
1558          * @throws IllegalArgumentException
1559          *         If the dependence is on the module that this builder was
1560          *         initialized to build
1561          * @throws IllegalStateException
1562          *         If the dependence on the module has already been declared
1563          *         or this builder is for an automatic module
1564          */

1565         public Builder requires(Requires req) {
1566             if (automatic)
1567                 throw new IllegalStateException("Automatic modules cannot declare"
1568                                                 + " dependences");
1569             String mn = req.name();
1570             if (name.equals(mn))
1571                 throw new IllegalArgumentException("Dependence on self");
1572             if (requires.containsKey(mn))
1573                 throw new IllegalStateException("Dependence upon " + mn
1574                                                 + " already declared");
1575             requires.put(mn, req);
1576             return this;
1577         }
1578
1579         /**
1580          * Adds a dependence on a module with the given (and possibly empty)
1581          * set of modifiers. The dependence includes the version of the
1582          * module that was recorded at compile-time.
1583          *
1584          * @param  ms
1585          *         The set of modifiers
1586          * @param  mn
1587          *         The module name
1588          * @param  compiledVersion
1589          *         The version of the module recorded at compile-time
1590          *
1591          * @return This builder
1592          *
1593          * @throws IllegalArgumentException
1594          *         If the module name is {@code null}, is not a legal module
1595          *         name, or is equal to the module name that this builder
1596          *         was initialized to build
1597          * @throws IllegalStateException
1598          *         If the dependence on the module has already been declared
1599          *         or this builder is for an automatic module
1600          */

1601         public Builder requires(Set<Requires.Modifier> ms,
1602                                 String mn,
1603                                 Version compiledVersion) {
1604             Objects.requireNonNull(compiledVersion);
1605             if (strict)
1606                 mn = requireModuleName(mn);
1607             return requires(new Requires(ms, mn, compiledVersion, null));
1608         }
1609
1610         /* package */Builder requires(Set<Requires.Modifier> ms,
1611                                       String mn,
1612                                       String rawCompiledVersion) {
1613             Requires r;
1614             try {
1615                 Version v = Version.parse(rawCompiledVersion);
1616                 r = new Requires(ms, mn, v, null);
1617             } catch (IllegalArgumentException e) {
1618                 if (strict) throw e;
1619                 r = new Requires(ms, mn, null, rawCompiledVersion);
1620             }
1621             return requires(r);
1622         }
1623
1624         /**
1625          * Adds a dependence on a module with the given (and possibly empty)
1626          * set of modifiers.
1627          *
1628          * @param  ms
1629          *         The set of modifiers
1630          * @param  mn
1631          *         The module name
1632          *
1633          * @return This builder
1634          *
1635          * @throws IllegalArgumentException
1636          *         If the module name is {@code null}, is not a legal module
1637          *         name, or is equal to the module name that this builder
1638          *         was initialized to build
1639          * @throws IllegalStateException
1640          *         If the dependence on the module has already been declared
1641          *         or this builder is for an automatic module
1642          */

1643         public Builder requires(Set<Requires.Modifier> ms, String mn) {
1644             if (strict)
1645                 mn = requireModuleName(mn);
1646             return requires(new Requires(ms, mn, nullnull));
1647         }
1648
1649         /**
1650          * Adds a dependence on a module with an empty set of modifiers.
1651          *
1652          * @param  mn
1653          *         The module name
1654          *
1655          * @return This builder
1656          *
1657          * @throws IllegalArgumentException
1658          *         If the module name is {@code null}, is not a legal module
1659          *         name, or is equal to the module name that this builder
1660          *         was initialized to build
1661          * @throws IllegalStateException
1662          *         If the dependence on the module has already been declared
1663          *         or this builder is for an automatic module
1664          */

1665         public Builder requires(String mn) {
1666             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
1667         }
1668
1669         /**
1670          * Adds an exported package.
1671          *
1672          * @param  e
1673          *         The export
1674          *
1675          * @return This builder
1676          *
1677          * @throws IllegalStateException
1678          *         If the {@link Exports#source() package} is already declared as
1679          *         exported or this builder is for an automatic module
1680          */

1681         public Builder exports(Exports e) {
1682             if (automatic) {
1683                 throw new IllegalStateException("Automatic modules cannot declare"
1684                                                  + " exported packages");
1685             }
1686             String source = e.source();
1687             if (exports.containsKey(source)) {
1688                 throw new IllegalStateException("Exported package " + source
1689                                                  + " already declared");
1690             }
1691             exports.put(source, e);
1692             packages.add(source);
1693             return this;
1694         }
1695
1696         /**
1697          * Adds an exported package with the given (and possibly empty) set of
1698          * modifiers. The package is exported to a set of target modules.
1699          *
1700          * @param  ms
1701          *         The set of modifiers
1702          * @param  pn
1703          *         The package name
1704          * @param  targets
1705          *         The set of target modules names
1706          *
1707          * @return This builder
1708          *
1709          * @throws IllegalArgumentException
1710          *         If the package name is {@code null} or is not a legal
1711          *         package name, the set of target modules is empty, or the set
1712          *         of target modules contains a name that is not a legal module
1713          *         name
1714          * @throws IllegalStateException
1715          *         If the package is already declared as exported
1716          *         or this builder is for an automatic module
1717          */

1718         public Builder exports(Set<Exports.Modifier> ms,
1719                                String pn,
1720                                Set<String> targets)
1721         {
1722             targets = new HashSet<>(targets);
1723             if (targets.isEmpty())
1724                 throw new IllegalArgumentException("Empty target set");
1725             if (strict) {
1726                 requirePackageName(pn);
1727                 targets.forEach(Checks::requireModuleName);
1728             }
1729             Exports e = new Exports(ms, pn, targets);
1730             return exports(e);
1731         }
1732
1733         /**
1734          * Adds an exported package with the given (and possibly empty) set of
1735          * modifiers. The package is exported to all modules.
1736          *
1737          * @param  ms
1738          *         The set of modifiers
1739          * @param  pn
1740          *         The package name
1741          *
1742          * @return This builder
1743          *
1744          * @throws IllegalArgumentException
1745          *         If the package name is {@code null} or is not a legal
1746          *         package name
1747          * @throws IllegalStateException
1748          *         If the package is already declared as exported
1749          *         or this builder is for an automatic module
1750          */

1751         public Builder exports(Set<Exports.Modifier> ms, String pn) {
1752             if (strict) {
1753                 requirePackageName(pn);
1754             }
1755             Exports e = new Exports(ms, pn, Set.of());
1756             return exports(e);
1757         }
1758
1759         /**
1760          * Adds an exported package. The package is exported to a set of target
1761          * modules.
1762          *
1763          * @param  pn
1764          *         The package name
1765          * @param  targets
1766          *         The set of target modules names
1767          *
1768          * @return This builder
1769          *
1770          * @throws IllegalArgumentException
1771          *         If the package name is {@code null} or is not a legal
1772          *         package name, the set of target modules is empty, or the set
1773          *         of target modules contains a name that is not a legal module
1774          *         name
1775          * @throws IllegalStateException
1776          *         If the package is already declared as exported
1777          *         or this builder is for an automatic module
1778          */

1779         public Builder exports(String pn, Set<String> targets) {
1780             return exports(Set.of(), pn, targets);
1781         }
1782
1783         /**
1784          * Adds an exported package. The package is exported to all modules.
1785          *
1786          * @param  pn
1787          *         The package name
1788          *
1789          * @return This builder
1790          *
1791          * @throws IllegalArgumentException
1792          *         If the package name is {@code null} or is not a legal
1793          *         package name
1794          * @throws IllegalStateException
1795          *         If the package is already declared as exported
1796          *         or this builder is for an automatic module
1797          */

1798         public Builder exports(String pn) {
1799             return exports(Set.of(), pn);
1800         }
1801
1802         /**
1803          * Adds an open package.
1804          *
1805          * @param  obj
1806          *         The {@code Opens} object
1807          *
1808          * @return This builder
1809          *
1810          * @throws IllegalStateException
1811          *         If the package is already declared as open, or this is a
1812          *         builder for an open module or automatic module
1813          */

1814         public Builder opens(Opens obj) {
1815             if (open || automatic) {
1816                 throw new IllegalStateException("Open or automatic modules cannot"
1817                                                 + " declare open packages");
1818             }
1819             String source = obj.source();
1820             if (opens.containsKey(source)) {
1821                 throw new IllegalStateException("Open package " + source
1822                                                 + " already declared");
1823             }
1824             opens.put(source, obj);
1825             packages.add(source);
1826             return this;
1827         }
1828
1829
1830         /**
1831          * Adds an open package with the given (and possibly empty) set of
1832          * modifiers. The package is open to a set of target modules.
1833          *
1834          * @param  ms
1835          *         The set of modifiers
1836          * @param  pn
1837          *         The package name
1838          * @param  targets
1839          *         The set of target modules names
1840          *
1841          * @return This builder
1842          *
1843          * @throws IllegalArgumentException
1844          *         If the package name is {@code null} or is not a legal
1845          *         package name, the set of target modules is empty, or the set
1846          *         of target modules contains a name that is not a legal module
1847          *         name
1848          * @throws IllegalStateException
1849          *         If the package is already declared as open, or this is a
1850          *         builder for an open module or automatic module
1851          */

1852         public Builder opens(Set<Opens.Modifier> ms,
1853                              String pn,
1854                              Set<String> targets)
1855         {
1856             targets = new HashSet<>(targets);
1857             if (targets.isEmpty())
1858                 throw new IllegalArgumentException("Empty target set");
1859             if (strict) {
1860                 requirePackageName(pn);
1861                 targets.forEach(Checks::requireModuleName);
1862             }
1863             Opens opens = new Opens(ms, pn, targets);
1864             return opens(opens);
1865         }
1866
1867         /**
1868          * Adds an open package with the given (and possibly empty) set of
1869          * modifiers. The package is open to all modules.
1870          *
1871          * @param  ms
1872          *         The set of modifiers
1873          * @param  pn
1874          *         The package name
1875          *
1876          * @return This builder
1877          *
1878          * @throws IllegalArgumentException
1879          *         If the package name is {@code null} or is not a legal
1880          *         package name
1881          * @throws IllegalStateException
1882          *         If the package is already declared as open, or this is a
1883          *         builder for an open module or automatic module
1884          */

1885         public Builder opens(Set<Opens.Modifier> ms, String pn) {
1886             if (strict) {
1887                 requirePackageName(pn);
1888             }
1889             Opens e = new Opens(ms, pn, Set.of());
1890             return opens(e);
1891         }
1892
1893         /**
1894          * Adds an open package. The package is open to a set of target modules.
1895          *
1896          * @param  pn
1897          *         The package name
1898          * @param  targets
1899          *         The set of target modules names
1900          *
1901          * @return This builder
1902          *
1903          * @throws IllegalArgumentException
1904          *         If the package name is {@code null} or is not a legal
1905          *         package name, the set of target modules is empty, or the set
1906          *         of target modules contains a name that is not a legal module
1907          *         name
1908          * @throws IllegalStateException
1909          *         If the package is already declared as open, or this is a
1910          *         builder for an open module or automatic module
1911          */

1912         public Builder opens(String pn, Set<String> targets) {
1913             return opens(Set.of(), pn, targets);
1914         }
1915
1916         /**
1917          * Adds an open package. The package is open to all modules.
1918          *
1919          * @param  pn
1920          *         The package name
1921          *
1922          * @return This builder
1923          *
1924          * @throws IllegalArgumentException
1925          *         If the package name is {@code null} or is not a legal
1926          *         package name
1927          * @throws IllegalStateException
1928          *         If the package is already declared as open, or this is a
1929          *         builder for an open module or automatic module
1930          */

1931         public Builder opens(String pn) {
1932             return opens(Set.of(), pn);
1933         }
1934
1935         /**
1936          * Adds a service dependence.
1937          *
1938          * @param  service
1939          *         The service type
1940          *
1941          * @return This builder
1942          *
1943          * @throws IllegalArgumentException
1944          *         If the service type is {@code null} or not a qualified name of
1945          *         a class in a named package
1946          * @throws IllegalStateException
1947          *         If a dependency on the service type has already been declared
1948          *         or this is a builder for an automatic module
1949          */

1950         public Builder uses(String service) {
1951             if (automatic)
1952                 throw new IllegalStateException("Automatic modules can not declare"
1953                                                 + " service dependences");
1954             if (uses.contains(requireServiceTypeName(service)))
1955                 throw new IllegalStateException("Dependence upon service "
1956                                                 + service + " already declared");
1957             uses.add(service);
1958             return this;
1959         }
1960
1961         /**
1962          * Provides a service with one or more implementations. The package for
1963          * each {@link Provides#providers provider} (or provider factory) is
1964          * added to the module if not already added.
1965          *
1966          * @param  p
1967          *         The provides
1968          *
1969          * @return This builder
1970          *
1971          * @throws IllegalStateException
1972          *         If the providers for the service type have already been
1973          *         declared
1974          */

1975         public Builder provides(Provides p) {
1976             String service = p.service();
1977             if (provides.containsKey(service))
1978                 throw new IllegalStateException("Providers of service "
1979                                                 + service + " already declared");
1980             provides.put(service, p);
1981             p.providers().forEach(name -> packages.add(packageName(name)));
1982             return this;
1983         }
1984
1985         /**
1986          * Provides implementations of a service. The package for each provider
1987          * (or provider factory) is added to the module if not already added.
1988          *
1989          * @param  service
1990          *         The service type
1991          * @param  providers
1992          *         The list of provider or provider factory class names
1993          *
1994          * @return This builder
1995          *
1996          * @throws IllegalArgumentException
1997          *         If the service type or any of the provider class names is
1998          *         {@code null} or not a qualified name of a class in a named
1999          *         package, or the list of provider class names is empty
2000          * @throws IllegalStateException
2001          *         If the providers for the service type have already been
2002          *         declared
2003          */

2004         public Builder provides(String service, List<String> providers) {
2005             providers = new ArrayList<>(providers);
2006             if (providers.isEmpty())
2007                 throw new IllegalArgumentException("Empty providers set");
2008             if (strict) {
2009                 requireServiceTypeName(service);
2010                 providers.forEach(Checks::requireServiceProviderName);
2011             } else {
2012                 // Disallow service/providers in unnamed package
2013                 String pn = packageName(service);
2014                 if (pn.isEmpty()) {
2015                     throw new IllegalArgumentException(service
2016                                                        + ": unnamed package");
2017                 }
2018                 for (String name : providers) {
2019                     pn = packageName(name);
2020                     if (pn.isEmpty()) {
2021                         throw new IllegalArgumentException(name
2022                                                            + ": unnamed package");
2023                     }
2024                 }
2025             }
2026             Provides p = new Provides(service, providers);
2027             return provides(p);
2028         }
2029
2030         /**
2031          * Adds packages to the module. All packages in the set of package names
2032          * that are not in the module are added to module.
2033          *
2034          * @param  pns
2035          *         The (possibly empty) set of package names
2036          *
2037          * @return This builder
2038          *
2039          * @throws IllegalArgumentException
2040          *         If any of the package names is {@code null} or is not a
2041          *         legal package name
2042          */

2043         public Builder packages(Set<String> pns) {
2044             if (strict) {
2045                 pns = new HashSet<>(pns);
2046                 pns.forEach(Checks::requirePackageName);
2047             }
2048             this.packages.addAll(pns);
2049             return this;
2050         }
2051
2052         /**
2053          * Sets the module version.
2054          *
2055          * @param  v
2056          *         The version
2057          *
2058          * @return This builder
2059          */

2060         public Builder version(Version v) {
2061             version = requireNonNull(v);
2062             rawVersionString = null;
2063             return this;
2064         }
2065
2066         /**
2067          * Sets the module version.
2068          *
2069          * @param  vs
2070          *         The version string to parse
2071          *
2072          * @return This builder
2073          *
2074          * @throws IllegalArgumentException
2075          *         If {@code vs} is {@code null} or cannot be parsed as a
2076          *         version string
2077          *
2078          * @see Version#parse(String)
2079          */

2080         public Builder version(String vs) {
2081             try {
2082                 version = Version.parse(vs);
2083                 rawVersionString = null;
2084             } catch (IllegalArgumentException e) {
2085                 if (strict) throw e;
2086                 version = null;
2087                 rawVersionString = vs;
2088             }
2089             return this;
2090         }
2091
2092         /**
2093          * Sets the module main class. The package for the main class is added
2094          * to the module if not already added. In other words, this method is
2095          * equivalent to first invoking this builder's {@link #packages(Set)
2096          * packages} method to add the package name of the main class.
2097          *
2098          * @param  mc
2099          *         The module main class
2100          *
2101          * @return This builder
2102          *
2103          * @throws IllegalArgumentException
2104          *         If {@code mainClass} is {@code null} or not a qualified
2105          *         name of a class in a named package
2106          */

2107         public Builder mainClass(String mc) {
2108             String pn;
2109             if (strict) {
2110                 mc = requireQualifiedClassName("main class name", mc);
2111                 pn = packageName(mc);
2112                 assert !pn.isEmpty();
2113             } else {
2114                 // Disallow main class in unnamed package
2115                 pn = packageName(mc);
2116                 if (pn.isEmpty()) {
2117                     throw new IllegalArgumentException(mc + ": unnamed package");
2118                 }
2119             }
2120             packages.add(pn);
2121             mainClass = mc;
2122             return this;
2123         }
2124
2125         /**
2126          * Builds and returns a {@code ModuleDescriptor} from its components.
2127          *
2128          * <p> The module will require "{@code java.base}" even if the dependence
2129          * has not been declared (the exception is when building a module named
2130          * "{@code java.base}" as it cannot require itself). The dependence on
2131          * "{@code java.base}" will have the {@link
2132          * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
2133          * modifier if the dependence was not declared. </p>
2134          *
2135          * @return The module descriptor
2136          */

2137         public ModuleDescriptor build() {
2138             Set<Requires> requires = new HashSet<>(this.requires.values());
2139             Set<Exports> exports = new HashSet<>(this.exports.values());
2140             Set<Opens> opens = new HashSet<>(this.opens.values());
2141
2142             // add dependency on java.base
2143             if (strict
2144                     && !name.equals("java.base")
2145                     && !this.requires.containsKey("java.base")) {
2146                 requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
2147                                           "java.base",
2148                                           null,
2149                                           null));
2150             }
2151
2152             Set<Provides> provides = new HashSet<>(this.provides.values());
2153
2154             return new ModuleDescriptor(name,
2155                                         version,
2156                                         rawVersionString,
2157                                         modifiers,
2158                                         requires,
2159                                         exports,
2160                                         opens,
2161                                         uses,
2162                                         provides,
2163                                         packages,
2164                                         mainClass);
2165         }
2166
2167     }
2168
2169     /**
2170      * Compares this module descriptor to another.
2171      *
2172      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
2173      * module names lexicographically. Where the module names are equal then the
2174      * module versions are compared. When comparing the module versions then a
2175      * module descriptor with a version is considered to succeed a module
2176      * descriptor that does not have a version. If both versions are {@linkplain
2177      * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
2178      * raw version strings} are compared lexicographically. Where the module names
2179      * are equal and the versions are equal (or not present in both), then the
2180      * set of modifiers are compared. Sets of modifiers are compared by comparing
2181      * a <em>binary value</em> computed for each set. If a modifier is present
2182      * in the set then the bit at the position of its ordinal is {@code 1}
2183      * in the binary value, otherwise {@code 0}. If the two set of modifiers
2184      * are also equal then the other components of the module descriptors are
2185      * compared in a manner that is consistent with {@code equals}. </p>
2186      *
2187      * @param  that
2188      *         The module descriptor to compare
2189      *
2190      * @return A negative integer, zero, or a positive integer if this module
2191      *         descriptor is less than, equal to, or greater than the given
2192      *         module descriptor
2193      */

2194     @Override
2195     public int compareTo(ModuleDescriptor that) {
2196         if (this == that) return 0;
2197
2198         int c = this.name().compareTo(that.name());
2199         if (c != 0) return c;
2200
2201         c = compare(this.version, that.version);
2202         if (c != 0) return c;
2203
2204         c = compare(this.rawVersionString, that.rawVersionString);
2205         if (c != 0) return c;
2206
2207         long v1 = modsValue(this.modifiers());
2208         long v2 = modsValue(that.modifiers());
2209         c = Long.compare(v1, v2);
2210         if (c != 0) return c;
2211
2212         c = compare(this.requires, that.requires);
2213         if (c != 0) return c;
2214
2215         c = compare(this.packages, that.packages);
2216         if (c != 0) return c;
2217
2218         c = compare(this.exports, that.exports);
2219         if (c != 0) return c;
2220
2221         c = compare(this.opens, that.opens);
2222         if (c != 0) return c;
2223
2224         c = compare(this.uses, that.uses);
2225         if (c != 0) return c;
2226
2227         c = compare(this.provides, that.provides);
2228         if (c != 0) return c;
2229
2230         c = compare(this.mainClass, that.mainClass);
2231         if (c != 0) return c;
2232
2233         return 0;
2234     }
2235
2236     /**
2237      * Tests this module descriptor for equality with the given object.
2238      *
2239      * <p> If the given object is not a {@code ModuleDescriptor} then this
2240      * method returns {@code false}. Two module descriptors are equal if each
2241      * of their corresponding components is equal. </p>
2242      *
2243      * <p> This method satisfies the general contract of the {@link
2244      * java.lang.Object#equals(Object) Object.equals} method. </p>
2245      *
2246      * @param   ob
2247      *          the object to which this object is to be compared
2248      *
2249      * @return  {@code trueif, and only if, the given object is a module
2250      *          descriptor that is equal to this module descriptor
2251      */

2252     @Override
2253     public boolean equals(Object ob) {
2254         if (ob == this)
2255             return true;
2256         if (!(ob instanceof ModuleDescriptor))
2257             return false;
2258         ModuleDescriptor that = (ModuleDescriptor)ob;
2259         return (name.equals(that.name)
2260                 && modifiers.equals(that.modifiers)
2261                 && requires.equals(that.requires)
2262                 && Objects.equals(packages, that.packages)
2263                 && exports.equals(that.exports)
2264                 && opens.equals(that.opens)
2265                 && uses.equals(that.uses)
2266                 && provides.equals(that.provides)
2267                 && Objects.equals(version, that.version)
2268                 && Objects.equals(rawVersionString, that.rawVersionString)
2269                 && Objects.equals(mainClass, that.mainClass));
2270     }
2271
2272     /**
2273      * Computes a hash code for this module descriptor.
2274      *
2275      * <p> The hash code is based upon the components of the module descriptor,
2276      * and satisfies the general contract of the {@link Object#hashCode
2277      * Object.hashCode} method. </p>
2278      *
2279      * @return The hash-code value for this module descriptor
2280      */

2281     @Override
2282     public int hashCode() {
2283         int hc = hash;
2284         if (hc == 0) {
2285             hc = name.hashCode();
2286             hc = hc * 43 + Objects.hashCode(modifiers);
2287             hc = hc * 43 + requires.hashCode();
2288             hc = hc * 43 + Objects.hashCode(packages);
2289             hc = hc * 43 + exports.hashCode();
2290             hc = hc * 43 + opens.hashCode();
2291             hc = hc * 43 + uses.hashCode();
2292             hc = hc * 43 + provides.hashCode();
2293             hc = hc * 43 + Objects.hashCode(version);
2294             hc = hc * 43 + Objects.hashCode(rawVersionString);
2295             hc = hc * 43 + Objects.hashCode(mainClass);
2296             if (hc == 0)
2297                 hc = -1;
2298             hash = hc;
2299         }
2300         return hc;
2301     }
2302     private transient int hash;  // cached hash code
2303
2304     /**
2305      * <p> Returns a string describing the module. </p>
2306      *
2307      * @return A string describing the module
2308      */

2309     @Override
2310     public String toString() {
2311         StringBuilder sb = new StringBuilder();
2312
2313         if (isOpen())
2314             sb.append("open ");
2315         sb.append("module { name: ").append(toNameAndVersion());
2316         if (!requires.isEmpty())
2317             sb.append(", ").append(requires);
2318         if (!uses.isEmpty())
2319             sb.append(", uses: ").append(uses);
2320         if (!exports.isEmpty())
2321             sb.append(", exports: ").append(exports);
2322         if (!opens.isEmpty())
2323             sb.append(", opens: ").append(opens);
2324         if (!provides.isEmpty()) {
2325             sb.append(", provides: ").append(provides);
2326         }
2327         sb.append(" }");
2328         return sb.toString();
2329     }
2330
2331
2332     /**
2333      * Instantiates a builder to build a module descriptor.
2334      *
2335      * @param  name
2336      *         The module name
2337      * @param  ms
2338      *         The set of module modifiers
2339      *
2340      * @return A new builder
2341      *
2342      * @throws IllegalArgumentException
2343      *         If the module name is {@code null} or is not a legal module
2344      *         name, or the set of modifiers contains {@link
2345      *         Modifier#AUTOMATIC AUTOMATIC} with other modifiers
2346      */

2347     public static Builder newModule(String name, Set<Modifier> ms) {
2348         Set<Modifier> mods = new HashSet<>(ms);
2349         if (mods.contains(Modifier.AUTOMATIC) && mods.size() > 1)
2350             throw new IllegalArgumentException("AUTOMATIC cannot be used with"
2351                                                + " other modifiers");
2352
2353         return new Builder(name, true, mods);
2354     }
2355
2356     /**
2357      * Instantiates a builder to build a module descriptor for a <em>normal</em>
2358      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2359      * newModule} with an empty set of {@link ModuleDescriptor.Modifier modifiers}.
2360      *
2361      * @param  name
2362      *         The module name
2363      *
2364      * @return A new builder
2365      *
2366      * @throws IllegalArgumentException
2367      *         If the module name is {@code null} or is not a legal module
2368      *         name
2369      */

2370     public static Builder newModule(String name) {
2371         return new Builder(name, true, Set.of());
2372     }
2373
2374     /**
2375      * Instantiates a builder to build a module descriptor for an open module.
2376      * This method is equivalent to invoking {@link #newModule(String,Set)
2377      * newModule} with the {@link ModuleDescriptor.Modifier#OPEN OPEN} modifier.
2378      *
2379      * <p> The builder for an open module cannot be used to declare any open
2380      * packages. </p>
2381      *
2382      * @param  name
2383      *         The module name
2384      *
2385      * @return A new builder that builds an open module
2386      *
2387      * @throws IllegalArgumentException
2388      *         If the module name is {@code null} or is not a legal module
2389      *         name
2390      */

2391     public static Builder newOpenModule(String name) {
2392         return new Builder(name, true, Set.of(Modifier.OPEN));
2393     }
2394
2395     /**
2396      * Instantiates a builder to build a module descriptor for an automatic
2397      * module. This method is equivalent to invoking {@link #newModule(String,Set)
2398      * newModule} with the {@link ModuleDescriptor.Modifier#AUTOMATIC AUTOMATIC}
2399      * modifier.
2400      *
2401      * <p> The builder for an automatic module cannot be used to declare module
2402      * or service dependences. It also cannot be used to declare any exported
2403      * or open packages. </p>
2404      *
2405      * @param  name
2406      *         The module name
2407      *
2408      * @return A new builder that builds an automatic module
2409      *
2410      * @throws IllegalArgumentException
2411      *         If the module name is {@code null} or is not a legal module
2412      *         name
2413      *
2414      * @see ModuleFinder#of(Path[])
2415      */

2416     public static Builder newAutomaticModule(String name) {
2417         return new Builder(name, true, Set.of(Modifier.AUTOMATIC));
2418     }
2419
2420
2421     /**
2422      * Reads the binary form of a module declaration from an input stream
2423      * as a module descriptor.
2424      *
2425      * <p> If the descriptor encoded in the input stream does not indicate a
2426      * set of packages in the module then the {@code packageFinder} will be
2427      * invoked. The set of packages that the {@code packageFinder} returns
2428      * must include all the packages that the module exports, opens, as well
2429      * as the packages of the service implementations that the module provides,
2430      * and the package of the main class (if the module has a main class). If
2431      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2432      * {@link IOException} cause will be re-thrown. </p>
2433      *
2434      * <p> If there are bytes following the module descriptor then it is
2435      * implementation specific as to whether those bytes are read, ignored,
2436      * or reported as an {@code InvalidModuleDescriptorException}. If this
2437      * method fails with an {@code InvalidModuleDescriptorException} or {@code
2438      * IOException} then it may do so after some, but not all, bytes have
2439      * been read from the input stream. It is strongly recommended that the
2440      * stream be promptly closed and discarded if an exception occurs. </p>
2441      *
2442      * @apiNote The {@code packageFinder} parameter is for use when reading
2443      * module descriptors from legacy module-artifact formats that do not
2444      * record the set of packages in the descriptor itself.
2445      *
2446      * @param  in
2447      *         The input stream
2448      * @param  packageFinder
2449      *         A supplier that can produce the set of packages
2450      *
2451      * @return The module descriptor
2452      *
2453      * @throws InvalidModuleDescriptorException
2454      *         If an invalid module descriptor is detected or the set of
2455      *         packages returned by the {@code packageFinder} does not include
2456      *         all of the packages obtained from the module descriptor
2457      * @throws IOException
2458      *         If an I/O error occurs reading from the input stream or {@code
2459      *         UncheckedIOException} is thrown by the package finder
2460      */

2461     public static ModuleDescriptor read(InputStream in,
2462                                         Supplier<Set<String>> packageFinder)
2463         throws IOException
2464     {
2465         return ModuleInfo.read(in, requireNonNull(packageFinder)).descriptor();
2466     }
2467
2468     /**
2469      * Reads the binary form of a module declaration from an input stream as a
2470      * module descriptor. This method works exactly as specified by the 2-arg
2471      * {@link #read(InputStream,Supplier) read} method with the exception that
2472      * a packager finder is not used to find additional packages when the
2473      * module descriptor read from the stream does not indicate the set of
2474      * packages.
2475      *
2476      * @param  in
2477      *         The input stream
2478      *
2479      * @return The module descriptor
2480      *
2481      * @throws InvalidModuleDescriptorException
2482      *         If an invalid module descriptor is detected
2483      * @throws IOException
2484      *         If an I/O error occurs reading from the input stream
2485      */

2486     public static ModuleDescriptor read(InputStream in) throws IOException {
2487         return ModuleInfo.read(in, null).descriptor();
2488     }
2489
2490     /**
2491      * Reads the binary form of a module declaration from a byte buffer
2492      * as a module descriptor.
2493      *
2494      * <p> If the descriptor encoded in the byte buffer does not indicate a
2495      * set of packages in the module then the {@code packageFinder} will be
2496      * invoked. The set of packages that the {@code packageFinder} returns
2497      * must include all the packages that the module exports, opens, as well
2498      * as the packages of the service implementations that the module provides,
2499      * and the package of the main class (if the module has a main class). If
2500      * the {@code packageFinder} throws an {@link UncheckedIOException} then
2501      * {@link IOException} cause will be re-thrown. </p>
2502      *
2503      * <p> The module descriptor is read from the buffer starting at index
2504      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
2505      * position} when this method is invoked. Upon return the buffer's position
2506      * will be equal to {@code p + n} where {@code n} is the number of bytes
2507      * read from the buffer. </p>
2508      *
2509      * <p> If there are bytes following the module descriptor then it is
2510      * implementation specific as to whether those bytes are read, ignored,
2511      * or reported as an {@code InvalidModuleDescriptorException}. If this
2512      * method fails with an {@code InvalidModuleDescriptorException} then it
2513      * may do so after some, but not all, bytes have been read. </p>
2514      *
2515      * @apiNote The {@code packageFinder} parameter is for use when reading
2516      * module descriptors from legacy module-artifact formats that do not
2517      * record the set of packages in the descriptor itself.
2518      *
2519      * @param  bb
2520      *         The byte buffer
2521      * @param  packageFinder
2522      *         A supplier that can produce the set of packages
2523      *
2524      * @return The module descriptor
2525      *
2526      * @throws InvalidModuleDescriptorException
2527      *         If an invalid module descriptor is detected or the set of
2528      *         packages returned by the {@code packageFinder} does not include
2529      *         all of the packages obtained from the module descriptor
2530      */

2531     public static ModuleDescriptor read(ByteBuffer bb,
2532                                         Supplier<Set<String>> packageFinder)
2533     {
2534         return ModuleInfo.read(bb, requireNonNull(packageFinder)).descriptor();
2535     }
2536
2537     /**
2538      * Reads the binary form of a module declaration from a byte buffer as a
2539      * module descriptor. This method works exactly as specified by the 2-arg
2540      * {@link #read(ByteBuffer,Supplier) read} method with the exception that a
2541      * packager finder is not used to find additional packages when the module
2542      * descriptor encoded in the buffer does not indicate the set of packages.
2543      *
2544      * @param  bb
2545      *         The byte buffer
2546      *
2547      * @return The module descriptor
2548      *
2549      * @throws InvalidModuleDescriptorException
2550      *         If an invalid module descriptor is detected
2551      */

2552     public static ModuleDescriptor read(ByteBuffer bb) {
2553         return ModuleInfo.read(bb, null).descriptor();
2554     }
2555
2556     private static String packageName(String cn) {
2557         int index = cn.lastIndexOf('.');
2558         return (index == -1) ? "" : cn.substring(0, index);
2559     }
2560
2561     /**
2562      * Returns a string containing the given set of modifiers and label.
2563      */

2564     private static <M> String toString(Set<M> mods, String what) {
2565         return (Stream.concat(mods.stream().map(e -> e.toString()
2566                                                       .toLowerCase(Locale.ROOT)),
2567                               Stream.of(what)))
2568                 .collect(Collectors.joining(" "));
2569     }
2570
2571     private static <T extends Object & Comparable<? super T>>
2572     int compare(T obj1, T obj2) {
2573         if (obj1 != null) {
2574             return (obj2 != null) ? obj1.compareTo(obj2) : 1;
2575         } else {
2576             return (obj2 == null) ? 0 : -1;
2577         }
2578     }
2579
2580     /**
2581      * Compares two sets of {@code Comparable} objects.
2582      */

2583     @SuppressWarnings("unchecked")
2584     private static <T extends Object & Comparable<? super T>>
2585     int compare(Set<T> s1, Set<T> s2) {
2586         T[] a1 = (T[]) s1.toArray();
2587         T[] a2 = (T[]) s2.toArray();
2588         Arrays.sort(a1);
2589         Arrays.sort(a2);
2590         return Arrays.compare(a1, a2);
2591     }
2592
2593     private static <E extends Enum<E>> long modsValue(Set<E> set) {
2594         long value = 0;
2595         for (Enum<E> e : set) {
2596             value += 1 << e.ordinal();
2597         }
2598         return value;
2599     }
2600
2601     static {
2602         /**
2603          * Setup the shared secret to allow code in other packages access
2604          * private package methods in java.lang.module.
2605          */

2606         jdk.internal.misc.SharedSecrets
2607             .setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
2608                 @Override
2609                 public Builder newModuleBuilder(String mn,
2610                                                 boolean strict,
2611                                                 Set<ModuleDescriptor.Modifier> modifiers) {
2612                     return new Builder(mn, strict, modifiers);
2613                 }
2614
2615                 @Override
2616                 public Set<String> packages(ModuleDescriptor.Builder builder) {
2617                     return builder.packages();
2618                 }
2619
2620                 @Override
2621                 public void requires(ModuleDescriptor.Builder builder,
2622                                      Set<Requires.Modifier> ms,
2623                                      String mn,
2624                                      String rawCompiledVersion) {
2625                     builder.requires(ms, mn, rawCompiledVersion);
2626                 }
2627
2628                 @Override
2629                 public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
2630                     return new Requires(ms, mn, v, true);
2631                 }
2632
2633                 @Override
2634                 public Exports newExports(Set<Exports.Modifier> ms, String source) {
2635                     return new Exports(ms, source, Set.of(), true);
2636                 }
2637
2638                 @Override
2639                 public Exports newExports(Set<Exports.Modifier> ms,
2640                                           String source,
2641                                           Set<String> targets) {
2642                     return new Exports(ms, source, targets, true);
2643                 }
2644
2645                 @Override
2646                 public Opens newOpens(Set<Opens.Modifier> ms,
2647                                       String source,
2648                                       Set<String> targets) {
2649                     return new Opens(ms, source, targets, true);
2650                 }
2651
2652                 @Override
2653                 public Opens newOpens(Set<Opens.Modifier> ms, String source) {
2654                     return new Opens(ms, source, Set.of(), true);
2655                 }
2656
2657                 @Override
2658                 public Provides newProvides(String service, List<String> providers) {
2659                     return new Provides(service, providers, true);
2660                 }
2661
2662                 @Override
2663                 public ModuleDescriptor newModuleDescriptor(String name,
2664                                                             Version version,
2665                                                             Set<ModuleDescriptor.Modifier> modifiers,
2666                                                             Set<Requires> requires,
2667                                                             Set<Exports> exports,
2668                                                             Set<Opens> opens,
2669                                                             Set<String> uses,
2670                                                             Set<Provides> provides,
2671                                                             Set<String> packages,
2672                                                             String mainClass,
2673                                                             int hashCode) {
2674                     return new ModuleDescriptor(name,
2675                                                 version,
2676                                                 modifiers,
2677                                                 requires,
2678                                                 exports,
2679                                                 opens,
2680                                                 uses,
2681                                                 provides,
2682                                                 packages,
2683                                                 mainClass,
2684                                                 hashCode,
2685                                                 false);
2686                 }
2687
2688                 @Override
2689                 public Configuration resolveAndBind(ModuleFinder finder,
2690                                                     Collection<String> roots,
2691                                                     PrintStream traceOutput)
2692                 {
2693                     return Configuration.resolveAndBind(finder, roots, traceOutput);
2694                 }
2695
2696                 @Override
2697                 public Configuration newConfiguration(ModuleFinder finder,
2698                                                       Map<String, Set<String>> graph) {
2699                     return new Configuration(finder, graph);
2700                 }
2701             });
2702     }
2703
2704 }
2705