001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.internal; 014 015import static java.util.logging.Level.*; 016import static org.apache.juneau.internal.StringUtils.*; 017 018import java.text.*; 019import java.util.*; 020import java.util.concurrent.*; 021import java.util.logging.*; 022 023import org.apache.juneau.json.*; 024import org.apache.juneau.serializer.*; 025 026/** 027 * Wraps and extends the {@link java.util.logging.Logger} class to provide some additional convenience methods. 028 * 029 * @deprecated Methods introduced in Java 8 Logging API renders this class obsolete. 030 */ 031@Deprecated 032public class JuneauLogger extends java.util.logging.Logger { 033 034 private static final WriterSerializer serializer = JsonSerializer.create().ssq().build(); 035 036 private static final ConcurrentHashMap<Class<?>,String> rbMap = new ConcurrentHashMap<>(); 037 038 private final ResourceBundle rb; 039 private final java.util.logging.Logger innerLogger; 040 041 /** 042 * Get logger for specified class. 043 * 044 * @param forClass The class to create a logger for. 045 * @return A new <l>BasicLogger</l>. 046 */ 047 public static JuneauLogger getLogger(Class<?> forClass) { 048 return getLogger(forClass.getName()); 049 } 050 051 /** 052 * Get logger for specified class. 053 * 054 * @param loggerName The logger name. 055 * @return A new <l>BasicLogger</l>. 056 */ 057 public static JuneauLogger getLogger(String loggerName) { 058 return new JuneauLogger(java.util.logging.Logger.getLogger(loggerName)); 059 } 060 061 /** 062 * Get logger for specified class using the specified resource bundle name. 063 * 064 * @param forClass The class to create a logger for. 065 * @param resourceBundleName 066 * The name of the resource bundle. 067 * Can be any of the following formats: 068 * <ol> 069 * <li>An absolute path. E.g. <js>"com/foo/nls/Messages"</js>. 070 * <li>A path relative to the package of the class. E.g. <js>"nls/Messages"</js>. 071 * </ol> 072 * Both <js>'.'</js> and <js>'/'</js> can be used as path delimiters. 073 * @return A new <l>BasicLogger</l>. 074 */ 075 public static JuneauLogger getLogger(Class<?> forClass, String resourceBundleName) { 076 return new JuneauLogger(java.util.logging.Logger.getLogger(forClass.getName(), resolveResourceBundleName(forClass, resourceBundleName))); 077 } 078 079 /** 080 * Get logger with specified name using the specified resource bundle name. 081 * 082 * @param name The name of the logger to use. 083 * @param resourceBundleName 084 * The name of the resource bundle. 085 * Can be any of the following formats: 086 * <ol> 087 * <li>An absolute path. E.g. <js>"com/foo/nls/Messages"</js>. 088 * <li>A path relative to the package of the class. E.g. <js>"nls/Messages"</js>. 089 * </ol> 090 * Both <js>'.'</js> and <js>'/'</js> can be used as path delimiters. 091 * @return A new <l>BasicLogger</l>. 092 */ 093 public static synchronized JuneauLogger getLogger(String name, String resourceBundleName) { 094 return new JuneauLogger(java.util.logging.Logger.getLogger(name, resourceBundleName)); 095 } 096 097 /** 098 * Wrap the specified logger 099 * 100 * @param logger The java logger to use for logging. 101 * @return A new <l>BasicLogger</l>. 102 */ 103 public static synchronized JuneauLogger getLogger(java.util.logging.Logger logger) { 104 return new JuneauLogger(logger); 105 } 106 107 /** 108 * Constructor. 109 * 110 * @param innerLogger The wrapped logger. 111 */ 112 public JuneauLogger(java.util.logging.Logger innerLogger) { 113 super(innerLogger.getName(), innerLogger.getResourceBundleName()); 114 this.innerLogger = innerLogger; 115 this.rb = getResourceBundle(); 116 } 117 118 /** 119 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#SEVERE} level. 120 * 121 * @param msg The message to log. 122 * @param args Optional {@link MessageFormat}-style arguments. 123 */ 124 public void severe(String msg, Object...args) { 125 if (isLoggable(SEVERE)) 126 log(SEVERE, msg, args); 127 } 128 129 /** 130 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#WARNING} level. 131 * 132 * @param msg The message to log. 133 * @param args Optional {@link MessageFormat}-style arguments. 134 */ 135 public void warning(String msg, Object...args) { 136 if (isLoggable(WARNING)) 137 log(WARNING, msg, args); 138 } 139 140 /** 141 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#INFO} level. 142 * 143 * @param msg The message to log. 144 * @param args Optional {@link MessageFormat}-style arguments. 145 */ 146 public void info(String msg, Object...args) { 147 if (isLoggable(INFO)) 148 log(INFO, msg, args); 149 } 150 151 /** 152 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#CONFIG} level. 153 * 154 * @param msg The message to log. 155 * @param args Optional {@link MessageFormat}-style arguments. 156 */ 157 public void config(String msg, Object...args) { 158 if (isLoggable(CONFIG)) 159 log(CONFIG, msg, args); 160 } 161 162 /** 163 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINE} level. 164 * 165 * @param msg The message to log. 166 * @param args Optional {@link MessageFormat}-style arguments. 167 */ 168 public void fine(String msg, Object...args) { 169 if (isLoggable(FINE)) 170 log(FINE, msg, args); 171 } 172 173 /** 174 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINER} level. 175 * 176 * @param msg The message to log. 177 * @param args Optional {@link MessageFormat}-style arguments. 178 */ 179 public void finer(String msg, Object...args) { 180 if (isLoggable(FINER)) 181 log(FINER, msg, args); 182 } 183 184 /** 185 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINEST} level. 186 * 187 * @param msg The message to log. 188 * @param args Optional {@link MessageFormat}-style arguments. 189 */ 190 public void finest(String msg, Object...args) { 191 if (isLoggable(FINEST)) 192 log(FINEST, msg, args); 193 } 194 195 /** 196 * Logs an exception as {@link Level#SEVERE} level. 197 * 198 * @param t The Throwable object to log. 199 */ 200 public void severe(Throwable t) { 201 if (isLoggable(SEVERE)) 202 log(SEVERE, t.getLocalizedMessage(), t); 203 } 204 205 /** 206 * Logs an exception as {@link Level#WARNING} level. 207 * 208 * @param t The Throwable object to log. 209 */ 210 public void warning(Throwable t) { 211 if (isLoggable(WARNING)) 212 log(WARNING, t.getLocalizedMessage(), t); 213 } 214 215 /** 216 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#SEVERE} level. 217 * 218 * @param t The Throwable object associated with the event that needs to be logged. 219 * @param msg The message to log. 220 * @param args Optional {@link MessageFormat}-style arguments. 221 */ 222 public void severe(Throwable t, String msg, Object...args) { 223 if (isLoggable(SEVERE)) 224 log(SEVERE, getMessage(msg, args), t); 225 } 226 227 /** 228 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#WARNING} level. 229 * 230 * @param t The Throwable object associated with the event that needs to be logged. 231 * @param msg The message to log. 232 * @param args Optional {@link MessageFormat}-style arguments. 233 */ 234 public void warning(Throwable t, String msg, Object...args) { 235 if (isLoggable(WARNING)) 236 log(WARNING, getMessage(msg, args), t); 237 } 238 239 /** 240 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#INFO} level. 241 * 242 * @param t The Throwable object associated with the event that needs to be logged. 243 * @param msg The message to log. 244 * @param args Optional {@link MessageFormat}-style arguments. 245 */ 246 public void info(Throwable t, String msg, Object...args) { 247 if (isLoggable(INFO)) 248 log(INFO, getMessage(msg, args), t); 249 } 250 251 @Override /* Logger */ 252 public void log(LogRecord record) { 253 innerLogger.log(record); 254 } 255 256 /** 257 * Logs a message with the specified {@link MessageFormat}-style arguments at the specified level. 258 * 259 * @param level The log level. 260 * @param cause The Throwable object associated with the event that needs to be logged. 261 * @param msg The message to log. 262 * @param args Optional {@link MessageFormat}-style arguments. 263 */ 264 public void log(Level level, Throwable cause, String msg, Object...args) { 265 if (isLoggable(level)) 266 log(level, getMessage(msg, args), cause); 267 } 268 269 @Override /* Logger */ 270 public boolean isLoggable(Level level) { 271 return innerLogger.isLoggable(level); 272 } 273 274 /** 275 * Similar to {@link #log(Level, String, Object[])}, except arguments are converted to objects 276 * that are serialized using the {@link JsonSerializer#toStringObject(Object)} method. 277 * 278 * <p> 279 * This allows arbitrary POJOs to be serialized as message parameters. 280 * 281 * @param level The level of the given message. 282 * @param msg The message to log. 283 * @param args The POJO arguments. 284 */ 285 public void logObjects(Level level, String msg, Object...args) { 286 if (isLoggable(level)) { 287 for (int i = 0; i < args.length; i++) 288 args[i] = serializer.toStringObject(args[i]); 289 log(level, msg, args); 290 } 291 } 292 293 private String getMessage(String msg, Object...args) { 294 if (args.length == 0) 295 return msg; 296 if (rb != null && rb.containsKey(msg)) 297 msg = rb.getString(msg); 298 return format(msg, args); 299 } 300 301 private static String resolveResourceBundleName(Class<?> forClass, String path) { 302 if (isEmpty(path)) 303 return null; 304 String rb = rbMap.get(forClass); 305 if (rb == null) { 306 path = path.replace('/', '.'); 307 if (path.startsWith(".")) 308 path = path.substring(1); 309 ClassLoader cl = forClass.getClassLoader(); 310 try { 311 ResourceBundle.getBundle(path, Locale.getDefault(), cl); 312 rbMap.putIfAbsent(forClass, path); 313 } catch (MissingResourceException e) { 314 try { 315 path = forClass.getPackage().getName() + '.' + path; 316 ResourceBundle.getBundle(path, Locale.getDefault(), cl); 317 rbMap.putIfAbsent(forClass, path); 318 } catch (MissingResourceException e2) { 319 rbMap.putIfAbsent(forClass, ""); 320 } 321 } 322 rb = rbMap.get(forClass); 323 } 324 return ("".equals(rb) ? null : rb); 325 } 326}