Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java
41161 views
1
/*
2
* Copyright (c) 2015, 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
27
package sun.util.logging.internal;
28
29
import java.security.AccessController;
30
import java.security.PrivilegedAction;
31
import java.util.ResourceBundle;
32
import java.util.function.Supplier;
33
import java.lang.System.LoggerFinder;
34
import java.lang.System.Logger;
35
import java.util.Objects;
36
import java.util.logging.LogManager;
37
import jdk.internal.logger.DefaultLoggerFinder;
38
import java.util.logging.LoggingPermission;
39
import sun.util.logging.PlatformLogger;
40
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
41
42
/**
43
* This {@code LoggingProviderImpl} is the JDK internal implementation of the
44
* {@link jdk.internal.logger.DefaultLoggerFinder} which is used by
45
* the default implementation of the {@link Logger}
46
* when no {@link LoggerFinder} is found
47
* and {@code java.util.logging} is present.
48
* When {@code java.util.logging} is present, the {@code LoggingProviderImpl}
49
* is {@linkplain java.util.ServiceLoader#loadInstalled(Class) installed} as
50
* an internal service provider, making it possible to use {@code java.util.logging}
51
* as the backend for loggers returned by the default LoggerFinder implementation.
52
* <p>
53
* This implementation of {@link DefaultLoggerFinder} returns instances of
54
* {@link java.lang.System.Logger} which
55
* delegate to a wrapped instance of {@link java.util.logging.Logger
56
* java.util.logging.Logger}.
57
* <br>
58
* Loggers returned by this class can therefore be configured by accessing
59
* their wrapped implementation through the regular {@code java.util.logging}
60
* APIs - such as {@link java.util.logging.LogManager java.util.logging.LogManager}
61
* and {@link java.util.logging.Logger java.util.logging.Logger}.
62
*
63
* @apiNote Programmers are not expected to call this class directly.
64
* Instead they should rely on the static methods defined by
65
* {@link java.lang.System java.lang.System}.
66
* <p>
67
* To replace this default
68
* {@code java.util.logging} backend, an application is expected to install
69
* its own {@link java.lang.System.LoggerFinder}.
70
*
71
* @see java.lang.System.Logger
72
* @see java.lang.System.LoggerFinder
73
* @see sun.util.logging.PlatformLogger.Bridge
74
* @see java.lang.System
75
* @see jdk.internal.logger
76
* @see jdk.internal.logger
77
*
78
*/
79
public final class LoggingProviderImpl extends DefaultLoggerFinder {
80
static final RuntimePermission LOGGERFINDER_PERMISSION =
81
new RuntimePermission("loggerFinder");
82
private static final LoggingPermission LOGGING_CONTROL_PERMISSION =
83
new LoggingPermission("control", null);
84
85
/**
86
* Creates a new instance of LoggingProviderImpl.
87
* @throws SecurityException if the calling code does not have the
88
* {@code RuntimePermission("loggerFinder")}.
89
*/
90
public LoggingProviderImpl() {
91
}
92
93
/**
94
* A logger that delegates to a java.util.logging.Logger delegate.
95
*/
96
static final class JULWrapper extends LoggerConfiguration
97
implements System.Logger, PlatformLogger.Bridge,
98
PlatformLogger.ConfigurableBridge {
99
100
101
private static final java.util.logging.Level[] spi2JulLevelMapping = {
102
java.util.logging.Level.ALL, // mapped from ALL
103
java.util.logging.Level.FINER, // mapped from TRACE
104
java.util.logging.Level.FINE, // mapped from DEBUG
105
java.util.logging.Level.INFO, // mapped from INFO
106
java.util.logging.Level.WARNING, // mapped from WARNING
107
java.util.logging.Level.SEVERE, // mapped from ERROR
108
java.util.logging.Level.OFF // mapped from OFF
109
};
110
111
private static final java.util.logging.Level[] platform2JulLevelMapping = {
112
java.util.logging.Level.ALL, // mapped from ALL
113
java.util.logging.Level.FINEST, // mapped from FINEST
114
java.util.logging.Level.FINER, // mapped from FINER
115
java.util.logging.Level.FINE, // mapped from FINE
116
java.util.logging.Level.CONFIG, // mapped from CONFIG
117
java.util.logging.Level.INFO, // mapped from INFO
118
java.util.logging.Level.WARNING, // mapped from WARNING
119
java.util.logging.Level.SEVERE, // mapped from SEVERE
120
java.util.logging.Level.OFF // mapped from OFF
121
};
122
123
private final java.util.logging.Logger julLogger;
124
125
126
private JULWrapper(java.util.logging.Logger logger) {
127
this.julLogger = logger;
128
}
129
130
@Override
131
public String getName() {
132
return julLogger.getName();
133
}
134
@Override
135
public void log(sun.util.logging.PlatformLogger.Level level, String msg, Throwable throwable) {
136
julLogger.log(toJUL(level), msg, throwable);
137
}
138
139
@Override
140
public void log(sun.util.logging.PlatformLogger.Level level, String format, Object... params) {
141
julLogger.log(toJUL(level), format, params);
142
}
143
144
@Override
145
public void log(sun.util.logging.PlatformLogger.Level level, String msg) {
146
julLogger.log(toJUL(level), msg);
147
}
148
149
@Override
150
public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSuppier) {
151
julLogger.log(toJUL(level), msgSuppier);
152
}
153
154
@Override
155
public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSuppier) {
156
julLogger.log(toJUL(level), thrown, msgSuppier);
157
}
158
159
@Override
160
public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, String key, Throwable throwable) {
161
julLogger.logrb(toJUL(level), bundle, key, throwable);
162
}
163
164
@Override
165
public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, String key, Object... params) {
166
julLogger.logrb(toJUL(level), bundle, key, params);
167
}
168
169
@Override
170
public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod, String msg) {
171
julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg);
172
}
173
174
@Override
175
public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
176
Supplier<String> msgSupplier) {
177
julLogger.logp(toJUL(level), sourceClass, sourceMethod, msgSupplier);
178
}
179
180
@Override
181
public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
182
String msg, Object... params) {
183
julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg, params);
184
}
185
186
@Override
187
public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
188
String msg, Throwable thrown) {
189
julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg, thrown);
190
}
191
192
@Override
193
public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
194
Throwable thrown, Supplier<String> msgSupplier) {
195
julLogger.logp(toJUL(level), sourceClass, sourceMethod,
196
thrown, msgSupplier);
197
}
198
199
@Override
200
public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
201
ResourceBundle bundle, String key, Object... params) {
202
julLogger.logrb(toJUL(level), sourceClass, sourceMethod,
203
bundle, key, params);
204
}
205
206
@Override
207
public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
208
ResourceBundle bundle, String key, Throwable thrown) {
209
julLogger.logrb(toJUL(level), sourceClass, sourceMethod,
210
bundle, key, thrown);
211
}
212
213
@Override
214
public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) {
215
return julLogger.isLoggable(toJUL(level));
216
}
217
218
// -----------------------------------------------------------------
219
// Generic methods taking a Level as parameter
220
// -----------------------------------------------------------------
221
222
223
@Override
224
public boolean isLoggable(Level level) {
225
return julLogger.isLoggable(toJUL(level));
226
}
227
228
@Override
229
public void log(Level level, String msg) {
230
julLogger.log(toJUL(level), msg);
231
}
232
233
@Override
234
public void log(Level level,
235
Supplier<String> msgSupplier) {
236
// We need to check for null here to satisfy the contract
237
// of System.Logger - because the underlying implementation
238
// of julLogger will check for it only if the level is
239
// loggable
240
Objects.requireNonNull(msgSupplier);
241
julLogger.log(toJUL(level), msgSupplier);
242
}
243
244
@Override
245
public void log(Level level, Object obj) {
246
// We need to check for null here to satisfy the contract
247
// of System.Logger - because the underlying implementation
248
// of julLogger will check for it only if the level is
249
// loggable
250
Objects.requireNonNull(obj);
251
julLogger.log(toJUL(level), () -> obj.toString());
252
}
253
254
@Override
255
public void log(Level level,
256
String msg, Throwable thrown) {
257
julLogger.log(toJUL(level), msg, thrown);
258
}
259
260
@Override
261
public void log(Level level, Supplier<String> msgSupplier,
262
Throwable thrown) {
263
// We need to check for null here to satisfy the contract
264
// of System.Logger - because the underlying implementation
265
// of julLogger will check for it only if the level is
266
// loggable
267
Objects.requireNonNull(msgSupplier);
268
julLogger.log(toJUL(level), thrown, msgSupplier);
269
}
270
271
@Override
272
public void log(Level level,
273
String format, Object... params) {
274
julLogger.log(toJUL(level), format, params);
275
}
276
277
@Override
278
public void log(Level level, ResourceBundle bundle,
279
String key, Throwable thrown) {
280
julLogger.logrb(toJUL(level), bundle, key, thrown);
281
}
282
283
@Override
284
public void log(Level level, ResourceBundle bundle,
285
String format, Object... params) {
286
julLogger.logrb(toJUL(level), bundle, format, params);
287
}
288
289
static java.util.logging.Level toJUL(Level level) {
290
if (level == null) return null;
291
assert level.ordinal() < spi2JulLevelMapping.length;
292
return spi2JulLevelMapping[level.ordinal()];
293
}
294
295
// ---------------------------------------------------------
296
// Methods from PlatformLogger.Bridge
297
// ---------------------------------------------------------
298
299
@Override
300
public boolean isEnabled() {
301
return julLogger.getLevel() != java.util.logging.Level.OFF;
302
}
303
304
@Override
305
public PlatformLogger.Level getPlatformLevel() {
306
final java.util.logging.Level javaLevel = julLogger.getLevel();
307
if (javaLevel == null) return null;
308
try {
309
return PlatformLogger.Level.valueOf(javaLevel.getName());
310
} catch (IllegalArgumentException e) {
311
return PlatformLogger.Level.valueOf(javaLevel.intValue());
312
}
313
}
314
315
@Override
316
public void setPlatformLevel(PlatformLogger.Level level) {
317
// null is allowed here
318
julLogger.setLevel(toJUL(level));
319
}
320
321
@Override
322
public LoggerConfiguration getLoggerConfiguration() {
323
return this;
324
}
325
326
static java.util.logging.Level toJUL(PlatformLogger.Level level) {
327
// The caller will throw if null is invalid in its context.
328
// There's at least one case where a null level is valid.
329
if (level == null) return null;
330
assert level.ordinal() < platform2JulLevelMapping.length;
331
return platform2JulLevelMapping[level.ordinal()];
332
}
333
334
@Override
335
public boolean equals(Object obj) {
336
return (obj instanceof JULWrapper)
337
&& obj.getClass() == this.getClass()
338
&& ((JULWrapper)obj).julLogger == this.julLogger;
339
}
340
341
@Override
342
public int hashCode() {
343
return julLogger.hashCode();
344
}
345
346
// A JULWrapper is just a stateless thin shell over a JUL logger - so
347
// for a given JUL logger, we could always return the same wrapper.
348
//
349
// This is an optimization which may - or may not - be worth the
350
// trouble: if many classes use the same logger, and if each class
351
// keeps a reference to that logger, then caching the wrapper will
352
// be worthwhile. Otherwise, if each logger is only referred once,
353
// then the cache will eat up more memory than would be necessary...
354
//
355
// Here is an example of how we could implement JULWrapper.of(...)
356
// if we wanted to create at most one wrapper instance for each logger
357
// instance:
358
//
359
// static final WeakHashMap<JULWrapper, WeakReference<JULWrapper>>
360
// wrappers = new WeakHashMap<>();
361
//
362
// static JULWrapper of(java.util.logging.Logger logger) {
363
//
364
// // First access without synchronizing
365
// final JULWrapper candidate = new JULWrapper(logger);
366
// WeakReference<JULWrapper> ref = wrappers.get(candidate);
367
// JULWrapper found = ref.get();
368
//
369
// // OK - we found it - lets return it.
370
// if (found != null) return found;
371
//
372
// // Not found. Need to synchronize.
373
// synchronized (wrappers) {
374
// ref = wrappers.get(candidate);
375
// found = ref.get();
376
// if (found == null) {
377
// wrappers.put(candidate, new WeakReference<>(candidate));
378
// found = candidate;
379
// }
380
// }
381
// assert found != null;
382
// return found;
383
// }
384
//
385
// But given that it may end up eating more memory in the nominal case
386
// (where each class that does logging has its own logger with the
387
// class name as logger name and stashes that logger away in a static
388
// field, thus making the cache redundant - as only one wrapper will
389
// ever be created anyway) - then we will simply return a new wrapper
390
// for each invocation of JULWrapper.of(...) - which may
391
// still prove more efficient in terms of memory consumption...
392
//
393
static JULWrapper of(java.util.logging.Logger logger) {
394
return new JULWrapper(logger);
395
}
396
397
398
}
399
400
/**
401
* Creates a java.util.logging.Logger for the given module.
402
* @param name the logger name.
403
* @param module the module for which the logger should be created.
404
* @return a Logger suitable for use in the given module.
405
*/
406
@SuppressWarnings("removal")
407
private static java.util.logging.Logger demandJULLoggerFor(final String name,
408
Module module) {
409
final LogManager manager = LogManager.getLogManager();
410
final SecurityManager sm = System.getSecurityManager();
411
if (sm == null) {
412
return logManagerAccess.demandLoggerFor(manager, name, module);
413
} else {
414
final PrivilegedAction<java.util.logging.Logger> pa =
415
() -> logManagerAccess.demandLoggerFor(manager, name, module);
416
return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION);
417
}
418
}
419
420
/**
421
* {@inheritDoc}
422
*
423
* @apiNote The logger returned by this method can be configured through
424
* its {@linkplain java.util.logging.LogManager#getLogger(String)
425
* corresponding java.util.logging.Logger backend}.
426
*
427
* @return {@inheritDoc}
428
* @throws SecurityException if the calling code doesn't have the
429
* {@code RuntimePermission("loggerFinder")}.
430
*/
431
@Override
432
protected Logger demandLoggerFor(String name, Module module) {
433
@SuppressWarnings("removal")
434
final SecurityManager sm = System.getSecurityManager();
435
if (sm != null) {
436
sm.checkPermission(LOGGERFINDER_PERMISSION);
437
}
438
return JULWrapper.of(demandJULLoggerFor(name,module));
439
}
440
441
public static interface LogManagerAccess {
442
java.util.logging.Logger demandLoggerFor(LogManager manager,
443
String name, Module module);
444
}
445
446
// Hook for tests
447
public static LogManagerAccess getLogManagerAccess() {
448
@SuppressWarnings("removal")
449
final SecurityManager sm = System.getSecurityManager();
450
if (sm != null) {
451
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
452
}
453
// Triggers initialization of accessJulLogger if not set.
454
if (logManagerAccess == null) LogManager.getLogManager();
455
return logManagerAccess;
456
}
457
458
459
private static volatile LogManagerAccess logManagerAccess;
460
public static void setLogManagerAccess(LogManagerAccess accesLoggers) {
461
@SuppressWarnings("removal")
462
final SecurityManager sm = System.getSecurityManager();
463
if (sm != null) {
464
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
465
}
466
logManagerAccess = accesLoggers;
467
}
468
469
}
470
471