ModuleReferenceImpl.java revision 16909:085c764a3e5b
1193323Sed/* 2193323Sed * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3193323Sed * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4193323Sed * 5193323Sed * This code is free software; you can redistribute it and/or modify it 6193323Sed * under the terms of the GNU General Public License version 2 only, as 7193323Sed * published by the Free Software Foundation. Oracle designates this 8193323Sed * particular file as subject to the "Classpath" exception as provided 9193323Sed * by Oracle in the LICENSE file that accompanied this code. 10193323Sed * 11193323Sed * This code is distributed in the hope that it will be useful, but WITHOUT 12193323Sed * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13193323Sed * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14193323Sed * version 2 for more details (a copy is included in the LICENSE file that 15193323Sed * accompanied this code). 16234353Sdim * 17249423Sdim * You should have received a copy of the GNU General Public License version 18249423Sdim * 2 along with this work; if not, write to the Free Software Foundation, 19249423Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20263508Sdim * 21193323Sed * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22249423Sdim * or visit www.oracle.com if you need additional information or have any 23193323Sed * questions. 24193323Sed */ 25193323Sed 26206274Srdivackypackage jdk.internal.module; 27193323Sed 28193323Sedimport java.io.IOException; 29249423Sdimimport java.io.UncheckedIOException; 30249423Sdimimport java.lang.module.ModuleDescriptor; 31249423Sdimimport java.lang.module.ModuleReader; 32203954Srdivackyimport java.lang.module.ModuleReference; 33203954Srdivackyimport java.net.URI; 34202375Srdivackyimport java.util.Objects; 35249423Sdimimport java.util.function.Supplier; 36249423Sdim 37249423Sdim/** 38195340Sed * A ModuleReference implementation that supports referencing a module that 39193323Sed * is patched and/or can be tied to other modules by means of hashes. 40193323Sed */ 41193323Sed 42203954Srdivackypublic class ModuleReferenceImpl extends ModuleReference { 43193323Sed 44203954Srdivacky private final Supplier<ModuleReader> readerSupplier; 45193323Sed 46198090Srdivacky // non-null if the module is patched 47198090Srdivacky private final ModulePatcher patcher; 48198090Srdivacky 49193323Sed // ModuleTarget if the module is OS/architecture specific 50193323Sed private final ModuleTarget target; 51193323Sed 52193323Sed // the hashes of other modules recorded in this module 53207618Srdivacky private final ModuleHashes recordedHashes; 54218893Sdim 55218893Sdim // the function that computes the hash of this module 56218893Sdim private final ModuleHashes.HashSupplier hasher; 57193323Sed 58263508Sdim // ModuleResolution flags 59193323Sed private final ModuleResolution moduleResolution; 60193323Sed 61263508Sdim // cached hash of this module to avoid needing to compute it many times 62193323Sed private byte[] cachedHash; 63263508Sdim 64263508Sdim /** 65263508Sdim * Constructs a new instance of this class. 66249423Sdim */ 67249423Sdim ModuleReferenceImpl(ModuleDescriptor descriptor, 68243830Sdim URI location, 69249423Sdim Supplier<ModuleReader> readerSupplier, 70263508Sdim ModulePatcher patcher, 71263508Sdim ModuleTarget target, 72223017Sdim ModuleHashes recordedHashes, 73263508Sdim ModuleHashes.HashSupplier hasher, 74223017Sdim ModuleResolution moduleResolution) 75249423Sdim { 76249423Sdim super(descriptor, Objects.requireNonNull(location)); 77223017Sdim this.readerSupplier = readerSupplier; 78223017Sdim this.patcher = patcher; 79263508Sdim this.target = target; 80203954Srdivacky this.recordedHashes = recordedHashes; 81203954Srdivacky this.hasher = hasher; 82193323Sed this.moduleResolution = moduleResolution; 83193323Sed } 84193323Sed 85249423Sdim @Override 86249423Sdim public ModuleReader open() throws IOException { 87249423Sdim try { 88249423Sdim return readerSupplier.get(); 89249423Sdim } catch (UncheckedIOException e) { 90249423Sdim throw e.getCause(); 91249423Sdim } 92193323Sed } 93249423Sdim 94193323Sed /** 95195098Sed * Returns {@code true} if this module has been patched via --patch-module. 96195098Sed */ 97195098Sed public boolean isPatched() { 98195098Sed return (patcher != null); 99193323Sed } 100195098Sed 101195098Sed /** 102193323Sed * Returns the ModuleTarget or {@code null} if the no target platform. 103239462Sdim */ 104239462Sdim public ModuleTarget moduleTarget() { 105239462Sdim return target; 106239462Sdim } 107239462Sdim 108239462Sdim /** 109239462Sdim * Returns the hashes recorded in this module or {@code null} if there 110203954Srdivacky * are no hashes recorded. 111203954Srdivacky */ 112203954Srdivacky public ModuleHashes recordedHashes() { 113203954Srdivacky return recordedHashes; 114193323Sed } 115193323Sed 116203954Srdivacky /** 117203954Srdivacky * Returns the supplier that computes the hash of this module. 118203954Srdivacky */ 119203954Srdivacky ModuleHashes.HashSupplier hasher() { 120203954Srdivacky return hasher; 121239462Sdim } 122205407Srdivacky 123203954Srdivacky /** 124203954Srdivacky * Returns the ModuleResolution flags. 125203954Srdivacky */ 126193323Sed public ModuleResolution moduleResolution() { 127193323Sed return moduleResolution; 128193323Sed } 129193323Sed 130193323Sed /** 131193323Sed * Computes the hash of this module. Returns {@code null} if the hash 132193323Sed * cannot be computed. 133193323Sed * 134193323Sed * @throws java.io.UncheckedIOException if an I/O error occurs 135193323Sed */ 136193323Sed public byte[] computeHash(String algorithm) { 137193323Sed byte[] result = cachedHash; 138193323Sed if (result != null) 139239462Sdim return result; 140193323Sed if (hasher == null) 141193323Sed return null; 142193323Sed cachedHash = result = hasher.generate(algorithm); 143193323Sed return result; 144239462Sdim } 145193323Sed 146193323Sed @Override 147193323Sed public int hashCode() { 148193323Sed int hc = hash; 149193323Sed if (hc == 0) { 150193323Sed hc = descriptor().hashCode(); 151193323Sed hc = 43 * hc + Objects.hashCode(location()); 152193323Sed hc = 43 * hc + Objects.hashCode(patcher); 153239462Sdim if (hc == 0) 154193323Sed hc = -1; 155193323Sed hash = hc; 156193323Sed } 157193323Sed return hc; 158193323Sed } 159193323Sed 160193323Sed private int hash; 161239462Sdim 162193323Sed @Override 163193323Sed public boolean equals(Object ob) { 164193323Sed if (!(ob instanceof ModuleReferenceImpl)) 165193323Sed return false; 166193323Sed ModuleReferenceImpl that = (ModuleReferenceImpl)ob; 167193323Sed 168193323Sed // assume module content, recorded hashes, etc. are the same 169193323Sed // when the modules have equal module descriptors, are at the 170193323Sed // same location, and are patched by the same patcher. 171193323Sed return Objects.equals(this.descriptor(), that.descriptor()) 172193323Sed && Objects.equals(this.location(), that.location()) 173224145Sdim && Objects.equals(this.patcher, that.patcher); 174193323Sed } 175193323Sed 176249423Sdim @Override 177193323Sed public String toString() { 178193323Sed StringBuilder sb = new StringBuilder(); 179193323Sed sb.append("[module "); 180203954Srdivacky sb.append(descriptor().name()); 181193323Sed sb.append(", location="); 182193323Sed sb.append(location().orElseThrow(() -> new InternalError())); 183193323Sed if (isPatched()) sb.append(" (patched)"); 184193323Sed sb.append("]"); 185193323Sed return sb.toString(); 186193323Sed } 187193323Sed 188193323Sed} 189193323Sed