jdk/src/java.base/share/classes/jdk/internal/jimage/ImageReader.java
author chegar
Wed, 03 Dec 2014 14:22:58 +0000
changeset 27565 729f9700483a
child 31673 135283550686
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.jimage;
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.IOException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    28
import java.io.UncheckedIOException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    29
import java.net.URI;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    30
import java.nio.ByteBuffer;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    31
import java.nio.ByteOrder;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    32
import java.nio.IntBuffer;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    33
import java.nio.file.Files;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    34
import java.nio.file.FileSystem;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    35
import java.nio.file.attribute.BasicFileAttributes;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    36
import java.nio.file.attribute.FileTime;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    37
import java.nio.file.Paths;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    38
import java.nio.file.Path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    39
import java.util.ArrayList;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    40
import java.util.Collections;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    41
import java.util.HashMap;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    42
import java.util.List;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    43
import java.util.Map;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    44
import java.util.function.Consumer;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    45
import java.util.function.Supplier;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    46
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    47
public class ImageReader extends BasicImageReader {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    48
    // well-known strings needed for image file system.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    49
    static final UTF8String ROOT = new UTF8String("/");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    50
    static final UTF8String META_INF = new UTF8String("/META-INF");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    51
    static final UTF8String PACKAGES_OFFSETS = new UTF8String("packages.offsets");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    52
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    53
    // attributes of the .jimage file. jimage file does not contain
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    54
    // attributes for the individual resources (yet). We use attributes
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    55
    // of the jimage file itself (creation, modification, access times).
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    56
    // Iniitalized lazily, see {@link #imageFileAttributes()}.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    57
    private BasicFileAttributes imageFileAttributes;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    58
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    59
    private final Map<String, String> packageMap;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    60
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    61
    // directory management implementation
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    62
    private final Map<UTF8String, Node> nodes;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    63
    private volatile Directory rootDir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    64
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    65
    ImageReader(String imagePath, ByteOrder byteOrder) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    66
        super(imagePath, byteOrder);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    67
        this.packageMap = PackageModuleMap.readFrom(this);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    68
        this.nodes = Collections.synchronizedMap(new HashMap<>());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    69
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    70
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    71
    ImageReader(String imagePath) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    72
        this(imagePath, ByteOrder.nativeOrder());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    73
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    74
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    75
    public static ImageReader open(String imagePath, ByteOrder byteOrder) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    76
        return new ImageReader(imagePath, byteOrder);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    77
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    78
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    79
    /**
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    80
     * Opens the given file path as an image file, returning an {@code ImageReader}.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    81
     */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    82
    public static ImageReader open(String imagePath) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    83
        return open(imagePath, ByteOrder.nativeOrder());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    84
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    85
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    86
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    87
    public synchronized void close() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    88
        super.close();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    89
        clearNodes();
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
    /**
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    93
     * Return the module name that contains the given package name.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    94
     */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    95
    public String getModule(String pkg) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    96
        return packageMap.get(pkg);
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
    // jimage file does not store directory structure. We build nodes
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   100
    // using the "path" strings found in the jimage file.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   101
    // Node can be a directory or a resource
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   102
    public static abstract class Node {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   103
        private static final int ROOT_DIR = 0b0000_0000_0000_0001;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   104
        private static final int MODULE_DIR = 0b0000_0000_0000_0010;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   105
        private static final int METAINF_DIR = 0b0000_0000_0000_0100;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   106
        private static final int TOPLEVEL_PKG_DIR = 0b0000_0000_0000_1000;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   107
        private static final int HIDDEN = 0b0000_0000_0001_0000;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   108
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   109
        private int flags;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   110
        private final UTF8String name;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   111
        private final BasicFileAttributes fileAttrs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   112
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   113
        Node(UTF8String name, BasicFileAttributes fileAttrs) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   114
            assert name != null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   115
            assert fileAttrs != null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   116
            this.name = name;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   117
            this.fileAttrs = fileAttrs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   118
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   119
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   120
        public final void setIsRootDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   121
            flags |= ROOT_DIR;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   122
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   123
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   124
        public final boolean isRootDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   125
            return (flags & ROOT_DIR) != 0;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   126
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   127
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   128
        public final void setIsModuleDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   129
            flags |= MODULE_DIR;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   130
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   131
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   132
        public final boolean isModuleDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   133
            return (flags & MODULE_DIR) != 0;
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
        public final void setIsMetaInfDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   137
            flags |= METAINF_DIR;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   138
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   139
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   140
        public final boolean isMetaInfDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   141
            return (flags & METAINF_DIR) != 0;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   142
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   143
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   144
        public final void setIsTopLevelPackageDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   145
            flags |= TOPLEVEL_PKG_DIR;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   146
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   147
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   148
        public final boolean isTopLevelPackageDir() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   149
            return (flags & TOPLEVEL_PKG_DIR) != 0;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   150
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   151
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   152
        public final void setIsHidden() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   153
            flags |= HIDDEN;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   154
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   155
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   156
        public final boolean isHidden() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   157
            return (flags & HIDDEN) != 0;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   158
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   159
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   160
        public final boolean isVisible() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   161
            return !isHidden();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   162
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   163
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   164
        public final UTF8String getName() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   165
            return name;
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
        public final BasicFileAttributes getFileAttributes() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   169
            return fileAttrs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   170
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   171
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   172
        public boolean isDirectory() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   173
            return false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   174
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   175
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   176
        public List<Node> getChildren() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   177
            throw new IllegalArgumentException("not a directory: " + getNameString());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   178
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   179
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   180
        public boolean isResource() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   181
            return false;
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
        public ImageLocation getLocation() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   185
            throw new IllegalArgumentException("not a resource: " + getNameString());
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
        public long size() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   189
            return 0L;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   190
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   191
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   192
        public long compressedSize() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   193
            return 0L;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   194
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   195
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   196
        public String extension() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   197
            return null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   198
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   199
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   200
        public long contentOffset() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   201
            return 0L;
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
        public final FileTime creationTime() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   205
            return fileAttrs.creationTime();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   206
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   207
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   208
        public final FileTime lastAccessTime() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   209
            return fileAttrs.lastAccessTime();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   210
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   211
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   212
        public final FileTime lastModifiedTime() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   213
            return fileAttrs.lastModifiedTime();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   214
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   215
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   216
        public final String getNameString() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   217
            return name.toString();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   218
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   219
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   220
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   221
        public final String toString() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   222
            return getNameString();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   223
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   224
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   225
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   226
        public final int hashCode() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   227
            return name.hashCode();
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
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   231
        public final boolean equals(Object other) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   232
            if (this == other) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   233
                return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   234
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   235
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   236
            if (other instanceof Node) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   237
                return name.equals(((Node) other).name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   238
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   239
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   240
            return false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   241
        }
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
    // directory node - directory has full path name without '/' at end.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   245
    public static final class Directory extends Node {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   246
        private final List<Node> children;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   247
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   248
        @SuppressWarnings("LeakingThisInConstructor")
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   249
        Directory(Directory parent, UTF8String name, BasicFileAttributes fileAttrs) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   250
            super(name, fileAttrs);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   251
            children = new ArrayList<>();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   252
            if (parent != null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   253
                parent.addChild(this);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   254
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   255
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   256
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   257
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   258
        public boolean isDirectory() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   259
            return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   260
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   261
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   262
        public List<Node> getChildren() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   263
            return Collections.unmodifiableList(children);
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
        void addChild(Node node) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   267
            children.add(node);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   268
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   269
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   270
        public void walk(Consumer<? super Node> consumer) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   271
            consumer.accept(this);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   272
            for ( Node child : children ) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   273
                if (child.isDirectory()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   274
                    ((Directory)child).walk(consumer);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   275
                } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   276
                    consumer.accept(child);
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
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   280
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   281
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   282
    // "resource" is .class or any other resource (compressed/uncompressed) in a jimage.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   283
    // full path of the resource is the "name" of the resource.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   284
    public static class Resource extends Node {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   285
        private final ImageLocation loc;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   286
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   287
        @SuppressWarnings("LeakingThisInConstructor")
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   288
        Resource(Directory parent, ImageLocation loc, BasicFileAttributes fileAttrs) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   289
            this(parent, ROOT.concat(loc.getFullname()), loc, fileAttrs);
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
        @SuppressWarnings("LeakingThisInConstructor")
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   293
        Resource(Directory parent, UTF8String name, ImageLocation loc, BasicFileAttributes fileAttrs) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   294
            super(name, fileAttrs);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   295
            this.loc = loc;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   296
            parent.addChild(this);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   297
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   298
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   299
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   300
        public boolean isResource() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   301
            return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   302
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   303
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   304
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   305
        public ImageLocation getLocation() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   306
            return loc;
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
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   310
        public long size() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   311
            return loc.getUncompressedSize();
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
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   315
        public long compressedSize() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   316
            return loc.getCompressedSize();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   317
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   318
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   319
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   320
        public String extension() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   321
            return loc.getExtensionString();
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
        @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   325
        public long contentOffset() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   326
            return loc.getContentOffset();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   327
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   328
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   329
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   330
    // directory management interface
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   331
    public Directory getRootDirectory() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   332
        return buildRootDirectory();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   333
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   334
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   335
    public Node findNode(String name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   336
        return findNode(new UTF8String(name));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   337
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   338
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   339
    public Node findNode(byte[] name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   340
        return findNode(new UTF8String(name));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   341
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   342
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   343
    public synchronized Node findNode(UTF8String name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   344
        buildRootDirectory();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   345
        return nodes.get(name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   346
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   347
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   348
    private synchronized void clearNodes() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   349
        nodes.clear();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   350
        rootDir = null;
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
    /**
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   354
     * Returns the file attributes of the image file.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   355
     */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   356
    private BasicFileAttributes imageFileAttributes() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   357
        BasicFileAttributes attrs = imageFileAttributes;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   358
        if (attrs == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   359
            try {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   360
                Path file = Paths.get(imagePath());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   361
                attrs = Files.readAttributes(file, BasicFileAttributes.class);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   362
            } catch (IOException ioe) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   363
                throw new UncheckedIOException(ioe);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   364
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   365
            imageFileAttributes = attrs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   366
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   367
        return attrs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   368
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   369
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   370
    private synchronized Directory buildRootDirectory() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   371
        if (rootDir != null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   372
            return rootDir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   373
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   374
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   375
        // FIXME no time information per resource in jimage file (yet?)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   376
        // we use file attributes of jimage itself.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   377
        // root directory
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   378
        rootDir = new Directory(null, ROOT, imageFileAttributes());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   379
        rootDir.setIsRootDir();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   380
        nodes.put(rootDir.getName(), rootDir);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   381
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   382
        ImageLocation[] locs = getAllLocations(true);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   383
        for (ImageLocation loc : locs) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   384
            UTF8String parent = loc.getParent();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   385
            // directory where this location goes as child
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   386
            Directory dir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   387
            if (parent == null || parent.isEmpty()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   388
                // top level entry under root
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   389
                dir = rootDir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   390
            } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   391
                int idx = parent.lastIndexOf('/');
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   392
                assert idx != -1 : "invalid parent string";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   393
                UTF8String name = ROOT.concat(parent.substring(0, idx));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   394
                dir = (Directory) nodes.get(name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   395
                if (dir == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   396
                    // make all parent directories (as needed)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   397
                    dir = makeDirectories(parent);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   398
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   399
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   400
            Resource entry = new Resource(dir, loc, imageFileAttributes());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   401
            nodes.put(entry.getName(), entry);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   402
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   403
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   404
        Node metaInf = nodes.get(META_INF);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   405
        if (metaInf instanceof Directory) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   406
            metaInf.setIsMetaInfDir();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   407
            ((Directory)metaInf).walk(Node::setIsHidden);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   408
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   409
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   410
        fillPackageModuleInfo();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   411
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   412
        return rootDir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   413
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   414
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   415
    private Directory newDirectory(Directory parent, UTF8String name) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   416
        Directory dir = new Directory(parent, name, imageFileAttributes());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   417
        nodes.put(dir.getName(), dir);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   418
        return dir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   419
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   420
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   421
    private Directory makeDirectories(UTF8String parent) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   422
        assert !parent.isEmpty() : "non empty parent expected";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   423
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   424
        int idx = parent.indexOf('/');
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   425
        assert idx != -1 : "invalid parent string";
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   426
        UTF8String name = ROOT.concat(parent.substring(0, idx));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   427
        Directory top = (Directory) nodes.get(name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   428
        if (top == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   429
            top = newDirectory(rootDir, name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   430
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   431
        Directory last = top;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   432
        while ((idx = parent.indexOf('/', idx + 1)) != -1) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   433
            name = ROOT.concat(parent.substring(0, idx));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   434
            Directory nextDir = (Directory) nodes.get(name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   435
            if (nextDir == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   436
                nextDir = newDirectory(last, name);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   437
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   438
            last = nextDir;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   439
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   440
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   441
        return last;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   442
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   443
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   444
    private void fillPackageModuleInfo() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   445
        assert rootDir != null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   446
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   447
        packageMap.entrySet().stream().sorted((x, y)->x.getKey().compareTo(y.getKey())).forEach((entry) -> {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   448
              UTF8String moduleName = new UTF8String("/" + entry.getValue());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   449
              UTF8String fullName = moduleName.concat(new UTF8String(entry.getKey() + "/"));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   450
              if (! nodes.containsKey(fullName)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   451
                  Directory module = (Directory) nodes.get(moduleName);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   452
                  assert module != null : "module directory missing " + moduleName;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   453
                  module.setIsModuleDir();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   454
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   455
                  // hide "packages.offsets" in module directories
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   456
                  Node packagesOffsets = nodes.get(moduleName.concat(ROOT, PACKAGES_OFFSETS));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   457
                  if (packagesOffsets != null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   458
                      packagesOffsets.setIsHidden();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   459
                  }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   460
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   461
                  // package name without front '/'
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   462
                  UTF8String pkgName = new UTF8String(entry.getKey() + "/");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   463
                  int idx = -1;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   464
                  Directory moduleSubDir = module;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   465
                  while ((idx = pkgName.indexOf('/', idx + 1)) != -1) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   466
                      UTF8String subPkg = pkgName.substring(0, idx);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   467
                      UTF8String moduleSubDirName = moduleName.concat(ROOT, subPkg);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   468
                      Directory tmp = (Directory) nodes.get(moduleSubDirName);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   469
                      if (tmp == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   470
                          moduleSubDir = newDirectory(moduleSubDir, moduleSubDirName);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   471
                      } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   472
                          moduleSubDir = tmp;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   473
                      }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   474
                  }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   475
                  // copy pkgDir "resources"
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   476
                  Directory pkgDir = (Directory) nodes.get(ROOT.concat(pkgName.substring(0, pkgName.length() - 1)));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   477
                  pkgDir.setIsTopLevelPackageDir();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   478
                  pkgDir.walk(n -> n.setIsHidden());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   479
                  for (Node child : pkgDir.getChildren()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   480
                      if (child.isResource()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   481
                          ImageLocation loc = child.getLocation();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   482
                          BasicFileAttributes imageFileAttrs = child.getFileAttributes();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   483
                          UTF8String rsName = moduleName.concat(child.getName());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   484
                          Resource rs = new Resource(moduleSubDir, rsName, loc, imageFileAttrs);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   485
                          nodes.put(rs.getName(), rs);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   486
                      }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   487
                  }
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
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   491
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   492
    public byte[] getResource(Node node) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   493
        if (node.isResource()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   494
            return super.getResource(node.getLocation());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   495
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   496
        throw new IOException("Not a resource: " + node);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   497
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   498
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   499
    public byte[] getResource(Resource rs) throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   500
        return super.getResource(rs.getLocation());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   501
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   502
}