Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/java/ClassPath.java
38918 views
1
/*
2
* Copyright (c) 1994, 2012, 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
26
package sun.tools.java;
27
28
import java.util.Enumeration;
29
import java.util.Hashtable;
30
import java.io.File;
31
import java.io.IOException;
32
import java.util.zip.*;
33
34
/**
35
* This class is used to represent a class path, which can contain both
36
* directories and zip files.
37
*
38
* WARNING: The contents of this source file are not part of any
39
* supported API. Code that depends on them does so at its own risk:
40
* they are subject to change or removal without notice.
41
*/
42
public
43
class ClassPath {
44
static final char dirSeparator = File.pathSeparatorChar;
45
46
/**
47
* The original class path string
48
*/
49
String pathstr;
50
51
/**
52
* List of class path entries
53
*/
54
private ClassPathEntry[] path;
55
56
/**
57
* Build a class path from the specified path string
58
*/
59
public ClassPath(String pathstr) {
60
init(pathstr);
61
}
62
63
/**
64
* Build a class path from the specified array of class path
65
* element strings. This constructor, and the corresponding
66
* "init" method, were added as part of the fix for 6473331, which
67
* adds support for Class-Path manifest entries in JAR files to
68
* rmic. It is conceivable that the value of a Class-Path
69
* manifest entry will contain a path separator, which would cause
70
* incorrect behavior if the expanded path were passed to the
71
* previous constructor as a single path-separator-delimited
72
* string; use of this constructor avoids that problem.
73
*/
74
public ClassPath(String[] patharray) {
75
init(patharray);
76
}
77
78
/**
79
* Build a default class path from the path strings specified by
80
* the properties sun.boot.class.path and env.class.path, in that
81
* order.
82
*/
83
public ClassPath() {
84
String syscp = System.getProperty("sun.boot.class.path");
85
String envcp = System.getProperty("env.class.path");
86
if (envcp == null) envcp = ".";
87
String cp = syscp + File.pathSeparator + envcp;
88
init(cp);
89
}
90
91
private void init(String pathstr) {
92
int i, j, n;
93
// Save original class path string
94
this.pathstr = pathstr;
95
96
if (pathstr.length() == 0) {
97
this.path = new ClassPathEntry[0];
98
}
99
100
// Count the number of path separators
101
i = n = 0;
102
while ((i = pathstr.indexOf(dirSeparator, i)) != -1) {
103
n++; i++;
104
}
105
// Build the class path
106
ClassPathEntry[] path = new ClassPathEntry[n+1];
107
int len = pathstr.length();
108
for (i = n = 0; i < len; i = j + 1) {
109
if ((j = pathstr.indexOf(dirSeparator, i)) == -1) {
110
j = len;
111
}
112
if (i == j) {
113
path[n] = new ClassPathEntry();
114
path[n++].dir = new File(".");
115
} else {
116
File file = new File(pathstr.substring(i, j));
117
if (file.isFile()) {
118
try {
119
ZipFile zip = new ZipFile(file);
120
path[n] = new ClassPathEntry();
121
path[n++].zip = zip;
122
} catch (ZipException e) {
123
} catch (IOException e) {
124
// Ignore exceptions, at least for now...
125
}
126
} else {
127
path[n] = new ClassPathEntry();
128
path[n++].dir = file;
129
}
130
}
131
}
132
// Trim class path to exact size
133
this.path = new ClassPathEntry[n];
134
System.arraycopy((Object)path, 0, (Object)this.path, 0, n);
135
}
136
137
private void init(String[] patharray) {
138
// Save original class path string
139
if (patharray.length == 0) {
140
this.pathstr = "";
141
} else {
142
StringBuilder sb = new StringBuilder(patharray[0]);
143
for (int i = 1; i < patharray.length; i++) {
144
sb.append(File.pathSeparatorChar);
145
sb.append(patharray[i]);
146
}
147
this.pathstr = sb.toString();
148
}
149
150
// Build the class path
151
ClassPathEntry[] path = new ClassPathEntry[patharray.length];
152
int n = 0;
153
for (String name : patharray) {
154
File file = new File(name);
155
if (file.isFile()) {
156
try {
157
ZipFile zip = new ZipFile(file);
158
path[n] = new ClassPathEntry();
159
path[n++].zip = zip;
160
} catch (ZipException e) {
161
} catch (IOException e) {
162
// Ignore exceptions, at least for now...
163
}
164
} else {
165
path[n] = new ClassPathEntry();
166
path[n++].dir = file;
167
}
168
}
169
// Trim class path to exact size
170
this.path = new ClassPathEntry[n];
171
System.arraycopy((Object)path, 0, (Object)this.path, 0, n);
172
}
173
174
/**
175
* Find the specified directory in the class path
176
*/
177
public ClassFile getDirectory(String name) {
178
return getFile(name, true);
179
}
180
181
/**
182
* Load the specified file from the class path
183
*/
184
public ClassFile getFile(String name) {
185
return getFile(name, false);
186
}
187
188
private final String fileSeparatorChar = "" + File.separatorChar;
189
190
private ClassFile getFile(String name, boolean isDirectory) {
191
String subdir = name;
192
String basename = "";
193
if (!isDirectory) {
194
int i = name.lastIndexOf(File.separatorChar);
195
subdir = name.substring(0, i + 1);
196
basename = name.substring(i + 1);
197
} else if (!subdir.equals("")
198
&& !subdir.endsWith(fileSeparatorChar)) {
199
// zip files are picky about "foo" vs. "foo/".
200
// also, the getFiles caches are keyed with a trailing /
201
subdir = subdir + File.separatorChar;
202
name = subdir; // Note: isDirectory==true & basename==""
203
}
204
for (int i = 0; i < path.length; i++) {
205
if (path[i].zip != null) {
206
String newname = name.replace(File.separatorChar, '/');
207
ZipEntry entry = path[i].zip.getEntry(newname);
208
if (entry != null) {
209
return new ClassFile(path[i].zip, entry);
210
}
211
} else {
212
File file = new File(path[i].dir.getPath(), name);
213
String list[] = path[i].getFiles(subdir);
214
if (isDirectory) {
215
if (list.length > 0) {
216
return new ClassFile(file);
217
}
218
} else {
219
for (int j = 0; j < list.length; j++) {
220
if (basename.equals(list[j])) {
221
// Don't bother checking !file.isDir,
222
// since we only look for names which
223
// cannot already be packages (foo.java, etc).
224
return new ClassFile(file);
225
}
226
}
227
}
228
}
229
}
230
return null;
231
}
232
233
/**
234
* Returns list of files given a package name and extension.
235
*/
236
public Enumeration getFiles(String pkg, String ext) {
237
Hashtable files = new Hashtable();
238
for (int i = path.length; --i >= 0; ) {
239
if (path[i].zip != null) {
240
Enumeration e = path[i].zip.entries();
241
while (e.hasMoreElements()) {
242
ZipEntry entry = (ZipEntry)e.nextElement();
243
String name = entry.getName();
244
name = name.replace('/', File.separatorChar);
245
if (name.startsWith(pkg) && name.endsWith(ext)) {
246
files.put(name, new ClassFile(path[i].zip, entry));
247
}
248
}
249
} else {
250
String[] list = path[i].getFiles(pkg);
251
for (int j = 0; j < list.length; j++) {
252
String name = list[j];
253
if (name.endsWith(ext)) {
254
name = pkg + File.separatorChar + name;
255
File file = new File(path[i].dir.getPath(), name);
256
files.put(name, new ClassFile(file));
257
}
258
}
259
}
260
}
261
return files.elements();
262
}
263
264
/**
265
* Release resources.
266
*/
267
public void close() throws IOException {
268
for (int i = path.length; --i >= 0; ) {
269
if (path[i].zip != null) {
270
path[i].zip.close();
271
}
272
}
273
}
274
275
/**
276
* Returns original class path string
277
*/
278
public String toString() {
279
return pathstr;
280
}
281
}
282
283
/**
284
* A class path entry, which can either be a directory or an open zip file.
285
*/
286
class ClassPathEntry {
287
File dir;
288
ZipFile zip;
289
290
Hashtable subdirs = new Hashtable(29); // cache of sub-directory listings
291
String[] getFiles(String subdir) {
292
String files[] = (String[]) subdirs.get(subdir);
293
if (files == null) {
294
// search the directory, exactly once
295
File sd = new File(dir.getPath(), subdir);
296
if (sd.isDirectory()) {
297
files = sd.list();
298
if (files == null) {
299
// should not happen, but just in case, fail silently
300
files = new String[0];
301
}
302
if (files.length == 0) {
303
String nonEmpty[] = { "" };
304
files = nonEmpty;
305
}
306
} else {
307
files = new String[0];
308
}
309
subdirs.put(subdir, files);
310
}
311
return files;
312
}
313
314
}
315
316