1 17 18 package org.apache.juli; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.net.URLClassLoader ; 25 import java.security.AccessController ; 26 import java.security.PrivilegedAction ; 27 import java.util.Collections ; 28 import java.util.Enumeration ; 29 import java.util.HashMap ; 30 import java.util.Iterator ; 31 import java.util.Map ; 32 import java.util.Properties ; 33 import java.util.StringTokenizer ; 34 import java.util.WeakHashMap ; 35 import java.util.logging.Handler ; 36 import java.util.logging.Level ; 37 import java.util.logging.LogManager ; 38 import java.util.logging.Logger ; 39 40 41 44 public class ClassLoaderLogManager extends LogManager { 45 46 47 49 50 55 protected final Map <ClassLoader , ClassLoaderLogInfo> classLoaderLoggers = 56 new WeakHashMap <ClassLoader , ClassLoaderLogInfo>(); 57 58 59 63 protected ThreadLocal <String > prefix = new ThreadLocal <String >(); 64 65 66 68 69 74 public synchronized boolean addLogger(final Logger logger) { 75 76 final String loggerName = logger.getName(); 77 78 ClassLoader classLoader = 79 Thread.currentThread().getContextClassLoader(); 80 ClassLoaderLogInfo info = getClassLoaderInfo(classLoader); 81 if (info.loggers.containsKey(loggerName)) { 82 return false; 83 } 84 info.loggers.put(loggerName, logger); 85 86 final String levelString = getProperty(loggerName + ".level"); 88 if (levelString != null) { 89 try { 90 AccessController.doPrivileged(new PrivilegedAction () { 91 public Object run() { 92 logger.setLevel(Level.parse(levelString.trim())); 93 return null; 94 } 95 }); 96 } catch (IllegalArgumentException e) { 97 } 99 } 100 101 int dotIndex = loggerName.lastIndexOf('.'); 104 while (dotIndex >= 0) { 105 final String parentName = loggerName.substring(0, dotIndex); 106 if (getProperty(parentName + ".level") != null) { 107 Logger.getLogger(parentName); 108 break; 109 } 110 dotIndex = loggerName.lastIndexOf('.', dotIndex - 1); 111 } 112 113 LogNode node = info.rootNode.findNode(loggerName); 115 node.logger = logger; 116 117 Logger parentLogger = node.findParentLogger(); 119 if (parentLogger != null) { 120 doSetParentLogger(logger, parentLogger); 121 } 122 123 node.setParentLogger(logger); 125 126 String handlers = getProperty(loggerName + ".handlers"); 129 if (handlers != null) { 130 logger.setUseParentHandlers(false); 131 StringTokenizer tok = new StringTokenizer (handlers, ","); 132 while (tok.hasMoreTokens()) { 133 String handlerName = (tok.nextToken().trim()); 134 Handler handler = null; 135 ClassLoader current = classLoader; 136 while (current != null) { 137 info = (ClassLoaderLogInfo) classLoaderLoggers.get(current); 138 if (info != null) { 139 handler = (Handler ) info.handlers.get(handlerName); 140 if (handler != null) { 141 break; 142 } 143 } 144 current = current.getParent(); 145 } 146 if (handler != null) { 147 logger.addHandler(handler); 148 } 149 } 150 } 151 152 String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); 156 if (Boolean.valueOf(useParentHandlersString).booleanValue()) { 157 logger.setUseParentHandlers(true); 158 } 159 160 return true; 161 } 162 163 164 173 public synchronized Logger getLogger(final String name) { 174 ClassLoader classLoader = Thread.currentThread() 175 .getContextClassLoader(); 176 return (Logger ) getClassLoaderInfo(classLoader).loggers.get(name); 177 } 178 179 180 184 public synchronized Enumeration <String > getLoggerNames() { 185 ClassLoader classLoader = Thread.currentThread() 186 .getContextClassLoader(); 187 return Collections.enumeration(getClassLoaderInfo(classLoader).loggers.keySet()); 188 } 189 190 191 197 public String getProperty(String name) { 198 ClassLoader classLoader = Thread.currentThread() 199 .getContextClassLoader(); 200 String prefix = (String ) this.prefix.get(); 201 if (prefix != null) { 202 name = prefix + name; 203 } 204 ClassLoaderLogInfo info = getClassLoaderInfo(classLoader); 205 String result = info.props.getProperty(name); 206 if ((result == null) && (info.props.isEmpty())) { 210 ClassLoader current = classLoader.getParent(); 211 while (current != null) { 212 info = (ClassLoaderLogInfo) classLoaderLoggers.get(current); 213 if (info != null) { 214 result = info.props.getProperty(name); 215 if ((result != null) || (!info.props.isEmpty())) { 216 break; 217 } 218 } 219 current = current.getParent(); 220 } 221 if (result == null) { 222 result = super.getProperty(name); 223 } 224 } 225 if (result != null) { 227 result = replace(result); 228 } 229 return result; 230 } 231 232 233 public void readConfiguration() 234 throws IOException , SecurityException { 235 236 checkAccess(); 237 238 readConfiguration(Thread.currentThread().getContextClassLoader()); 239 240 } 241 242 public void readConfiguration(InputStream is) 243 throws IOException , SecurityException { 244 245 checkAccess(); 246 reset(); 247 248 readConfiguration(is, Thread.currentThread().getContextClassLoader()); 249 250 } 251 252 254 255 262 protected ClassLoaderLogInfo getClassLoaderInfo(ClassLoader classLoader) { 263 264 if (classLoader == null) { 265 classLoader = ClassLoader.getSystemClassLoader(); 266 } 267 ClassLoaderLogInfo info = (ClassLoaderLogInfo) classLoaderLoggers 268 .get(classLoader); 269 if (info == null) { 270 final ClassLoader classLoaderParam = classLoader; 271 AccessController.doPrivileged(new PrivilegedAction () { 272 public Object run() { 273 try { 274 readConfiguration(classLoaderParam); 275 } catch (IOException e) { 276 } 278 return null; 279 } 280 }); 281 info = (ClassLoaderLogInfo) classLoaderLoggers.get(classLoader); 282 } 283 return info; 284 } 285 286 287 293 protected void readConfiguration(ClassLoader classLoader) 294 throws IOException { 295 296 InputStream is = null; 297 if ((classLoader instanceof URLClassLoader ) 300 && (((URLClassLoader ) classLoader).findResource("logging.properties") != null)) { 301 is = classLoader.getResourceAsStream("logging.properties"); 302 } 303 if ((is == null) && (classLoader == ClassLoader.getSystemClassLoader())) { 304 String configFileStr = System.getProperty("java.util.logging.config.file"); 305 if (configFileStr != null) { 306 try { 307 is = new FileInputStream (replace(configFileStr)); 308 } catch (IOException e) { 309 } 311 } 312 if (is == null) { 314 File defaultFile = new File (new File (System.getProperty("java.home"), "lib"), 315 "logging.properties"); 316 try { 317 is = new FileInputStream (defaultFile); 318 } catch (IOException e) { 319 } 321 } 322 } 323 324 Logger localRootLogger = new RootLogger(); 325 if (is == null) { 326 ClassLoader current = classLoader.getParent(); 328 ClassLoaderLogInfo info = null; 329 while (current != null && info == null) { 330 info = getClassLoaderInfo(current); 331 current = current.getParent(); 332 } 333 if (info != null) { 334 localRootLogger.setParent(info.rootNode.logger); 335 } 336 } 337 ClassLoaderLogInfo info = 338 new ClassLoaderLogInfo(new LogNode(null, localRootLogger)); 339 classLoaderLoggers.put(classLoader, info); 340 341 if (is != null) { 342 readConfiguration(is, classLoader); 343 } 344 addLogger(localRootLogger); 345 346 } 347 348 349 356 protected void readConfiguration(InputStream is, ClassLoader classLoader) 357 throws IOException { 358 359 ClassLoaderLogInfo info = 360 (ClassLoaderLogInfo) classLoaderLoggers.get(classLoader); 361 362 try { 363 info.props.load(is); 364 } catch (IOException e) { 365 System.err.println("Configuration error"); 367 e.printStackTrace(); 368 } finally { 369 try { 370 is.close(); 371 } catch (Throwable t) {} 372 } 373 374 String rootHandlers = info.props.getProperty(".handlers"); 376 String handlers = info.props.getProperty("handlers"); 377 Logger localRootLogger = info.rootNode.logger; 378 if (handlers != null) { 379 StringTokenizer tok = new StringTokenizer (handlers, ","); 380 while (tok.hasMoreTokens()) { 381 String handlerName = (tok.nextToken().trim()); 382 String handlerClassName = handlerName; 383 String prefix = ""; 384 if (handlerClassName.length() <= 0) { 385 continue; 386 } 387 if (Character.isDigit(handlerClassName.charAt(0))) { 390 int pos = handlerClassName.indexOf('.'); 391 if (pos >= 0) { 392 prefix = handlerClassName.substring(0, pos + 1); 393 handlerClassName = handlerClassName.substring(pos + 1); 394 } 395 } 396 try { 397 this.prefix.set(prefix); 398 Handler handler = 399 (Handler ) classLoader.loadClass(handlerClassName).newInstance(); 400 this.prefix.set(null); 404 info.handlers.put(handlerName, handler); 405 if (rootHandlers == null) { 406 localRootLogger.addHandler(handler); 407 } 408 } catch (Exception e) { 409 System.err.println("Handler error"); 411 e.printStackTrace(); 412 } 413 } 414 415 if (rootHandlers != null) { 417 StringTokenizer tok2 = new StringTokenizer (rootHandlers, ","); 418 while (tok2.hasMoreTokens()) { 419 String handlerName = (tok2.nextToken().trim()); 420 Handler handler = (Handler ) info.handlers.get(handlerName); 421 if (handler != null) { 422 localRootLogger.addHandler(handler); 423 } 424 } 425 } 426 427 } 428 429 } 430 431 432 438 protected static void doSetParentLogger(final Logger logger, 439 final Logger parent) { 440 AccessController.doPrivileged(new PrivilegedAction () { 441 public Object run() { 442 logger.setParent(parent); 443 return null; 444 } 445 }); 446 } 447 448 449 455 protected String replace(String str) { 456 String result = str.trim(); 457 if (result.startsWith("${")) { 458 int pos = result.indexOf('}'); 459 if (pos != -1) { 460 String propName = result.substring(2, pos); 461 String replacement = System.getProperty(propName); 462 if (replacement != null) { 463 result = replacement + result.substring(pos + 1); 464 } 465 } 466 } 467 return result; 468 } 469 470 471 473 474 protected static final class LogNode { 475 Logger logger; 476 477 protected final Map <String , LogNode> children = 478 new HashMap <String , LogNode>(); 479 480 protected final LogNode parent; 481 482 LogNode(final LogNode parent, final Logger logger) { 483 this.parent = parent; 484 this.logger = logger; 485 } 486 487 LogNode(final LogNode parent) { 488 this(parent, null); 489 } 490 491 LogNode findNode(String name) { 492 LogNode currentNode = this; 493 if (logger.getName().equals(name)) { 494 return this; 495 } 496 while (name != null) { 497 final int dotIndex = name.indexOf('.'); 498 final String nextName; 499 if (dotIndex < 0) { 500 nextName = name; 501 name = null; 502 } else { 503 nextName = name.substring(0, dotIndex); 504 name = name.substring(dotIndex + 1); 505 } 506 LogNode childNode = (LogNode) currentNode.children 507 .get(nextName); 508 if (childNode == null) { 509 childNode = new LogNode(currentNode); 510 currentNode.children.put(nextName, childNode); 511 } 512 currentNode = childNode; 513 } 514 return currentNode; 515 } 516 517 Logger findParentLogger() { 518 Logger logger = null; 519 LogNode node = parent; 520 while (node != null && logger == null) { 521 logger = node.logger; 522 node = node.parent; 523 } 524 return logger; 525 } 526 527 void setParentLogger(final Logger parent) { 528 for (final Iterator iter = children.values().iterator(); iter 529 .hasNext();) { 530 final LogNode childNode = (LogNode) iter.next(); 531 if (childNode.logger == null) { 532 childNode.setParentLogger(parent); 533 } else { 534 doSetParentLogger(childNode.logger, parent); 535 } 536 } 537 } 538 539 } 540 541 542 544 545 protected static final class ClassLoaderLogInfo { 546 final LogNode rootNode; 547 final Map <String , Logger > loggers = new HashMap <String , Logger >(); 548 final Map <String , Handler > handlers = new HashMap <String , Handler >(); 549 final Properties props = new Properties (); 550 551 ClassLoaderLogInfo(final LogNode rootNode) { 552 this.rootNode = rootNode; 553 } 554 555 } 556 557 558 560 561 565 protected class RootLogger extends Logger { 566 public RootLogger() { 567 super("", null); 568 } 569 } 570 571 572 } 573 | Popular Tags |