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.IOException; 29 import java.io.UncheckedIOException; 30 import java.net.URI; 31 import java.util.Objects; 32 import java.util.Optional; 33 import java.util.function.Supplier; 34 35 import jdk.internal.module.ModuleHashes.HashSupplier; 36 37 38 /** 39 * A reference to a module's content. 40 * 41 * <p> A module reference contains the module's descriptor and its location, if 42 * known. It also has the ability to create a {@link ModuleReader} in order to 43 * access the module's content, which may be inside the Java run-time system 44 * itself or in an artifact such as a modular JAR file. 45 * 46 * @see ModuleFinder 47 * @see ModuleReader 48 * @since 9 49 */ 50 51 public final class ModuleReference { 52 53 private final ModuleDescriptor descriptor; 54 private final URI location; 55 private final Supplier<ModuleReader> readerSupplier; 56 57 // true if this is a reference to a patched module 58 private boolean patched; 59 60 // the function that computes the hash of this module reference 61 private final HashSupplier hasher; 62 63 // cached hash to avoid needing to compute it many times 64 private byte[] cachedHash; 65 66 67 /** 68 * Constructs a new instance of this class. 69 */ 70 ModuleReference(ModuleDescriptor descriptor, 71 URI location, 72 Supplier<ModuleReader> readerSupplier, 73 boolean patched, 74 HashSupplier hasher) 75 76 { 77 this.descriptor = Objects.requireNonNull(descriptor); 78 this.location = location; 79 this.readerSupplier = Objects.requireNonNull(readerSupplier); 80 this.patched = patched; 81 this.hasher = hasher; 82 } 83 84 /** 85 * Constructs a new instance of this class. 86 */ 87 ModuleReference(ModuleDescriptor descriptor, 88 URI location, 89 Supplier<ModuleReader> readerSupplier, 90 HashSupplier hasher) 91 92 { 93 this(descriptor, location, readerSupplier, false, hasher); 94 } 95 96 97 /** 98 * Constructs a new instance of this class. 99 * 100 * <p> The {@code readSupplier} parameter is the supplier of the {@link 101 * ModuleReader} that may be used to read the module content. Its {@link 102 * Supplier#get() get()} method throws {@link UncheckedIOException} if an 103 * I/O error occurs opening the module content. The {@code get()} method 104 * throws {@link SecurityException} if opening the module is denied by the 105 * security manager. 106 * 107 * @param descriptor 108 * The module descriptor 109 * @param location 110 * The module location or {@code null} if not known 111 * @param readerSupplier 112 * The {@code Supplier} of the {@code ModuleReader} 113 */ 114 public ModuleReference(ModuleDescriptor descriptor, 115 URI location, 116 Supplier<ModuleReader> readerSupplier) 117 { 118 this(descriptor, location, readerSupplier, false, null); 119 } 120 121 /** 122 * Returns the module descriptor. 123 * 124 * @return The module descriptor 125 */ 126 public ModuleDescriptor descriptor() { 127 return descriptor; 128 } 129 130 131 /** 132 * Returns the location of this module's content, if known. 133 * 134 * <p> This URI, when present, is used as the {@linkplain 135 * java.security.CodeSource#getLocation location} value of a {@link 136 * java.security.CodeSource CodeSource} so that a module's classes can be 137 * granted specific permissions when loaded by a {@link 138 * java.security.SecureClassLoader SecureClassLoader}. 139 * 140 * @return The location or an empty {@code Optional} if not known 141 */ 142 public Optional<URI> location() { 143 return Optional.ofNullable(location); 144 } 145 146 147 /** 148 * Opens the module content for reading. 149 * 150 * <p> This method opens the module content by invoking the {@link 151 * Supplier#get() get()} method of the {@code readSupplier} specified at 152 * construction time. </p> 153 * 154 * @return A {@code ModuleReader} to read the module 155 * 156 * @throws IOException 157 * If an I/O error occurs 158 * @throws SecurityException 159 * If denied by the security manager 160 */ 161 public ModuleReader open() throws IOException { 162 try { 163 return readerSupplier.get(); 164 } catch (UncheckedIOException e) { 165 throw e.getCause(); 166 } 167 168 } 169 170 171 /** 172 * Returns {@code true} if this module has been patched via --patch-module. 173 */ 174 boolean isPatched() { 175 return patched; 176 } 177 178 /** 179 * Returns the hash supplier for this module. 180 */ 181 HashSupplier hasher() { 182 return hasher; 183 } 184 185 /** 186 * Computes the hash of this module. Returns {@code null} if the hash 187 * cannot be computed. 188 * 189 * @throws java.io.UncheckedIOException if an I/O error occurs 190 */ 191 byte[] computeHash(String algorithm) { 192 byte[] result = cachedHash; 193 if (result != null) 194 return result; 195 if (hasher == null) 196 return null; 197 cachedHash = result = hasher.generate(algorithm); 198 return result; 199 } 200 201 /** 202 * Computes a hash code for this module reference. 203 * 204 * <p> The hash code is based upon the components of the reference, and 205 * satisfies the general contract of the {@link Object#hashCode 206 * Object.hashCode} method. </p> 207 * 208 * @return The hash-code value for this module reference 209 */ 210 @Override 211 public int hashCode() { 212 int hc = hash; 213 if (hc == 0) { 214 hc = descriptor.hashCode(); 215 hc = 43 * hc + readerSupplier.hashCode(); 216 hc = 43 * hc + Objects.hashCode(location); 217 hc = 43 * hc + Objects.hashCode(hasher); 218 hc = 43 * hc + Boolean.hashCode(patched); 219 if (hc == 0) 220 hc = -1; 221 hash = hc; 222 } 223 return hc; 224 } 225 226 private int hash; 227 228 /** 229 * Tests this module reference for equality with the given object. 230 * 231 * <p> If the given object is not a {@code ModuleReference} then this 232 * method returns {@code false}. Two module references are equal if their 233 * module descriptors are equal, their locations are equal or both unknown, 234 * and were created with equal supplier objects to access the module 235 * content. </p> 236 * 237 * <p> This method satisfies the general contract of the {@link 238 * java.lang.Object#equals(Object) Object.equals} method. </p> 239 * 240 * @param ob 241 * the object to which this object is to be compared 242 * 243 * @return {@code true} if, and only if, the given object is a module 244 * reference that is equal to this module reference 245 */ 246 @Override 247 public boolean equals(Object ob) { 248 if (!(ob instanceof ModuleReference)) 249 return false; 250 ModuleReference that = (ModuleReference)ob; 251 252 return Objects.equals(this.descriptor, that.descriptor) 253 && Objects.equals(this.location, that.location) 254 && Objects.equals(this.readerSupplier, that.readerSupplier) 255 && Objects.equals(this.hasher, that.hasher) 256 && this.patched == that.patched; 257 } 258 259 /** 260 * Returns a string describing this module reference. 261 * 262 * @return A string describing this module reference 263 */ 264 @Override 265 public String toString() { 266 return ("[module " + descriptor().name() 267 + ", location=" + location + "]"); 268 } 269 270 } | 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.IOException; 29 import java.net.URI; 30 import java.util.Objects; 31 import java.util.Optional; 32 33 34 /** 35 * A reference to a module's content. 36 * 37 * <p> A module reference is a concrete implementation of this class that 38 * implements the abstract methods defined by this class. It contains the 39 * module's descriptor and its location, if known. It also has the ability to 40 * create a {@link ModuleReader} in order to access the module's content, which 41 * may be inside the Java run-time system itself or in an artifact such as a 42 * modular JAR file. 43 * 44 * @see ModuleFinder 45 * @see ModuleReader 46 * @since 9 47 */ 48 49 public abstract class ModuleReference { 50 51 private final ModuleDescriptor descriptor; 52 private final URI location; 53 54 /** 55 * Constructs a new instance of this class. 56 * 57 * @param descriptor 58 * The module descriptor 59 * @param location 60 * The module location or {@code null} if not known 61 */ 62 protected ModuleReference(ModuleDescriptor descriptor, URI location) { 63 this.descriptor = Objects.requireNonNull(descriptor); 64 this.location = location; 65 } 66 67 /** 68 * Returns the module descriptor. 69 * 70 * @return The module descriptor 71 */ 72 public final ModuleDescriptor descriptor() { 73 return descriptor; 74 } 75 76 /** 77 * Returns the location of this module's content, if known. 78 * 79 * <p> This URI, when present, is used as the {@linkplain 80 * java.security.CodeSource#getLocation location} value of a {@link 81 * java.security.CodeSource CodeSource} so that a module's classes can be 82 * granted specific permissions when loaded by a {@link 83 * java.security.SecureClassLoader SecureClassLoader}. 84 * 85 * @return The location or an empty {@code Optional} if not known 86 */ 87 public final Optional<URI> location() { 88 return Optional.ofNullable(location); 89 } 90 91 /** 92 * Opens the module content for reading. 93 * 94 * @return A {@code ModuleReader} to read the module 95 * 96 * @throws IOException 97 * If an I/O error occurs 98 * @throws SecurityException 99 * If denied by the security manager 100 */ 101 public abstract ModuleReader open() throws IOException; 102 } |