--- old/src/share/classes/java/util/logging/LoggingProxyImpl.java 2013-04-04 14:24:29.000000000 -0700 +++ new/src/share/classes/java/util/logging/LoggingProxyImpl.java 2013-04-04 14:24:29.000000000 -0700 @@ -106,6 +106,11 @@ } @Override + public int getLevelValue(Object level) { + return ((Level) level).intValue(); + } + + @Override public String getProperty(String key) { return LogManager.getLogManager().getProperty(key); } --- old/src/share/classes/sun/util/logging/LoggingProxy.java 2013-04-04 14:24:30.000000000 -0700 +++ new/src/share/classes/sun/util/logging/LoggingProxy.java 2013-04-04 14:24:30.000000000 -0700 @@ -61,6 +61,8 @@ public String getLevelName(Object level); + public int getLevelValue(Object level); + // return the logging property public String getProperty(String key); } --- old/src/share/classes/sun/util/logging/LoggingSupport.java 2013-04-04 14:24:31.000000000 -0700 +++ new/src/share/classes/sun/util/logging/LoggingSupport.java 2013-04-04 14:24:31.000000000 -0700 @@ -140,6 +140,11 @@ return proxy.getLevelName(level); } + public static int getLevelValue(Object level) { + ensureAvailable(); + return proxy.getLevelValue(level); + } + private static final String DEFAULT_FORMAT = "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n"; --- old/src/share/classes/sun/util/logging/PlatformLogger.java 2013-04-04 14:24:32.000000000 -0700 +++ new/src/share/classes/sun/util/logging/PlatformLogger.java 2013-04-04 14:24:32.000000000 -0700 @@ -32,6 +32,7 @@ import java.io.StringWriter; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -84,31 +85,38 @@ * @since 1.7 */ public class PlatformLogger { - // shortcut to PlatformLogger.Level enums - public static final Level OFF = Level.OFF; - public static final Level SEVERE = Level.SEVERE; - public static final Level WARNING = Level.WARNING; - public static final Level INFO = Level.INFO; - public static final Level CONFIG = Level.CONFIG; - public static final Level FINE = Level.FINE; - public static final Level FINER = Level.FINER; - public static final Level FINEST = Level.FINEST; - public static final Level ALL = Level.ALL; + /* + * These constants should be shortcuts to Level enum constants that + * the clients of sun.util.logging.PlatformLogger require no source + * modification and avoid the conversion from int to Level enum. + * + * This can be done when JavaFX is converted to use the new PlatformLogger.Level API. + */ + public static final int OFF = Integer.MAX_VALUE; + public static final int SEVERE = 1000; + public static final int WARNING = 900; + public static final int INFO = 800; + public static final int CONFIG = 700; + public static final int FINE = 500; + public static final int FINER = 400; + public static final int FINEST = 300; + public static final int ALL = Integer.MIN_VALUE; /** * PlatformLogger logging levels. */ public static enum Level { - // The name and value must match that of {@code java.util.logging.Level} objects. - ALL(Integer.MIN_VALUE), - FINEST(300), - FINER(400), - FINE(500), - CONFIG(700), - INFO(800), - WARNING(900), - SEVERE(1000), - OFF(Integer.MAX_VALUE); + // The name and value must match that of {@code java.util.logging.Level}s. + // Declare in ascending order of the given value for binary search. + ALL, + FINEST, + FINER, + FINE, + CONFIG, + INFO, + WARNING, + SEVERE, + OFF; /** * Associated java.util.logging.Level lazily initialized in @@ -118,17 +126,39 @@ */ /* java.util.logging.Level */ Object javaLevel; - private final int value; + // ascending order for binary search matching the list of enum constants + private static final int[] levelValues = new int[] { + PlatformLogger.ALL, PlatformLogger.FINEST, PlatformLogger.FINER, + PlatformLogger.FINE, PlatformLogger.CONFIG, PlatformLogger.INFO, + PlatformLogger.WARNING, PlatformLogger.SEVERE, PlatformLogger.OFF + }; + public int intValue() { - return value; + return levelValues[this.ordinal()]; } - Level(int value) { - this.value = value; + static Level valueOf(int level) { + switch (level) { + // ordering per the highest occurences in the jdk source + // finest, fine, finer, info first + case PlatformLogger.FINEST : return Level.FINEST; + case PlatformLogger.FINE : return Level.FINE; + case PlatformLogger.FINER : return Level.FINER; + case PlatformLogger.INFO : return Level.INFO; + case PlatformLogger.WARNING : return Level.WARNING; + case PlatformLogger.CONFIG : return Level.CONFIG; + case PlatformLogger.SEVERE : return Level.SEVERE; + case PlatformLogger.OFF : return Level.OFF; + case PlatformLogger.ALL : return Level.ALL; + } + // return the nearest Level value >= the given level, + // for level > SEVERE, return SEVERE and exclude OFF + int i = Arrays.binarySearch(levelValues, 0, levelValues.length-2, level); + return values()[i >= 0 ? i : (-i-1)]; } } - private static final Level DEFAULT_LEVEL = INFO; + private static final Level DEFAULT_LEVEL = Level.INFO; private static boolean loggingEnabled; static { loggingEnabled = AccessController.doPrivileged( @@ -234,8 +264,44 @@ /** * Returns true if a message of the given level would actually * be logged by this logger. + * + * @deprecated Use isLoggable(Level) instead. + */ + @Deprecated + public boolean isLoggable(int levelValue) { + return isLoggable(Level.valueOf(levelValue)); + } + + /** + * Gets the current log level. Returns 0 if the current effective level is + * not set (equivalent to Logger.getLevel() returns null). + * + * @deprecated Use level() instead + */ + @Deprecated + public int getLevel() { + Level level = loggerProxy.getLevel(); + return level != null ? level.intValue() : 0; + } + + /** + * Sets the log level. + * + * @deprecated Use setLevel(Level) instead + */ + @Deprecated + public void setLevel(int newLevel) { + loggerProxy.setLevel(newLevel == 0 ? null : Level.valueOf(newLevel)); + } + + /** + * Returns true if a message of the given level would actually + * be logged by this logger. */ public boolean isLoggable(Level level) { + if (level == null) { + throw new NullPointerException(); + } // performance-sensitive method: use two monomorphic call-sites JavaLoggerProxy jlp = javaLoggerProxy; return jlp != null ? jlp.isLoggable(level) : loggerProxy.isLoggable(level); @@ -246,15 +312,9 @@ * The result may be null, which means that this logger's * effective level will be inherited from its parent. * - * This method is primarily for testing purpose and not recommended - * to be used at runtime since it does not support custom j.u.l.Level. - * * @return this PlatformLogger's level - * - * @throw IllegalArgumentException if j.u.l.Logger is set to - * a custom j.u.l.Level when java.util.logging facility is enabled */ - public Level getLevel() { + public Level level() { return loggerProxy.getLevel(); } @@ -278,105 +338,105 @@ * Logs a SEVERE message. */ public void severe(String msg) { - loggerProxy.doLog(SEVERE, msg); + loggerProxy.doLog(Level.SEVERE, msg); } public void severe(String msg, Throwable t) { - loggerProxy.doLog(SEVERE, msg, t); + loggerProxy.doLog(Level.SEVERE, msg, t); } public void severe(String msg, Object... params) { - loggerProxy.doLog(SEVERE, msg, params); + loggerProxy.doLog(Level.SEVERE, msg, params); } /** * Logs a WARNING message. */ public void warning(String msg) { - loggerProxy.doLog(WARNING, msg); + loggerProxy.doLog(Level.WARNING, msg); } public void warning(String msg, Throwable t) { - loggerProxy.doLog(WARNING, msg, t); + loggerProxy.doLog(Level.WARNING, msg, t); } public void warning(String msg, Object... params) { - loggerProxy.doLog(WARNING, msg, params); + loggerProxy.doLog(Level.WARNING, msg, params); } /** * Logs an INFO message. */ public void info(String msg) { - loggerProxy.doLog(INFO, msg); + loggerProxy.doLog(Level.INFO, msg); } public void info(String msg, Throwable t) { - loggerProxy.doLog(INFO, msg, t); + loggerProxy.doLog(Level.INFO, msg, t); } public void info(String msg, Object... params) { - loggerProxy.doLog(INFO, msg, params); + loggerProxy.doLog(Level.INFO, msg, params); } /** * Logs a CONFIG message. */ public void config(String msg) { - loggerProxy.doLog(CONFIG, msg); + loggerProxy.doLog(Level.CONFIG, msg); } public void config(String msg, Throwable t) { - loggerProxy.doLog(CONFIG, msg, t); + loggerProxy.doLog(Level.CONFIG, msg, t); } public void config(String msg, Object... params) { - loggerProxy.doLog(CONFIG, msg, params); + loggerProxy.doLog(Level.CONFIG, msg, params); } /** * Logs a FINE message. */ public void fine(String msg) { - loggerProxy.doLog(FINE, msg); + loggerProxy.doLog(Level.FINE, msg); } public void fine(String msg, Throwable t) { - loggerProxy.doLog(FINE, msg, t); + loggerProxy.doLog(Level.FINE, msg, t); } public void fine(String msg, Object... params) { - loggerProxy.doLog(FINE, msg, params); + loggerProxy.doLog(Level.FINE, msg, params); } /** * Logs a FINER message. */ public void finer(String msg) { - loggerProxy.doLog(FINER, msg); + loggerProxy.doLog(Level.FINER, msg); } public void finer(String msg, Throwable t) { - loggerProxy.doLog(FINER, msg, t); + loggerProxy.doLog(Level.FINER, msg, t); } public void finer(String msg, Object... params) { - loggerProxy.doLog(FINER, msg, params); + loggerProxy.doLog(Level.FINER, msg, params); } /** * Logs a FINEST message. */ public void finest(String msg) { - loggerProxy.doLog(FINEST, msg); + loggerProxy.doLog(Level.FINEST, msg); } public void finest(String msg, Throwable t) { - loggerProxy.doLog(FINEST, msg, t); + loggerProxy.doLog(Level.FINEST, msg, t); } public void finest(String msg, Object... params) { - loggerProxy.doLog(FINEST, msg, params); + loggerProxy.doLog(Level.FINEST, msg, params); } /** @@ -421,7 +481,7 @@ } boolean isEnabled() { - return effectiveLevel != OFF; + return effectiveLevel != Level.OFF; } Level getLevel() { @@ -457,7 +517,7 @@ boolean isLoggable(Level level) { Level effectiveLevel = this.effectiveLevel; - return level.intValue() >= effectiveLevel.intValue() && effectiveLevel != OFF; + return level.intValue() >= effectiveLevel.intValue() && effectiveLevel != Level.OFF; } // derive effective level (could do inheritance search like j.u.l.Logger) @@ -611,15 +671,18 @@ /** * Returns the PlatformLogger.Level mapped from j.u.l.Level - * set in the logger. - * @throw IllegalArgumentException if j.u.l.Logger is set to - * a custom j.u.l.Level + * set in the logger. If the j.u.l.Logger is set to a custom Level, + * this method will return the nearest Level. */ Level getLevel() { Object javaLevel = LoggingSupport.getLevel(javaLogger); - return javaLevel == null - ? null - : Level.valueOf(LoggingSupport.getLevelName(javaLevel)); + if (javaLevel == null) return null; + + try { + return Level.valueOf(LoggingSupport.getLevelName(javaLevel)); + } catch (IllegalArgumentException e) { + return Level.valueOf(LoggingSupport.getLevelValue(javaLevel)); + } } void setLevel(Level level) { --- old/test/sun/util/logging/PlatformLoggerTest.java 2013-04-04 14:24:33.000000000 -0700 +++ new/test/sun/util/logging/PlatformLoggerTest.java 2013-04-04 14:24:33.000000000 -0700 @@ -36,6 +36,7 @@ import java.lang.reflect.Field; import java.util.logging.*; import sun.util.logging.PlatformLogger; +import static sun.util.logging.PlatformLogger.Level.*; public class PlatformLoggerTest { public static void main(String[] args) throws Exception { @@ -69,40 +70,63 @@ checkLogger(GOO_PLATFORM_LOGGER, null); checkLogger(BAR_LOGGER, Level.WARNING); - foo.setLevel(PlatformLogger.SEVERE); + foo.setLevel(PlatformLogger.Level.SEVERE); checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE); checkPlatformLoggerLevels(foo, bar); } + // don't use java.util.logging here to prevent it from initialized private static void checkPlatformLogger(PlatformLogger logger, String name) { if (!logger.getName().equals(name)) { throw new RuntimeException("Invalid logger's name " + logger.getName() + " but expected " + name); } - if (logger.getLevel() != null) { + if (logger.level() != null) { throw new RuntimeException("Invalid default level for logger " + - logger.getName() + ": " + logger.getLevel()); + logger.getName() + ": " + logger.level()); } - if (logger.isLoggable(PlatformLogger.FINE) != false) { - throw new RuntimeException("isLoggerable(FINE) returns true for logger " + - logger.getName() + " but expected false"); + checkLoggable(logger, FINE, false); + + logger.setLevel(FINER); + checkLevel(logger, FINER); + checkLoggable(logger, FINER, true); + checkLoggable(logger, FINE, true); + checkLoggable(logger, FINEST, false); + + logger.info("OK: Testing log message"); + } + + private static void checkLoggable(PlatformLogger logger, PlatformLogger.Level level, boolean expected) { + if (logger.isLoggable(level) != expected) { + throw new RuntimeException("logger " + logger.getName() + ": " + level + + (expected ? " not loggable" : " loggable")); } - logger.setLevel(PlatformLogger.FINER); - if (logger.getLevel() != PlatformLogger.FINER) { - throw new RuntimeException("Invalid level for logger " + - logger.getName() + " " + logger.getLevel()); + if (logger.isLoggable(level.intValue()) != expected) { + throw new RuntimeException("logger " + logger.getName() + ": " + level.intValue() + + (expected ? " not loggable" : " loggable")); } - if (logger.isLoggable(PlatformLogger.FINE) != true) { - throw new RuntimeException("isLoggerable(FINE) returns false for logger " + - logger.getName() + " but expected true"); + int value = level.intValue() + 5; // custom level value + if (expected && !logger.isLoggable(value)) { + throw new RuntimeException("logger " + logger.getName() + ": " + value + + " not loggable"); } + } - logger.info("OK: Testing log message"); + private static void checkLevel(PlatformLogger logger, PlatformLogger.Level level) { + if (logger.level() != level) { + throw new RuntimeException("Invalid level for logger " + + logger.getName() + ": " + logger.level() + " != " + level); + } + + if (logger.getLevel() != level.intValue()) { + throw new RuntimeException("Invalid level for logger " + + logger.getName() + ": " + logger.getLevel() + " != " + level.intValue()); + } } private static void checkLogger(String name, Level level) { @@ -146,26 +170,32 @@ for (Level level : levels) { PlatformLogger.Level platformLevel = PlatformLogger.Level.valueOf(level.getName()); for (PlatformLogger logger : loggers) { - // verify PlatformLogger.setLevel to a given level - logger.setLevel(platformLevel); - PlatformLogger.Level retrievedPlatformLevel = logger.getLevel(); - if (platformLevel != retrievedPlatformLevel) { - throw new RuntimeException("Retrieved PlatformLogger level " + - retrievedPlatformLevel + - " is not the same as set level " + platformLevel); - } - - // check the level set in java.util.logging.Logger - Logger javaLogger = LogManager.getLogManager().getLogger(logger.getName()); - Level javaLevel = javaLogger.getLevel(); - if (javaLogger.getLevel() != level) { - throw new RuntimeException("Retrieved backing java.util.logging.Logger level " + - javaLevel + " is not the expected " + level); - } + logger.setLevel(platformLevel); // setLevel(PlatformLogger.Level) + checkLoggerLevel(logger, level); + + logger.setLevel(ALL); // setLevel(int) + checkLoggerLevel(logger, Level.ALL); } } } + private static void checkLoggerLevel(PlatformLogger logger, Level level) { + PlatformLogger.Level plevel = PlatformLogger.Level.valueOf(level.getName()); + if (plevel != logger.level()) { + throw new RuntimeException("Retrieved PlatformLogger level " + + logger.level() + + " is not the same as set level " + plevel); + } + + // check the level set in java.util.logging.Logger + Logger javaLogger = LogManager.getLogManager().getLogger(logger.getName()); + Level javaLevel = javaLogger.getLevel(); + if (javaLogger.getLevel() != level) { + throw new RuntimeException("Retrieved backing java.util.logging.Logger level " + + javaLevel + " is not the expected " + level); + } + } + private static void checkPlatformLoggerLevelMapping(Level level) { // map the given level to PlatformLogger.Level of the same name and value PlatformLogger.Level platformLevel = PlatformLogger.Level.valueOf(level.getName()); @@ -174,21 +204,23 @@ + " PlatformLogger.Level" + platformLevel); } - PlatformLogger.Level plevel; try { // validate if there is a public static final field in PlatformLogger - // matching the level name - Field platformLevelField = PlatformLogger.class.getField(level.getName()); - plevel = (PlatformLogger.Level) platformLevelField.get(null); + Field constantField = PlatformLogger.class.getField(level.getName()); + int l = (int) constantField.get(null); + if (l != platformLevel.intValue()) { + throw new RuntimeException("static final " + level.getName() + " (" + + l + ") != " + platformLevel.intValue()); + } } catch (Exception e) { throw new RuntimeException("No public static PlatformLogger." + level.getName() + " field", e); } - if (!plevel.name().equals(level.getName())) + if (!platformLevel.name().equals(level.getName())) throw new RuntimeException("The value of PlatformLogger." + level.getName() + ".name() is " + platformLevel.name() + " but expected " + level.getName()); - if (plevel.intValue() != level.intValue()) + if (platformLevel.intValue() != level.intValue()) throw new RuntimeException("The value of PlatformLogger." + level.intValue() + ".intValue() is " + platformLevel.intValue() + " but expected " + level.intValue()); }