jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java
author chegar
Wed, 03 Dec 2014 14:22:58 +0000
changeset 27565 729f9700483a
child 29270 0f65e3c44659
permissions -rw-r--r--
8049367: Modular Run-Time Images Reviewed-by: chegar, dfuchs, ihse, joehw, mullan, psandoz, wetmore Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, bradford.wetmore@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, james.laskey@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com, sundararajan.athijegannathan@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27565
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     1
/*
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     4
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    10
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    15
 * accompanied this code).
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    16
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    20
 *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    23
 * questions.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    24
 */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    25
package jdk.internal.jrtfs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    26
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    27
import java.io.ByteArrayInputStream;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    28
import java.io.IOException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    29
import java.io.InputStream;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    30
import java.io.OutputStream;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    31
import java.nio.ByteBuffer;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    32
import java.nio.channels.*;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    33
import java.nio.charset.Charset;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    34
import java.nio.file.AccessMode;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    35
import java.nio.file.ClosedFileSystemException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    36
import java.nio.file.CopyOption;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    37
import java.nio.file.FileStore;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    38
import java.nio.file.FileSystem;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    39
import java.nio.file.FileSystemException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    40
import java.nio.file.FileSystemNotFoundException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    41
import java.nio.file.Files;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    42
import java.nio.file.NoSuchFileException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    43
import java.nio.file.NotDirectoryException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    44
import java.nio.file.OpenOption;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    45
import java.nio.file.Path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    46
import java.nio.file.PathMatcher;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    47
import java.nio.file.ReadOnlyFileSystemException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    48
import java.nio.file.StandardCopyOption;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    49
import java.nio.file.StandardOpenOption;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    50
import java.nio.file.WatchService;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    51
import java.nio.file.attribute.FileAttribute;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    52
import java.nio.file.attribute.FileTime;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    53
import java.nio.file.attribute.UserPrincipalLookupService;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    54
import java.nio.file.spi.FileSystemProvider;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    55
import java.security.AccessController;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    56
import java.security.PrivilegedActionException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    57
import java.security.PrivilegedExceptionAction;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    58
import java.util.ArrayList;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    59
import java.util.Arrays;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    60
import java.util.Collections;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    61
import java.util.HashSet;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    62
import java.util.Iterator;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    63
import java.util.List;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    64
import java.util.Map;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    65
import java.util.Set;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    66
import java.util.regex.Pattern;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    67
import java.util.stream.Collectors;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    68
import jdk.internal.jimage.ImageReader;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    69
import jdk.internal.jimage.ImageReader.Node;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    70
import jdk.internal.jimage.UTF8String;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    71
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    72
/**
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    73
 * A FileSystem built on System jimage files.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    74
 */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    75
