< 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 >