8222276: (zipfs) Refactoring and cleanups to prepare for JDK-8213031

Reviewed-by: lancea
This commit is contained in:
Christoph Langer 2019-05-17 09:00:39 +01:00
parent cb983d1bd7
commit 00a7dce177
8 changed files with 394 additions and 456 deletions

@ -42,7 +42,7 @@ import java.util.jar.Manifest;
/**
* Adds aliasing to ZipFileSystem to support multi-release jar files. An alias map
* is created by {@link JarFileSystem#createVersionedLinks(int)}. The map is then
* consulted when an entry is looked up in {@link JarFileSystem#getEntry(byte[])}
* consulted when an entry is looked up in {@link JarFileSystem#getInode(byte[])}
* to determine if the entry has a corresponding versioned entry. If so, the
* versioned entry is returned.
*
@ -116,7 +116,7 @@ class JarFileSystem extends ZipFileSystem {
getVersionMap(version, verdir).values().forEach(versionNode ->
walk(versionNode.child, entryNode ->
aliasMap.put(
getNodeInRootTree(getRootName(entryNode, versionNode), entryNode.isdir),
getOrCreateInode(getRootName(entryNode, versionNode), entryNode.isdir),
entryNode.name))
);
lookup = path -> {
@ -125,51 +125,6 @@ class JarFileSystem extends ZipFileSystem {
};
}
/**
* Return the node from the root tree. Create it, if it doesn't exist.
*/
private IndexNode getNodeInRootTree(byte[] path, boolean isdir) {
IndexNode node = getInode(path);
if (node != null) {
return node;
}
IndexNode parent = getParentDir(path);
beginWrite();
try {
node = new IndexNode(path, isdir);
node.sibling = parent.child;
parent.child = node;
inodes.put(node, node);
return node;
} finally {
endWrite();
}
}
/**
* Return the parent directory node of a path. If the node doesn't exist,
* it will be created. Parent directories will be created recursively.
* Recursion fuse: We assume at latest the root path can be resolved to a node.
*/
private IndexNode getParentDir(byte[] path) {
byte[] parentPath = getParent(path);
IndexNode node = inodes.get(IndexNode.keyOf(parentPath));
if (node != null) {
return node;
}
IndexNode parent = getParentDir(parentPath);
beginWrite();
try {
node = new IndexNode(parentPath, true);
node.sibling = parent.child;
parent.child = node;
inodes.put(node, node);
return node;
} finally {
endWrite();
}
}
/**
* create a sorted version map of version -> inode, for inodes <= max version
* 9 -> META-INF/versions/9

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,6 @@ package jdk.nio.zipfs;
import java.io.IOException;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.util.LinkedHashMap;
import java.util.Map;
@ -36,7 +35,7 @@ import java.util.Map;
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
class ZipFileAttributeView implements BasicFileAttributeView {
private static enum AttrID {
private enum AttrID {
size,
creationTime,
lastAccessTime,
@ -49,44 +48,24 @@ class ZipFileAttributeView implements BasicFileAttributeView {
compressedSize,
crc,
method
};
}
private final ZipPath path;
private final boolean isZipView;
private ZipFileAttributeView(ZipPath path, boolean isZipView) {
ZipFileAttributeView(ZipPath path, boolean isZipView) {
this.path = path;
this.isZipView = isZipView;
}
@SuppressWarnings("unchecked") // Cast to V
static <V extends FileAttributeView> V get(ZipPath path, Class<V> type) {
if (type == null)
throw new NullPointerException();
if (type == BasicFileAttributeView.class)
return (V)new ZipFileAttributeView(path, false);
if (type == ZipFileAttributeView.class)
return (V)new ZipFileAttributeView(path, true);
return null;
}
static ZipFileAttributeView get(ZipPath path, String type) {
if (type == null)
throw new NullPointerException();
if (type.equals("basic"))
return new ZipFileAttributeView(path, false);
if (type.equals("zip"))
return new ZipFileAttributeView(path, true);
return null;
}
@Override
public String name() {
return isZipView ? "zip" : "basic";
}
@Override
public ZipFileAttributes readAttributes() throws IOException {
return path.getAttributes();
return path.readAttributes();
}
@Override
@ -108,10 +87,10 @@ class ZipFileAttributeView implements BasicFileAttributeView {
setTimes(null, (FileTime)value, null);
if (AttrID.valueOf(attribute) == AttrID.creationTime)
setTimes(null, null, (FileTime)value);
return;
} catch (IllegalArgumentException x) {}
throw new UnsupportedOperationException("'" + attribute +
"' is unknown or read-only attribute");
} catch (IllegalArgumentException x) {
throw new UnsupportedOperationException("'" + attribute +
"' is unknown or read-only attribute");
}
}
Map<String, Object> readAttributes(String attributes)
@ -136,7 +115,7 @@ class ZipFileAttributeView implements BasicFileAttributeView {
return map;
}
Object attribute(AttrID id, ZipFileAttributes zfas) {
private Object attribute(AttrID id, ZipFileAttributes zfas) {
switch (id) {
case size:
return zfas.size();
@ -168,6 +147,8 @@ class ZipFileAttributeView implements BasicFileAttributeView {
if (isZipView)
return zfas.method();
break;
default:
break;
}
return null;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,13 +30,12 @@ import java.nio.file.attribute.BasicFileAttributes;
/**
* The attributes of a file stored in a zip file.
*
* @author Xueming Shen, Rajendra Gutupalli,Jaya Hangal
* @author Xueming Shen, Rajendra Gutupalli, Jaya Hangal
*/
interface ZipFileAttributes extends BasicFileAttributes {
public long compressedSize();
public long crc();
public int method();
public byte[] extra();
public byte[] comment();
public String toString();
long compressedSize();
long crc();
int method();
byte[] extra();
byte[] comment();
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -68,14 +68,14 @@ class ZipFileStore extends FileStore {
@Override
public boolean supportsFileAttributeView(String name) {
return name.equals("basic") || name.equals("zip");
return "basic".equals(name) || "zip".equals(name);
}
@Override
public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
return (V)null;
return null;
}
@Override
@ -108,7 +108,7 @@ class ZipFileStore extends FileStore {
final FileStore fstore;
final long size;
public ZipFileStoreAttributes(ZipFileStore fileStore)
ZipFileStoreAttributes(ZipFileStore fileStore)
throws IOException
{
Path path = FileSystems.getDefault().getPath(fileStore.name());
@ -116,17 +116,17 @@ class ZipFileStore extends FileStore {
this.fstore = Files.getFileStore(path);
}
public long totalSpace() {
long totalSpace() {
return size;
}
public long usableSpace() throws IOException {
long usableSpace() throws IOException {
if (!fstore.isReadOnly())
return fstore.getUsableSpace();
return 0;
}
public long unallocatedSpace() throws IOException {
long unallocatedSpace() throws IOException {
if (!fstore.isReadOnly())
return fstore.getUnallocatedSpace();
return 0;

File diff suppressed because it is too large Load Diff

@ -175,7 +175,7 @@ public class ZipFileSystemProvider extends FileSystemProvider {
}
// Checks that the given file is a UnixPath
static final ZipPath toZipPath(Path path) {
private static ZipPath toZipPath(Path path) {
if (path == null)
throw new NullPointerException();
if (!(path instanceof ZipPath))
@ -211,7 +211,7 @@ public class ZipFileSystemProvider extends FileSystemProvider {
public <V extends FileAttributeView> V
getFileAttributeView(Path path, Class<V> type, LinkOption... options)
{
return ZipFileAttributeView.get(toZipPath(path), type);
return toZipPath(path).getFileAttributeView(type);
}
@Override
@ -241,7 +241,6 @@ public class ZipFileSystemProvider extends FileSystemProvider {
Set<? extends OpenOption> options,
ExecutorService exec,
FileAttribute<?>... attrs)
throws IOException
{
throw new UnsupportedOperationException();
}
@ -286,26 +285,23 @@ public class ZipFileSystemProvider extends FileSystemProvider {
}
@Override
@SuppressWarnings("unchecked") // Cast to A
public <A extends BasicFileAttributes> A
readAttributes(Path path, Class<A> type, LinkOption... options)
throws IOException
{
if (type == BasicFileAttributes.class || type == ZipFileAttributes.class)
return (A)toZipPath(path).getAttributes();
return null;
return toZipPath(path).readAttributes(type);
}
@Override
public Map<String, Object>
readAttributes(Path path, String attribute, LinkOption... options)
readAttributes(Path path, String attributes, LinkOption... options)
throws IOException
{
return toZipPath(path).readAttributes(attribute, options);
return toZipPath(path).readAttributes(attributes, options);
}
@Override
public Path readSymbolicLink(Path link) throws IOException {
public Path readSymbolicLink(Path link) {
throw new UnsupportedOperationException("Not supported.");
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package jdk.nio.zipfs;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import java.util.zip.ZipException;
import static jdk.nio.zipfs.ZipConstants.*;
import static jdk.nio.zipfs.ZipUtils.dosToJavaTime;
@ -65,12 +66,12 @@ public class ZipInfo {
// twice
long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
ZipFileSystem.zerror("read loc header failed");
throw new ZipException("read loc header failed");
if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
// have to read the second time;
len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
ZipFileSystem.zerror("read loc header failed");
throw new ZipException("read loc header failed");
}
printLOC(buf);
pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
@ -79,11 +80,11 @@ public class ZipInfo {
}
}
static void print(String fmt, Object... objs) {
private static void print(String fmt, Object... objs) {
System.out.printf(fmt, objs);
}
static void printLOC(byte[] loc) {
private static void printLOC(byte[] loc) {
print("%n");
print("[Local File Header]%n");
print(" Signature : %#010x%n", LOCSIG(loc));
@ -107,7 +108,7 @@ public class ZipInfo {
printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
}
static void printCEN(byte[] cen, int off) {
private static void printCEN(byte[] cen, int off) {
print("[Central Directory Header]%n");
print(" Signature : %#010x%n", CENSIG(cen, off));
if (CENSIG(cen, off) != CENSIG) {
@ -140,7 +141,7 @@ public class ZipInfo {
}
static long locoff(byte[] cen, int pos) {
private static long locoff(byte[] cen, int pos) {
long locoff = CENOFF(cen, pos);
if (locoff == ZIP64_MINVAL) { //ZIP64
int off = pos + CENHDR + CENNAM(cen, pos);
@ -164,7 +165,7 @@ public class ZipInfo {
return locoff;
}
static void printExtra(byte[] extra, int off, int len) {
private static void printExtra(byte[] extra, int off, int len) {
int end = off + len;
while (off + 4 <= end) {
int tag = SH(extra, off);

@ -35,7 +35,9 @@ import java.nio.channels.SeekableByteChannel;
import java.nio.file.*;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;
import java.util.Iterator;
@ -211,13 +213,13 @@ final class ZipPath implements Path {
private boolean equalsNameAt(ZipPath other, int index) {
int mbegin = offsets[index];
int mlen = 0;
int mlen;
if (index == (offsets.length-1))
mlen = path.length - mbegin;
else
mlen = offsets[index + 1] - mbegin - 1;
int obegin = other.offsets[index];
int olen = 0;
int olen;
if (index == (other.offsets.length - 1))
olen = other.path.length - obegin;
else
@ -298,7 +300,7 @@ final class ZipPath implements Path {
// opath is normalized, just concat
private ZipPath resolve(byte[] opath) {
byte[] resolved = null;
byte[] resolved;
byte[] tpath = this.path;
int tlen = tpath.length;
int olen = opath.length;
@ -626,9 +628,8 @@ final class ZipPath implements Path {
@Override
public boolean equals(Object obj) {
return obj != null &&
obj instanceof ZipPath &&
this.zfs == ((ZipPath)obj).zfs &&
return obj instanceof ZipPath &&
this.zfs == ((ZipPath) obj).zfs &&
compareTo((Path) obj) == 0;
}
@ -639,13 +640,11 @@ final class ZipPath implements Path {
int len2 = o.path.length;
int n = Math.min(len1, len2);
byte v1[] = this.path;
byte v2[] = o.path;
int k = 0;
while (k < n) {
int c1 = v1[k] & 0xff;
int c2 = v2[k] & 0xff;
int c1 = this.path[k] & 0xff;
int c2 = o.path[k] & 0xff;
if (c1 != c2)
return c1 - c2;
k++;
@ -704,6 +703,27 @@ final class ZipPath implements Path {
/////////////////////////////////////////////////////////////////////
@SuppressWarnings("unchecked") // Cast to V
<V extends FileAttributeView> V getFileAttributeView(Class<V> type) {
if (type == null)
throw new NullPointerException();
if (type == BasicFileAttributeView.class)
return (V)new ZipFileAttributeView(this, false);
if (type == ZipFileAttributeView.class)
return (V)new ZipFileAttributeView(this, true);
throw new UnsupportedOperationException("view <" + type + "> is not supported");
}
private ZipFileAttributeView getFileAttributeView(String type) {
if (type == null)
throw new NullPointerException();
if ("basic".equals(type))
return new ZipFileAttributeView(this, false);
if ("zip".equals(type))
return new ZipFileAttributeView(this, true);
throw new UnsupportedOperationException("view <" + type + "> is not supported");
}
void createDirectory(FileAttribute<?>... attrs)
throws IOException
{
@ -731,18 +751,27 @@ final class ZipPath implements Path {
zfs.deleteFile(getResolvedPath(), true);
}
void deleteIfExists() throws IOException {
private void deleteIfExists() throws IOException {
zfs.deleteFile(getResolvedPath(), false);
}
ZipFileAttributes getAttributes() throws IOException
{
ZipFileAttributes readAttributes() throws IOException {
ZipFileAttributes zfas = zfs.getFileAttributes(getResolvedPath());
if (zfas == null)
throw new NoSuchFileException(toString());
return zfas;
}
@SuppressWarnings("unchecked") // Cast to A
<A extends BasicFileAttributes> A readAttributes(Class<A> type) throws IOException {
if (type == BasicFileAttributes.class || type == ZipFileAttributes.class) {
return (A)readAttributes();
}
throw new UnsupportedOperationException("Attributes of type " +
type.getName() + " not supported");
}
void setAttribute(String attribute, Object value, LinkOption... options)
throws IOException
{
@ -756,10 +785,7 @@ final class ZipPath implements Path {
type = attribute.substring(0, colonPos++);
attr = attribute.substring(colonPos);
}
ZipFileAttributeView view = ZipFileAttributeView.get(this, type);
if (view == null)
throw new UnsupportedOperationException("view <" + view + "> is not supported");
view.setAttribute(attr, value);
getFileAttributeView(type).setAttribute(attr, value);
}
void setTimes(FileTime mtime, FileTime atime, FileTime ctime)
@ -782,11 +808,7 @@ final class ZipPath implements Path {
view = attributes.substring(0, colonPos++);
attrs = attributes.substring(colonPos);
}
ZipFileAttributeView zfv = ZipFileAttributeView.get(this, view);
if (zfv == null) {
throw new UnsupportedOperationException("view not supported");
}
return zfv.readAttributes(attrs);
return getFileAttributeView(view).readAttributes(attrs);
}
FileStore getFileStore() throws IOException {
@ -846,11 +868,8 @@ final class ZipPath implements Path {
}
}
boolean exists() {
try {
return zfs.exists(getResolvedPath());
} catch (IOException x) {}
return false;
private boolean exists() {
return zfs.exists(getResolvedPath());
}
OutputStream newOutputStream(OpenOption... options) throws IOException
@ -898,7 +917,7 @@ final class ZipPath implements Path {
copyAttrs = true;
}
// attributes of source file
ZipFileAttributes zfas = getAttributes();
ZipFileAttributes zfas = readAttributes();
// check if target exists
boolean exists;
if (replaceExisting) {
@ -918,25 +937,19 @@ final class ZipPath implements Path {
// create directory or file
target.createDirectory();
} else {
InputStream is = zfs.newInputStream(getResolvedPath());
try {
OutputStream os = target.newOutputStream();
try {
byte[] buf = new byte[8192];
int n = 0;
while ((n = is.read(buf)) != -1) {
os.write(buf, 0, n);
}
} finally {
os.close();
try (InputStream is = zfs.newInputStream(getResolvedPath());
OutputStream os = target.newOutputStream())
{
byte[] buf = new byte[8192];
int n;
while ((n = is.read(buf)) != -1) {
os.write(buf, 0, n);
}
} finally {
is.close();
}
}
if (copyAttrs) {
BasicFileAttributeView view =
ZipFileAttributeView.get(target, BasicFileAttributeView.class);
target.getFileAttributeView(BasicFileAttributeView.class);
try {
view.setTimes(zfas.lastModifiedTime(),
zfas.lastAccessTime(),
@ -963,9 +976,9 @@ final class ZipPath implements Path {
}
// to avoid double escape
static String decodeUri(String s) {
private static String decodeUri(String s) {
if (s == null)
return s;
return null;
int n = s.length();
if (n == 0)
return s;