Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java
38899 views
1
/*
2
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package com.sun.tools.jdeps;
26
27
import com.sun.tools.classfile.ClassFile;
28
import com.sun.tools.classfile.ConstantPoolException;
29
import com.sun.tools.classfile.Dependencies.ClassFileError;
30
import java.io.*;
31
import java.nio.file.FileVisitResult;
32
import java.nio.file.Files;
33
import java.nio.file.Path;
34
import java.nio.file.SimpleFileVisitor;
35
import java.nio.file.attribute.BasicFileAttributes;
36
import java.util.*;
37
import java.util.jar.Attributes;
38
import java.util.jar.JarEntry;
39
import java.util.jar.JarFile;
40
import java.util.jar.Manifest;
41
42
/**
43
* ClassFileReader reads ClassFile(s) of a given path that can be
44
* a .class file, a directory, or a JAR file.
45
*/
46
public class ClassFileReader {
47
/**
48
* Returns a ClassFileReader instance of a given path.
49
*/
50
public static ClassFileReader newInstance(Path path) throws IOException {
51
if (!Files.exists(path)) {
52
throw new FileNotFoundException(path.toString());
53
}
54
55
if (Files.isDirectory(path)) {
56
return new DirectoryReader(path);
57
} else if (path.getFileName().toString().endsWith(".jar")) {
58
return new JarFileReader(path);
59
} else {
60
return new ClassFileReader(path);
61
}
62
}
63
64
/**
65
* Returns a ClassFileReader instance of a given JarFile.
66
*/
67
public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException {
68
return new JarFileReader(path, jf);
69
}
70
71
protected final Path path;
72
protected final String baseFileName;
73
protected final List<String> skippedEntries = new ArrayList<>();
74
protected ClassFileReader(Path path) {
75
this.path = path;
76
this.baseFileName = path.getFileName() != null
77
? path.getFileName().toString()
78
: path.toString();
79
}
80
81
public String getFileName() {
82
return baseFileName;
83
}
84
85
public List<String> skippedEntries() {
86
return skippedEntries;
87
}
88
89
/**
90
* Returns the ClassFile matching the given binary name
91
* or a fully-qualified class name.
92
*/
93
public ClassFile getClassFile(String name) throws IOException {
94
if (name.indexOf('.') > 0) {
95
int i = name.lastIndexOf('.');
96
String pathname = name.replace('.', File.separatorChar) + ".class";
97
if (baseFileName.equals(pathname) ||
98
baseFileName.equals(pathname.substring(0, i) + "$" +
99
pathname.substring(i+1, pathname.length()))) {
100
return readClassFile(path);
101
}
102
} else {
103
if (baseFileName.equals(name.replace('/', File.separatorChar) + ".class")) {
104
return readClassFile(path);
105
}
106
}
107
return null;
108
}
109
110
public Iterable<ClassFile> getClassFiles() throws IOException {
111
return new Iterable<ClassFile>() {
112
public Iterator<ClassFile> iterator() {
113
return new FileIterator();
114
}
115
};
116
}
117
118
protected ClassFile readClassFile(Path p) throws IOException {
119
InputStream is = null;
120
try {
121
is = Files.newInputStream(p);
122
return ClassFile.read(is);
123
} catch (ConstantPoolException e) {
124
throw new ClassFileError(e);
125
} finally {
126
if (is != null) {
127
is.close();
128
}
129
}
130
}
131
132
class FileIterator implements Iterator<ClassFile> {
133
int count;
134
FileIterator() {
135
this.count = 0;
136
}
137
public boolean hasNext() {
138
return count == 0 && baseFileName.endsWith(".class");
139
}
140
141
public ClassFile next() {
142
if (!hasNext()) {
143
throw new NoSuchElementException();
144
}
145
try {
146
ClassFile cf = readClassFile(path);
147
count++;
148
return cf;
149
} catch (IOException e) {
150
throw new ClassFileError(e);
151
}
152
}
153
154
public void remove() {
155
throw new UnsupportedOperationException("Not supported yet.");
156
}
157
}
158
159
public boolean isMultiReleaseJar() throws IOException { return false; }
160
161
public String toString() {
162
return path.toString();
163
}
164
165
private static class DirectoryReader extends ClassFileReader {
166
DirectoryReader(Path path) throws IOException {
167
super(path);
168
}
169
170
public ClassFile getClassFile(String name) throws IOException {
171
if (name.indexOf('.') > 0) {
172
int i = name.lastIndexOf('.');
173
String pathname = name.replace('.', File.separatorChar) + ".class";
174
Path p = path.resolve(pathname);
175
if (!Files.exists(p)) {
176
p = path.resolve(pathname.substring(0, i) + "$" +
177
pathname.substring(i+1, pathname.length()));
178
}
179
if (Files.exists(p)) {
180
return readClassFile(p);
181
}
182
} else {
183
Path p = path.resolve(name + ".class");
184
if (Files.exists(p)) {
185
return readClassFile(p);
186
}
187
}
188
return null;
189
}
190
191
public Iterable<ClassFile> getClassFiles() throws IOException {
192
final Iterator<ClassFile> iter = new DirectoryIterator();
193
return new Iterable<ClassFile>() {
194
public Iterator<ClassFile> iterator() {
195
return iter;
196
}
197
};
198
}
199
200
private List<Path> walkTree(Path dir) throws IOException {
201
final List<Path> files = new ArrayList<Path>();
202
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
203
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
204
throws IOException {
205
if (file.getFileName().toString().endsWith(".class")) {
206
files.add(file);
207
}
208
return FileVisitResult.CONTINUE;
209
}
210
});
211
return files;
212
}
213
214
class DirectoryIterator implements Iterator<ClassFile> {
215
private List<Path> entries;
216
private int index = 0;
217
DirectoryIterator() throws IOException {
218
entries = walkTree(path);
219
index = 0;
220
}
221
222
public boolean hasNext() {
223
return index != entries.size();
224
}
225
226
public ClassFile next() {
227
if (!hasNext()) {
228
throw new NoSuchElementException();
229
}
230
Path path = entries.get(index++);
231
try {
232
return readClassFile(path);
233
} catch (IOException e) {
234
throw new ClassFileError(e);
235
}
236
}
237
238
public void remove() {
239
throw new UnsupportedOperationException("Not supported yet.");
240
}
241
}
242
}
243
244
static class JarFileReader extends ClassFileReader {
245
private final JarFile jarfile;
246
JarFileReader(Path path) throws IOException {
247
this(path, new JarFile(path.toFile(), false));
248
}
249
250
JarFileReader(Path path, JarFile jf) throws IOException {
251
super(path);
252
this.jarfile = jf;
253
}
254
255
public ClassFile getClassFile(String name) throws IOException {
256
if (name.indexOf('.') > 0) {
257
int i = name.lastIndexOf('.');
258
String entryName = name.replace('.', '/') + ".class";
259
JarEntry e = jarfile.getJarEntry(entryName);
260
if (e == null) {
261
e = jarfile.getJarEntry(entryName.substring(0, i) + "$"
262
+ entryName.substring(i + 1, entryName.length()));
263
}
264
if (e != null) {
265
return readClassFile(jarfile, e);
266
}
267
} else {
268
JarEntry e = jarfile.getJarEntry(name + ".class");
269
if (e != null) {
270
return readClassFile(jarfile, e);
271
}
272
}
273
return null;
274
}
275
276
protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException {
277
InputStream is = null;
278
try {
279
is = jarfile.getInputStream(e);
280
return ClassFile.read(is);
281
} catch (ConstantPoolException ex) {
282
throw new ClassFileError(ex);
283
} finally {
284
if (is != null)
285
is.close();
286
}
287
}
288
289
public Iterable<ClassFile> getClassFiles() throws IOException {
290
final Iterator<ClassFile> iter = new JarFileIterator(this, jarfile);
291
return new Iterable<ClassFile>() {
292
public Iterator<ClassFile> iterator() {
293
return iter;
294
}
295
};
296
}
297
298
@Override
299
public boolean isMultiReleaseJar() throws IOException {
300
Manifest mf = this.jarfile.getManifest();
301
if (mf != null) {
302
Attributes atts = mf.getMainAttributes();
303
return "true".equalsIgnoreCase(atts.getValue("Multi-Release"));
304
}
305
return false;
306
}
307
}
308
309
class JarFileIterator implements Iterator<ClassFile> {
310
protected final JarFileReader reader;
311
protected Enumeration<JarEntry> entries;
312
protected JarFile jf;
313
protected JarEntry nextEntry;
314
protected ClassFile cf;
315
JarFileIterator(JarFileReader reader) {
316
this(reader, null);
317
}
318
JarFileIterator(JarFileReader reader, JarFile jarfile) {
319
this.reader = reader;
320
setJarFile(jarfile);
321
}
322
323
void setJarFile(JarFile jarfile) {
324
if (jarfile == null) return;
325
326
this.jf = jarfile;
327
this.entries = jf.entries();
328
this.nextEntry = nextEntry();
329
}
330
331
public boolean hasNext() {
332
if (nextEntry != null && cf != null) {
333
return true;
334
}
335
while (nextEntry != null) {
336
try {
337
cf = reader.readClassFile(jf, nextEntry);
338
return true;
339
} catch (ClassFileError | IOException ex) {
340
skippedEntries.add(nextEntry.getName());
341
}
342
nextEntry = nextEntry();
343
}
344
return false;
345
}
346
347
public ClassFile next() {
348
if (!hasNext()) {
349
throw new NoSuchElementException();
350
}
351
ClassFile classFile = cf;
352
cf = null;
353
nextEntry = nextEntry();
354
return classFile;
355
}
356
357
protected JarEntry nextEntry() {
358
while (entries.hasMoreElements()) {
359
JarEntry e = entries.nextElement();
360
String name = e.getName();
361
if (name.endsWith(".class")) {
362
return e;
363
}
364
}
365
return null;
366
}
367
368
public void remove() {
369
throw new UnsupportedOperationException("Not supported yet.");
370
}
371
}
372
}
373
374