< prev index next >
src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
Print this page
@@ -177,26 +177,30 @@
}
private final Set<Modifier> mods;
private final String name;
private final Version compiledVersion;
+ private final String rawCompiledVersion;
- private Requires(Set<Modifier> ms, String mn, Version v) {
+ private Requires(Set<Modifier> ms, String mn, Version v, String vs) {
+ assert v == null || vs == null;
if (ms.isEmpty()) {
ms = Collections.emptySet();
} else {
ms = Collections.unmodifiableSet(EnumSet.copyOf(ms));
}
this.mods = ms;
this.name = mn;
this.compiledVersion = v;
+ this.rawCompiledVersion = vs;
}
private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
this.mods = ms;
this.name = mn;
this.compiledVersion = v;
+ this.rawCompiledVersion = null;
}
/**
* Returns the set of modifiers.
*
@@ -216,17 +220,37 @@
}
/**
* Returns the version of the module if recorded at compile-time.
*
- * @return 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<Version> 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
+ *
+ * @see #compiledVersion()
+ */
+ public Optional<String> rawCompiledVersion() {
+ if (compiledVersion != null) {
+ return Optional.of(compiledVersion.toString());
+ } else {
+ return Optional.ofNullable(rawCompiledVersion);
+ }
+ }
+
+ /**
* Compares this module dependence to another.
*
* <p> 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
@@ -234,11 +258,14 @@
* 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. </p>
+ * recorded version. If both recorded versions are {@linkplain
+ * Version#parse(String) unparseable} then the {@linkplain
+ * #rawCompiledVersion() raw version strings} are compared
+ * lexicographically. </p>
*
* @param that
* The module dependence to compare
*
* @return A negative integer, zero, or a positive integer if this module
@@ -260,10 +287,14 @@
// 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.
@@ -287,11 +318,12 @@
public boolean equals(Object ob) {
if (!(ob instanceof Requires))
return false;
Requires that = (Requires)ob;
return name.equals(that.name) && mods.equals(that.mods)
- && Objects.equals(compiledVersion, that.compiledVersion);
+ && Objects.equals(compiledVersion, that.compiledVersion)
+ && Objects.equals(rawCompiledVersion, that.rawCompiledVersion);
}
/**
* Computes a hash code for this module dependence.
*
@@ -304,10 +336,12 @@
@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.
@@ -772,11 +806,11 @@
}
/**
* Returns the fully qualified class name of the service type.
*
- * @return 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
@@ -1197,40 +1231,38 @@
}
private final String name;
private final Version version;
+ private final String rawVersionString;
private final Set<Modifier> modifiers;
private final boolean open; // true if modifiers contains OPEN
private final boolean automatic; // true if modifiers contains AUTOMATIC
private final Set<Requires> requires;
private final Set<Exports> exports;
private final Set<Opens> opens;
private final Set<String> uses;
private final Set<Provides> provides;
private final Set<String> packages;
private final String mainClass;
- private final String osName;
- private final String osArch;
- private final String osVersion;
private ModuleDescriptor(String name,
Version version,
+ String rawVersionString,
Set<Modifier> modifiers,
Set<Requires> requires,
Set<Exports> exports,
Set<Opens> opens,
Set<String> uses,
Set<Provides> provides,
Set<String> packages,
- String mainClass,
- String osName,
- String osArch,
- String osVersion)
+ String mainClass)
{
+ assert version == null || rawVersionString == null;
this.name = name;
this.version = version;
+ this.rawVersionString = rawVersionString;
this.modifiers = emptyOrUnmodifiableSet(modifiers);
this.open = modifiers.contains(Modifier.OPEN);
this.automatic = modifiers.contains(Modifier.AUTOMATIC);
assert (requires.stream().map(Requires::name).distinct().count()
== requires.size());
@@ -1240,13 +1272,10 @@
this.uses = emptyOrUnmodifiableSet(uses);
this.provides = emptyOrUnmodifiableSet(provides);
this.packages = emptyOrUnmodifiableSet(packages);
this.mainClass = mainClass;
- this.osName = osName;
- this.osArch = osArch;
- this.osVersion = osVersion;
}
/**
* Creates a module descriptor from its components.
* The arguments are pre-validated and sets are unmodifiable sets.
@@ -1259,30 +1288,25 @@
Set<Opens> opens,
Set<String> uses,
Set<Provides> provides,
Set<String> packages,
String mainClass,
- String osName,
- String osArch,
- String osVersion,
int hashCode,
boolean unused) {
this.name = name;
this.version = version;
+ this.rawVersionString = null;
this.modifiers = modifiers;
this.open = modifiers.contains(Modifier.OPEN);
this.automatic = modifiers.contains(Modifier.AUTOMATIC);
this.requires = requires;
this.exports = exports;
this.opens = opens;
this.uses = uses;
this.provides = provides;
this.packages = packages;
this.mainClass = mainClass;
- this.osName = osName;
- this.osArch = osArch;
- this.osVersion = osVersion;
this.hash = hashCode;
}
/**
* <p> Returns the module name. </p>
@@ -1392,22 +1416,40 @@
}
/**
* <p> Returns the module version. </p>
*
- * @return This module's version
+ * @return This module's version, or an empty {@code Optional} if the
+ * module does not have a version or the version is
+ * {@linkplain Version#parse(String) unparseable}
*/
public Optional<Version> version() {
return Optional.ofNullable(version);
}
/**
+ * <p> Returns the string with the possibly-unparseable version of the
+ * module </p>
+ *
+ * @return The string containing the version of the module
+ *
+ * @see #version()
+ */
+ public Optional<String> rawVersion() {
+ if (version != null) {
+ return Optional.of(version.toString());
+ } else {
+ return Optional.ofNullable(rawVersionString);
+ }
+ }
+
+ /**
* <p> Returns a string containing the module name and, if present, its
* version. </p>
*
* @return A string containing the module name and, if present, its
- * version.
+ * version
*/
public String toNameAndVersion() {
if (version != null) {
return name() + "@" + version;
} else {
@@ -1423,45 +1465,16 @@
public Optional<String> mainClass() {
return Optional.ofNullable(mainClass);
}
/**
- * Returns the operating system name if the module is operating system
- * specific.
- *
- * @return The operating system name or an empty {@code Optional}
- * if the module is not operating system specific
- */
- public Optional<String> osName() {
- return Optional.ofNullable(osName);
- }
-
- /**
- * Returns the operating system architecture if the module is operating
- * system architecture specific.
- *
- * @return The operating system architecture or an empty {@code Optional}
- * if the module is not operating system architecture specific
- */
- public Optional<String> osArch() {
- return Optional.ofNullable(osArch);
- }
-
- /**
- * Returns the operating system version if the module is operating
- * system version specific.
- *
- * @return The operating system version or an empty {@code Optional}
- * if the module is not operating system version specific
- */
- public Optional<String> osVersion() {
- return Optional.ofNullable(osVersion);
- }
-
- /**
* Returns the set of packages in the module.
*
+ * <p> The set of packages includes all exported and open packages, as well
+ * as the packages of any service providers, and the package for the main
+ * class. </p>
+ *
* @return A possibly-empty unmodifiable set of the packages in the module
*/
public Set<String> packages() {
return packages;
}
@@ -1516,13 +1529,11 @@
final Map<String, Exports> exports = new HashMap<>();
final Map<String, Opens> opens = new HashMap<>();
final Set<String> uses = new HashSet<>();
final Map<String, Provides> provides = new HashMap<>();
Version version;
- String osName;
- String osArch;
- String osVersion;
+ String rawVersionString;
String mainClass;
/**
* Initializes a new builder with the given module name.
*
@@ -1602,28 +1613,25 @@
String mn,
Version compiledVersion) {
Objects.requireNonNull(compiledVersion);
if (strict)
mn = requireModuleName(mn);
- return requires(new Requires(ms, mn, compiledVersion));
+ return requires(new Requires(ms, mn, compiledVersion, null));
}
/* package */Builder requires(Set<Requires.Modifier> ms,
String mn,
- String compiledVersion) {
- Version v = null;
+ String rawCompiledVersion) {
+ Requires r;
try {
- v = Version.parse(compiledVersion);
+ Version v = Version.parse(rawCompiledVersion);
+ r = new Requires(ms, mn, v, null);
} catch (IllegalArgumentException e) {
- // for now, drop un-parsable version when non-strict
if (strict) throw e;
+ r = new Requires(ms, mn, null, rawCompiledVersion);
}
- if (v == null) {
- return requires(ms, mn);
- } else {
- return requires(ms, mn, v);
- }
+ return requires(r);
}
/**
* Adds a dependence on a module with the given (and possibly empty)
* set of modifiers.
@@ -1644,11 +1652,11 @@
* or this builder is for an automatic module
*/
public Builder requires(Set<Requires.Modifier> ms, String mn) {
if (strict)
mn = requireModuleName(mn);
- return requires(new Requires(ms, mn, null));
+ return requires(new Requires(ms, mn, null, null));
}
/**
* Adds a dependence on a module with an empty set of modifiers.
*
@@ -1950,11 +1958,11 @@
* @throws IllegalArgumentException
* If the service type is {@code null} or not a qualified name of
* a class in a named package
* @throws IllegalStateException
* If a dependency on the service type has already been declared
- * or this is a builder for an an automatic module
+ * or this is a builder for an automatic module
*/
public Builder uses(String service) {
if (automatic)
throw new IllegalStateException("Automatic modules can not declare"
+ " service dependences");
@@ -2066,10 +2074,11 @@
*
* @return This builder
*/
public Builder version(Version v) {
version = requireNonNull(v);
+ rawVersionString = null;
return this;
}
/**
* Sets the module version.
@@ -2084,22 +2093,19 @@
* version string
*
* @see Version#parse(String)
*/
public Builder version(String vs) {
- Version v;
- if (strict) {
- v = Version.parse(vs);
- } else {
try {
- v = Version.parse(vs);
- } catch (IllegalArgumentException ignore) {
- // for now, ignore when non-strict
- return this;
- }
+ version = Version.parse(vs);
+ rawVersionString = null;
+ } catch (IllegalArgumentException e) {
+ if (strict) throw e;
+ version = null;
+ rawVersionString = vs;
}
- return version(v);
+ return this;
}
/**
* Sets the module main class. The package for the main class is added
* to the module if not already added.
@@ -2130,64 +2136,10 @@
packages.add(pn);
return this;
}
/**
- * Sets the operating system name.
- *
- * @param name
- * The operating system name
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osName(String name) {
- if (name == null || name.isEmpty())
- throw new IllegalArgumentException("OS name is null or empty");
- osName = name;
- return this;
- }
-
- /**
- * Sets the operating system architecture.
- *
- * @param arch
- * The operating system architecture
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osArch(String arch) {
- if (arch == null || arch.isEmpty())
- throw new IllegalArgumentException("OS arch is null or empty");
- osArch = arch;
- return this;
- }
-
- /**
- * Sets the operating system version.
- *
- * @param version
- * The operating system version
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If {@code name} is {@code null} or the empty String
- */
- public Builder osVersion(String version) {
- if (version == null || version.isEmpty())
- throw new IllegalArgumentException("OS version is null or empty");
- osVersion = version;
- return this;
- }
-
- /**
* Builds and returns a {@code ModuleDescriptor} from its components.
*
* <p> The module will require "{@code java.base}" even if the dependence
* has not been declared (the exception is when building a module named
* "{@code java.base}" as it cannot require itself). The dependence on
@@ -2206,28 +2158,27 @@
if (strict
&& !name.equals("java.base")
&& !this.requires.containsKey("java.base")) {
requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
"java.base",
+ null,
null));
}
Set<Provides> provides = new HashSet<>(this.provides.values());
return new ModuleDescriptor(name,
version,
+ rawVersionString,
modifiers,
requires,
exports,
opens,
uses,
provides,
packages,
- mainClass,
- osName,
- osArch,
- osVersion);
+ mainClass);
}
}
/**
@@ -2235,13 +2186,15 @@
*
* <p> Two {@code ModuleDescriptor} objects are compared by comparing their
* module names lexicographically. Where the module names are equal then the
* module versions are compared. When comparing the module versions then a
* module descriptor with a version is considered to succeed a module
- * descriptor that does not have a version. Where the module names are equal
- * and the versions are equal (or not present in both), then the set of
- * modifiers are compared. Sets of modifiers are compared by comparing
+ * descriptor that does not have a version. If both versions are {@linkplain
+ * Version#parse(String) unparseable} then the {@linkplain #rawVersion()
+ * raw version strings} are compared lexicographically. Where the module names
+ * are equal and the versions are equal (or not present in both), then the
+ * set of modifiers are compared. Sets of modifiers are compared by comparing
* a <em>binary value</em> computed for each set. If a modifier is present
* in the set then the bit at the position of its ordinal is {@code 1}
* in the binary value, otherwise {@code 0}. If the two set of modifiers
* are also equal then the other components of the module descriptors are
* compared in a manner that is consistent with {@code equals}. </p>
@@ -2261,10 +2214,13 @@
if (c != 0) return c;
c = compare(this.version, that.version);
if (c != 0) return c;
+ c = compare(this.rawVersionString, that.rawVersionString);
+ if (c != 0) return c;
+
long v1 = modsValue(this.modifiers());
long v2 = modsValue(that.modifiers());
c = Long.compare(v1, v2);
if (c != 0) return c;
@@ -2287,19 +2243,10 @@
if (c != 0) return c;
c = compare(this.mainClass, that.mainClass);
if (c != 0) return c;
- c = compare(this.osName, that.osName);
- if (c != 0) return c;
-
- c = compare(this.osArch, that.osArch);
- if (c != 0) return c;
-
- c = compare(this.osVersion, that.osVersion);
- if (c != 0) return c;
-
return 0;
}
/**
* Tests this module descriptor for equality with the given object.
@@ -2331,14 +2278,12 @@
&& exports.equals(that.exports)
&& opens.equals(that.opens)
&& uses.equals(that.uses)
&& provides.equals(that.provides)
&& Objects.equals(version, that.version)
- && Objects.equals(mainClass, that.mainClass)
- && Objects.equals(osName, that.osName)
- && Objects.equals(osArch, that.osArch)
- && Objects.equals(osVersion, that.osVersion));
+ && Objects.equals(rawVersionString, that.rawVersionString)
+ && Objects.equals(mainClass, that.mainClass));
}
/**
* Computes a hash code for this module descriptor.
*
@@ -2359,14 +2304,12 @@
hc = hc * 43 + exports.hashCode();
hc = hc * 43 + opens.hashCode();
hc = hc * 43 + uses.hashCode();
hc = hc * 43 + provides.hashCode();
hc = hc * 43 + Objects.hashCode(version);
+ hc = hc * 43 + Objects.hashCode(rawVersionString);
hc = hc * 43 + Objects.hashCode(mainClass);
- hc = hc * 43 + Objects.hashCode(osName);
- hc = hc * 43 + Objects.hashCode(osArch);
- hc = hc * 43 + Objects.hashCode(osVersion);
if (hc == 0)
hc = -1;
hash = hc;
}
return hc;
@@ -2711,12 +2654,12 @@
@Override
public void requires(ModuleDescriptor.Builder builder,
Set<Requires.Modifier> ms,
String mn,
- String compiledVersion) {
- builder.requires(ms, mn, compiledVersion);
+ String rawCompiledVersion) {
+ builder.requires(ms, mn, rawCompiledVersion);
}
@Override
public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
return new Requires(ms, mn, v, true);
@@ -2760,13 +2703,10 @@
Set<Opens> opens,
Set<String> uses,
Set<Provides> provides,
Set<String> packages,
String mainClass,
- String osName,
- String osArch,
- String osVersion,
int hashCode) {
return new ModuleDescriptor(name,
version,
modifiers,
requires,
@@ -2774,13 +2714,10 @@
opens,
uses,
provides,
packages,
mainClass,
- osName,
- osArch,
- osVersion,
hashCode,
false);
}
@Override
< prev index next >