--- /dev/null 2015-10-09 21:42:07.000000000 +0200
+++ new/jdk/src/java.logging/share/classes/sun/util/logging/internal/JdkLoggingProvider.java 2015-10-09 21:42:07.000000000 +0200
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.util.logging.internal;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ResourceBundle;
+import java.util.function.Supplier;
+import java.lang.System.LoggerFinder;
+import java.lang.System.Logger;
+import sun.util.logger.JdkLoggerProvider;
+import java.util.logging.LoggingPermission;
+import sun.util.logging.ConfigurableLoggerBridge;
+import sun.util.logging.PlatformLogger;
+import sun.util.logging.ConfigurableLoggerBridge.LoggerConfiguration;
+import sun.util.logging.PlatformLoggerBridge;
+
+/**
+ * This {@code JdkLoggingProvider} is the JDK internal implementation of the
+ * {@link sun.util.logger.JdkLoggerProvider} which is used by
+ * the default implementation of the {@link Logger}
+ * when no {@link LoggerFinder} is found
+ * and {@code java.util.logging} is present.
+ * When {@code java.util.logging} is present, the {@code JdkLoggingProvider}
+ * is {@linkplain java.util.ServiceLoader#loadInstalled(Class) installed} as
+ * an internal service provider, making it possible to use {@code java.util.logging}
+ * as the backend for loggers returned by the default LoggerFinder implementation.
+ *
+ * This implementation of {@link JdkLoggerProvider} returns instances of
+ * {@link java.lang.System.Logger} which
+ * delegate to a wrapped instance of {@link java.util.logging.Logger
+ * java.util.logging.Logger}.
+ *
+ * Loggers returned by this class can therefore be configured by accessing
+ * their wrapped implementation through the regular {@code java.util.logging}
+ * APIs - such as {@link java.util.logging.LogManager java.util.logging.LogManager}
+ * and {@link java.util.logging.Logger java.util.logging.Logger}.
+ *
+ * @apiNote Programmers are not expected to call this class directly.
+ * Instead they should rely on the static methods defined by
+ * {@link java.lang.System java.lang.System}.
+ *
+ * To replace this default
+ * {@code java.util.logging} backend, an application is expected to install
+ * its own {@link java.lang.System.LoggerFinder}.
+ *
+ * @see java.lang.System.Logger
+ * @see java.lang.System.LoggerFinder
+ * @see sun.util.logging.PlatformLoggerBridge
+ * @see java.lang.System
+ * @see sun.util.logger
+ * @see sun.util.logging.internal
+ *
+ */
+public final class JdkLoggingProvider extends JdkLoggerProvider {
+ private static final RuntimePermission LOGGER_CONTROL_PERMISSION =
+ LoggerFinder.LOGGERFINDER_PERMISSION;
+ private static final LoggingPermission LOGGING_CONTROL_PERMISSION =
+ new LoggingPermission("control", null);
+ private static final LoggingPermission LOGGING_DEMANDLOGGER_PERMISSION =
+ new LoggingPermission("demandLogger", null);
+
+ /**
+ * Creates a new instance of JdkLoggingProvider.
+ * @throws SecurityException if the calling code does not have the
+ * {@code RuntimePermission("loggerFinder")}.
+ */
+ public JdkLoggingProvider() {
+ super();
+ }
+
+ /**
+ * A logger that delegates to a java.util.logging.Logger delegate.
+ */
+ static final class JULWrapper extends LoggerConfiguration
+ implements System.Logger, PlatformLoggerBridge,
+ ConfigurableLoggerBridge {
+
+
+ private static final java.util.logging.Level[] spi2JulLevelMapping = {
+ java.util.logging.Level.ALL, // mapped from ALL
+ java.util.logging.Level.FINER, // mapped from TRACE
+ java.util.logging.Level.FINE, // mapped from DEBUG
+ java.util.logging.Level.INFO, // mapped from INFO
+ java.util.logging.Level.WARNING, // mapped from WARNING
+ java.util.logging.Level.SEVERE, // mapped from ERROR
+ java.util.logging.Level.OFF // mapped from OFF
+ };
+
+ private static final java.util.logging.Level[] platform2JulLevelMapping = {
+ java.util.logging.Level.ALL, // mapped from ALL
+ java.util.logging.Level.FINEST, // mapped from FINEST
+ java.util.logging.Level.FINER, // mapped from FINER
+ java.util.logging.Level.FINE, // mapped from FINE
+ java.util.logging.Level.CONFIG, // mapped from CONFIG
+ java.util.logging.Level.INFO, // mapped from INFO
+ java.util.logging.Level.WARNING, // mapped from WARNING
+ java.util.logging.Level.SEVERE, // mapped from SEVERE
+ java.util.logging.Level.OFF // mapped from OFF
+ };
+
+ private final java.util.logging.Logger julLogger;
+
+
+ private JULWrapper(java.util.logging.Logger logger) {
+ this.julLogger = logger;
+ }
+
+ @Override
+ public String getName() {
+ return julLogger.getName();
+ }
+ @Override
+ public void log(sun.util.logging.PlatformLogger.Level level, String msg, Throwable throwable) {
+ julLogger.log(toJUL(level), msg, throwable);
+ }
+
+ @Override
+ public void log(sun.util.logging.PlatformLogger.Level level, String format, Object... params) {
+ julLogger.log(toJUL(level), format, params);
+ }
+
+ @Override
+ public void log(sun.util.logging.PlatformLogger.Level level, String msg) {
+ julLogger.log(toJUL(level), msg);
+ }
+
+ @Override
+ public void log(sun.util.logging.PlatformLogger.Level level, Supplier msgSuppier) {
+ julLogger.log(toJUL(level), msgSuppier);
+ }
+
+ @Override
+ public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier msgSuppier) {
+ julLogger.log(toJUL(level), thrown, msgSuppier);
+ }
+
+ @Override
+ public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, String key, Throwable throwable) {
+ julLogger.logrb(toJUL(level), bundle, key, throwable);
+ }
+
+ @Override
+ public void logrb(sun.util.logging.PlatformLogger.Level level, ResourceBundle bundle, String key, Object... params) {
+ julLogger.logrb(toJUL(level), bundle, key, params);
+ }
+
+ @Override
+ public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod, String msg) {
+ julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg);
+ }
+
+ @Override
+ public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ Supplier msgSupplier) {
+ julLogger.logp(toJUL(level), sourceClass, sourceMethod, msgSupplier);
+ }
+
+ @Override
+ public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ String msg, Object... params) {
+ julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg, params);
+ }
+
+ @Override
+ public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ String msg, Throwable thrown) {
+ julLogger.logp(toJUL(level), sourceClass, sourceMethod, msg, thrown);
+ }
+
+ @Override
+ public void logp(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ Throwable thrown, Supplier msgSupplier) {
+ julLogger.logp(toJUL(level), sourceClass, sourceMethod,
+ thrown, msgSupplier);
+ }
+
+ @Override
+ public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ ResourceBundle bundle, String key, Object... params) {
+ julLogger.logrb(toJUL(level), sourceClass, sourceMethod,
+ bundle, key, params);
+ }
+
+ @Override
+ public void logrb(sun.util.logging.PlatformLogger.Level level, String sourceClass, String sourceMethod,
+ ResourceBundle bundle, String key, Throwable thrown) {
+ julLogger.logrb(toJUL(level), sourceClass, sourceMethod,
+ bundle, key, thrown);
+ }
+
+ @Override
+ public boolean isLoggable(sun.util.logging.PlatformLogger.Level level) {
+ return julLogger.isLoggable(toJUL(level));
+ }
+
+ // -----------------------------------------------------------------
+ // Generic methods taking a Level as parameter
+ // -----------------------------------------------------------------
+
+
+ @Override
+ public boolean isLoggable(Level level) {
+ return julLogger.isLoggable(toJUL(level));
+ }
+
+ @Override
+ public void log(Level level, String msg) {
+ julLogger.log(toJUL(level), msg);
+ }
+
+ @Override
+ public void log(Level level,
+ Supplier msgSupplier) {
+ julLogger.log(toJUL(level), msgSupplier);
+ }
+
+ @Override
+ public void log(Level level, Object obj) {
+ julLogger.log(toJUL(level), () -> obj.toString());
+ }
+
+ @Override
+ public void log(Level level,
+ String msg, Throwable thrown) {
+ julLogger.log(toJUL(level), msg, thrown);
+ }
+
+ @Override
+ public void log(Level level, Supplier msgSupplier,
+ Throwable thrown) {
+ julLogger.log(toJUL(level), thrown, msgSupplier);
+ }
+
+ @Override
+ public void log(Level level,
+ String format, Object... params) {
+ julLogger.log(toJUL(level), format, params);
+ }
+
+ @Override
+ public void log(Level level, ResourceBundle bundle,
+ String key, Throwable thrown) {
+ julLogger.logrb(toJUL(level), bundle, key, thrown);
+ }
+
+ @Override
+ public void log(Level level, ResourceBundle bundle,
+ String format, Object... params) {
+ julLogger.logrb(toJUL(level), bundle, format, params);
+ }
+
+ static java.util.logging.Level toJUL(Level level) {
+ if (level == null) return null;
+ assert level.ordinal() < spi2JulLevelMapping.length;
+ return spi2JulLevelMapping[level.ordinal()];
+ }
+
+ // ---------------------------------------------------------
+ // Methods from PlatformLoggerBridge
+ // ---------------------------------------------------------
+
+ @Override
+ public boolean isEnabled() {
+ return julLogger.getLevel() != java.util.logging.Level.OFF;
+ }
+
+ @Override
+ public PlatformLogger.Level getPlatformLevel() {
+ final java.util.logging.Level javaLevel = julLogger.getLevel();
+ if (javaLevel == null) return null;
+ try {
+ return PlatformLogger.Level.valueOf(javaLevel.getName());
+ } catch (IllegalArgumentException e) {
+ return PlatformLogger.Level.valueOf(javaLevel.intValue());
+ }
+ }
+
+ @Override
+ public void setPlatformLevel(PlatformLogger.Level level) {
+ julLogger.setLevel(toJUL(level));
+ }
+
+ @Override
+ public LoggerConfiguration getLoggerConfiguration() {
+ return this;
+ }
+
+ static java.util.logging.Level toJUL(PlatformLogger.Level level) {
+ if (level == null) return null;
+ assert level.ordinal() < platform2JulLevelMapping.length;
+ return platform2JulLevelMapping[level.ordinal()];
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof JULWrapper)
+ && obj.getClass() == this.getClass()
+ && ((JULWrapper)obj).julLogger == this.julLogger;
+ }
+
+ @Override
+ public int hashCode() {
+ return julLogger.hashCode();
+ }
+
+ // A JULWrapper is just a stateless thin shell over a JUL logger - so
+ // for a given JUL logger, we could always return the same wrapper.
+ //
+ // This is an optimization which may - or may not - be worth the
+ // trouble: if many classes use the same logger, and if each class
+ // keeps a reference to that logger, then caching the wrapper will
+ // be worthwhile. Otherwise, if each logger is only referred once,
+ // then the cache will eat up more memory than would be necessary...
+ //
+ // Here is an example of how we could implement JULWrapper.of(...)
+ // if we wanted to create at most one wrapper instance for each logger
+ // instance:
+ //
+ // static final WeakHashMap>
+ // wrappers = new WeakHashMap<>();
+ //
+ // static JULWrapper of(java.util.logging.Logger logger) {
+ //
+ // // First access without synchronizing
+ // final JULWrapper candidate = new JULWrapper(logger);
+ // WeakReference ref = wrappers.get(candidate);
+ // JULWrapper found = ref.get();
+ //
+ // // OK - we found it - lets return it.
+ // if (found != null) return found;
+ //
+ // // Not found. Need to synchronize.
+ // synchronized (wrappers) {
+ // ref = wrappers.get(candidate);
+ // found = ref.get();
+ // if (found == null) {
+ // wrappers.put(candidate, new WeakReference<>(candidate));
+ // found = candidate;
+ // }
+ // }
+ // assert found != null;
+ // return found;
+ // }
+ //
+ // But given that it may end up eating more memory in the nominal case
+ // (where each class that does logging has its own logger with the
+ // class name as logger name and stashes that logger away in a static
+ // field, thus making the cache redundant - as only one wrapper will
+ // ever be created anyway) - then we will simply return a new wrapper
+ // for each invocation of JULWrapper.of(...) - which may
+ // still prove more efficient in terms of memory consumption...
+ //
+ static JULWrapper of(java.util.logging.Logger logger) {
+ return new JULWrapper(logger);
+ }
+
+
+ }
+
+ /**
+ * Creates a java.util.logging.Logger for the given caller.
+ * @param name the logger name.
+ * @param caller the caller for which the logger should be created.
+ * @return a Logger suitable for use in the given caller.
+ */
+ private static java.util.logging.Logger demandJULLoggerFor(final String name,
+ /* Module */
+ final Class> caller) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ return java.util.logging.LogManager.demandLoggerFor(name, caller);
+ } else {
+ return AccessController.doPrivileged(
+ (PrivilegedAction)
+ () -> java.util.logging.LogManager.demandLoggerFor(name, caller),
+ null, LOGGING_DEMANDLOGGER_PERMISSION);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @apiNote The logger returned by this method can be configured through
+ * its {@linkplain java.util.logging.LogManager#getLogger(String)
+ * corresponding java.util.logging.Logger backend}.
+ *
+ * @return {@inheritDoc}
+ * @throws SecurityException if the calling code doesn't have the
+ * {@code RuntimePermission("loggerFinder")}.
+ */
+ @Override
+ protected Logger demandLoggerFor(String name, /* Module */ Class> caller) {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(LOGGER_CONTROL_PERMISSION);
+ }
+ return JULWrapper.of(demandJULLoggerFor(name,caller));
+ }
+
+}