8011380: FX dependency on PlatformLogger broken by 8010309
authormchung
Fri, 05 Apr 2013 10:41:46 -0700
changeset 16736 f1e17f49191a
parent 16735 73b1a1971a76
child 16737 8f36190e097a
8011380: FX dependency on PlatformLogger broken by 8010309 Reviewed-by: alanb
jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java
jdk/src/share/classes/sun/util/logging/LoggingProxy.java
jdk/src/share/classes/sun/util/logging/LoggingSupport.java
jdk/src/share/classes/sun/util/logging/PlatformLogger.java
jdk/test/sun/util/logging/PlatformLoggerTest.java
--- a/jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java	Thu Apr 04 20:05:47 2013 -0700
+++ b/jdk/src/share/classes/java/util/logging/LoggingProxyImpl.java	Fri Apr 05 10:41:46 2013 -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);
     }
--- a/jdk/src/share/classes/sun/util/logging/LoggingProxy.java	Thu Apr 04 20:05:47 2013 -0700
+++ b/jdk/src/share/classes/sun/util/logging/LoggingProxy.java	Fri Apr 05 10:41:46 2013 -0700
@@ -61,6 +61,8 @@
 
     public String getLevelName(Object level);
 
+    public int getLevelValue(Object level);
+
     // return the logging property
     public String getProperty(String key);
 }
--- a/jdk/src/share/classes/sun/util/logging/LoggingSupport.java	Thu Apr 04 20:05:47 2013 -0700
+++ b/jdk/src/share/classes/sun/util/logging/LoggingSupport.java	Fri Apr 05 10:41:46 2013 -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";
 
--- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Thu Apr 04 20:05:47 2013 -0700
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java	Fri Apr 05 10:41:46 2013 -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) {
--- a/jdk/test/sun/util/logging/PlatformLoggerTest.java	Thu Apr 04 20:05:47 2013 -0700
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java	Fri Apr 05 10:41:46 2013 -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");
+        }
+    }
+
+    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);
         }
 
-        logger.info("OK: Testing log message");
+        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,23 +170,29 @@
         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);
-                }
+                logger.setLevel(platformLevel);       // setLevel(PlatformLogger.Level)
+                checkLoggerLevel(logger, level);
+
+                logger.setLevel(ALL);  // setLevel(int)
+                checkLoggerLevel(logger, Level.ALL);
+            }
+        }
+    }
 
-                // 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 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);
         }
     }
 
@@ -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());
     }