class JrtFileSystem extends FileSystem {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    76
    private static final Charset UTF_8 = Charset.forName("UTF-8");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    77
    private final JrtFileSystemProvider provider;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    78
    // System image readers
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    79
    private ImageReader bootImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    80
    private ImageReader extImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    81
    private ImageReader appImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    82
    // root path
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    83
    private final JrtPath rootPath;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    84
    private volatile boolean isOpen;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    85
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    86
    private static void checkExists(Path path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    87
        if (Files.notExists(path)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    88
            throw new FileSystemNotFoundException(path.toString());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    89
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    90
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    91
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    92
    // open a .jimage and build directory structure
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    93
    private static ImageReader openImage(Path path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    94
        ImageReader image = ImageReader.open(path.toString());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    95
        image.getRootDirectory();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    96
        return image;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    97
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    98
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    99
    JrtFileSystem(JrtFileSystemProvider provider,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   100
            Map<String, ?> env)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   101
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   102
        this.provider = provider;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   103
        checkExists(SystemImages.bootImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   104
        checkExists(SystemImages.extImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   105
        checkExists(SystemImages.appImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   106
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   107
        // open image files
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   108
        this.bootImage = openImage(SystemImages.bootImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   109
        this.extImage = openImage(SystemImages.extImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   110
        this.appImage = openImage(SystemImages.appImagePath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   111
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   112
        rootPath = new JrtPath(this, new byte[]{'/'});
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   113
        isOpen = true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   114
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   115
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   116
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   117
    public FileSystemProvider provider() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   118
        return provider;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   119
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   120
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   121
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   122
    public String getSeparator() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   123
        return "/";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   124
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   125
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   126
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   127
    public boolean isOpen() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   128
        return isOpen;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   129
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   130
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   131
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   132
    public void close() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   133
        cleanup();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   134
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   135
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   136
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   137
    protected void finalize() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   138
        try {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   139
            cleanup();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   140
        } catch (IOException ignored) {}
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   141
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   142
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   143
    // clean up this file system - called from finalize and close
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   144
    private void cleanup() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   145
        if (!isOpen) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   146
            return;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   147
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   148
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   149
        synchronized(this) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   150
            isOpen = false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   151
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   152
            // close all image readers and null out
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   153
            bootImage.close();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   154
            extImage.close();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   155
            appImage.close();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   156
            bootImage = null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   157
            extImage = null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   158
            appImage = null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   159
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   160
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   161
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   162
    private void ensureOpen() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   163
        if (!isOpen) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   164
            throw new ClosedFileSystemException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   165
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   166
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   167
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   168
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   169
    public boolean isReadOnly() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   170
        return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   171
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   172
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   173
    private ReadOnlyFileSystemException readOnly() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   174
        return new ReadOnlyFileSystemException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   175
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   176
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   177
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   178
    public Iterable<Path> getRootDirectories() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   179
        ArrayList<Path> pathArr = new ArrayList<>();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   180
        pathArr.add(rootPath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   181
        return pathArr;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   182
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   183
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   184
    JrtPath getRootPath() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   185
        return rootPath;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   186
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   187
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   188
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   189
    public JrtPath getPath(String first, String... more) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   190
        String path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   191
        if (more.length == 0) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   192
            path = first;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   193
        } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   194
            StringBuilder sb = new StringBuilder();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   195
            sb.append(first);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   196
            for (String segment : more) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   197
                if (segment.length() > 0) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   198
                    if (sb.length() > 0) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   199
                        sb.append('/');
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   200
                    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   201
                    sb.append(segment);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   202
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   203
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   204
            path = sb.toString();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   205
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   206
        return new JrtPath(this, getBytes(path));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   207
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   208
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   209
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   210
    public UserPrincipalLookupService getUserPrincipalLookupService() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   211
        throw new UnsupportedOperationException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   212
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   213
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   214
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   215
    public WatchService newWatchService() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   216
        throw new UnsupportedOperationException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   217
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   218
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   219
    FileStore getFileStore(JrtPath path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   220
        return new JrtFileStore(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   221
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   222
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   223
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   224
    public Iterable<FileStore> getFileStores() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   225
        ArrayList<FileStore> list = new ArrayList<>(1);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   226
        list.add(new JrtFileStore(new JrtPath(this, new byte[]{'/'})));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   227
        return list;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   228
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   229
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   230
    private static final Set<String> supportedFileAttributeViews
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   231
            = Collections.unmodifiableSet(
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   232
                    new HashSet<String>(Arrays.asList("basic", "jrt")));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   233
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   234
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   235
    public Set<String> supportedFileAttributeViews() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   236
        return supportedFileAttributeViews;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   237
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   238
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   239
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   240
    public String toString() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   241
        return "jrt:/";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   242
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   243
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   244
    private static final String GLOB_SYNTAX = "glob";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   245
    private static final String REGEX_SYNTAX = "regex";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   246
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   247
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   248
    public PathMatcher getPathMatcher(String syntaxAndInput) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   249
        int pos = syntaxAndInput.indexOf(':');
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   250
        if (pos <= 0 || pos == syntaxAndInput.length()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   251
            throw new IllegalArgumentException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   252
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   253
        String syntax = syntaxAndInput.substring(0, pos);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   254
        String input = syntaxAndInput.substring(pos + 1);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   255
        String expr;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   256
        if (syntax.equals(GLOB_SYNTAX)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   257
            expr = JrtUtils.toRegexPattern(input);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   258
        } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   259
            if (syntax.equals(REGEX_SYNTAX)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   260
                expr = input;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   261
            } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   262
                throw new UnsupportedOperationException("Syntax '" + syntax
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   263
                        + "' not recognized");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   264
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   265
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   266
        // return matcher
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   267
        final Pattern pattern = Pattern.compile(expr);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   268
        return (Path path) -> pattern.matcher(path.toString()).matches();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   269
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   270
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   271
    static byte[] getBytes(String name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   272
        return name.getBytes(UTF_8);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   273
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   274
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   275
    static String getString(byte[] name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   276
        return new String(name, UTF_8);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   277
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   278
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   279
    private static class NodeAndImage {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   280
        final Node node;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   281
        final ImageReader image;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   282
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   283
        NodeAndImage(Node node, ImageReader image) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   284
            this.node = node; this.image = image;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   285
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   286
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   287
        byte[] getResource() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   288
            return image.getResource(node);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   289
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   290
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   291
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   292
    private NodeAndImage findNode(byte[] path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   293
        ImageReader image = bootImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   294
        Node node = bootImage.findNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   295
        if (node == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   296
            image = extImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   297
            node = extImage.findNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   298
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   299
        if (node == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   300
            image = appImage;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   301
            node = appImage.findNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   302
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   303
        if (node == null || node.isHidden()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   304
            throw new NoSuchFileException(getString(path));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   305
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   306
        return new NodeAndImage(node, image);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   307
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   308
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   309
    private NodeAndImage checkNode(byte[] path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   310
        ensureOpen();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   311
        return findNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   312
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   313
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   314
    private NodeAndImage checkResource(byte[] path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   315
        NodeAndImage ni = checkNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   316
        if (ni.node.isDirectory()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   317
            throw new FileSystemException(getString(path) + " is a directory");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   318
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   319
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   320
        assert ni.node.isResource() : "resource node expected here";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   321
        return ni;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   322
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   323
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   324
    // package private helpers
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   325
    JrtFileAttributes getFileAttributes(byte[] path)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   326
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   327
        NodeAndImage ni = checkNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   328
        return new JrtFileAttributes(ni.node);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   329
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   330
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   331
    void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   332
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   333
        throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   334
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   335
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   336
    boolean exists(byte[] path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   337
        ensureOpen();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   338
        try {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   339
            findNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   340
        } catch (NoSuchFileException exp) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   341
            return false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   342
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   343
        return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   344
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   345
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   346
    boolean isDirectory(byte[] path)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   347
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   348
        ensureOpen();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   349
        NodeAndImage ni = checkNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   350
        return ni.node.isDirectory();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   351
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   352
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   353
    JrtPath toJrtPath(String path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   354
        return toJrtPath(getBytes(path));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   355
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   356
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   357
    JrtPath toJrtPath(byte[] path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   358
        return new JrtPath(this, path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   359
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   360
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   361
    /**
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   362
     * returns the list of child paths of the given directory "path"
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   363
     *
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   364
     * @param path name of the directory whose content is listed
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   365
     * @param childPrefix prefix added to returned children names - may be null
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   366
              in which case absolute child paths are returned
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   367
     * @return iterator for child paths of the given directory path
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   368
     */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   369
    Iterator<Path> iteratorOf(byte[] path, String childPrefix)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   370
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   371
        NodeAndImage ni = checkNode(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   372
        if (!ni.node.isDirectory()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   373
            throw new NotDirectoryException(getString(path));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   374
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   375
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   376
        if (ni.node.isRootDir()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   377
            return rootDirIterator(path, childPrefix);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   378
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   379
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   380
        return nodesToIterator(toJrtPath(path), childPrefix, ni.node.getChildren());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   381
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   382
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   383
    private Iterator<Path> nodesToIterator(Path path, String childPrefix, List<Node> childNodes) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   384
        List<Path> childPaths;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   385
        if (childPrefix == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   386
            childPaths = childNodes.stream()
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   387
                .filter(Node::isVisible)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   388
                .map(child -> toJrtPath(child.getNameString()))
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   389
                .collect(Collectors.toCollection(ArrayList::new));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   390
        } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   391
            childPaths = childNodes.stream()
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   392
                .filter(Node::isVisible)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   393
                .map(child -> toJrtPath(childPrefix + child.getNameString().substring(1)))
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   394
                .collect(Collectors.toCollection(ArrayList::new));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   395
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   396
        return childPaths.iterator();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   397
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   398
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   399
    private List<Node> rootChildren;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   400
    private static void addRootDirContent(List<Node> dest, List<Node> src) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   401
        for (Node n : src) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   402
            // only module directories at the top level. Filter other stuff!
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   403
            if (n.isModuleDir()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   404
                dest.add(n);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   405
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   406
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   407
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   408
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   409
    private synchronized void initRootChildren(byte[] path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   410
        if (rootChildren == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   411
            rootChildren = new ArrayList<>();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   412
            addRootDirContent(rootChildren, bootImage.findNode(path).getChildren());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   413
            addRootDirContent(rootChildren, extImage.findNode(path).getChildren());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   414
            addRootDirContent(rootChildren, appImage.findNode(path).getChildren());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   415
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   416
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   417
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   418
    private Iterator<Path> rootDirIterator(byte[] path, String childPrefix) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   419
        initRootChildren(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   420
        return nodesToIterator(rootPath, childPrefix, rootChildren);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   421
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   422
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   423
    void createDirectory(byte[] dir, FileAttribute<?>... attrs)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   424
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   425
        throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   426
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   427
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   428
    void copyFile(boolean deletesrc, byte[] src, byte[] dst, CopyOption... options)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   429
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   430
        throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   431
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   432
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   433
    public void deleteFile(byte[] path, boolean failIfNotExists)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   434
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   435
        throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   436
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   437
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   438
    OutputStream newOutputStream(byte[] path, OpenOption... options)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   439
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   440
        throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   441
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   442
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   443
    private void checkOptions(Set<? extends OpenOption> options) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   444
        // check for options of null type and option is an intance of StandardOpenOption
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   445
        for (OpenOption option : options) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   446
            if (option == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   447
                throw new NullPointerException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   448
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   449
            if (!(option instanceof StandardOpenOption)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   450
                throw new IllegalArgumentException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   451
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   452
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   453
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   454
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   455
    // Returns an input stream for reading the contents of the specified
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   456
    // file entry.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   457
    InputStream newInputStream(byte[] path) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   458
        final NodeAndImage ni = checkResource(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   459
        return new ByteArrayInputStream(ni.getResource());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   460
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   461
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   462
    SeekableByteChannel newByteChannel(byte[] path,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   463
            Set<? extends OpenOption> options,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   464
            FileAttribute<?>... attrs)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   465
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   466
        checkOptions(options);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   467
        if (options.contains(StandardOpenOption.WRITE)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   468
                || options.contains(StandardOpenOption.APPEND)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   469
            throw readOnly();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   470
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   471
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   472
        NodeAndImage ni = checkResource(path);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   473
        byte[] buf = ni.getResource();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   474
        final ReadableByteChannel rbc
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   475
                = Channels.newChannel(new ByteArrayInputStream(buf));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   476
        final long size = buf.length;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   477
        return new SeekableByteChannel() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   478
            long read = 0;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   479
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   480
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   481
            public boolean isOpen() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   482
                return rbc.isOpen();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   483
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   484
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   485
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   486
            public long position() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   487
                return read;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   488
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   489
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   490
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   491
            public SeekableByteChannel position(long pos)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   492
                    throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   493
                throw new UnsupportedOperationException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   494
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   495
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   496
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   497
            public int read(ByteBuffer dst) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   498
                int n = rbc.read(dst);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   499
                if (n > 0) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   500
                    read += n;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   501
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   502
                return n;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   503
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   504
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   505
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   506
            public SeekableByteChannel truncate(long size)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   507
                    throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   508
                throw new NonWritableChannelException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   509
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   510
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   511
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   512
            public int write(ByteBuffer src) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   513
                throw new NonWritableChannelException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   514
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   515
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   516
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   517
            public long size() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   518
                return size;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   519
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   520
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   521
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   522
            public void close() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   523
                rbc.close();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   524
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   525
        };
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   526
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   527
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   528
    // Returns a FileChannel of the specified path.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   529
    FileChannel newFileChannel(byte[] path,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   530
            Set<? extends OpenOption> options,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   531
            FileAttribute<?>... attrs)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   532
            throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   533
        throw new UnsupportedOperationException("newFileChannel");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   534
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   535
}