langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndex.java
changeset 27225 8369cde9152a
parent 25874 83c19f00452c
child 27226 53535e4e1b08
equal deleted inserted replaced
27224:228abfa87080 27225:8369cde9152a
     1 /*
     1 /*
     2  * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.javac.file;
    26 package com.sun.tools.javac.file;
    27 
    27 
    28 
    28 
    29 import java.io.File;
       
    30 import java.io.FileNotFoundException;
    29 import java.io.FileNotFoundException;
    31 import java.io.IOException;
    30 import java.io.IOException;
    32 import java.io.RandomAccessFile;
    31 import java.io.RandomAccessFile;
    33 import java.lang.ref.Reference;
    32 import java.lang.ref.Reference;
    34 import java.lang.ref.SoftReference;
    33 import java.lang.ref.SoftReference;
       
    34 import java.nio.file.Files;
       
    35 import java.nio.file.Path;
       
    36 import java.nio.file.Paths;
    35 import java.util.ArrayList;
    37 import java.util.ArrayList;
    36 import java.util.Arrays;
    38 import java.util.Arrays;
    37 import java.util.Calendar;
    39 import java.util.Calendar;
    38 import java.util.Collections;
    40 import java.util.Collections;
       
    41 import java.util.HashMap;
    39 import java.util.LinkedHashMap;
    42 import java.util.LinkedHashMap;
    40 import java.util.HashMap;
       
    41 import java.util.List;
    43 import java.util.List;
    42 import java.util.Map;
    44 import java.util.Map;
    43 import java.util.Set;
    45 import java.util.Set;
    44 import java.util.zip.DataFormatException;
    46 import java.util.zip.DataFormatException;
    45 import java.util.zip.Inflater;
    47 import java.util.zip.Inflater;
    89             Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
    91             Collections.<RelativeDirectory, DirectoryEntry>emptyMap();
    90     private Set<RelativeDirectory> allDirs =
    92     private Set<RelativeDirectory> allDirs =
    91             Collections.<RelativeDirectory>emptySet();
    93             Collections.<RelativeDirectory>emptySet();
    92 
    94 
    93     // ZipFileIndex data entries
    95     // ZipFileIndex data entries
    94     final File zipFile;
    96     final Path zipFile;
    95     private Reference<File> absFileRef;
    97     private Reference<Path> absFileRef;
    96     long zipFileLastModified = NOT_MODIFIED;
    98     long zipFileLastModified = NOT_MODIFIED;
    97     private RandomAccessFile zipRandomFile;
    99     private RandomAccessFile zipRandomFile;
    98     private Entry[] entries;
   100     private Entry[] entries;
    99 
   101 
   100     private boolean readFromIndex = false;
   102     private boolean readFromIndex = false;
   101     private File zipIndexFile = null;
   103     private Path zipIndexFile = null;
   102     private boolean triedToReadIndex = false;
   104     private boolean triedToReadIndex = false;
   103     final RelativeDirectory symbolFilePrefix;
   105     final RelativeDirectory symbolFilePrefix;
   104     private final int symbolFilePrefixLength;
   106     private final int symbolFilePrefixLength;
   105     private boolean hasPopulatedData = false;
   107     private boolean hasPopulatedData = false;
   106     long lastReferenceTimeStamp = NOT_MODIFIED;
   108     long lastReferenceTimeStamp = NOT_MODIFIED;
   115 
   117 
   116     public synchronized boolean isOpen() {
   118     public synchronized boolean isOpen() {
   117         return (zipRandomFile != null);
   119         return (zipRandomFile != null);
   118     }
   120     }
   119 
   121 
   120     ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
   122     ZipFileIndex(Path zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
   121             boolean useCache, String cacheLocation) throws IOException {
   123             boolean useCache, String cacheLocation) throws IOException {
   122         this.zipFile = zipFile;
   124         this.zipFile = zipFile;
   123         this.symbolFilePrefix = symbolFilePrefix;
   125         this.symbolFilePrefix = symbolFilePrefix;
   124         this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 :
   126         this.symbolFilePrefixLength = (symbolFilePrefix == null ? 0 :
   125             symbolFilePrefix.getPath().getBytes("UTF-8").length);
   127             symbolFilePrefix.getPath().getBytes("UTF-8").length);
   126         this.writeIndex = writeIndex;
   128         this.writeIndex = writeIndex;
   127         this.usePreindexedCache = useCache;
   129         this.usePreindexedCache = useCache;
   128         this.preindexedCacheLocation = cacheLocation;
   130         this.preindexedCacheLocation = cacheLocation;
   129 
   131 
   130         if (zipFile != null) {
   132         if (zipFile != null) {
   131             this.zipFileLastModified = zipFile.lastModified();
   133             this.zipFileLastModified = Files.getLastModifiedTime(zipFile).toMillis();
   132         }
   134         }
   133 
   135 
   134         // Validate integrity of the zip file
   136         // Validate integrity of the zip file
   135         checkIndex();
   137         checkIndex();
   136     }
   138     }
   146         closeFile();
   148         closeFile();
   147         super.finalize();
   149         super.finalize();
   148     }
   150     }
   149 
   151 
   150     private boolean isUpToDate() {
   152     private boolean isUpToDate() {
   151         if (zipFile != null
   153         try {
   152                 && ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified())
   154             return (zipFile != null
   153                 && hasPopulatedData) {
   155                     && ((!NON_BATCH_MODE) || zipFileLastModified == Files.getLastModifiedTime(zipFile).toMillis())
   154             return true;
   156                     && hasPopulatedData);
       
   157         } catch (IOException ignore) {
   155         }
   158         }
   156 
   159 
   157         return false;
   160         return false;
   158     }
   161     }
   159 
   162 
   197         lastReferenceTimeStamp = System.currentTimeMillis();
   200         lastReferenceTimeStamp = System.currentTimeMillis();
   198     }
   201     }
   199 
   202 
   200     private void openFile() throws FileNotFoundException {
   203     private void openFile() throws FileNotFoundException {
   201         if (zipRandomFile == null && zipFile != null) {
   204         if (zipRandomFile == null && zipFile != null) {
   202             zipRandomFile = new RandomAccessFile(zipFile, "r");
   205             zipRandomFile = new RandomAccessFile(zipFile.toFile(), "r");
   203         }
   206         }
   204     }
   207     }
   205 
   208 
   206     private void cleanupState() {
   209     private void cleanupState() {
   207         // Make sure there is a valid but empty index if the file doesn't exist
   210         // Make sure there is a valid but empty index if the file doesn't exist
   783 
   786 
   784                 for (int i = from; i < to; i++) {
   787                 for (int i = from; i < to; i++) {
   785                     entries.add(zipFileIndex.entries[i]);
   788                     entries.add(zipFileIndex.entries[i]);
   786                 }
   789                 }
   787             } else {
   790             } else {
   788                 File indexFile = zipFileIndex.getIndexFile();
   791                 Path indexFile = zipFileIndex.getIndexFile();
   789                 if (indexFile != null) {
   792                 if (indexFile != null) {
   790                     RandomAccessFile raf = null;
   793                     RandomAccessFile raf = null;
   791                     try {
   794                     try {
   792                         raf = new RandomAccessFile(indexFile, "r");
   795                         raf = new RandomAccessFile(indexFile.toFile(), "r");
   793                         raf.seek(writtenOffsetOffset);
   796                         raf.seek(writtenOffsetOffset);
   794 
   797 
   795                         for (int nFiles = 0; nFiles < numEntries; nFiles++) {
   798                         for (int nFiles = 0; nFiles < numEntries; nFiles++) {
   796                             // Read the name bytes
   799                             // Read the name bytes
   797                             int zfieNameBytesLen = raf.readInt();
   800                             int zfieNameBytesLen = raf.readInt();
   854         boolean ret = false;
   857         boolean ret = false;
   855         synchronized (this) {
   858         synchronized (this) {
   856             triedToReadIndex = true;
   859             triedToReadIndex = true;
   857             RandomAccessFile raf = null;
   860             RandomAccessFile raf = null;
   858             try {
   861             try {
   859                 File indexFileName = getIndexFile();
   862                 Path indexFileName = getIndexFile();
   860                 raf = new RandomAccessFile(indexFileName, "r");
   863                 raf = new RandomAccessFile(indexFileName.toFile(), "r");
   861 
   864 
   862                 long fileStamp = raf.readLong();
   865                 long fileStamp = raf.readLong();
   863                 if (zipFile.lastModified() != fileStamp) {
   866                 if (Files.getLastModifiedTime(zipFile).toMillis() != fileStamp) {
   864                     ret = false;
   867                     ret = false;
   865                 } else {
   868                 } else {
   866                     directories = new LinkedHashMap<>();
   869                     directories = new LinkedHashMap<>();
   867                     int numDirs = raf.readInt();
   870                     int numDirs = raf.readInt();
   868                     for (int nDirs = 0; nDirs < numDirs; nDirs++) {
   871                     for (int nDirs = 0; nDirs < numDirs; nDirs++) {
   906 
   909 
   907         if (!writeIndex) {
   910         if (!writeIndex) {
   908             return true;
   911             return true;
   909         }
   912         }
   910 
   913 
   911         File indexFile = getIndexFile();
   914         Path indexFile = getIndexFile();
   912         if (indexFile == null) {
   915         if (indexFile == null) {
   913             return false;
   916             return false;
   914         }
   917         }
   915 
   918 
   916         RandomAccessFile raf = null;
   919         RandomAccessFile raf = null;
   917         long writtenSoFar = 0;
   920         long writtenSoFar = 0;
   918         try {
   921         try {
   919             raf = new RandomAccessFile(indexFile, "rw");
   922             raf = new RandomAccessFile(indexFile.toFile(), "rw");
   920 
   923 
   921             raf.writeLong(zipFileLastModified);
   924             raf.writeLong(zipFileLastModified);
   922             writtenSoFar += 8;
   925             writtenSoFar += 8;
   923 
   926 
   924             List<DirectoryEntry> directoriesToWrite = new ArrayList<>();
   927             List<DirectoryEntry> directoriesToWrite = new ArrayList<>();
  1014         synchronized (this) {
  1017         synchronized (this) {
  1015             return writeIndex();
  1018             return writeIndex();
  1016         }
  1019         }
  1017     }
  1020     }
  1018 
  1021 
  1019     private File getIndexFile() {
  1022     private Path getIndexFile() {
  1020         if (zipIndexFile == null) {
  1023         if (zipIndexFile == null) {
  1021             if (zipFile == null) {
  1024             if (zipFile == null) {
  1022                 return null;
  1025                 return null;
  1023             }
  1026             }
  1024 
  1027 
  1025             zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
  1028             zipIndexFile = Paths.get((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
  1026                     zipFile.getName() + ".index");
  1029                     zipFile.getFileName() + ".index");
  1027         }
  1030         }
  1028 
  1031 
  1029         return zipIndexFile;
  1032         return zipIndexFile;
  1030     }
  1033     }
  1031 
  1034 
  1032     public File getZipFile() {
  1035     public Path getZipFile() {
  1033         return zipFile;
  1036         return zipFile;
  1034     }
  1037     }
  1035 
  1038 
  1036     File getAbsoluteFile() {
  1039     Path getAbsoluteFile() {
  1037         File absFile = (absFileRef == null ? null : absFileRef.get());
  1040         Path absFile = (absFileRef == null ? null : absFileRef.get());
  1038         if (absFile == null) {
  1041         if (absFile == null) {
  1039             absFile = zipFile.getAbsoluteFile();
  1042             absFile = zipFile.toAbsolutePath();
  1040             absFileRef = new SoftReference<>(absFile);
  1043             absFileRef = new SoftReference<>(absFile);
  1041         }
  1044         }
  1042         return absFile;
  1045         return absFile;
  1043     }
  1046     }
  1044 
  1047