1 29 30 package com.caucho.jmx; 31 32 import com.caucho.loader.Environment; 33 import com.caucho.loader.WeakCloseListener; 34 import com.caucho.log.Log; 35 import com.caucho.util.L10N; 36 37 import javax.management.*; 38 import javax.management.loading.ClassLoaderRepository ; 39 import java.lang.ref.WeakReference ; 40 import java.util.ArrayList ; 41 import java.util.Hashtable ; 42 import java.util.LinkedHashMap ; 43 import java.util.Map ; 44 import java.util.logging.Level ; 45 import java.util.logging.Logger ; 46 47 50 public class MBeanContext { 51 private static final Logger log = Log.open(MBeanContext.class); 52 private static final L10N L = new L10N(MBeanContext.class); 53 54 private AbstractMBeanServer _mbeanServer; 56 57 private MBeanServerDelegate _delegate; 58 private long _seq; 59 60 private ClassLoader _loader; 62 63 private String _domain = "resin"; 64 private LinkedHashMap <String ,String > _properties = 65 new LinkedHashMap <String ,String >(); 66 67 private ClassLoaderRepositoryImpl _classLoaderRepository = 68 new ClassLoaderRepositoryImpl(); 69 70 private Hashtable <ObjectName,MBeanWrapper> _mbeans 72 = new Hashtable <ObjectName,MBeanWrapper>(); 73 74 private ArrayList <Listener> _listeners = new ArrayList <Listener>(); 75 76 private MBeanView _view; 78 private MBeanView _globalView; 80 81 MBeanContext(AbstractMBeanServer mbeanServer, 82 ClassLoader loader, 83 MBeanServerDelegate delegate) 84 { 85 _mbeanServer = mbeanServer; 86 _loader = loader; 87 _delegate = delegate; 88 89 Environment.addClassLoaderListener(new WeakCloseListener(this), _loader); 90 91 _classLoaderRepository.addClassLoader(_loader); 92 93 _view = new MBeanView(mbeanServer, _loader, "resin"); 94 _globalView = new MBeanView(mbeanServer, _loader, "resin"); 95 } 96 97 100 protected MBeanView getParentView() 101 { 102 return _mbeanServer.getParentView(); 103 } 104 105 108 public ClassLoaderRepository getClassLoaderRepository() 109 { 110 return _classLoaderRepository; 111 } 112 113 116 public ClassLoader getClassLoader() 117 { 118 return _loader; 119 } 120 121 124 MBeanView getView() 125 { 126 return _view; 127 } 128 129 132 MBeanView getGlobalView() 133 { 134 return _globalView; 135 } 136 137 140 public void setProperties(Map <String ,String > props) 141 { 142 _properties.clear(); 143 _properties.putAll(props); 144 } 145 146 149 public LinkedHashMap <String ,String > copyProperties() 150 { 151 return new LinkedHashMap <String ,String >(_properties); 152 } 153 154 157 public ObjectName getObjectName(String name) 158 throws MalformedObjectNameException 159 { 160 if (name.indexOf(':') < 0) { 161 LinkedHashMap <String ,String > properties; 162 properties = new LinkedHashMap <String ,String >(); 163 164 properties.putAll(_properties); 165 Jmx.parseProperties(properties, name); 166 167 return Jmx.getObjectName(_domain, properties); 168 } 169 else 170 return new ObjectName(name); 171 } 172 173 176 public MBeanWrapper getMBean(ObjectName name) 177 { 178 if (name != null) 179 return _mbeans.get(name); 180 else 181 return null; 182 } 183 184 192 ObjectInstance registerMBean(MBeanWrapper mbean, 193 ObjectName name) 194 throws InstanceAlreadyExistsException, 195 MBeanRegistrationException, 196 NotCompliantMBeanException 197 { 198 if (mbean == null) 199 throw new NotCompliantMBeanException(L.l("{0} is a null mbean", 200 name)); 201 if (_mbeans.get(name) != null) 202 throw new InstanceAlreadyExistsException(String.valueOf(name)); 203 204 Object object = mbean.getObject(); 205 206 MBeanRegistration registration = null; 207 208 if (object instanceof MBeanRegistration) 209 registration = (MBeanRegistration) object; 210 211 try { 212 if (registration != null) 213 name = registration.preRegister(_mbeanServer, name); 214 } catch (Exception e) { 215 throw new MBeanRegistrationException(e); 216 } 217 218 addMBean(name, mbean); 219 220 try { 221 if (registration != null) 222 registration.postRegister(new Boolean (true)); 223 } catch (Exception e) { 224 throw new MBeanRegistrationException(e); 225 } 226 227 return mbean.getObjectInstance(); 228 } 229 230 235 public void unregisterMBean(ObjectName name) 236 throws InstanceNotFoundException, 237 MBeanRegistrationException 238 { 239 if (_mbeans == null) { 240 removeMBean(name); 241 return; 242 } 243 244 if (name.getDomain().equals("JMImplementation")) 245 return; 246 247 MBeanWrapper mbean = _mbeans.get(name); 248 249 if (mbean == null) 250 throw new InstanceNotFoundException(String.valueOf(name)); 251 252 Object obj = mbean.getObject(); 253 MBeanRegistration registration = null; 254 255 if (obj instanceof MBeanRegistration) 256 registration = (MBeanRegistration) obj; 257 258 try { 259 if (registration != null) { 260 try { 261 registration.preDeregister(); 262 } catch (Throwable e) { 263 log.log(Level.WARNING, e.toString()); 264 } 265 } 266 267 removeMBean(name); 268 269 if (registration != null) { 270 try { 271 registration.postDeregister(); 272 } catch (Throwable e) { 273 log.log(Level.WARNING, e.toString()); 274 } 275 } 276 } catch (Exception e) { 277 throw new MBeanRegistrationException(e); 278 } 279 } 280 281 288 public ObjectInstance getObjectInstance(ObjectName name) 289 throws InstanceNotFoundException 290 { 291 MBeanWrapper mbean = getMBean(name); 292 293 if (mbean == null) 294 throw new InstanceNotFoundException(String.valueOf(name)); 295 296 return mbean.getObjectInstance(); 297 } 298 299 306 public boolean isRegistered(ObjectName name) 307 { 308 return _mbeans.get(name) != null; 309 } 310 311 316 public int getMBeanCount() 317 { 318 return _mbeans.size(); 319 } 320 321 324 private void addMBean(ObjectName name, MBeanWrapper mbean) 325 { 326 if (mbean == null) { 327 log.warning(L.l("'{0}' is an empty mbean", name)); 328 return; 329 } 330 331 log.fine(getDebugName(name, mbean) + " registered in " + this); 332 334 _mbeans.put(name, mbean); 335 336 _view.add(name, mbean, true); 337 _globalView.add(name, mbean, true); 338 339 sendRegisterNotification(name); 340 341 MBeanContext context = this; 342 while (context._loader != null) { 343 ClassLoader parentLoader = context._loader.getParent(); 344 345 MBeanContext parentContext = _mbeanServer.getContext(parentLoader); 346 347 if (parentContext == null || 348 parentContext == context) 349 break; 350 351 if (parentContext._globalView == null) { 352 log.finer("global view is empty"); 353 } 354 else if (parentContext._globalView.add(name, mbean, false)) 355 parentContext.sendRegisterNotification(name); 356 357 context = parentContext; 358 } 359 } 360 361 364 private MBeanWrapper removeMBean(ObjectName name) 365 { 366 MBeanWrapper mbean = null; 367 368 if (_mbeans != null) 369 mbean = _mbeans.remove(name); 370 371 if (_view != null) 372 _view.remove(name); 373 374 if (_globalView != null && _globalView.remove(name) != null) { 375 try { 376 sendUnregisterNotification(name); 377 } catch (Throwable e) { 378 log.log(Level.WARNING, e.toString(), e); 379 } 380 } 381 382 MBeanContext context = this; 383 while (true) { 384 ClassLoader parentLoader = context._loader.getParent(); 385 386 MBeanContext parentContext = _mbeanServer.getExistingContext(parentLoader); 387 388 if (parentContext == null || parentContext == context) { 389 break; 390 } 391 392 try { 393 if (parentContext._globalView == null) { 394 } 395 else if (mbean == null && 396 (mbean = parentContext._globalView.remove(name)) != null) 397 parentContext.sendUnregisterNotification(name); 398 else if (mbean != null && 399 parentContext._globalView.remove(name, mbean) != null) 400 parentContext.sendUnregisterNotification(name); 401 } catch (Throwable e) { 402 log.log(Level.WARNING, e.toString(), e); 403 } 404 405 context = parentContext; 406 } 407 408 return mbean; 409 } 410 411 419 void addNotificationListener(ObjectName name, 420 NotificationListener listener, 421 NotificationFilter filter, 422 Object handback) 423 { 424 synchronized (_listeners) { 425 _listeners.add(new Listener(name, listener, filter, handback)); 426 } 427 } 428 429 435 public void removeNotificationListener(ObjectName mbean, 436 NotificationListener listener) 437 { 438 synchronized (_listeners) { 439 for (int i = _listeners.size() - 1; i >= 0; i--) { 440 Listener oldListener = _listeners.get(i); 441 442 if (oldListener.match(mbean, listener)) 443 _listeners.remove(i); 444 } 445 } 446 } 447 448 456 public void removeNotificationListener(ObjectName mbean, 457 NotificationListener listener, 458 NotificationFilter filter, 459 Object handback) 460 { 461 synchronized (_listeners) { 462 for (int i = _listeners.size() - 1; i >= 0; i--) { 463 Listener oldListener = _listeners.get(i); 464 465 if (oldListener.match(mbean, listener, filter, handback)) 466 _listeners.remove(i); 467 } 468 } 469 } 470 471 474 void sendRegisterNotification(ObjectName name) 475 { 476 serverNotification(name, MBeanServerNotification.REGISTRATION_NOTIFICATION); 477 } 478 479 482 void sendUnregisterNotification(ObjectName name) 483 { 484 serverNotification(name, MBeanServerNotification.UNREGISTRATION_NOTIFICATION); 485 } 486 487 490 private void serverNotification(ObjectName name, String type) 491 { 492 MBeanServerNotification notif; 493 494 ObjectName delegateName = _mbeanServer.SERVER_DELEGATE_NAME; 495 496 notif = new MBeanServerNotification(type, delegateName, _seq++, name); 497 498 _delegate.sendNotification(notif); 499 } 500 501 504 public void destroy() 505 { 506 if (_mbeans == null) 507 return; 508 509 ArrayList <ObjectName> list = new ArrayList <ObjectName>(_mbeans.keySet()); 510 511 ArrayList <Listener> listeners = new ArrayList <Listener>(_listeners); 512 513 for (int i = 0; i < listeners.size(); i++) { 514 Listener listener = listeners.get(i); 515 516 try { 517 MBeanWrapper mbean = _globalView.getMBean(listener.getName()); 518 519 if (mbean != null) 520 mbean.removeNotificationListener(listener.getListener(), 521 listener.getFilter(), 522 listener.getHandback()); 523 } catch (Throwable e) { 524 log.log(Level.FINER, e.toString(), e); 525 } 526 } 527 528 for (int i = 0; i < list.size(); i++) { 529 ObjectName name = list.get(i); 530 531 try { 532 unregisterMBean(name); 533 } catch (Throwable e) { 534 log.log(Level.FINE, e.toString(), e); 535 } 536 } 537 538 _mbeanServer.removeContext(this, _loader); 539 540 _listeners = null; 541 _mbeans = null; 542 _view = null; 543 _globalView = null; 544 } 545 546 553 private String getDebugName(ObjectName name, MBeanWrapper mbean) 554 { 555 String className = mbean.getMBeanInfo().getClassName(); 556 557 int p = className.lastIndexOf('.'); 558 if (p > 0) 559 className = className.substring(p + 1); 560 561 return className + "[" + name + "]"; 562 } 563 564 567 public String toString() 568 { 569 return "MBeanContext[" + _loader + "]"; 570 } 571 572 575 584 585 588 static class Listener { 589 private ObjectName _name; 590 private WeakReference <NotificationListener> _listenerRef; 591 private WeakReference <NotificationFilter> _filterRef; 592 private WeakReference <Object > _handbackRef; 593 594 Listener(ObjectName name, 595 NotificationListener listener, 596 NotificationFilter filter, 597 Object handback) 598 { 599 _name = name; 600 _listenerRef = new WeakReference <NotificationListener>(listener); 601 602 if (filter != null) 603 _filterRef = new WeakReference <NotificationFilter>(filter); 604 605 if (handback != null) 606 _handbackRef = new WeakReference <Object >(handback); 607 } 608 609 ObjectName getName() 610 { 611 return _name; 612 } 613 614 NotificationListener getListener() 615 { 616 return _listenerRef.get(); 617 } 618 619 NotificationFilter getFilter() 620 { 621 return _filterRef != null ? _filterRef.get() : null; 622 } 623 624 Object getHandback() 625 { 626 return _handbackRef != null ? _handbackRef.get() : null; 627 } 628 629 boolean match(ObjectName name, 630 NotificationListener listener, 631 NotificationFilter filter, 632 Object handback) 633 { 634 if (! _name.equals(name)) 635 return false; 636 637 else if (listener != _listenerRef.get()) 638 return false; 639 640 else if (filter == null && _filterRef != null) 641 return false; 642 643 else if (_filterRef != null && _filterRef.get() != filter) 644 return false; 645 646 else if (handback == null && _handbackRef != null) 647 return false; 648 649 else if (_handbackRef != null && _handbackRef.get() != handback) 650 return false; 651 652 else 653 return true; 654 } 655 656 boolean match(ObjectName name, 657 NotificationListener listener) 658 { 659 if (! _name.equals(name)) 660 return false; 661 662 else if (listener != _listenerRef.get()) 663 return false; 664 665 else 666 return true; 667 } 668 } 669 } 670 671 | Popular Tags |