jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtDirectoryStream.java
changeset 37365 9cc4eb4d7491
parent 36511 9d0388c6b336
child 40570 9217de724b92
equal deleted inserted replaced
37364:80be215c8c51 37365:9cc4eb4d7491
    28 import java.nio.file.ClosedDirectoryStreamException;
    28 import java.nio.file.ClosedDirectoryStreamException;
    29 import java.nio.file.DirectoryIteratorException;
    29 import java.nio.file.DirectoryIteratorException;
    30 import java.nio.file.NotDirectoryException;
    30 import java.nio.file.NotDirectoryException;
    31 import java.nio.file.Path;
    31 import java.nio.file.Path;
    32 import java.util.Iterator;
    32 import java.util.Iterator;
       
    33 import java.util.Objects;
    33 import java.util.NoSuchElementException;
    34 import java.util.NoSuchElementException;
    34 import java.io.IOException;
    35 import java.io.IOException;
    35 
    36 
    36 /**
    37 /**
    37  * DirectoryStream implementation for jrt file system implementations.
    38  * DirectoryStream implementation for jrt file system implementations.
    42  * but also compiled and delivered as part of the jrtfs.jar to support access
    43  * but also compiled and delivered as part of the jrtfs.jar to support access
    43  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
    44  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
    44  */
    45  */
    45 final class JrtDirectoryStream implements DirectoryStream<Path> {
    46 final class JrtDirectoryStream implements DirectoryStream<Path> {
    46 
    47 
    47     private final AbstractJrtFileSystem jrtfs;
    48     private final JrtPath dir;
    48     private final AbstractJrtPath dir;
       
    49     private final DirectoryStream.Filter<? super Path> filter;
    49     private final DirectoryStream.Filter<? super Path> filter;
    50     private volatile boolean isClosed;
    50     private volatile boolean isClosed;
    51     private volatile Iterator<Path> itr;
    51     private volatile Iterator<Path> itr;
    52 
    52 
    53     JrtDirectoryStream(AbstractJrtPath jrtPath,
    53     JrtDirectoryStream(JrtPath dir,
    54             DirectoryStream.Filter<? super java.nio.file.Path> filter)
    54             DirectoryStream.Filter<? super java.nio.file.Path> filter)
    55             throws IOException {
    55             throws IOException
    56         this.jrtfs = jrtPath.getFileSystem();
    56     {
    57         this.dir = jrtPath;
    57         this.dir = dir;
    58         // sanity check
    58         if (!dir.jrtfs.isDirectory(dir, true)) {  // sanity check
    59         if (!jrtfs.isDirectory(dir, true)) {
    59             throw new NotDirectoryException(dir.toString());
    60             throw new NotDirectoryException(jrtPath.toString());
       
    61         }
    60         }
    62 
       
    63         this.filter = filter;
    61         this.filter = filter;
    64     }
    62     }
    65 
    63 
    66     @Override
    64     @Override
    67     public synchronized Iterator<Path> iterator() {
    65     public synchronized Iterator<Path> iterator() {
    68         if (isClosed) {
    66         if (isClosed)
    69             throw new ClosedDirectoryStreamException();
    67             throw new ClosedDirectoryStreamException();
    70         }
    68         if (itr != null)
    71         if (itr != null) {
       
    72             throw new IllegalStateException("Iterator has already been returned");
    69             throw new IllegalStateException("Iterator has already been returned");
    73         }
       
    74 
       
    75         try {
    70         try {
    76             itr = jrtfs.iteratorOf(dir);
    71             itr = dir.jrtfs.iteratorOf(dir, filter);
    77         } catch (IOException e) {
    72         } catch (IOException e) {
    78             throw new IllegalStateException(e);
    73             throw new IllegalStateException(e);
    79         }
    74         }
    80         return new Iterator<Path>() {
    75         return new Iterator<Path>() {
    81             /*
       
    82              * next Path value to return from this iterator.
       
    83              * null value means hasNext() not called yet
       
    84              * or last hasNext() returned false or resulted
       
    85              * in exception. If last hasNext() returned true,
       
    86              * then this field has non-null value.
       
    87              */
       
    88             private Path next;
    76             private Path next;
    89 
       
    90             // get-and-clear and set-next by these methods
       
    91             private Path getAndClearNext() {
       
    92                 assert next != null;
       
    93                 Path result = this.next;
       
    94                 this.next = null;
       
    95                 return result;
       
    96             }
       
    97 
       
    98             private void setNext(Path path) {
       
    99                 assert path != null;
       
   100                 this.next = path;
       
   101             }
       
   102 
       
   103             // if hasNext() returns true, 'next' field has non-null Path
       
   104             @Override
    77             @Override
   105             public synchronized boolean hasNext() {
    78             public synchronized boolean hasNext() {
   106                 if (next != null) {
    79                 if (isClosed)
   107                     return true;
       
   108                 }
       
   109 
       
   110                 if (isClosed) {
       
   111                     return false;
    80                     return false;
   112                 }
    81                 return itr.hasNext();
   113 
       
   114                 if (filter == null) {
       
   115                     if (itr.hasNext()) {
       
   116                         setNext(itr.next());
       
   117                         return true;
       
   118                     } else {
       
   119                         return false;
       
   120                     }
       
   121                 } else {
       
   122                     while (itr.hasNext()) {
       
   123                         Path tmpPath = itr.next();
       
   124                         try {
       
   125                             if (filter.accept(tmpPath)) {
       
   126                                 setNext(tmpPath);
       
   127                                 return true;
       
   128                             }
       
   129                         } catch (IOException ioe) {
       
   130                             throw new DirectoryIteratorException(ioe);
       
   131                         }
       
   132                     }
       
   133 
       
   134                     return false;
       
   135                 }
       
   136             }
    82             }
   137 
    83 
   138             @Override
    84             @Override
   139             public synchronized Path next() {
    85             public synchronized Path next() {
   140                 if (next != null) {
    86                 if (isClosed)
   141                     return getAndClearNext();
       
   142                 }
       
   143 
       
   144                 if (isClosed) {
       
   145                     throw new NoSuchElementException();
    87                     throw new NoSuchElementException();
   146                 }
    88                 return itr.next();
   147 
       
   148                 if (next == null && itr.hasNext()) {
       
   149                     // missing hasNext() between next() calls.
       
   150                     if (hasNext()) {
       
   151                         return getAndClearNext();
       
   152                     }
       
   153                 }
       
   154 
       
   155                 throw new NoSuchElementException();
       
   156             }
    89             }
   157 
    90 
   158             @Override
    91             @Override
   159             public void remove() {
    92             public void remove() {
   160                 throw new UnsupportedOperationException();
    93                 throw new UnsupportedOperationException();