jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.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
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    26
package jdk.internal.jrtfs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    27
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    28
import java.nio.file.DirectoryStream;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    29
import java.nio.file.ClosedDirectoryStreamException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    30
import java.nio.file.DirectoryIteratorException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    31
import java.nio.file.NotDirectoryException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    32
import java.nio.file.Path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    33
import java.util.Iterator;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    34
import java.util.NoSuchElementException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    35
import java.io.IOException;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    36
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    37
final class JrtDirectoryStream implements DirectoryStream<Path> {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    38
    private final JrtFileSystem jrtfs;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    39
    private final byte[] path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    40
    // prefix to be used for children of this directory
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    41
    // so that child path are reported relatively (if needed)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    42
    private final String childPrefix;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    43
    private final DirectoryStream.Filter<? super Path> filter;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    44
    private volatile boolean isClosed;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    45
    private volatile Iterator<Path> itr;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    46
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    47
    JrtDirectoryStream(JrtPath jrtPath,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    48
                       DirectoryStream.Filter<? super java.nio.file.Path> filter)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    49
        throws IOException
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    50
    {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    51
        this.jrtfs = jrtPath.getFileSystem();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    52
        this.path = jrtPath.getResolvedPath();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    53
        // sanity check
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    54
        if (!jrtfs.isDirectory(path))
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    55
            throw new NotDirectoryException(jrtPath.toString());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    56
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    57
        // absolute path and does not have funky chars in front like /./java.base
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    58
        if (jrtPath.isAbsolute() && (path.length == jrtPath.getPathLength())) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    59
            childPrefix = null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    60
        } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    61
            // cases where directory content needs to modified with prefix
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    62
            // like ./java.base, /./java.base, java.base and so on.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    63
            String dirName = jrtPath.toString();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    64
            int idx = dirName.indexOf(JrtFileSystem.getString(path).substring(1));
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    65
            childPrefix = dirName.substring(0, idx);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    66
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    67
        this.filter = filter;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    68
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    69
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    70
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    71
    public synchronized Iterator<Path> iterator() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    72
        if (isClosed)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    73
            throw new ClosedDirectoryStreamException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    74
        if (itr != null)
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    75
            throw new IllegalStateException("Iterator has already been returned");
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    76
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    77
        try {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    78
            itr = jrtfs.iteratorOf(path, childPrefix);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    79
        } catch (IOException e) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    80
            throw new IllegalStateException(e);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    81
        }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    82
        return new Iterator<Path>() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    83
            /*
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    84
             * next Path value to return from this iterator.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    85
             * null value means hasNext() not called yet
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    86
             * or last hasNext() returned false or resulted
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    87
             * in exception. If last hasNext() returned true,
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    88
             * then this field has non-null value.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    89
             */
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    90
            private Path next;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    91
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    92
            // get-and-clear and set-next by these methods
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    93
            private Path getAndClearNext() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    94
                assert next != null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    95
                Path result = this.next;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    96
                this.next = null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    97
                return result;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    98
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
    99
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   100
            private void setNext(Path path) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   101
                assert path != null;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   102
                this.next = path;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   103
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   104
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   105
            // if hasNext() returns true, 'next' field has non-null Path
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   106
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   107
            public synchronized boolean hasNext() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   108
                if (next != null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   109
                    return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   110
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   111
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   112
                if (isClosed) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   113
                    return false;
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
                if (filter == null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   117
                    if (itr.hasNext()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   118
                        setNext(itr.next());
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   119
                        return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   120
                    } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   121
                        return false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   122
                    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   123
                } else {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   124
                    while (itr.hasNext()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   125
                        Path tmpPath = itr.next();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   126
                        try {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   127
                            if (filter.accept(tmpPath)) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   128
                                setNext(tmpPath);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   129
                                return true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   130
                            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   131
                        } catch (IOException ioe) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   132
                            throw new DirectoryIteratorException(ioe);
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   133
                        }
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
                    return false;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   137
                }
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
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   141
            public synchronized Path next() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   142
                if (next != null) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   143
                    return getAndClearNext();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   144
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   145
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   146
                if (isClosed) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   147
                    throw new NoSuchElementException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   148
                }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   149
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   150
                if (next == null && itr.hasNext()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   151
                    // missing hasNext() between next() calls.
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   152
                    if (hasNext()) {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   153
                        return getAndClearNext();
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
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   157
                throw new NoSuchElementException();
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
            @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   161
            public void remove() {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   162
                throw new UnsupportedOperationException();
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   163
            }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   164
        };
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
    @Override
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   168
    public synchronized void close() throws IOException {
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   169
        isClosed = true;
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   170
    }
729f9700483a 8049367: Modular Run-Time Images
chegar
parents:
diff changeset
   171
}