Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/com/sun/naming/internal/VersionHelper.java
41161 views
1
/*
2
* Copyright (c) 1999, 2021, 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 com.sun.naming.internal;
27
28
import javax.naming.NamingEnumeration;
29
import java.io.IOException;
30
import java.io.InputStream;
31
import java.net.MalformedURLException;
32
import java.net.URL;
33
import java.net.URLClassLoader;
34
import java.nio.file.Files;
35
import java.nio.file.Path;
36
import java.security.AccessController;
37
import java.security.PrivilegedAction;
38
import java.security.PrivilegedActionException;
39
import java.security.PrivilegedExceptionAction;
40
import java.util.*;
41
42
/**
43
* VersionHelper was used by JNDI to accommodate differences between
44
* JDK 1.1.x and the Java 2 platform. As this is no longer necessary
45
* since JNDI's inclusion in the platform, this class currently
46
* serves as a set of utilities for performing system-level things,
47
* such as class-loading and reading system properties.
48
*
49
* @author Rosanna Lee
50
* @author Scott Seligman
51
*/
52
53
public final class VersionHelper {
54
private static final VersionHelper helper = new VersionHelper();
55
56
/**
57
* Determines whether classes may be loaded from an arbitrary URL code base.
58
*/
59
private static final boolean TRUST_URL_CODE_BASE;
60
61
static {
62
// System property to control whether classes may be loaded from an
63
// arbitrary URL code base
64
PrivilegedAction<String> act
65
= () -> System.getProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false");
66
@SuppressWarnings("removal")
67
String trust = AccessController.doPrivileged(act);
68
TRUST_URL_CODE_BASE = "true".equalsIgnoreCase(trust);
69
}
70
71
static final String[] PROPS = new String[]{
72
javax.naming.Context.INITIAL_CONTEXT_FACTORY,
73
javax.naming.Context.OBJECT_FACTORIES,
74
javax.naming.Context.URL_PKG_PREFIXES,
75
javax.naming.Context.STATE_FACTORIES,
76
javax.naming.Context.PROVIDER_URL,
77
javax.naming.Context.DNS_URL,
78
// The following shouldn't create a runtime dependence on ldap package.
79
javax.naming.ldap.LdapContext.CONTROL_FACTORIES
80
};
81
82
public static final int INITIAL_CONTEXT_FACTORY = 0;
83
public static final int OBJECT_FACTORIES = 1;
84
public static final int URL_PKG_PREFIXES = 2;
85
public static final int STATE_FACTORIES = 3;
86
public static final int PROVIDER_URL = 4;
87
public static final int DNS_URL = 5;
88
public static final int CONTROL_FACTORIES = 6;
89
90
private VersionHelper() {} // Disallow anyone from creating one of these.
91
92
public static VersionHelper getVersionHelper() {
93
return helper;
94
}
95
96
public Class<?> loadClass(String className) throws ClassNotFoundException {
97
return loadClass(className, getContextClassLoader());
98
}
99
100
public Class<?> loadClassWithoutInit(String className) throws ClassNotFoundException {
101
return loadClass(className, false, getContextClassLoader());
102
}
103
104
/**
105
* @param className A non-null fully qualified class name.
106
* @param codebase A non-null, space-separated list of URL strings.
107
*/
108
public Class<?> loadClass(String className, String codebase)
109
throws ClassNotFoundException, MalformedURLException {
110
if (TRUST_URL_CODE_BASE) {
111
ClassLoader parent = getContextClassLoader();
112
ClassLoader cl
113
= URLClassLoader.newInstance(getUrlArray(codebase), parent);
114
return loadClass(className, cl);
115
} else {
116
return null;
117
}
118
}
119
120
/**
121
* Package private.
122
* <p>
123
* This internal method is used with Thread Context Class Loader (TCCL),
124
* please don't expose this method as public.
125
*/
126
Class<?> loadClass(String className, boolean initialize, ClassLoader cl)
127
throws ClassNotFoundException {
128
Class<?> cls = Class.forName(className, initialize, cl);
129
return cls;
130
}
131
132
Class<?> loadClass(String className, ClassLoader cl)
133
throws ClassNotFoundException {
134
return loadClass(className, true, cl);
135
}
136
137
/*
138
* Returns a JNDI property from the system properties. Returns
139
* null if the property is not set, or if there is no permission
140
* to read it.
141
*/
142
@SuppressWarnings("removal")
143
String getJndiProperty(int i) {
144
PrivilegedAction<String> act = () -> {
145
try {
146
return System.getProperty(PROPS[i]);
147
} catch (SecurityException e) {
148
return null;
149
}
150
};
151
return AccessController.doPrivileged(act);
152
}
153
154
/*
155
* Reads each property in PROPS from the system properties, and
156
* returns their values -- in order -- in an array. For each
157
* unset property, the corresponding array element is set to null.
158
* Returns null if there is no permission to call System.getProperties().
159
*/
160
String[] getJndiProperties() {
161
PrivilegedAction<Properties> act = () -> {
162
try {
163
return System.getProperties();
164
} catch (SecurityException e) {
165
return null;
166
}
167
};
168
@SuppressWarnings("removal")
169
Properties sysProps = AccessController.doPrivileged(act);
170
if (sysProps == null) {
171
return null;
172
}
173
String[] jProps = new String[PROPS.length];
174
for (int i = 0; i < PROPS.length; i++) {
175
jProps[i] = sysProps.getProperty(PROPS[i]);
176
}
177
return jProps;
178
}
179
180
private static String resolveName(Class<?> c, String name) {
181
if (name == null) {
182
return name;
183
}
184
if (!name.startsWith("/")) {
185
if (!c.isPrimitive()) {
186
String baseName = c.getPackageName();
187
if (!baseName.isEmpty()) {
188
name = baseName.replace('.', '/') + "/"
189
+ name;
190
}
191
}
192
} else {
193
name = name.substring(1);
194
}
195
return name;
196
}
197
198
/*
199
* Returns the resource of a given name associated with a particular
200
* class (never null), or null if none can be found.
201
*/
202
@SuppressWarnings("removal")
203
InputStream getResourceAsStream(Class<?> c, String name) {
204
PrivilegedAction<InputStream> act = () -> {
205
try {
206
return c.getModule().getResourceAsStream(resolveName(c, name));
207
} catch (IOException x) {
208
return null;
209
}
210
};
211
return AccessController.doPrivileged(act);
212
}
213
214
/*
215
* Returns an input stream for a file in <java.home>/conf,
216
* or null if it cannot be located or opened.
217
*
218
* @param filename The file name, sans directory.
219
*/
220
@SuppressWarnings("removal")
221
InputStream getJavaHomeConfStream(String filename) {
222
PrivilegedAction<InputStream> act = () -> {
223
try {
224
String javahome = System.getProperty("java.home");
225
if (javahome == null) {
226
return null;
227
}
228
return Files.newInputStream(Path.of(javahome, "conf", filename));
229
} catch (Exception e) {
230
return null;
231
}
232
};
233
return AccessController.doPrivileged(act);
234
}
235
236
/*
237
* Returns an enumeration (never null) of InputStreams of the
238
* resources of a given name associated with a particular class
239
* loader. Null represents the bootstrap class loader in some
240
* Java implementations.
241
*/
242
@SuppressWarnings("removal")
243
NamingEnumeration<InputStream> getResources(ClassLoader cl,
244
String name) throws IOException {
245
Enumeration<URL> urls;
246
PrivilegedExceptionAction<Enumeration<URL>> act = () ->
247
(cl == null)
248
? ClassLoader.getSystemResources(name)
249
: cl.getResources(name);
250
try {
251
urls = AccessController.doPrivileged(act);
252
} catch (PrivilegedActionException e) {
253
throw (IOException) e.getException();
254
}
255
return new InputStreamEnumeration(urls);
256
}
257
258
259
/**
260
* Package private.
261
* <p>
262
* This internal method returns Thread Context Class Loader (TCCL),
263
* if null, returns the system Class Loader.
264
* <p>
265
* Please don't expose this method as public.
266
* @throws SecurityException if the class loader is not accessible
267
*/
268
@SuppressWarnings("removal")
269
ClassLoader getContextClassLoader() {
270
271
PrivilegedAction<ClassLoader> act = () -> {
272
ClassLoader loader = Thread.currentThread().getContextClassLoader();
273
if (loader == null) {
274
// Don't use bootstrap class loader directly!
275
loader = ClassLoader.getSystemClassLoader();
276
}
277
return loader;
278
};
279
return AccessController.doPrivileged(act);
280
}
281
282
private static URL[] getUrlArray(String codebase)
283
throws MalformedURLException {
284
// Parse codebase into separate URLs
285
StringTokenizer parser = new StringTokenizer(codebase);
286
List<URL> list = new ArrayList<>();
287
while (parser.hasMoreTokens()) {
288
list.add(new URL(parser.nextToken()));
289
}
290
return list.toArray(new URL[0]);
291
}
292
293
/**
294
* Given an enumeration of URLs, an instance of this class represents
295
* an enumeration of their InputStreams. Each operation on the URL
296
* enumeration is performed within a doPrivileged block.
297
* This is used to enumerate the resources under a foreign codebase.
298
* This class is not MT-safe.
299
*/
300
private class InputStreamEnumeration implements
301
NamingEnumeration<InputStream> {
302
303
private final Enumeration<URL> urls;
304
305
private InputStream nextElement;
306
307
InputStreamEnumeration(Enumeration<URL> urls) {
308
this.urls = urls;
309
}
310
311
/*
312
* Returns the next InputStream, or null if there are no more.
313
* An InputStream that cannot be opened is skipped.
314
*/
315
@SuppressWarnings("removal")
316
private InputStream getNextElement() {
317
PrivilegedAction<InputStream> act = () -> {
318
while (urls.hasMoreElements()) {
319
try {
320
return urls.nextElement().openStream();
321
} catch (IOException e) {
322
// skip this URL
323
}
324
}
325
return null;
326
};
327
return AccessController.doPrivileged(act);
328
}
329
330
public boolean hasMore() {
331
if (nextElement != null) {
332
return true;
333
}
334
nextElement = getNextElement();
335
return (nextElement != null);
336
}
337
338
public boolean hasMoreElements() {
339
return hasMore();
340
}
341
342
public InputStream next() {
343
if (hasMore()) {
344
InputStream res = nextElement;
345
nextElement = null;
346
return res;
347
} else {
348
throw new NoSuchElementException();
349
}
350
}
351
352
public InputStream nextElement() {
353
return next();
354
}
355
356
public void close() {
357
}
358
}
359
}
360
361