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 } |
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 |