1 /* 2 * Copyright (c) 2009, 2018, 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.javafx.logging; 27 28 import java.lang.ref.WeakReference; 29 import java.util.Arrays; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.ResourceBundle; 33 34 /** 35 * Platform logger provides an API for the JavaFX components to log 36 * messages. It is an internal logger intended to be used by JavaFX modules. 37 * 38 * The PlatformLogger uses an underlying System.Logger 39 * obtained by calling {@link java.lang.System.Logger#getLogger(String)} 40 * 41 * PlatformLogger implements System.Logger as to facilitiate logging of 42 * calling class and method. 43 * Note : JDK internal loggers know to skip any calls from System.Logger 44 * classes when looking for the calling class / method. 45 */ 46 public class PlatformLogger implements System.Logger { 47 48 /** 49 * PlatformLogger logging levels. 50 */ 51 public static enum Level { 52 // The name and value must match that of {@code java.lang.System.Level}s. 53 // Declare in ascending order of the given value for binary search. 54 ALL(System.Logger.Level.ALL), 55 FINEST(System.Logger.Level.TRACE), 56 FINER(System.Logger.Level.TRACE), 57 FINE(System.Logger.Level.DEBUG), 58 CONFIG(System.Logger.Level.DEBUG), 59 INFO(System.Logger.Level.INFO), 60 WARNING(System.Logger.Level.WARNING), 61 SEVERE(System.Logger.Level.ERROR), 62 OFF(System.Logger.Level.OFF); 63 64 final System.Logger.Level systemLevel; 65 Level(System.Logger.Level systemLevel) { 66 this.systemLevel = systemLevel; 67 } 68 69 // The integer values must match that of {@code java.util.logging.Level} 70 // objects. 71 private static final int SEVERITY_OFF = Integer.MAX_VALUE; 72 private static final int SEVERITY_SEVERE = 1000; 73 private static final int SEVERITY_WARNING = 900; 74 private static final int SEVERITY_INFO = 800; 75 private static final int SEVERITY_CONFIG = 700; 76 private static final int SEVERITY_FINE = 500; 77 private static final int SEVERITY_FINER = 400; 78 private static final int SEVERITY_FINEST = 300; 79 private static final int SEVERITY_ALL = Integer.MIN_VALUE; 80 81 // ascending order for binary search matching the list of enum constants 82 private static final int[] LEVEL_VALUES = new int[] { 83 SEVERITY_ALL, SEVERITY_FINEST, SEVERITY_FINER, 84 SEVERITY_FINE, SEVERITY_CONFIG, SEVERITY_INFO, 85 SEVERITY_WARNING, SEVERITY_SEVERE, SEVERITY_OFF 86 }; 87 88 public System.Logger.Level systemLevel() { 89 return systemLevel; 90 } 91 92 public int intValue() { 93 return LEVEL_VALUES[this.ordinal()]; 94 } 95 96 /** 97 * Maps a severity value to an effective logger level. 98 * @param level The severity of the messages that should be 99 * logged with a logger set to the returned level. 100 * @return The effective logger level, which is the nearest Level value 101 * whose severity is greater or equal to the given level. 102 * For level > SEVERE (OFF excluded), return SEVERE. 103 */ 104 public static Level valueOf(int level) { 105 switch (level) { 106 // ordering per the highest occurrences in the jdk source 107 // finest, fine, finer, info first 108 case SEVERITY_FINEST : return Level.FINEST; 109 case SEVERITY_FINE : return Level.FINE; 110 case SEVERITY_FINER : return Level.FINER; 111 case SEVERITY_INFO : return Level.INFO; 112 case SEVERITY_WARNING : return Level.WARNING; 113 case SEVERITY_CONFIG : return Level.CONFIG; 114 case SEVERITY_SEVERE : return Level.SEVERE; 115 case SEVERITY_OFF : return Level.OFF; 116 case SEVERITY_ALL : return Level.ALL; 117 } 118 // return the nearest Level value >= the given level, 119 // for level > SEVERE, return SEVERE and exclude OFF 120 int i = Arrays.binarySearch(LEVEL_VALUES, 0, LEVEL_VALUES.length-2, level); 121 return values()[i >= 0 ? i : (-i-1)]; 122 } 123 } 124 125 private System.Logger.Level getSystemLoggerLevel(Level l) { 126 switch (l) { 127 case ALL : return System.Logger.Level.ALL; 128 case FINEST: return System.Logger.Level.TRACE; 129 case FINER: return System.Logger.Level.TRACE; 130 case FINE: return System.Logger.Level.DEBUG; 131 case CONFIG: return System.Logger.Level.DEBUG; 132 case INFO: return System.Logger.Level.INFO; 133 case WARNING: return System.Logger.Level.WARNING; 134 case SEVERE: return System.Logger.Level.ERROR; 135 case OFF: return System.Logger.Level.OFF; 136 default : return System.Logger.Level.ALL; 137 } 138 } 139 140 141 // Table of known loggers. Maps names to PlatformLoggers. 142 private static final Map<String,WeakReference<PlatformLogger>> loggers = 143 new HashMap<>(); 144 145 /** 146 * Returns a PlatformLogger of a given name. 147 * @param name the name of the logger 148 * @return a PlatformLogger 149 */ 150 public static synchronized PlatformLogger getLogger(String name) { 151 PlatformLogger log = null; 152 WeakReference<PlatformLogger> ref = loggers.get(name); 153 if (ref != null) { 154 log = ref.get(); 155 } 156 if (log == null) { 157 log = new PlatformLogger(System.getLogger(name)); 158 loggers.put(name, new WeakReference<>(log)); 159 } 160 return log; 161 } 162 163 164 private final System.Logger loggerProxy; 165 private PlatformLogger(System.Logger loggerProxy) { 166 this.loggerProxy = loggerProxy; 167 } 168 169 // ------------------------------------------------------------------------ 170 // From System.Logger interface 171 // ------------------------------------------------------------------------ 172 173 /** 174 * Gets the name for this platform logger. 175 * @return the name of the platform logger. 176 */ 177 @Override 178 public String getName() { 179 throw new UnsupportedOperationException("not implemented"); 180 } 181 182 @Override 183 public boolean isLoggable(System.Logger.Level level) { 184 throw new UnsupportedOperationException("not implemented"); 185 } 186 187 @Override 188 public void log(System.Logger.Level level, ResourceBundle bundle, String format, Object... params) { 189 throw new UnsupportedOperationException("not implemented"); 190 } 191 192 @Override 193 public void log(System.Logger.Level level, ResourceBundle bundle, String msg, Throwable thrown) { 194 throw new UnsupportedOperationException("not implemented"); 195 } 196 197 // ------------------------------------------------------------------------ 198 199 200 /** 201 * Returns true if a message of the given level would actually 202 * be logged by this logger. 203 * @param level the level 204 * @return whether a message of that level would be logged 205 */ 206 public boolean isLoggable(Level level) { 207 if (level == null) { 208 throw new NullPointerException(); 209 } 210 211 return loggerProxy.isLoggable(getSystemLoggerLevel(level)); 212 } 213 214 /** 215 * Logs a SEVERE message. 216 * @param msg the message 217 */ 218 public void severe(String msg) { 219 if (!loggingEnabled) return; 220 loggerProxy.log(System.Logger.Level.ERROR, msg, (Object[])null); 221 } 222 223 public void severe(String msg, Throwable t) { 224 if (!loggingEnabled) return; 225 loggerProxy.log(System.Logger.Level.ERROR, msg, t); 226 } 227 228 public void severe(String msg, Object... params) { 229 if (!loggingEnabled) return; 230 loggerProxy.log(System.Logger.Level.ERROR, msg, params); 231 } 232 233 /** 234 * Logs a WARNING message. 235 * @param msg the message 236 */ 237 public void warning(String msg) { 238 if (!loggingEnabled) return; 239 loggerProxy.log(System.Logger.Level.WARNING, msg, (Object[])null); 240 } 241 242 public void warning(String msg, Throwable t) { 243 if (!loggingEnabled) return; 244 loggerProxy.log(System.Logger.Level.WARNING, msg, t); 245 } 246 247 public void warning(String msg, Object... params) { 248 if (!loggingEnabled) return; 249 loggerProxy.log(System.Logger.Level.WARNING, msg, params); 250 } 251 252 /** 253 * Logs an INFO message. 254 * @param msg the message 255 */ 256 public void info(String msg) { 257 if (!loggingEnabled) return; 258 loggerProxy.log(System.Logger.Level.INFO, msg, (Object[])null); 259 } 260 261 public void info(String msg, Throwable t) { 262 if (!loggingEnabled) return; 263 loggerProxy.log(System.Logger.Level.INFO, msg, t); 264 } 265 266 public void info(String msg, Object... params) { 267 if (!loggingEnabled) return; 268 loggerProxy.log(System.Logger.Level.INFO, msg, params); 269 } 270 271 /** 272 * Logs a CONFIG message. 273 * @param msg the message 274 */ 275 public void config(String msg) { 276 if (!loggingEnabled) return; 277 loggerProxy.log(System.Logger.Level.DEBUG, msg, (Object[])null); 278 } 279 280 public void config(String msg, Throwable t) { 281 if (!loggingEnabled) return; 282 loggerProxy.log(System.Logger.Level.DEBUG, msg, t); 283 } 284 285 public void config(String msg, Object... params) { 286 if (!loggingEnabled) return; 287 loggerProxy.log(System.Logger.Level.DEBUG, msg, params); 288 } 289 290 /** 291 * Logs a FINE message. 292 * @param msg the message 293 */ 294 public void fine(String msg) { 295 if (!loggingEnabled) return; 296 loggerProxy.log(System.Logger.Level.DEBUG, msg, (Object[])null); 297 } 298 299 public void fine(String msg, Throwable t) { 300 if (!loggingEnabled) return; 301 loggerProxy.log(System.Logger.Level.DEBUG, msg, t); 302 } 303 304 public void fine(String msg, Object... params) { 305 if (!loggingEnabled) return; 306 loggerProxy.log(System.Logger.Level.DEBUG, msg, params); 307 } 308 309 /** 310 * Logs a FINER message. 311 * @param msg the message 312 */ 313 public void finer(String msg) { 314 if (!loggingEnabled) return; 315 loggerProxy.log(System.Logger.Level.TRACE, msg, (Object[])null); 316 } 317 318 public void finer(String msg, Throwable t) { 319 if (!loggingEnabled) return; 320 loggerProxy.log(System.Logger.Level.TRACE, msg, t); 321 } 322 323 public void finer(String msg, Object... params) { 324 if (!loggingEnabled) return; 325 loggerProxy.log(System.Logger.Level.TRACE, msg, params); 326 } 327 328 /** 329 * Logs a FINEST message. 330 * @param msg the message 331 */ 332 public void finest(String msg) { 333 if (!loggingEnabled) return; 334 loggerProxy.log(System.Logger.Level.TRACE, msg, (Object[])null); 335 } 336 337 public void finest(String msg, Throwable t) { 338 if (!loggingEnabled) return; 339 loggerProxy.log(System.Logger.Level.TRACE, msg, t); 340 } 341 342 public void finest(String msg, Object... params) { 343 if (!loggingEnabled) return; 344 loggerProxy.log(System.Logger.Level.TRACE, msg, params); 345 } 346 347 // Methods for unit tests 348 private boolean loggingEnabled = true; 349 public void enableLogging() { 350 loggingEnabled = true; 351 }; 352 353 public void disableLogging() { 354 loggingEnabled = false; 355 } 356 } 357