1 29 30 package com.caucho.log; 31 32 import com.caucho.loader.ClassLoaderListener; 33 import com.caucho.loader.DynamicClassLoader; 34 import com.caucho.loader.Environment; 35 import com.caucho.loader.EnvironmentClassLoader; 36 import com.caucho.loader.EnvironmentLocal; 37 38 import java.lang.ref.WeakReference ; 39 import java.util.ArrayList ; 40 import java.util.logging.Handler ; 41 import java.util.logging.Level ; 42 import java.util.logging.LogRecord ; 43 import java.util.logging.Logger ; 44 45 48 class EnvironmentLogger extends Logger implements ClassLoaderListener { 49 private final EnvironmentLocal<Logger > _localLoggers 51 = new EnvironmentLocal<Logger >(); 52 53 private final EnvironmentLocal<Handler []> _localHandlers 55 = new EnvironmentLocal<Handler []>(); 56 57 private final EnvironmentLocal<HandlerEntry> _ownHandlers 59 = new EnvironmentLocal<HandlerEntry>(); 60 61 private final EnvironmentLocal<Boolean > _useParentHandlers 63 = new EnvironmentLocal<Boolean >(); 64 65 private boolean _hasLocalLevel; 66 67 private final EnvironmentLocal<Level > _localLevel 69 = new EnvironmentLocal<Level >(); 70 71 private EnvironmentLogger _parent; 72 73 private Level _assignedLevel = Level.INFO; 75 76 private Level _handlerLevel = Level.OFF; 78 79 private final ArrayList <WeakReference <EnvironmentLogger>> _children 82 = new ArrayList <WeakReference <EnvironmentLogger>>(); 83 84 private final ArrayList <WeakReference <ClassLoader >> _loaders 86 = new ArrayList <WeakReference <ClassLoader >>(); 87 88 public EnvironmentLogger(String name, String resourceBundleName) 89 { 90 super(name, resourceBundleName); 91 } 92 93 97 public void setParent(Logger parent) 98 { 99 if (parent.equals(_parent)) 100 return; 101 102 super.setParent(parent); 103 104 if (parent instanceof EnvironmentLogger) { 105 _parent = (EnvironmentLogger) parent; 106 107 _assignedLevel = _parent.getAssignedLevel(); 108 _handlerLevel = _parent.getHandlerLevel(); 109 110 setEffectiveLevel(); 111 112 _parent.addChild(this); 113 } 114 } 115 116 private Level getHandlerLevel() 117 { 118 return _handlerLevel; 119 } 120 121 124 void addChild(EnvironmentLogger child) 125 { 126 _children.add(new WeakReference <EnvironmentLogger>(child)); 127 } 128 129 132 public synchronized void addHandler(Handler handler) 133 { 134 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 135 136 boolean hasLoader = false; 137 for (int i = _loaders.size() - 1; i >= 0; i--) { 138 WeakReference <ClassLoader > ref = _loaders.get(i); 139 ClassLoader refLoader = ref.get(); 140 141 if (refLoader == null) 142 _loaders.remove(i); 143 144 if (refLoader == loader) 145 hasLoader = true; 146 147 if (isParentLoader(loader, refLoader)) 148 addHandler(handler, refLoader); 149 } 150 151 if (! hasLoader) { 152 _loaders.add(new WeakReference <ClassLoader >(loader)); 153 addHandler(handler, loader); 154 Environment.addClassLoaderListener(this, loader); 155 } 156 157 HandlerEntry ownHandlers = _ownHandlers.get(); 158 if (ownHandlers == null) { 159 ownHandlers = new HandlerEntry(this); 160 _ownHandlers.set(ownHandlers); 161 } 162 163 ownHandlers.addHandler(handler); 164 } 165 166 169 private void addHandler(Handler handler, ClassLoader loader) 170 { 171 ArrayList <Handler > handlers = new ArrayList <Handler >(); 173 174 handlers.add(handler); 175 176 for (ClassLoader ptr = loader; ptr != null; ptr = ptr.getParent()) { 177 Handler []localHandlers = _localHandlers.getLevel(ptr); 178 179 if (localHandlers != null) { 180 for (int i = 0; i < localHandlers.length; i++) { 181 int p = handlers.indexOf(localHandlers[i]); 182 183 if (p < 0) { 184 handlers.add(localHandlers[i]); 185 } 186 else { 187 Handler oldHandler = handlers.get(p); 188 189 if (localHandlers[i].getLevel().intValue() 190 < oldHandler.getLevel().intValue()) { 191 handlers.set(p, localHandlers[i]); 192 } 193 } 194 } 195 } 196 } 197 198 Handler []newHandlers = new Handler [handlers.size()]; 199 handlers.toArray(newHandlers); 200 201 _localHandlers.set(newHandlers); 202 203 setHandlerLevel(handler.getLevel()); 204 } 205 206 209 public synchronized void removeHandler(Handler handler) 210 { 211 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 212 213 boolean hasLoader = false; 214 for (int i = _loaders.size() - 1; i >= 0; i--) { 215 WeakReference <ClassLoader > ref = _loaders.get(i); 216 ClassLoader refLoader = ref.get(); 217 218 if (refLoader == null) 219 _loaders.remove(i); 220 221 if (isParentLoader(loader, refLoader)) 222 removeHandler(handler, refLoader); 223 } 224 225 HandlerEntry ownHandlers = _ownHandlers.get(); 226 if (ownHandlers != null) 227 ownHandlers.removeHandler(handler); 228 } 229 230 private void removeHandler(Handler handler, ClassLoader loader) 231 { 232 ArrayList <Handler > handlers = new ArrayList <Handler >(); 233 234 for (ClassLoader ptr = loader; ptr != null; ptr = ptr.getParent()) { 235 Handler []localHandlers = _localHandlers.getLevel(ptr); 236 237 if (localHandlers != null) { 238 for (int i = 0; i < localHandlers.length; i++) { 239 if (! localHandlers[i].equals(handler)) { 240 int p = handlers.indexOf(localHandlers[i]); 241 242 if (p < 0) { 243 handlers.add(localHandlers[i]); 244 } 245 else { 246 Handler oldHandler = handlers.get(p); 247 248 if (localHandlers[i].getLevel().intValue() 249 < oldHandler.getLevel().intValue()) { 250 handlers.set(p, localHandlers[i]); 251 } 252 } 253 } 254 } 255 } 256 } 257 258 Handler []newHandlers = new Handler [handlers.size()]; 259 handlers.toArray(newHandlers); 260 261 _localHandlers.set(newHandlers); 262 263 setHandlerLevel(handler.getLevel()); 264 } 265 266 272 private boolean isParentLoader(ClassLoader parent, ClassLoader child) 273 { 274 for (; child != null; child = child.getParent()) { 275 if (child == parent) 276 return true; 277 } 278 279 return false; 280 } 281 282 285 boolean addLogger(Logger logger) 286 { 287 if (logger.getClass().getName().startsWith("java")) 288 return false; 289 290 Logger oldLogger = _localLoggers.get(); 291 292 if (oldLogger != null) 293 return false; 294 295 _localLoggers.set(logger); 296 298 return true; 299 } 300 301 304 Logger getLogger() 305 { 306 return _localLoggers.get(); 307 } 308 309 312 public void log(LogRecord record) 313 { 314 if (record == null) 315 return; 316 317 if (_hasLocalLevel) { 318 Level level = _localLevel.get(); 319 320 if (level != null && record.getLevel().intValue() < level.intValue()) 321 return; 322 } 323 324 super.log(record); 325 } 326 327 330 public Handler []getHandlers() 331 { 332 return _localHandlers.get(); 333 } 334 335 338 public boolean getUseParentHandlers() 339 { 340 Boolean value = _useParentHandlers.get(); 341 342 if (value != null) 343 return Boolean.TRUE.equals(value); 344 else 345 return true; 346 } 347 348 351 public void setUseParentHandlers(boolean useParentHandlers) 352 { 353 _useParentHandlers.set(new Boolean (useParentHandlers)); 354 } 355 356 359 public void classLoaderInit(DynamicClassLoader env) 360 { 361 } 362 363 366 public void classLoaderDestroy(DynamicClassLoader loader) 367 { 368 removeLoader(loader); 369 370 _localHandlers.remove(loader); 371 372 HandlerEntry ownHandlers = _ownHandlers.getLevel(loader); 373 if (ownHandlers != null) 374 _ownHandlers.remove(loader); 375 376 if (ownHandlers != null) 377 ownHandlers.destroy(); 378 379 _localLevel.remove(loader); 380 381 updateAssignedLevel(); 382 updateHandlerLevel(); 383 } 384 385 390 public void setLevel(Level level) 391 { 392 _localLevel.set(level); 393 394 if (level != null) { 395 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 396 397 addLoader(loader); 398 } 399 400 updateAssignedLevel(); 401 } 402 403 406 private void addLoader(ClassLoader loader) 407 { 408 boolean hasLoader = false; 409 for (int i = _loaders.size() - 1; i >= 0; i--) { 410 WeakReference <ClassLoader > ref = _loaders.get(i); 411 ClassLoader refLoader = ref.get(); 412 413 if (refLoader == null) 414 _loaders.remove(i); 415 416 if (refLoader == loader) 417 return; 418 } 419 420 _loaders.add(new WeakReference <ClassLoader >(loader)); 421 Environment.addClassLoaderListener(this, loader); 422 } 423 424 427 public Level getLevel() 428 { 429 if (_hasLocalLevel) { 430 Level level = _localLevel.get(); 431 432 if (level != null) { 433 return level; 434 } 435 } 436 437 return null; 438 } 439 440 444 private Level getAssignedLevel() 445 { 446 for (Logger log = this; log != null; log = log.getParent()) { 447 Level level = log.getLevel(); 448 449 if (level != null) 450 return level; 451 } 452 453 return Level.INFO; 454 } 455 456 459 private void setHandlerLevel(Level level) 460 { 461 if (_handlerLevel.intValue() <= level.intValue()) 462 return; 463 464 _handlerLevel = level; 465 466 setEffectiveLevel(); 467 468 synchronized (this) { 469 for (int i = _children.size() - 1; i >= 0; i--) { 470 WeakReference <EnvironmentLogger> ref = _children.get(i); 471 EnvironmentLogger child = ref.get(); 472 473 if (child != null) { 474 if (_handlerLevel.intValue() < child._handlerLevel.intValue()) 476 child.setHandlerLevel(level); 477 } 478 else 479 _children.remove(i); 480 } 481 } 482 } 483 484 487 private synchronized void updateAssignedLevel() 488 { 489 Level oldAssignedLevel = _assignedLevel; 490 491 _assignedLevel = Level.INFO; 492 _hasLocalLevel = false; 493 494 if (_parent != null) { 495 _assignedLevel = _parent.getAssignedLevel(); 496 } 497 498 for (int i = _loaders.size() - 1; i >= 0; i--) { 499 WeakReference <ClassLoader > ref = _loaders.get(i); 500 ClassLoader loader = ref.get(); 501 502 if (loader == null) 503 _loaders.remove(i); 504 505 for (; loader != null; loader = loader.getParent()) { 506 if (loader instanceof EnvironmentClassLoader) { 507 EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader; 508 509 updateClassLoaderLevel(envLoader); 510 } 511 } 512 513 updateClassLoaderLevel(ClassLoader.getSystemClassLoader()); 514 } 515 516 setEffectiveLevel(); 517 518 if (oldAssignedLevel.intValue() != _assignedLevel.intValue()) { 521 for (int i = _children.size() - 1; i >= 0; i--) { 522 WeakReference <EnvironmentLogger> ref = _children.get(i); 523 EnvironmentLogger child = ref.get(); 524 525 if (child != null) 526 child.updateAssignedLevel(); 527 else 528 _children.remove(i); 529 } 530 } 531 } 532 533 private void updateClassLoaderLevel(ClassLoader loader) 534 { 535 Level localLevel = _localLevel.get(loader); 536 537 if (localLevel != null) { 538 if (! _hasLocalLevel) 539 _assignedLevel = localLevel; 540 else if (localLevel.intValue() < _assignedLevel.intValue()) 541 _assignedLevel = localLevel; 542 543 _hasLocalLevel = true; 544 } 545 } 546 547 550 private synchronized void updateHandlerLevel() 551 { 552 Level oldHandlerLevel = _handlerLevel; 553 554 _handlerLevel = Level.OFF; 555 556 if (_parent != null) 557 _handlerLevel = _parent.getHandlerLevel(); 558 559 for (int i = _loaders.size() - 1; i >= 0; i--) { 560 WeakReference <ClassLoader > ref = _loaders.get(i); 561 ClassLoader loader = ref.get(); 562 563 if (loader == null) 564 _loaders.remove(i); 565 566 for (; loader != null; loader = loader.getParent()) { 567 if (loader instanceof EnvironmentClassLoader) { 568 EnvironmentClassLoader envLoader = (EnvironmentClassLoader) loader; 569 570 Handler []handlers = _localHandlers.getLevel(envLoader); 571 572 for (int j = 0; handlers != null && j < handlers.length; j++) { 573 if (handlers[j].getLevel() != null) { 574 Level subLevel = handlers[j].getLevel(); 575 576 if (subLevel.intValue() < _handlerLevel.intValue()) 577 _handlerLevel = subLevel; 578 } 579 } 580 } 581 } 582 } 583 584 setEffectiveLevel(); 585 586 if (oldHandlerLevel.intValue() < _handlerLevel.intValue()) { 589 for (int i = _children.size() - 1; i >= 0; i--) { 590 WeakReference <EnvironmentLogger> ref = _children.get(i); 591 EnvironmentLogger child = ref.get(); 592 593 if (child != null) 594 child.updateHandlerLevel(); 595 else 596 _children.remove(i); 597 } 598 } 599 } 600 601 604 private void setEffectiveLevel() 605 { 606 if (_handlerLevel.intValue() < _assignedLevel.intValue()) 607 super.setLevel(_assignedLevel); 608 else 609 super.setLevel(_handlerLevel); 610 } 611 612 615 private synchronized void removeLoader(ClassLoader loader) 616 { 617 int i; 618 for (i = _loaders.size() - 1; i >= 0; i--) { 619 WeakReference <ClassLoader > ref = _loaders.get(i); 620 ClassLoader refLoader = ref.get(); 621 622 if (refLoader == null) 623 _loaders.remove(i); 624 else if (refLoader == loader) 625 _loaders.remove(i); 626 } 627 } 628 629 public String toString() 630 { 631 return "EnvironmentLogger[" + getName() + "]"; 632 } 633 634 638 static class HandlerEntry { 639 private final EnvironmentLogger _logger; 640 private ArrayList <Handler > _handlers = new ArrayList <Handler >(); 641 642 HandlerEntry(EnvironmentLogger logger) 643 { 644 _logger = logger; 645 } 646 647 void addHandler(Handler handler) 648 { 649 _handlers.add(handler); 650 } 651 652 void removeHandler(Handler handler) 653 { 654 _handlers.remove(handler); 655 } 656 657 void destroy() 658 { 659 ArrayList <Handler > handlers = _handlers; 660 _handlers = null; 661 662 for (int i = 0; handlers != null && i < handlers.size(); i++) { 663 Handler handler = handlers.get(i); 664 665 try { 666 handler.close(); 667 } catch (Throwable e) { 668 e.printStackTrace(); 669 } 670 } 671 } 672 } 673 } 674 | Popular Tags |