src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
Print this page
*** 26,35 ****
--- 26,36 ----
package org.openjdk.jigsaw;
import java.lang.module.*;
import java.io.*;
import java.net.URI;
+ import java.nio.file.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
*** 68,79 ****
protected final int maxMajorVersion;
protected final int maxMinorVersion;
protected int majorVersion;
protected int minorVersion;
! private FileConstants.Type type;
! private File file;
protected MetaData(int maxMajor, int maxMinor,
FileConstants.Type t, File f)
{
maxMajorVersion = majorVersion = maxMajor;
--- 69,80 ----
protected final int maxMajorVersion;
protected final int maxMinorVersion;
protected int majorVersion;
protected int minorVersion;
! private final FileConstants.Type type;
! private final File file;
protected MetaData(int maxMajor, int maxMinor,
FileConstants.Type t, File f)
{
maxMajorVersion = majorVersion = maxMajor;
*** 84,120 ****
protected abstract void storeRest(DataOutputStream out)
throws IOException;
void store() throws IOException {
! OutputStream fo = new FileOutputStream(file);
! DataOutputStream out
! = new DataOutputStream(new BufferedOutputStream(fo));
! try {
out.writeInt(FileConstants.MAGIC);
out.writeShort(type.value());
out.writeShort(majorVersion);
out.writeShort(minorVersion);
storeRest(out);
- } finally {
- out.close();
}
}
protected abstract void loadRest(DataInputStream in)
throws IOException;
protected void load() throws IOException {
! InputStream fi = new FileInputStream(file);
! try {
! DataInputStream in
! = new DataInputStream(new BufferedInputStream(fi));
! int m = in.readInt();
! if (m != FileConstants.MAGIC)
throw new IOException(file + ": Invalid magic number");
! int typ = in.readShort();
! if (typ != type.value())
throw new IOException(file + ": Invalid file type");
int maj = in.readShort();
int min = in.readShort();
if ( maj > maxMajorVersion
|| (maj == maxMajorVersion && min > maxMinorVersion)) {
--- 85,115 ----
protected abstract void storeRest(DataOutputStream out)
throws IOException;
void store() throws IOException {
! try (OutputStream fos = new FileOutputStream(file);
! BufferedOutputStream bos = new BufferedOutputStream(fos);
! DataOutputStream out = new DataOutputStream(bos)) {
out.writeInt(FileConstants.MAGIC);
out.writeShort(type.value());
out.writeShort(majorVersion);
out.writeShort(minorVersion);
storeRest(out);
}
}
protected abstract void loadRest(DataInputStream in)
throws IOException;
protected void load() throws IOException {
! try (InputStream fis = new FileInputStream(file);
! BufferedInputStream bis = new BufferedInputStream(fis);
! DataInputStream in = new DataInputStream(fis)) {
! if (in.readInt() != FileConstants.MAGIC)
throw new IOException(file + ": Invalid magic number");
! if (in.readShort() != type.value())
throw new IOException(file + ": Invalid file type");
int maj = in.readShort();
int min = in.readShort();
if ( maj > maxMajorVersion
|| (maj == maxMajorVersion && min > maxMinorVersion)) {
*** 123,139 ****
}
majorVersion = maj;
minorVersion = min;
loadRest(in);
} catch (EOFException x) {
! throw new IOException(file + ": Invalid library metadata",
! x);
! } finally {
! fi.close();
}
}
-
}
/**
* Defines the storage options that SimpleLibrary supports.
*/
--- 118,130 ----
}
majorVersion = maj;
minorVersion = min;
loadRest(in);
} catch (EOFException x) {
! throw new IOException(file + ": Invalid library metadata", x);
}
}
}
/**
* Defines the storage options that SimpleLibrary supports.
*/
*** 151,224 ****
private static final int MINOR_VERSION = 1;
private static final int DEFLATED = 1 << 0;
private File parent;
private Set<StorageOption> opts;
public File parent() { return parent; }
public boolean isDeflated() {
return opts.contains(StorageOption.DEFLATED);
}
! private Header(File root, File p, Set<StorageOption> opts) {
super(MAJOR_VERSION, MINOR_VERSION,
FileConstants.Type.LIBRARY_HEADER,
new File(root, FILE));
! this.parent = p;
this.opts = new HashSet<>(opts);
}
! private Header(File root) {
! this(root, null, Collections.<StorageOption>emptySet());
}
! protected void storeRest(DataOutputStream out)
! throws IOException
! {
int flags = 0;
if (isDeflated())
flags |= DEFLATED;
out.writeShort(flags);
! out.writeByte((parent != null) ? 1 : 0);
! if (parent != null)
! out.writeUTF(parent.toString());
}
! protected void loadRest(DataInputStream in)
! throws IOException
! {
opts = new HashSet<StorageOption>();
int flags = in.readShort();
if ((flags & DEFLATED) == DEFLATED)
opts.add(StorageOption.DEFLATED);
! int b = in.readByte();
! if (b != 0)
! parent = new File(in.readUTF());
}
! private static Header load(File f)
! throws IOException
! {
Header h = new Header(f);
h.load();
return h;
}
-
}
private final File root;
private final File canonicalRoot;
! private File parentPath = null;
! private SimpleLibrary parent = null;
private final Header hd;
public String name() { return root.toString(); }
public File root() { return canonicalRoot; }
public int majorVersion() { return hd.majorVersion; }
public int minorVersion() { return hd.minorVersion; }
public SimpleLibrary parent() { return parent; }
public boolean isDeflated() { return hd.isDeflated(); }
private URI location = null;
public URI location() {
if (location == null)
--- 142,247 ----
private static final int MINOR_VERSION = 1;
private static final int DEFLATED = 1 << 0;
private File parent;
+ // location of native libs for this library (may be outside the library)
+ // null:default, to use a per-module 'lib' directory
+ private File natlibs;
+ // location of native cmds for this library (may be outside the library)
+ // null:default, to use a per-module 'bin' directory
+ private File natcmds;
+ // location of config files for this library (may be outside the library)
+ // null:default, to use a per-module 'etc' directory
+ private File configs;
private Set<StorageOption> opts;
public File parent() { return parent; }
+ public File natlibs() { return natlibs; }
+ public File natcmds() { return natcmds; }
+ public File configs() { return configs; }
public boolean isDeflated() {
return opts.contains(StorageOption.DEFLATED);
}
! private Header(File root) {
super(MAJOR_VERSION, MINOR_VERSION,
FileConstants.Type.LIBRARY_HEADER,
new File(root, FILE));
! }
!
! private Header(File root, File parent, File natlibs, File natcmds,
! File configs, Set<StorageOption> opts) {
! this(root);
! this.parent = parent;
! this.natlibs = natlibs;
! this.natcmds = natcmds;
! this.configs = configs;
this.opts = new HashSet<>(opts);
}
! private void storePath(File p, DataOutputStream out) throws IOException {
! if (p != null) {
! out.writeByte(1);
! out.writeUTF(Files.convertSeparator(p.toString()));
! } else
! out.write(0);
}
! protected void storeRest(DataOutputStream out) throws IOException {
int flags = 0;
if (isDeflated())
flags |= DEFLATED;
out.writeShort(flags);
!
! storePath(parent, out);
! storePath(natlibs, out);
! storePath(natcmds, out);
! storePath(configs, out);
}
! private File loadPath(DataInputStream in) throws IOException {
! if (in.readByte() != 0)
! return new File(Files.platformSeparator(in.readUTF()));
! return null;
! }
!
! protected void loadRest(DataInputStream in) throws IOException {
opts = new HashSet<StorageOption>();
int flags = in.readShort();
if ((flags & DEFLATED) == DEFLATED)
opts.add(StorageOption.DEFLATED);
! parent = loadPath(in);
! natlibs = loadPath(in);
! natcmds = loadPath(in);
! configs = loadPath(in);
}
! private static Header load(File f) throws IOException {
Header h = new Header(f);
h.load();
return h;
}
}
private final File root;
private final File canonicalRoot;
! private File parentPath;
! private File natlibs;
! private File natcmds;
! private File configs;
! private SimpleLibrary parent;
private final Header hd;
public String name() { return root.toString(); }
public File root() { return canonicalRoot; }
public int majorVersion() { return hd.majorVersion; }
public int minorVersion() { return hd.minorVersion; }
public SimpleLibrary parent() { return parent; }
+ public File natlibs() { return natlibs; }
+ public File natcmds() { return natcmds; }
+ public File configs() { return configs; }
public boolean isDeflated() { return hd.isDeflated(); }
private URI location = null;
public URI location() {
if (location == null)
*** 231,290 ****
return (this.getClass().getName()
+ "[" + canonicalRoot
+ ", v" + hd.majorVersion + "." + hd.minorVersion + "]");
}
! private SimpleLibrary(File path, boolean create, File parentPath, Set<StorageOption> opts)
! throws IOException
! {
root = path;
canonicalRoot = root.getCanonicalFile();
! if (root.exists()) {
! if (!root.isDirectory())
! throw new IOException(root + ": Exists but is not a directory");
hd = Header.load(root);
if (hd.parent() != null) {
parent = open(hd.parent());
parentPath = hd.parent();
}
! return;
}
! if (!create)
! throw new FileNotFoundException(root.toString());
if (parentPath != null) {
this.parent = open(parentPath);
this.parentPath = this.parent.root();
}
! if (!root.mkdirs())
! throw new IOException(root + ": Cannot create library directory");
! hd = new Header(canonicalRoot, this.parentPath, opts);
hd.store();
}
public static SimpleLibrary create(File path, File parent, Set<StorageOption> opts)
throws IOException
{
! return new SimpleLibrary(path, true, parent, opts);
}
public static SimpleLibrary create(File path, File parent)
throws IOException
{
! return new SimpleLibrary(path, true, parent, Collections.<StorageOption>emptySet());
}
public static SimpleLibrary create(File path, Set<StorageOption> opts)
throws IOException
{
// ## Should default parent to $JAVA_HOME/lib/modules
! return new SimpleLibrary(path, true, null, opts);
}
public static SimpleLibrary open(File path)
throws IOException
{
! return new SimpleLibrary(path, false, null, Collections.<StorageOption>emptySet());
}
private static final JigsawModuleSystem jms
= JigsawModuleSystem.instance();
--- 254,362 ----
return (this.getClass().getName()
+ "[" + canonicalRoot
+ ", v" + hd.majorVersion + "." + hd.minorVersion + "]");
}
!
! private static File resolveAndEnsurePath(File path) throws IOException {
! if (path == null) { return null; }
!
! File p = path.getCanonicalFile();
! if (!p.exists())
! Files.mkdirs(p, p.toString());
! else {
! Files.ensureIsDirectory(p);
! Files.ensureWriteable(p);
! }
! return p;
! }
!
! private File relativize(File path) throws IOException {
! if (path == null) { return null; }
! // Return the path relative to the canonical root
! return (canonicalRoot.toPath().relativize(path.toPath().toRealPath())).toFile();
! }
!
! // Opens an existing library
! private SimpleLibrary(File path) throws IOException {
root = path;
canonicalRoot = root.getCanonicalFile();
! Files.ensureIsDirectory(root);
hd = Header.load(root);
if (hd.parent() != null) {
parent = open(hd.parent());
parentPath = hd.parent();
}
!
! if (hd.natlibs() != null)
! natlibs = new File(canonicalRoot, hd.natlibs().toString()).getCanonicalFile();
! if (hd.natcmds() != null)
! natcmds = new File(canonicalRoot, hd.natcmds().toString()).getCanonicalFile();
! if (hd.configs() != null)
! configs = new File(canonicalRoot, hd.configs().toString()).getCanonicalFile();
}
!
! // Creates a new library
! private SimpleLibrary(File path, File parentPath, File natlibs, File natcmds,
! File configs, Set<StorageOption> opts)
! throws IOException
! {
! root = path;
! canonicalRoot = root.getCanonicalFile();
! if (root.exists()) {
! Files.ensureIsDirectory(root);
! if (root.list().length != 0)
! throw new IOException(root + ": Already Exists");
! Files.ensureWriteable(root);
! } else
! Files.mkdirs(root, root.toString());
!
if (parentPath != null) {
this.parent = open(parentPath);
this.parentPath = this.parent.root();
}
!
! this.natlibs = resolveAndEnsurePath(natlibs);
! this.natcmds = resolveAndEnsurePath(natcmds);
! this.configs = resolveAndEnsurePath(configs);
!
! hd = new Header(canonicalRoot, this.parentPath, relativize(this.natlibs),
! relativize(this.natcmds), relativize(this.configs), opts);
hd.store();
}
+ public static SimpleLibrary create(File path, File parent, File natlibs,
+ File natcmds, File configs,
+ Set<StorageOption> opts)
+ throws IOException
+ {
+ return new SimpleLibrary(path, parent, natlibs, natcmds, configs, opts);
+ }
+
public static SimpleLibrary create(File path, File parent, Set<StorageOption> opts)
throws IOException
{
! return new SimpleLibrary(path, parent, null, null, null, opts);
}
public static SimpleLibrary create(File path, File parent)
throws IOException
{
! return SimpleLibrary.create(path, parent, Collections.<StorageOption>emptySet());
}
public static SimpleLibrary create(File path, Set<StorageOption> opts)
throws IOException
{
// ## Should default parent to $JAVA_HOME/lib/modules
! return SimpleLibrary.create(path, null, opts);
}
public static SimpleLibrary open(File path)
throws IOException
{
! return new SimpleLibrary(path);
}
private static final JigsawModuleSystem jms
= JigsawModuleSystem.instance();
*** 996,1009 ****
// Store signer info
new Signers(md, signers).store();
// Read and verify the rest of the hashes
! mr.readRest(md, isDeflated());
mfv.verifyHashesRest(mfvParams);
} else {
! mr.readRest(md, isDeflated());
}
if (strip)
strip(md);
reIndex(mid); // ## Could do this while reading module file
--- 1068,1081 ----
// Store signer info
new Signers(md, signers).store();
// Read and verify the rest of the hashes
! mr.readRest(md, isDeflated(), natlibs(), natcmds(), configs());
mfv.verifyHashesRest(mfvParams);
} else {
! mr.readRest(md, isDeflated(), natlibs(), natcmds(), configs());
}
if (strip)
strip(md);
reIndex(mid); // ## Could do this while reading module file
*** 1010,1020 ****
return mid;
} catch (IOException | SignatureException x) {
if (md != null && md.exists()) {
try {
! Files.deleteTree(md);
} catch (IOException y) {
y.initCause(x);
throw y;
}
}
--- 1082,1092 ----
return mid;
} catch (IOException | SignatureException x) {
if (md != null && md.exists()) {
try {
! ModuleFile.Reader.remove(md);
} catch (IOException y) {
y.initCause(x);
throw y;
}
}
*** 1184,1193 ****
--- 1256,1266 ----
{
ModuleId mid;
if (mf.getName().endsWith(".jar"))
mid = installFromJarFile(mf, verifySignature, strip);
else {
+ // Assume jmod file
try (FileInputStream in = new FileInputStream(mf)) {
mid = install(in, verifySignature, strip);
}
}
return mid;
*** 1336,1349 ****
}
public File findLocalNativeLibrary(ModuleId mid, String name)
throws IOException
{
! File md = findModuleDir(mid);
! if (md == null)
return null;
! File f = new File(new File(md, "lib"), name);
if (!f.exists())
return null;
return f;
}
--- 1409,1426 ----
}
public File findLocalNativeLibrary(ModuleId mid, String name)
throws IOException
{
! File f = natlibs();
! if (f == null) {
! f = findModuleDir(mid);
! if (f == null)
return null;
! f = new File(f, "lib");
! }
! f = new File(f, name);
if (!f.exists())
return null;
return f;
}