Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.module;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static jdk.internal.module.Checks.*;
import static java.util.Objects.*;
import jdk.internal.module.Checks;
import jdk.internal.module.ModuleInfo;
/**
* A module descriptor.
*
*
A module descriptor describes a named module and defines methods to
* obtain each of its components. The module descriptor for a named module
* in the Java virtual machine is obtained by invoking the {@link
* java.lang.Module Module}'s {@link java.lang.Module#getDescriptor
* getDescriptor} method. Module descriptors can also be created using the
* {@link ModuleDescriptor.Builder} class or by reading the binary form of a
* module declaration ({@code module-info.class}) using the {@link
* #read(InputStream,Supplier) read} methods defined here.
*
*
A module descriptor describes a normal, open, or automatic
* module. Normal modules and open modules describe their {@linkplain
* #requires() dependences}, {@link #exports() exported-packages}, the services
* that they {@linkplain #uses() use} or {@linkplain #provides() provide}, and other
* components. Normal modules may {@linkplain #opens() open} specific
* packages. The module descriptor for an open module does not declare any
* open packages (its {@code opens} method returns an empty set) but when
* instantiated in the Java virtual machine then it is treated as if all
* packages are open. The module descriptor for an automatic module does not
* declare any dependences (except for the mandatory dependency on {@code
* java.base}), and does not declare any exported or open packages. Automatic
* modules receive special treatment during resolution so that they read all
* other modules in the configuration. When an automatic module is instantiated
* in the Java virtual machine then it reads every unnamed module and is
* treated as if all packages are exported and open.
*
*
{@code ModuleDescriptor} objects are immutable and safe for use by
* multiple concurrent threads.
*
* @see java.lang.Module
* @since 9
*/
public class ModuleDescriptor
implements Comparable
{
/**
* A modifier on a module.
*
* @see ModuleDescriptor#modifiers()
* @since 9
*/
public enum Modifier {
/**
* An open module. An open module does not declare any open packages
* but the resulting module is treated as if all packages are open.
*/
OPEN,
/**
* An automatic module. An automatic module is treated as if it exports
* and opens all packages.
*
* @apiNote This modifier does not correspond to a module flag in the
* binary form of a module declaration ({@code module-info.class}).
*/
AUTOMATIC,
/**
* The module was not explicitly or implicitly declared.
*/
SYNTHETIC,
/**
* The module was implicitly declared.
*/
MANDATED;
}
/**
*
A dependence upon a module.
*
* @see ModuleDescriptor#requires()
* @since 9
*/
public static final class Requires
implements Comparable
{
/**
* A modifier on a module dependence.
*
* @see Requires#modifiers()
* @since 9
*/
public enum Modifier {
/**
* The dependence causes any module which depends on the current
* module to have an implicitly declared dependence on the module
* named by the {@code Requires}.
*/
TRANSITIVE,
/**
* The dependence is mandatory in the static phase, during compilation,
* but is optional in the dynamic phase, during execution.
*/
STATIC,
/**
* The dependence was not explicitly or implicitly declared in the
* source of the module declaration.
*/
SYNTHETIC,
/**
* The dependence was implicitly declared in the source of the module
* declaration.
*/
MANDATED;
}
private final Set mods;
private final String name;
private final Version compiledVersion;
private final String rawCompiledVersion;
private Requires(Set ms, String mn, Version v, String vs) {
assert v == null || vs == null;
this.mods = Set.copyOf(ms);
this.name = mn;
this.compiledVersion = v;
this.rawCompiledVersion = vs;
}
private Requires(Set ms, String mn, Version v, boolean unused) {
this.mods = ms;
this.name = mn;
this.compiledVersion = v;
this.rawCompiledVersion = null;
}
/**
* Returns the set of modifiers.
*
* @return A possibly-empty unmodifiable set of modifiers
*/
public Set modifiers() {
return mods;
}
/**
* Return the module name.
*
* @return The module name
*/
public String name() {
return name;
}
/**
* Returns the version of the module if recorded at compile-time.
*
* @return The version of the module if recorded at compile-time,
* or an empty {@code Optional} if no version was recorded or
* the version string recorded is {@linkplain Version#parse(String)
* unparseable}
*/
public Optional compiledVersion() {
return Optional.ofNullable(compiledVersion);
}
/**
* Returns the string with the possibly-unparseable version of the module
* if recorded at compile-time.
*
* @return The string containing the version of the module if recorded
* at compile-time, or an empty {@code Optional} if no version
* was recorded
*
* @see #compiledVersion()
*/
public Optional rawCompiledVersion() {
if (compiledVersion != null) {
return Optional.of(compiledVersion.toString());
} else {
return Optional.ofNullable(rawCompiledVersion);
}
}
/**
* Compares this module dependence to another.
*
*
Two {@code Requires} objects are compared by comparing their
* module names lexicographically. Where the module names are equal
* then the sets of modifiers are compared in the same way that
* module modifiers are compared (see {@link ModuleDescriptor#compareTo
* ModuleDescriptor.compareTo}). Where the module names are equal and
* the set of modifiers are equal then the version of the modules
* recorded at compile-time are compared. When comparing the versions
* recorded at compile-time then a dependence that has a recorded
* version is considered to succeed a dependence that does not have a
* recorded version. If both recorded versions are {@linkplain
* Version#parse(String) unparseable} then the {@linkplain
* #rawCompiledVersion() raw version strings} are compared
* lexicographically.
*
* @param that
* The module dependence to compare
*
* @return A negative integer, zero, or a positive integer if this module
* dependence is less than, equal to, or greater than the given
* module dependence
*/
@Override
public int compareTo(Requires that) {
if (this == that) return 0;
int c = this.name().compareTo(that.name());
if (c != 0) return c;
// modifiers
long v1 = modsValue(this.modifiers());
long v2 = modsValue(that.modifiers());
c = Long.compare(v1, v2);
if (c != 0) return c;
// compiledVersion
c = compare(this.compiledVersion, that.compiledVersion);
if (c != 0) return c;
// rawCompiledVersion
c = compare(this.rawCompiledVersion, that.rawCompiledVersion);
if (c != 0) return c;
return 0;
}
/**
* Tests this module dependence for equality with the given object.
*
*
If the given object is not a {@code Requires} then this method
* returns {@code false}. Two module dependence objects are equal if
* the module names are equal, set of modifiers are equal, and the
* compiled version of both modules is equal or not recorded for
* both modules.
*
*
This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method.
*
* @param ob
* the object to which this object is to be compared
*
* @return {@code true} if, and only if, the given object is a module
* dependence that is equal to this module dependence
*/
@Override
public boolean equals(Object ob) {
return (ob instanceof Requires that)
&& name.equals(that.name) && mods.equals(that.mods)
&& Objects.equals(compiledVersion, that.compiledVersion)
&& Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
}
/**
* Computes a hash code for this module dependence.
*
*
The hash code is based upon the module name, modifiers, and the
* module version if recorded at compile time. It satisfies the general
* contract of the {@link Object#hashCode Object.hashCode} method.
*
* @return The hash-code value for this module dependence
*/
@Override
public int hashCode() {
int hash = name.hashCode() * 43 + mods.hashCode();
if (compiledVersion != null)
hash = hash * 43 + compiledVersion.hashCode();
if (rawCompiledVersion != null)
hash = hash * 43 + rawCompiledVersion.hashCode();
return hash;
}
/**
* Returns a string describing this module dependence.
*
* @return A string describing this module dependence
*/
@Override
public String toString() {
String what;
if (compiledVersion != null) {
what = name() + " (@" + compiledVersion + ")";
} else {
what = name();
}
return ModuleDescriptor.toString(mods, what);
}
}
/**
*
A package exported by a module, may be qualified or unqualified.
*
* @see ModuleDescriptor#exports()
* @since 9
*/
public static final class Exports
implements Comparable
{
/**
* A modifier on an exported package.
*
* @see Exports#modifiers()
* @since 9
*/
public enum Modifier {
/**
* The export was not explicitly or implicitly declared in the
* source of the module declaration.
*/
SYNTHETIC,
/**
* The export was implicitly declared in the source of the module
* declaration.
*/
MANDATED;
}
private final Set mods;
private final String source;
private final Set targets; // empty if unqualified export
/**
* Constructs an export
*/
private Exports(Set ms, String source, Set targets) {
this.mods = Set.copyOf(ms);
this.source = source;
this.targets = Set.copyOf(targets);
}
private Exports(Set ms,
String source,
Set targets,
boolean unused) {
this.mods = ms;
this.source = source;
this.targets = targets;
}
/**
* Returns the set of modifiers.
*
* @return A possibly-empty unmodifiable set of modifiers
*/
public Set modifiers() {
return mods;
}
/**
* Returns {@code true} if this is a qualified export.
*
* @return {@code true} if this is a qualified export
*/
public boolean isQualified() {
return !targets.isEmpty();
}
/**
* Returns the package name.
*
* @return The package name
*/
public String source() {
return source;
}
/**
* For a qualified export, returns the non-empty and immutable set
* of the module names to which the package is exported. For an
* unqualified export, returns an empty set.
*
* @return The set of target module names or for an unqualified
* export, an empty set
*/
public Set targets() {
return targets;
}
/**
* Compares this module export to another.
*
*
Two {@code Exports} objects are compared by comparing the package
* names lexicographically. Where the packages names are equal then the
* sets of modifiers are compared in the same way that module modifiers
* are compared (see {@link ModuleDescriptor#compareTo
* ModuleDescriptor.compareTo}). Where the package names are equal and
* the set of modifiers are equal then the set of target modules are
* compared. This is done by sorting the names of the target modules
* in ascending order, and according to their natural ordering, and then
* comparing the corresponding elements lexicographically. Where the
* sets differ in size, and the larger set contains all elements of the
* smaller set, then the larger set is considered to succeed the smaller
* set.
*
* @param that
* The module export to compare
*
* @return A negative integer, zero, or a positive integer if this module
* export is less than, equal to, or greater than the given
* export dependence
*/
@Override
public int compareTo(Exports that) {
if (this == that) return 0;
int c = source.compareTo(that.source);
if (c != 0)
return c;
// modifiers
long v1 = modsValue(this.modifiers());
long v2 = modsValue(that.modifiers());
c = Long.compare(v1, v2);
if (c != 0)
return c;
// targets
c = compare(targets, that.targets);
if (c != 0)
return c;
return 0;
}
/**
* Computes a hash code for this module export.
*
*
The hash code is based upon the modifiers, the package name,
* and for a qualified export, the set of modules names to which the
* package is exported. It satisfies the general contract of the
* {@link Object#hashCode Object.hashCode} method.
*
* @return The hash-code value for this module export
*/
@Override
public int hashCode() {
int hash = mods.hashCode();
hash = hash * 43 + source.hashCode();
return hash * 43 + targets.hashCode();
}
/**
* Tests this module export for equality with the given object.
*
*
If the given object is not an {@code Exports} then this method
* returns {@code false}. Two module exports objects are equal if their
* set of modifiers is equal, the package names are equal and the set
* of target module names is equal.
*
*
This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method.
*
* @param ob
* the object to which this object is to be compared
*
* @return {@code true} if, and only if, the given object is a module
* dependence that is equal to this module dependence
*/
@Override
public boolean equals(Object ob) {
return (ob instanceof Exports other)
&& Objects.equals(this.mods, other.mods)
&& Objects.equals(this.source, other.source)
&& Objects.equals(this.targets, other.targets);
}
/**
* Returns a string describing the exported package.
*
* @return A string describing the exported package
*/
@Override
public String toString() {
String s = ModuleDescriptor.toString(mods, source);
if (targets.isEmpty())
return s;
else
return s + " to " + targets;
}
}
/**
*
A package opened by a module, may be qualified or unqualified.
*
*
The opens directive in a module declaration declares a
* package to be open to allow all types in the package, and all their
* members, not just public types and their public members to be reflected
* on by APIs that support private access or a way to bypass or suppress
* default Java language access control checks.
*
* @see ModuleDescriptor#opens()
* @since 9
*/
public static final class Opens
implements Comparable
{
/**
* A modifier on an open package.
*
* @see Opens#modifiers()
* @since 9
*/
public enum Modifier {
/**
* The open package was not explicitly or implicitly declared in
* the source of the module declaration.
*/
SYNTHETIC,
/**
* The open package was implicitly declared in the source of the
* module declaration.
*/
MANDATED;
}
private final Set mods;
private final String source;
private final Set targets; // empty if unqualified export
/**
* Constructs an {@code Opens}.
*/
private Opens(Set ms, String source, Set targets) {
this.mods = Set.copyOf(ms);
this.source = source;
this.targets = Set.copyOf(targets);
}
private Opens(Set ms,
String source,
Set targets,
boolean unused) {
this.mods = ms;
this.source = source;
this.targets = targets;
}
/**
* Returns the set of modifiers.
*
* @return A possibly-empty unmodifiable set of modifiers
*/
public Set modifiers() {
return mods;
}
/**
* Returns {@code true} if this is a qualified {@code Opens}.
*
* @return {@code true} if this is a qualified {@code Opens}
*/
public boolean isQualified() {
return !targets.isEmpty();
}
/**
* Returns the package name.
*
* @return The package name
*/
public String source() {
return source;
}
/**
* For a qualified {@code Opens}, returns the non-empty and immutable set
* of the module names to which the package is open. For an
* unqualified {@code Opens}, returns an empty set.
*
* @return The set of target module names or for an unqualified
* {@code Opens}, an empty set
*/
public Set targets() {
return targets;
}
/**
* Compares this module {@code Opens} to another.
*
*
Two {@code Opens} objects are compared by comparing the package
* names lexicographically. Where the packages names are equal then the
* sets of modifiers are compared in the same way that module modifiers
* are compared (see {@link ModuleDescriptor#compareTo
* ModuleDescriptor.compareTo}). Where the package names are equal and
* the set of modifiers are equal then the set of target modules are
* compared. This is done by sorting the names of the target modules
* in ascending order, and according to their natural ordering, and then
* comparing the corresponding elements lexicographically. Where the
* sets differ in size, and the larger set contains all elements of the
* smaller set, then the larger set is considered to succeed the smaller
* set.
*
* @param that
* The module {@code Opens} to compare
*
* @return A negative integer, zero, or a positive integer if this module
* {@code Opens} is less than, equal to, or greater than the given
* module {@code Opens}
*/
@Override
public int compareTo(Opens that) {
if (this == that) return 0;
int c = source.compareTo(that.source);
if (c != 0)
return c;
// modifiers
long v1 = modsValue(this.modifiers());
long v2 = modsValue(that.modifiers());
c = Long.compare(v1, v2);
if (c != 0)
return c;
// targets
c = compare(targets, that.targets);
if (c != 0)
return c;
return 0;
}
/**
* Computes a hash code for this module {@code Opens}.
*
*
The hash code is based upon the modifiers, the package name,
* and for a qualified {@code Opens}, the set of modules names to which the
* package is opened. It satisfies the general contract of the
* {@link Object#hashCode Object.hashCode} method.
*
* @return The hash-code value for this module {@code Opens}
*/
@Override
public int hashCode() {
int hash = mods.hashCode();
hash = hash * 43 + source.hashCode();
return hash * 43 + targets.hashCode();
}
/**
* Tests this module {@code Opens} for equality with the given object.
*
*
If the given object is not an {@code Opens} then this method
* returns {@code false}. Two {@code Opens} objects are equal if their
* set of modifiers is equal, the package names are equal and the set
* of target module names is equal.
*
*
This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method.
*
* @param ob
* the object to which this object is to be compared
*
* @return {@code true} if, and only if, the given object is a module
* dependence that is equal to this module dependence
*/
@Override
public boolean equals(Object ob) {
return (ob instanceof Opens other)
&& Objects.equals(this.mods, other.mods)
&& Objects.equals(this.source, other.source)
&& Objects.equals(this.targets, other.targets);
}
/**
* Returns a string describing the open package.
*
* @return A string describing the open package
*/
@Override
public String toString() {
String s = ModuleDescriptor.toString(mods, source);
if (targets.isEmpty())
return s;
else
return s + " to " + targets;
}
}
/**
*
A service that a module provides one or more implementations of.
*
* @see ModuleDescriptor#provides()
* @since 9
*/
public static final class Provides
implements Comparable
{
private final String service;
private final List providers;
private Provides(String service, List providers) {
this.service = service;
this.providers = List.copyOf(providers);
}
private Provides(String service, List providers, boolean unused) {
this.service = service;
this.providers = providers;
}
/**
* Returns the fully qualified class name of the service type.
*
* @return The fully qualified class name of the service type
*/
public String service() { return service; }
/**
* Returns the list of the fully qualified class names of the providers
* or provider factories.
*
* @return A non-empty and unmodifiable list of the fully qualified class
* names of the providers or provider factories
*/
public List providers() { return providers; }
/**
* Compares this {@code Provides} to another.
*
*
Two {@code Provides} objects are compared by comparing the fully
* qualified class name of the service type lexicographically. Where the
* class names are equal then the list of the provider class names are
* compared by comparing the corresponding elements of both lists
* lexicographically and in sequence. Where the lists differ in size,
* {@code N} is the size of the shorter list, and the first {@code N}
* corresponding elements are equal, then the longer list is considered
* to succeed the shorter list.
*
* @param that
* The {@code Provides} to compare
*
* @return A negative integer, zero, or a positive integer if this
* {@code Provides} is less than, equal to, or greater than
* the given {@code Provides}
*/
public int compareTo(Provides that) {
if (this == that) return 0;
int c = service.compareTo(that.service);
if (c != 0) return c;
// compare provider class names in sequence
int size1 = this.providers.size();
int size2 = that.providers.size();
for (int index=0; index size2) ? 1 : -1;
}
}
/**
* Computes a hash code for this {@code Provides}.
*
*
The hash code is based upon the service type and the set of
* providers. It satisfies the general contract of the {@link
* Object#hashCode Object.hashCode} method.
*
* @return The hash-code value for this module provides
*/
@Override
public int hashCode() {
return service.hashCode() * 43 + providers.hashCode();
}
/**
* Tests this {@code Provides} for equality with the given object.
*
*
If the given object is not a {@code Provides} then this method
* returns {@code false}. Two {@code Provides} objects are equal if the
* service type is equal and the list of providers is equal.
*
*
This method satisfies the general contract of the {@link
* java.lang.Object#equals(Object) Object.equals} method.
*
* @param ob
* the object to which this object is to be compared
*
* @return {@code true} if, and only if, the given object is a
* {@code Provides} that is equal to this {@code Provides}
*/
@Override
public boolean equals(Object ob) {
return (ob instanceof Provides other)
&& Objects.equals(this.service, other.service)
&& Objects.equals(this.providers, other.providers);
}
/**
* Returns a string describing this {@code Provides}.
*
* @return A string describing this {@code Provides}
*/
@Override
public String toString() {
return service + " with " + providers;
}
}
/**
* A module's version string.
*
*
A version string has three components: The version number itself, an
* optional pre-release version, and an optional build version. Each
* component is a sequence of tokens; each token is either a non-negative
* integer or a string. Tokens are separated by the punctuation characters
* {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a
* sequence of digits to a sequence of characters that are neither digits
* nor punctuation characters, or vice versa.
*
*
*
*
The version number is a sequence of tokens separated by
* {@code '.'} characters, terminated by the first {@code '-'} or {@code
* '+'} character.
*
*
The pre-release version is a sequence of tokens separated
* by {@code '.'} or {@code '-'} characters, terminated by the first
* {@code '+'} character.
*
*
The build version is a sequence of tokens separated by
* {@code '.'}, {@code '-'}, or {@code '+'} characters.
*
*
*
*
When comparing two version strings, the elements of their
* corresponding components are compared in pointwise fashion. If one
* component is longer than the other, but otherwise equal to it, then the
* first component is considered the greater of the two; otherwise, if two
* corresponding elements are integers then they are compared as such;
* otherwise, at least one of the elements is a string, so the other is
* converted into a string if it is an integer and the two are compared
* lexicographically. Trailing integer elements with the value zero are
* ignored.
*
*
Given two version strings, if their version numbers differ then the
* result of comparing them is the result of comparing their version
* numbers; otherwise, if one of them has a pre-release version but the
* other does not then the first is considered to precede the second,
* otherwise the result of comparing them is the result of comparing their
* pre-release versions; otherwise, the result of comparing them is the
* result of comparing their build versions.
*
* @see ModuleDescriptor#version()
* @since 9
*/
public static final class Version
implements Comparable
{
private final String version;
// If Java had disjunctive types then we'd write List here
//
private final List