|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package jdk.internal.module; |
|
|
|
import java.io.IOException; |
|
import java.io.UncheckedIOException; |
|
import java.lang.module.ModuleDescriptor; |
|
import java.lang.module.ModuleReader; |
|
import java.lang.module.ModuleReference; |
|
import java.net.URI; |
|
import java.util.Objects; |
|
import java.util.function.Supplier; |
|
|
|
/** |
|
* A ModuleReference implementation that supports referencing a module that |
|
* is patched and/or can be tied to other modules by means of hashes. |
|
*/ |
|
|
|
public class ModuleReferenceImpl extends ModuleReference { |
|
|
|
|
|
private final URI location; |
|
|
|
|
|
private final Supplier<ModuleReader> readerSupplier; |
|
|
|
|
|
private final ModulePatcher patcher; |
|
|
|
|
|
private final ModuleTarget target; |
|
|
|
|
|
private final ModuleHashes recordedHashes; |
|
|
|
|
|
private final ModuleHashes.HashSupplier hasher; |
|
|
|
|
|
private final ModuleResolution moduleResolution; |
|
|
|
|
|
private byte[] cachedHash; |
|
|
|
|
|
|
|
*/ |
|
public ModuleReferenceImpl(ModuleDescriptor descriptor, |
|
URI location, |
|
Supplier<ModuleReader> readerSupplier, |
|
ModulePatcher patcher, |
|
ModuleTarget target, |
|
ModuleHashes recordedHashes, |
|
ModuleHashes.HashSupplier hasher, |
|
ModuleResolution moduleResolution) |
|
{ |
|
super(descriptor, Objects.requireNonNull(location)); |
|
this.location = location; |
|
this.readerSupplier = readerSupplier; |
|
this.patcher = patcher; |
|
this.target = target; |
|
this.recordedHashes = recordedHashes; |
|
this.hasher = hasher; |
|
this.moduleResolution = moduleResolution; |
|
} |
|
|
|
@Override |
|
public ModuleReader open() throws IOException { |
|
try { |
|
return readerSupplier.get(); |
|
} catch (UncheckedIOException e) { |
|
throw e.getCause(); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
public boolean isPatched() { |
|
return (patcher != null); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ModuleTarget moduleTarget() { |
|
return target; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public ModuleHashes recordedHashes() { |
|
return recordedHashes; |
|
} |
|
|
|
|
|
|
|
*/ |
|
ModuleHashes.HashSupplier hasher() { |
|
return hasher; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ModuleResolution moduleResolution() { |
|
return moduleResolution; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public byte[] computeHash(String algorithm) { |
|
byte[] result = cachedHash; |
|
if (result != null) |
|
return result; |
|
if (hasher == null) |
|
return null; |
|
cachedHash = result = hasher.generate(algorithm); |
|
return result; |
|
} |
|
|
|
@Override |
|
public int hashCode() { |
|
int hc = hash; |
|
if (hc == 0) { |
|
hc = descriptor().hashCode(); |
|
hc = 43 * hc + Objects.hashCode(location); |
|
hc = 43 * hc + Objects.hashCode(patcher); |
|
if (hc == 0) |
|
hc = -1; |
|
hash = hc; |
|
} |
|
return hc; |
|
} |
|
|
|
private int hash; |
|
|
|
@Override |
|
public boolean equals(Object ob) { |
|
if (!(ob instanceof ModuleReferenceImpl)) |
|
return false; |
|
ModuleReferenceImpl that = (ModuleReferenceImpl)ob; |
|
|
|
// assume module content, recorded hashes, etc. are the same |
|
// when the modules have equal module descriptors, are at the |
|
|
|
return Objects.equals(this.descriptor(), that.descriptor()) |
|
&& Objects.equals(this.location, that.location) |
|
&& Objects.equals(this.patcher, that.patcher); |
|
} |
|
|
|
@Override |
|
public String toString() { |
|
StringBuilder sb = new StringBuilder(); |
|
sb.append("[module "); |
|
sb.append(descriptor().name()); |
|
sb.append(", location="); |
|
sb.append(location); |
|
if (isPatched()) sb.append(" (patched)"); |
|
sb.append("]"); |
|
return sb.toString(); |
|
} |
|
|
|
} |